blob: 706d78c1ccfe88ca6354baa10919a903fa1e3265 [file] [log] [blame]
markchienf87ebdc2019-12-07 22:02:28 +08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.net.util;
17
Hungming Chend0216992020-05-08 17:50:53 +080018import android.net.TetherStatsParcel;
markchienf053e4b2020-03-16 21:49:48 +080019import android.net.TetheringRequestParcel;
Tyler Wear90e40632020-03-13 11:38:38 -070020import android.util.Log;
markchienf053e4b2020-03-16 21:49:48 +080021
Hungming Chend0216992020-05-08 17:50:53 +080022import androidx.annotation.NonNull;
23
Hungming Chenb350d752020-12-29 21:15:01 +080024import com.android.networkstack.tethering.TetherStatsValue;
25
markchienf87ebdc2019-12-07 22:02:28 +080026import java.io.FileDescriptor;
Tyler Wear90e40632020-03-13 11:38:38 -070027import java.net.Inet6Address;
markchienf87ebdc2019-12-07 22:02:28 +080028import java.net.SocketException;
Tyler Wear90e40632020-03-13 11:38:38 -070029import java.net.UnknownHostException;
30import java.util.Arrays;
markchienf053e4b2020-03-16 21:49:48 +080031import java.util.Objects;
markchienf87ebdc2019-12-07 22:02:28 +080032
33/**
Hungming Chend0216992020-05-08 17:50:53 +080034 * The classes and the methods for tethering utilization.
markchienf87ebdc2019-12-07 22:02:28 +080035 *
36 * {@hide}
37 */
38public class TetheringUtils {
Tyler Wear90e40632020-03-13 11:38:38 -070039 public static final byte[] ALL_NODES = new byte[] {
40 (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
41 };
42
43 /**
44 * Configures a socket for receiving and sending ICMPv6 neighbor advertisments.
45 * @param fd the socket's {@link FileDescriptor}.
46 */
47 public static native void setupNaSocket(FileDescriptor fd)
48 throws SocketException;
49
50 /**
51 * Configures a socket for receiving and sending ICMPv6 neighbor solicitations.
52 * @param fd the socket's {@link FileDescriptor}.
53 */
54 public static native void setupNsSocket(FileDescriptor fd)
55 throws SocketException;
56
markchienf87ebdc2019-12-07 22:02:28 +080057 /**
Hungming Chend0216992020-05-08 17:50:53 +080058 * The object which records offload Tx/Rx forwarded bytes/packets.
59 * TODO: Replace the inner class ForwardedStats of class OffloadHardwareInterface with
60 * this class as well.
61 */
62 public static class ForwardedStats {
63 public final long rxBytes;
64 public final long rxPackets;
65 public final long txBytes;
66 public final long txPackets;
67
68 public ForwardedStats() {
69 rxBytes = 0;
70 rxPackets = 0;
71 txBytes = 0;
72 txPackets = 0;
73 }
74
75 public ForwardedStats(long rxBytes, long txBytes) {
76 this.rxBytes = rxBytes;
77 this.rxPackets = 0;
78 this.txBytes = txBytes;
79 this.txPackets = 0;
80 }
81
82 public ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets) {
83 this.rxBytes = rxBytes;
84 this.rxPackets = rxPackets;
85 this.txBytes = txBytes;
86 this.txPackets = txPackets;
87 }
88
89 public ForwardedStats(@NonNull TetherStatsParcel tetherStats) {
90 rxBytes = tetherStats.rxBytes;
91 rxPackets = tetherStats.rxPackets;
92 txBytes = tetherStats.txBytes;
93 txPackets = tetherStats.txPackets;
94 }
95
Hungming Chenb350d752020-12-29 21:15:01 +080096 public ForwardedStats(@NonNull TetherStatsValue tetherStats) {
97 rxBytes = tetherStats.rxBytes;
98 rxPackets = tetherStats.rxPackets;
99 txBytes = tetherStats.txBytes;
100 txPackets = tetherStats.txPackets;
101 }
102
Hungming Chend0216992020-05-08 17:50:53 +0800103 public ForwardedStats(@NonNull ForwardedStats other) {
104 rxBytes = other.rxBytes;
105 rxPackets = other.rxPackets;
106 txBytes = other.txBytes;
107 txPackets = other.txPackets;
108 }
109
110 /** Add Tx/Rx bytes/packets and return the result as a new object. */
111 @NonNull
112 public ForwardedStats add(@NonNull ForwardedStats other) {
113 return new ForwardedStats(rxBytes + other.rxBytes, rxPackets + other.rxPackets,
114 txBytes + other.txBytes, txPackets + other.txPackets);
115 }
116
117 /** Subtract Tx/Rx bytes/packets and return the result as a new object. */
118 @NonNull
119 public ForwardedStats subtract(@NonNull ForwardedStats other) {
120 // TODO: Perhaps throw an exception if any negative difference value just in case.
121 final long rxBytesDiff = Math.max(rxBytes - other.rxBytes, 0);
122 final long rxPacketsDiff = Math.max(rxPackets - other.rxPackets, 0);
123 final long txBytesDiff = Math.max(txBytes - other.txBytes, 0);
124 final long txPacketsDiff = Math.max(txPackets - other.txPackets, 0);
125 return new ForwardedStats(rxBytesDiff, rxPacketsDiff, txBytesDiff, txPacketsDiff);
126 }
127
128 /** Returns the string representation of this object. */
129 @NonNull
130 public String toString() {
131 return String.format("ForwardedStats(rxb: %d, rxp: %d, txb: %d, txp: %d)", rxBytes,
132 rxPackets, txBytes, txPackets);
133 }
134 }
135
136 /**
markchienf87ebdc2019-12-07 22:02:28 +0800137 * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements.
138 * @param fd the socket's {@link FileDescriptor}.
139 * @param ifIndex the interface index.
140 */
141 public static native void setupRaSocket(FileDescriptor fd, int ifIndex)
142 throws SocketException;
markchien6cf0e552019-12-06 15:24:53 +0800143
144 /**
145 * Read s as an unsigned 16-bit integer.
146 */
147 public static int uint16(short s) {
148 return s & 0xffff;
149 }
markchienf053e4b2020-03-16 21:49:48 +0800150
151 /** Check whether two TetheringRequestParcels are the same. */
152 public static boolean isTetheringRequestEquals(final TetheringRequestParcel request,
153 final TetheringRequestParcel otherRequest) {
154 if (request == otherRequest) return true;
155
156 return request != null && otherRequest != null
157 && request.tetheringType == otherRequest.tetheringType
158 && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address)
159 && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress)
160 && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck
161 && request.showProvisioningUi == otherRequest.showProvisioningUi;
162 }
Tyler Wear90e40632020-03-13 11:38:38 -0700163
164 /** Get inet6 address for all nodes given scope ID. */
165 public static Inet6Address getAllNodesForScopeId(int scopeId) {
166 try {
167 return Inet6Address.getByAddress("ff02::1", ALL_NODES, scopeId);
168 } catch (UnknownHostException uhe) {
169 Log.wtf("TetheringUtils", "Failed to construct Inet6Address from "
170 + Arrays.toString(ALL_NODES) + " and scopedId " + scopeId);
171 return null;
172 }
173 }
markchienf87ebdc2019-12-07 22:02:28 +0800174}