Merge "[AWARE] Add data-path security configuration (PMK)"
This commit is contained in:
@@ -31,7 +31,7 @@ import java.lang.ref.WeakReference;
|
|||||||
* {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
|
* {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
|
||||||
* class provides functionality common to both publish and subscribe discovery sessions:
|
* class provides functionality common to both publish and subscribe discovery sessions:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])}.
|
* <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
|
||||||
* <li>Creating a network-specifier when requesting a Aware connection:
|
* <li>Creating a network-specifier when requesting a Aware connection:
|
||||||
* {@link #createNetworkSpecifier(PeerHandle, byte[])}.
|
* {@link #createNetworkSpecifier(PeerHandle, byte[])}.
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -247,8 +247,8 @@ public class DiscoverySession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
|
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
|
||||||
* WiFi Aware connection to the specified peer. The
|
* unencrypted WiFi Aware connection (link) to the specified peer. The
|
||||||
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
||||||
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -256,7 +256,58 @@ public class DiscoverySession {
|
|||||||
* discovery or communication (in such scenarios the MAC address of the peer is shielded by
|
* discovery or communication (in such scenarios the MAC address of the peer is shielded by
|
||||||
* an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
|
* an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
|
||||||
* OOB (out-of-band) mechanism then use the alternative
|
* OOB (out-of-band) mechanism then use the alternative
|
||||||
* {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} method - which uses the
|
* {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the
|
||||||
|
* peer's MAC address.
|
||||||
|
* <p>
|
||||||
|
* Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
|
||||||
|
* and a Publisher is a RESPONDER.
|
||||||
|
*
|
||||||
|
* @param peerHandle The peer's handle obtained through
|
||||||
|
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
|
||||||
|
* or
|
||||||
|
* {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
|
||||||
|
* On a RESPONDER this value is used to gate the acceptance of a connection
|
||||||
|
* request from only that peer. A RESPONDER may specify a null - indicating
|
||||||
|
* that it will accept connection requests from any device.
|
||||||
|
*
|
||||||
|
* @return A string to be used to construct
|
||||||
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
|
* [or other varieties of that API].
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public String createNetworkSpecifierOpen(@Nullable PeerHandle peerHandle) {
|
||||||
|
if (mTerminated) {
|
||||||
|
Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
WifiAwareManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int role = this instanceof SubscribeDiscoverySession
|
||||||
|
? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
||||||
|
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
|
||||||
|
|
||||||
|
return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
|
||||||
|
* encrypted WiFi Aware connection (link) to the specified peer. The
|
||||||
|
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
||||||
|
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
||||||
|
* <p>
|
||||||
|
* This method should be used when setting up a connection with a peer discovered through Aware
|
||||||
|
* discovery or communication (in such scenarios the MAC address of the peer is shielded by
|
||||||
|
* an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
|
||||||
|
* OOB (out-of-band) mechanism then use the alternative
|
||||||
|
* {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses the
|
||||||
* peer's MAC address.
|
* peer's MAC address.
|
||||||
* <p>
|
* <p>
|
||||||
* Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
|
* Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
|
||||||
@@ -267,29 +318,34 @@ public class DiscoverySession {
|
|||||||
* byte[], java.util.List)} or
|
* byte[], java.util.List)} or
|
||||||
* {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
|
* {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
|
||||||
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
|
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
|
||||||
* from only that peer. A RESPONDER may specified a null - indicating that
|
* from only that peer. A RESPONDER may specify a null - indicating that
|
||||||
* it will accept connection requests from any device.
|
* it will accept connection requests from any device.
|
||||||
* @param token An arbitrary token (message) to be used to match connection initiation request
|
* @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
|
||||||
* to a responder setup. A RESPONDER is set up with a {@code token} which must
|
* encrypting the data-path. Use the
|
||||||
* be matched by the token provided by the INITIATOR. A null token is permitted
|
* {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an open (unencrypted)
|
||||||
* on the RESPONDER and matches any peer token. An empty ({@code ""}) token is
|
* link.
|
||||||
* not the same as a null token and requires the peer token to be empty as well.
|
|
||||||
*
|
*
|
||||||
* @return A string to be used to construct
|
* @return A string to be used to construct
|
||||||
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
* android.net.ConnectivityManager.NetworkCallback)}
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
* [or other varieties of that API].
|
* [or other varieties of that API].
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
*/
|
*/
|
||||||
public String createNetworkSpecifier(@Nullable PeerHandle peerHandle,
|
public String createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
|
||||||
@Nullable byte[] token) {
|
@NonNull byte[] pmk) {
|
||||||
|
if (pmk == null || pmk.length == 0) {
|
||||||
|
throw new IllegalArgumentException("PMK must not be null or empty");
|
||||||
|
}
|
||||||
|
|
||||||
if (mTerminated) {
|
if (mTerminated) {
|
||||||
Log.w(TAG, "createNetworkSpecifier: called on terminated session");
|
Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session");
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
WifiAwareManager mgr = mMgr.get();
|
WifiAwareManager mgr = mMgr.get();
|
||||||
if (mgr == null) {
|
if (mgr == null) {
|
||||||
Log.w(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
|
Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +353,30 @@ public class DiscoverySession {
|
|||||||
? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
||||||
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
|
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
|
||||||
|
|
||||||
return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, token);
|
return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place-holder for {@code createNetworkSpecifierOpen(PeerHandle)}. Present to enable
|
||||||
|
* development of replacements CL without causing an API change. Will be removed when new
|
||||||
|
* APIs are exposed.
|
||||||
|
*
|
||||||
|
* @param peerHandle The peer's handle obtained through
|
||||||
|
* {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
|
||||||
|
* byte[], java.util.List)} or
|
||||||
|
* {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
|
||||||
|
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
|
||||||
|
* from only that peer. A RESPONDER may specify a null - indicating that
|
||||||
|
* it will accept connection requests from any device.
|
||||||
|
* @param token Deprecated and ignored.
|
||||||
|
* @return A string to be used to construct
|
||||||
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
|
* [or other varieties of that API].
|
||||||
|
*/
|
||||||
|
public String createNetworkSpecifier(@Nullable PeerHandle peerHandle, @Nullable byte[] token) {
|
||||||
|
return createNetworkSpecifierOpen(peerHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,55 +130,34 @@ public class WifiAwareManager {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TYPE_1A: role, client_id, session_id, peer_id, token
|
* TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk optional
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_1A = 0;
|
public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TYPE_1B: role, client_id, session_id, peer_id [only permitted for RESPONDER]
|
* TYPE: in band, any peer: role, client_id, session_id, pmk optional
|
||||||
|
* [only permitted for RESPONDER]
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_1B = 1;
|
public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TYPE_1C: role, client_id, session_id, token [only permitted for RESPONDER]
|
* TYPE: out-of-band: role, client_id, peer_mac, pmk optional
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_1C = 2;
|
public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TYPE_1C: role, client_id, session_id [only permitted for RESPONDER]
|
* TYPE: out-of-band, any peer: role, client_id, pmk optional
|
||||||
|
* [only permitted for RESPONDER]
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_1D = 3;
|
public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
|
||||||
|
|
||||||
/**
|
|
||||||
* TYPE_2A: role, client_id, peer_mac, token
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_2A = 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TYPE_2B: role, client_id, peer_mac [only permitted for RESPONDER]
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_2B = 5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TYPE_2C: role, client_id, token [only permitted for RESPONDER]
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_2C = 6;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TYPE_2D: role, client_id [only permitted for RESPONDER]
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_2D = 7;
|
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_2D;
|
public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final String NETWORK_SPECIFIER_KEY_TYPE = "type";
|
public static final String NETWORK_SPECIFIER_KEY_TYPE = "type";
|
||||||
@@ -199,7 +178,7 @@ public class WifiAwareManager {
|
|||||||
public static final String NETWORK_SPECIFIER_KEY_PEER_MAC = "peer_mac";
|
public static final String NETWORK_SPECIFIER_KEY_PEER_MAC = "peer_mac";
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final String NETWORK_SPECIFIER_KEY_TOKEN = "token";
|
public static final String NETWORK_SPECIFIER_KEY_PMK = "pmk";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
|
* Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
|
||||||
@@ -494,23 +473,15 @@ public class WifiAwareManager {
|
|||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public String createNetworkSpecifier(int clientId, int role, int sessionId,
|
public String createNetworkSpecifier(int clientId, int role, int sessionId,
|
||||||
PeerHandle peerHandle, byte[] token) {
|
PeerHandle peerHandle, @Nullable byte[] pmk) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
|
Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
|
||||||
+ ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
|
+ ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
|
||||||
+ ", token=" + token);
|
+ ", pmk=" + ((pmk == null) ? "null" : "non-null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int type;
|
int type = (peerHandle == null) ? NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
|
||||||
if (token != null && peerHandle != null) {
|
: NETWORK_SPECIFIER_TYPE_IB;
|
||||||
type = NETWORK_SPECIFIER_TYPE_1A;
|
|
||||||
} else if (token == null && peerHandle != null) {
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_1B;
|
|
||||||
} else if (token != null && peerHandle == null) {
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_1C;
|
|
||||||
} else {
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_1D;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
||||||
&& role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
|
&& role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
|
||||||
@@ -519,10 +490,6 @@ public class WifiAwareManager {
|
|||||||
+ "specifier");
|
+ "specifier");
|
||||||
}
|
}
|
||||||
if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
|
if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
|
||||||
if (token == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"createNetworkSpecifier: Invalid null token - not permitted on INITIATOR");
|
|
||||||
}
|
|
||||||
if (peerHandle == null) {
|
if (peerHandle == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"createNetworkSpecifier: Invalid peer handle (value of null) - not "
|
"createNetworkSpecifier: Invalid peer handle (value of null) - not "
|
||||||
@@ -540,10 +507,11 @@ public class WifiAwareManager {
|
|||||||
if (peerHandle != null) {
|
if (peerHandle != null) {
|
||||||
json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId);
|
json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId);
|
||||||
}
|
}
|
||||||
if (token != null) {
|
if (pmk == null) {
|
||||||
json.put(NETWORK_SPECIFIER_KEY_TOKEN,
|
pmk = new byte[0];
|
||||||
Base64.encodeToString(token, 0, token.length, Base64.DEFAULT));
|
|
||||||
}
|
}
|
||||||
|
json.put(NETWORK_SPECIFIER_KEY_PMK,
|
||||||
|
Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -553,21 +521,14 @@ public class WifiAwareManager {
|
|||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public String createNetworkSpecifier(int clientId, @DataPathRole int role,
|
public String createNetworkSpecifier(int clientId, @DataPathRole int role,
|
||||||
@Nullable byte[] peer, @Nullable byte[] token) {
|
@Nullable byte[] peer, @Nullable byte[] pmk) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.v(TAG, "createNetworkSpecifier: role=" + role + ", token=" + token);
|
Log.v(TAG, "createNetworkSpecifier: role=" + role
|
||||||
|
+ ", pmk=" + ((pmk == null) ? "null" : "non-null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int type;
|
int type = (peer == null) ?
|
||||||
if (token != null && peer != null) {
|
NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER : NETWORK_SPECIFIER_TYPE_OOB;
|
||||||
type = NETWORK_SPECIFIER_TYPE_2A;
|
|
||||||
} else if (token == null && peer != null) {
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_2B;
|
|
||||||
} else if (token != null && peer == null) {
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_2C;
|
|
||||||
} else { // both are null
|
|
||||||
type = NETWORK_SPECIFIER_TYPE_2D;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
|
||||||
&& role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
|
&& role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
|
||||||
@@ -576,19 +537,13 @@ public class WifiAwareManager {
|
|||||||
+ "specifier");
|
+ "specifier");
|
||||||
}
|
}
|
||||||
if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
|
if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
|
||||||
if (peer == null || peer.length != 6) {
|
if (peer == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC "
|
||||||
"createNetworkSpecifier: Invalid peer MAC address");
|
+ "address - null not permitted on INITIATOR");
|
||||||
}
|
}
|
||||||
if (token == null) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"createNetworkSpecifier: Invalid null token - not permitted on INITIATOR");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (peer != null && peer.length != 6) {
|
if (peer != null && peer.length != 6) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
|
||||||
"createNetworkSpecifier: Invalid peer MAC address");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject json;
|
JSONObject json;
|
||||||
@@ -600,10 +555,11 @@ public class WifiAwareManager {
|
|||||||
if (peer != null) {
|
if (peer != null) {
|
||||||
json.put(NETWORK_SPECIFIER_KEY_PEER_MAC, new String(HexEncoding.encode(peer)));
|
json.put(NETWORK_SPECIFIER_KEY_PEER_MAC, new String(HexEncoding.encode(peer)));
|
||||||
}
|
}
|
||||||
if (token != null) {
|
if (pmk == null) {
|
||||||
json.put(NETWORK_SPECIFIER_KEY_TOKEN,
|
pmk = new byte[0];
|
||||||
Base64.encodeToString(token, 0, token.length, Base64.DEFAULT));
|
|
||||||
}
|
}
|
||||||
|
json.put(NETWORK_SPECIFIER_KEY_PMK,
|
||||||
|
Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,47 +183,114 @@ public class WifiAwareSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
|
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
|
||||||
* WiFi Aware connection to the specified peer. The
|
* unencrypted WiFi Aware connection (link) to the specified peer. The
|
||||||
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
||||||
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
||||||
* <p>
|
* <p>
|
||||||
* This API is targeted for applications which can obtain the peer MAC address using OOB
|
* This API is targeted for applications which can obtain the peer MAC address using OOB
|
||||||
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
|
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
|
||||||
* when using Aware discovery use the alternative network specifier method -
|
* when using Aware discovery use the alternative network specifier method -
|
||||||
* {@link DiscoverySession#createNetworkSpecifier(PeerHandle,
|
* {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)}.
|
||||||
* byte[])}.
|
|
||||||
*
|
*
|
||||||
* @param role The role of this device:
|
* @param role The role of this device:
|
||||||
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
|
||||||
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
|
||||||
* @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
|
* @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
|
||||||
* value is used to gate the acceptance of a connection request from only that
|
* value is used to gate the acceptance of a connection request from only that
|
||||||
* peer. A RESPONDER may specified a null - indicating that it will accept
|
* peer. A RESPONDER may specify a null - indicating that it will accept
|
||||||
* connection requests from any device.
|
* connection requests from any device.
|
||||||
* @param token An arbitrary token (message) to be used to match connection initiation request
|
|
||||||
* to a responder setup. A RESPONDER is set up with a {@code token} which must
|
|
||||||
* be matched by the token provided by the INITIATOR. A null token is permitted
|
|
||||||
* on the RESPONDER and matches any peer token. An empty ({@code ""}) token is
|
|
||||||
* not the same as a null token and requires the peer token to be empty as well.
|
|
||||||
*
|
*
|
||||||
* @return A string to be used to construct
|
* @return A string to be used to construct
|
||||||
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
* android.net.ConnectivityManager.NetworkCallback)}
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
* [or other varieties of that API].
|
* [or other varieties of that API].
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public String createNetworkSpecifierOpen(@WifiAwareManager.DataPathRole int role,
|
||||||
|
@Nullable byte[] peer) {
|
||||||
|
WifiAwareManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.e(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (mTerminated) {
|
||||||
|
Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return mgr.createNetworkSpecifier(mClientId, role, peer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
|
||||||
|
* encrypted WiFi Aware connection (link) to the specified peer. The
|
||||||
|
* {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
|
||||||
|
* {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
|
||||||
|
* <p>
|
||||||
|
* This API is targeted for applications which can obtain the peer MAC address using OOB
|
||||||
|
* (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
|
||||||
|
* when using Aware discovery use the alternative network specifier method -
|
||||||
|
* {@link DiscoverySession#createNetworkSpecifierPmk(PeerHandle, byte[])}}.
|
||||||
|
*
|
||||||
|
* @param role The role of this device:
|
||||||
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
|
||||||
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
|
||||||
|
* @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
|
||||||
|
* value is used to gate the acceptance of a connection request from only that
|
||||||
|
* peer. A RESPONDER may specify a null - indicating that it will accept
|
||||||
|
* connection requests from any device.
|
||||||
|
* @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
|
||||||
|
* encrypting the data-path. Use the {@link #createNetworkSpecifierOpen(int, byte[])}
|
||||||
|
* to specify an open (unencrypted) link.
|
||||||
|
*
|
||||||
|
* @return A string to be used to construct
|
||||||
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
|
* [or other varieties of that API].
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public String createNetworkSpecifierPmk(@WifiAwareManager.DataPathRole int role,
|
||||||
|
@Nullable byte[] peer, @NonNull byte[] pmk) {
|
||||||
|
WifiAwareManager mgr = mMgr.get();
|
||||||
|
if (mgr == null) {
|
||||||
|
Log.e(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (mTerminated) {
|
||||||
|
Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (pmk == null || pmk.length == 0) {
|
||||||
|
throw new IllegalArgumentException("PMK must not be null or empty");
|
||||||
|
}
|
||||||
|
return mgr.createNetworkSpecifier(mClientId, role, peer, pmk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place-holder for {@code #createNetworkSpecifierOpen(int, byte[])}. Present to enable
|
||||||
|
* development of replacements CL without causing an API change. Will be removed when new
|
||||||
|
* APIs are exposed.
|
||||||
|
*
|
||||||
|
* @param role The role of this device:
|
||||||
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
|
||||||
|
* {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
|
||||||
|
* @param peer The MAC address of the peer's Aware discovery interface. On a RESPONDER this
|
||||||
|
* value is used to gate the acceptance of a connection request from only that
|
||||||
|
* peer. A RESPONDER may specify a null - indicating that it will accept
|
||||||
|
* connection requests from any device.
|
||||||
|
* @param token Deprecated and ignored.
|
||||||
|
* @return A string to be used to construct
|
||||||
|
* {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
|
||||||
|
* {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
|
||||||
|
* android.net.ConnectivityManager.NetworkCallback)}
|
||||||
|
* [or other varieties of that API].
|
||||||
*/
|
*/
|
||||||
public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
|
public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
|
||||||
@Nullable byte[] peer, @Nullable byte[] token) {
|
@Nullable byte[] peer, @Nullable byte[] token) {
|
||||||
WifiAwareManager mgr = mMgr.get();
|
return createNetworkSpecifierOpen(role, peer);
|
||||||
if (mgr == null) {
|
|
||||||
Log.e(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (mTerminated) {
|
|
||||||
Log.e(TAG, "createNetworkSpecifier: called after termination");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return mgr.createNetworkSpecifier(mClientId, role, peer, token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -973,11 +973,11 @@ public class WifiAwareManagerTest {
|
|||||||
final int sessionId = 123;
|
final int sessionId = 123;
|
||||||
final PeerHandle peerHandle = new PeerHandle(123412);
|
final PeerHandle peerHandle = new PeerHandle(123412);
|
||||||
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
|
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
|
||||||
final String token = "Some arbitrary token string - can really be anything";
|
final byte[] pmk = "Some arbitrary byte array".getBytes();
|
||||||
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
|
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
|
||||||
final PublishConfig publishConfig = new PublishConfig.Builder().build();
|
final PublishConfig publishConfig = new PublishConfig.Builder().build();
|
||||||
|
|
||||||
String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
|
String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
|
||||||
|
|
||||||
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
|
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
|
||||||
WifiAwareSession.class);
|
WifiAwareSession.class);
|
||||||
@@ -1008,9 +1008,8 @@ public class WifiAwareManagerTest {
|
|||||||
mMockLooper.dispatchAll();
|
mMockLooper.dispatchAll();
|
||||||
inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
|
inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
|
||||||
|
|
||||||
// (3) request a network specifier from the session
|
// (3) request an open (unencrypted) network specifier from the session
|
||||||
String networkSpecifier = publishSession.getValue().createNetworkSpecifier(peerHandle,
|
String networkSpecifier = publishSession.getValue().createNetworkSpecifierOpen(peerHandle);
|
||||||
token.getBytes());
|
|
||||||
|
|
||||||
// validate format
|
// validate format
|
||||||
JSONObject jsonObject = new JSONObject(networkSpecifier);
|
JSONObject jsonObject = new JSONObject(networkSpecifier);
|
||||||
@@ -1022,8 +1021,22 @@ public class WifiAwareManagerTest {
|
|||||||
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
|
||||||
collector.checkThat("peer_id", peerHandle.peerId,
|
collector.checkThat("peer_id", peerHandle.peerId,
|
||||||
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
|
||||||
collector.checkThat("token", tokenB64,
|
|
||||||
equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_TOKEN)));
|
// (4) request an encrypted (PMK) network specifier from the session
|
||||||
|
networkSpecifier = publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
|
||||||
|
|
||||||
|
// validate format
|
||||||
|
jsonObject = new JSONObject(networkSpecifier);
|
||||||
|
collector.checkThat("role", role,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
|
||||||
|
collector.checkThat("client_id", clientId,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
|
||||||
|
collector.checkThat("session_id", sessionId,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
|
||||||
|
collector.checkThat("peer_id", peerHandle.peerId,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
|
||||||
|
collector.checkThat("pmk", pmkB64 ,
|
||||||
|
equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
|
||||||
|
|
||||||
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
|
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
|
||||||
mockPublishSession, mockRttListener);
|
mockPublishSession, mockRttListener);
|
||||||
@@ -1039,9 +1052,9 @@ public class WifiAwareManagerTest {
|
|||||||
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
|
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
|
||||||
final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
|
final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
|
||||||
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
|
final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
|
||||||
final String token = "Some arbitrary token string - can really be anything";
|
final byte[] pmk = "Some arbitrary pmk data".getBytes();
|
||||||
|
|
||||||
String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
|
String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
|
||||||
|
|
||||||
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
|
ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
|
||||||
WifiAwareSession.class);
|
WifiAwareSession.class);
|
||||||
@@ -1060,10 +1073,10 @@ public class WifiAwareManagerTest {
|
|||||||
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
|
inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
|
||||||
WifiAwareSession session = sessionCaptor.getValue();
|
WifiAwareSession session = sessionCaptor.getValue();
|
||||||
|
|
||||||
/* (2) request a direct network specifier*/
|
// (2) request an open (unencrypted) direct network specifier
|
||||||
String networkSpecifier = session.createNetworkSpecifier(role, someMac, token.getBytes());
|
String networkSpecifier = session.createNetworkSpecifierOpen(role, someMac);
|
||||||
|
|
||||||
/* validate format*/
|
// validate format
|
||||||
JSONObject jsonObject = new JSONObject(networkSpecifier);
|
JSONObject jsonObject = new JSONObject(networkSpecifier);
|
||||||
collector.checkThat("role", role,
|
collector.checkThat("role", role,
|
||||||
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
|
||||||
@@ -1072,8 +1085,21 @@ public class WifiAwareManagerTest {
|
|||||||
collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
|
collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
|
||||||
jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
|
jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
|
||||||
false)));
|
false)));
|
||||||
collector.checkThat("token", tokenB64,
|
|
||||||
equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_TOKEN)));
|
// (3) request an encrypted (PMK) direct network specifier
|
||||||
|
networkSpecifier = session.createNetworkSpecifierPmk(role, someMac, pmk);
|
||||||
|
|
||||||
|
// validate format
|
||||||
|
jsonObject = new JSONObject(networkSpecifier);
|
||||||
|
collector.checkThat("role", role,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
|
||||||
|
collector.checkThat("client_id", clientId,
|
||||||
|
equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
|
||||||
|
collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
|
||||||
|
jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
|
||||||
|
false)));
|
||||||
|
collector.checkThat("pmk", pmkB64,
|
||||||
|
equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
|
||||||
|
|
||||||
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
|
verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
|
||||||
mockPublishSession, mockRttListener);
|
mockPublishSession, mockRttListener);
|
||||||
|
|||||||
Reference in New Issue
Block a user