blob: 53b54f7de05dea34d9dca0b45a1e3bc6031d0b6a [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
markchienf87ebdc2019-12-07 22:02:28 +080024import java.io.FileDescriptor;
Tyler Wear90e40632020-03-13 11:38:38 -070025import java.net.Inet6Address;
markchienf87ebdc2019-12-07 22:02:28 +080026import java.net.SocketException;
Tyler Wear90e40632020-03-13 11:38:38 -070027import java.net.UnknownHostException;
28import java.util.Arrays;
markchienf053e4b2020-03-16 21:49:48 +080029import java.util.Objects;
markchienf87ebdc2019-12-07 22:02:28 +080030
31/**
Hungming Chend0216992020-05-08 17:50:53 +080032 * The classes and the methods for tethering utilization.
markchienf87ebdc2019-12-07 22:02:28 +080033 *
34 * {@hide}
35 */
36public class TetheringUtils {
Tyler Wear90e40632020-03-13 11:38:38 -070037 public static final byte[] ALL_NODES = new byte[] {
38 (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
39 };
40
41 /**
42 * Configures a socket for receiving and sending ICMPv6 neighbor advertisments.
43 * @param fd the socket's {@link FileDescriptor}.
44 */
45 public static native void setupNaSocket(FileDescriptor fd)
46 throws SocketException;
47
48 /**
49 * Configures a socket for receiving and sending ICMPv6 neighbor solicitations.
50 * @param fd the socket's {@link FileDescriptor}.
51 */
52 public static native void setupNsSocket(FileDescriptor fd)
53 throws SocketException;
54
markchienf87ebdc2019-12-07 22:02:28 +080055 /**
Hungming Chend0216992020-05-08 17:50:53 +080056 * The object which records offload Tx/Rx forwarded bytes/packets.
57 * TODO: Replace the inner class ForwardedStats of class OffloadHardwareInterface with
58 * this class as well.
59 */
60 public static class ForwardedStats {
61 public final long rxBytes;
62 public final long rxPackets;
63 public final long txBytes;
64 public final long txPackets;
65
66 public ForwardedStats() {
67 rxBytes = 0;
68 rxPackets = 0;
69 txBytes = 0;
70 txPackets = 0;
71 }
72
73 public ForwardedStats(long rxBytes, long txBytes) {
74 this.rxBytes = rxBytes;
75 this.rxPackets = 0;
76 this.txBytes = txBytes;
77 this.txPackets = 0;
78 }
79
80 public ForwardedStats(long rxBytes, long rxPackets, long txBytes, long txPackets) {
81 this.rxBytes = rxBytes;
82 this.rxPackets = rxPackets;
83 this.txBytes = txBytes;
84 this.txPackets = txPackets;
85 }
86
87 public ForwardedStats(@NonNull TetherStatsParcel tetherStats) {
88 rxBytes = tetherStats.rxBytes;
89 rxPackets = tetherStats.rxPackets;
90 txBytes = tetherStats.txBytes;
91 txPackets = tetherStats.txPackets;
92 }
93
94 public ForwardedStats(@NonNull ForwardedStats other) {
95 rxBytes = other.rxBytes;
96 rxPackets = other.rxPackets;
97 txBytes = other.txBytes;
98 txPackets = other.txPackets;
99 }
100
101 /** Add Tx/Rx bytes/packets and return the result as a new object. */
102 @NonNull
103 public ForwardedStats add(@NonNull ForwardedStats other) {
104 return new ForwardedStats(rxBytes + other.rxBytes, rxPackets + other.rxPackets,
105 txBytes + other.txBytes, txPackets + other.txPackets);
106 }
107
108 /** Subtract Tx/Rx bytes/packets and return the result as a new object. */
109 @NonNull
110 public ForwardedStats subtract(@NonNull ForwardedStats other) {
111 // TODO: Perhaps throw an exception if any negative difference value just in case.
112 final long rxBytesDiff = Math.max(rxBytes - other.rxBytes, 0);
113 final long rxPacketsDiff = Math.max(rxPackets - other.rxPackets, 0);
114 final long txBytesDiff = Math.max(txBytes - other.txBytes, 0);
115 final long txPacketsDiff = Math.max(txPackets - other.txPackets, 0);
116 return new ForwardedStats(rxBytesDiff, rxPacketsDiff, txBytesDiff, txPacketsDiff);
117 }
118
119 /** Returns the string representation of this object. */
120 @NonNull
121 public String toString() {
122 return String.format("ForwardedStats(rxb: %d, rxp: %d, txb: %d, txp: %d)", rxBytes,
123 rxPackets, txBytes, txPackets);
124 }
125 }
126
127 /**
markchienf87ebdc2019-12-07 22:02:28 +0800128 * Configures a socket for receiving ICMPv6 router solicitations and sending advertisements.
129 * @param fd the socket's {@link FileDescriptor}.
130 * @param ifIndex the interface index.
131 */
132 public static native void setupRaSocket(FileDescriptor fd, int ifIndex)
133 throws SocketException;
markchien6cf0e552019-12-06 15:24:53 +0800134
135 /**
136 * Read s as an unsigned 16-bit integer.
137 */
138 public static int uint16(short s) {
139 return s & 0xffff;
140 }
markchienf053e4b2020-03-16 21:49:48 +0800141
142 /** Check whether two TetheringRequestParcels are the same. */
143 public static boolean isTetheringRequestEquals(final TetheringRequestParcel request,
144 final TetheringRequestParcel otherRequest) {
145 if (request == otherRequest) return true;
146
147 return request != null && otherRequest != null
148 && request.tetheringType == otherRequest.tetheringType
149 && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address)
150 && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress)
151 && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck
152 && request.showProvisioningUi == otherRequest.showProvisioningUi;
153 }
Tyler Wear90e40632020-03-13 11:38:38 -0700154
155 /** Get inet6 address for all nodes given scope ID. */
156 public static Inet6Address getAllNodesForScopeId(int scopeId) {
157 try {
158 return Inet6Address.getByAddress("ff02::1", ALL_NODES, scopeId);
159 } catch (UnknownHostException uhe) {
160 Log.wtf("TetheringUtils", "Failed to construct Inet6Address from "
161 + Arrays.toString(ALL_NODES) + " and scopedId " + scopeId);
162 return null;
163 }
164 }
markchienf87ebdc2019-12-07 22:02:28 +0800165}