1 /* 2 * Copyright (C) 2017 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 */ 16 17 package android.net.wifi.aware; 18 19 import android.net.NetworkSpecifier; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.util.Log; 23 24 import java.util.Arrays; 25 import java.util.Objects; 26 27 /** 28 * Network specifier object used to request a Wi-Fi Aware network. Apps do not create these objects 29 * directly but obtain them using 30 * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or 31 * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or their secure (Passphrase) 32 * versions. 33 * 34 * @hide 35 */ 36 public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable { 37 /** 38 * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk/passphrase optional 39 * @hide 40 */ 41 public static final int NETWORK_SPECIFIER_TYPE_IB = 0; 42 43 /** 44 * TYPE: in band, any peer: role, client_id, session_id, pmk/passphrase optional 45 * [only permitted for RESPONDER] 46 * @hide 47 */ 48 public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1; 49 50 /** 51 * TYPE: out-of-band: role, client_id, peer_mac, pmk/passphrase optional 52 * @hide 53 */ 54 public static final int NETWORK_SPECIFIER_TYPE_OOB = 2; 55 56 /** 57 * TYPE: out-of-band, any peer: role, client_id, pmk/passphrase optional 58 * [only permitted for RESPONDER] 59 * @hide 60 */ 61 public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3; 62 63 /** @hide */ 64 public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER; 65 66 /** 67 * One of the NETWORK_SPECIFIER_TYPE_* constants. The type of the network specifier object. 68 * @hide 69 */ 70 public final int type; 71 72 /** 73 * The role of the device: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR or 74 * WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER. 75 * @hide 76 */ 77 public final int role; 78 79 /** 80 * The client ID of the device. 81 * @hide 82 */ 83 public final int clientId; 84 85 /** 86 * The session ID in which context to request a data-path. Only relevant for IB requests. 87 * @hide 88 */ 89 public final int sessionId; 90 91 /** 92 * The peer ID of the device which the data-path should be connected to. Only relevant for 93 * IB requests (i.e. not IB_ANY_PEER or OOB*). 94 * @hide 95 */ 96 public final int peerId; 97 98 /** 99 * The peer MAC address of the device which the data-path should be connected to. Only relevant 100 * for OB requests (i.e. not OOB_ANY_PEER or IB*). 101 * @hide 102 */ 103 public final byte[] peerMac; 104 105 /** 106 * The PMK of the requested data-path. Can be null. Only one or none of pmk or passphrase should 107 * be specified. 108 * @hide 109 */ 110 public final byte[] pmk; 111 112 /** 113 * The Passphrase of the requested data-path. Can be null. Only one or none of the pmk or 114 * passphrase should be specified. 115 * @hide 116 */ 117 public final String passphrase; 118 119 /** 120 * The UID of the process initializing this network specifier. Validated by receiver using 121 * checkUidIfNecessary() and is used by satisfiedBy() to determine whether matches the 122 * offered network. 123 * 124 * @hide 125 */ 126 public final int requestorUid; 127 128 /** @hide */ 129 public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId, 130 byte[] peerMac, byte[] pmk, String passphrase, int requestorUid) { 131 this.type = type; 132 this.role = role; 133 this.clientId = clientId; 134 this.sessionId = sessionId; 135 this.peerId = peerId; 136 this.peerMac = peerMac; 137 this.pmk = pmk; 138 this.passphrase = passphrase; 139 this.requestorUid = requestorUid; 140 } 141 142 public static final Creator<WifiAwareNetworkSpecifier> CREATOR = 143 new Creator<WifiAwareNetworkSpecifier>() { 144 @Override 145 public WifiAwareNetworkSpecifier createFromParcel(Parcel in) { 146 return new WifiAwareNetworkSpecifier( 147 in.readInt(), // type 148 in.readInt(), // role 149 in.readInt(), // clientId 150 in.readInt(), // sessionId 151 in.readInt(), // peerId 152 in.createByteArray(), // peerMac 153 in.createByteArray(), // pmk 154 in.readString(), // passphrase 155 in.readInt()); // requestorUid 156 } 157 158 @Override 159 public WifiAwareNetworkSpecifier[] newArray(int size) { 160 return new WifiAwareNetworkSpecifier[size]; 161 } 162 }; 163 164 /** 165 * Indicates whether the network specifier specifies an OOB (out-of-band) data-path - i.e. a 166 * data-path created without a corresponding Aware discovery session. 167 * 168 * @hide 169 */ 170 public boolean isOutOfBand() { 171 return type == NETWORK_SPECIFIER_TYPE_OOB || type == NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER; 172 } 173 174 @Override 175 public int describeContents() { 176 return 0; 177 } 178 179 @Override 180 public void writeToParcel(Parcel dest, int flags) { 181 dest.writeInt(type); 182 dest.writeInt(role); 183 dest.writeInt(clientId); 184 dest.writeInt(sessionId); 185 dest.writeInt(peerId); 186 dest.writeByteArray(peerMac); 187 dest.writeByteArray(pmk); 188 dest.writeString(passphrase); 189 dest.writeInt(requestorUid); 190 } 191 192 /** @hide */ 193 @Override 194 public boolean satisfiedBy(NetworkSpecifier other) { 195 // MatchAllNetworkSpecifier is taken care in NetworkCapabilities#satisfiedBySpecifier. 196 if (other instanceof WifiAwareAgentNetworkSpecifier) { 197 return ((WifiAwareAgentNetworkSpecifier) other).satisfiesAwareNetworkSpecifier(this); 198 } 199 return equals(other); 200 } 201 202 /** @hide */ 203 @Override 204 public int hashCode() { 205 int result = 17; 206 207 result = 31 * result + type; 208 result = 31 * result + role; 209 result = 31 * result + clientId; 210 result = 31 * result + sessionId; 211 result = 31 * result + peerId; 212 result = 31 * result + Arrays.hashCode(peerMac); 213 result = 31 * result + Arrays.hashCode(pmk); 214 result = 31 * result + Objects.hashCode(passphrase); 215 result = 31 * result + requestorUid; 216 217 return result; 218 } 219 220 /** @hide */ 221 @Override 222 public boolean equals(Object obj) { 223 if (this == obj) { 224 return true; 225 } 226 227 if (!(obj instanceof WifiAwareNetworkSpecifier)) { 228 return false; 229 } 230 231 WifiAwareNetworkSpecifier lhs = (WifiAwareNetworkSpecifier) obj; 232 233 return type == lhs.type 234 && role == lhs.role 235 && clientId == lhs.clientId 236 && sessionId == lhs.sessionId 237 && peerId == lhs.peerId 238 && Arrays.equals(peerMac, lhs.peerMac) 239 && Arrays.equals(pmk, lhs.pmk) 240 && Objects.equals(passphrase, lhs.passphrase) 241 && requestorUid == lhs.requestorUid; 242 } 243 244 /** @hide */ 245 @Override 246 public String toString() { 247 StringBuilder sb = new StringBuilder("WifiAwareNetworkSpecifier ["); 248 sb.append("type=").append(type) 249 .append(", role=").append(role) 250 .append(", clientId=").append(clientId) 251 .append(", sessionId=").append(sessionId) 252 .append(", peerId=").append(peerId) 253 // masking potential PII (although low impact information) 254 .append(", peerMac=").append((peerMac == null) ? "<null>" : "<non-null>") 255 // masking PII 256 .append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>") 257 // masking PII 258 .append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>") 259 .append(", requestorUid=").append(requestorUid) 260 .append("]"); 261 return sb.toString(); 262 } 263 264 /** @hide */ 265 @Override 266 public void assertValidFromUid(int requestorUid) { 267 if (this.requestorUid != requestorUid) { 268 throw new SecurityException("mismatched UIDs"); 269 } 270 } 271 } 272