Merge "p2p fixes"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5fa47298af
@@ -560,18 +560,12 @@ public class WifiMonitor {
|
||||
*/
|
||||
private void handleHostApEvents(String dataString) {
|
||||
String[] tokens = dataString.split(" ");
|
||||
/* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
|
||||
/* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
|
||||
if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
|
||||
String[] nameValue = tokens[2].split("=");
|
||||
if (nameValue.length != 2) return;
|
||||
WifiP2pDevice device = new WifiP2pDevice();
|
||||
device.interfaceAddress = tokens[1];
|
||||
device.deviceAddress = nameValue[1];
|
||||
mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, device);
|
||||
/* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
|
||||
mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
|
||||
/* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
|
||||
} else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
|
||||
//TODO: fix this once wpa_supplicant reports this consistently
|
||||
mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, tokens[1]);
|
||||
mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -577,26 +577,6 @@ public class WifiNative {
|
||||
}
|
||||
|
||||
|
||||
public String p2pGetInterfaceAddress(String deviceAddress) {
|
||||
if (TextUtils.isEmpty(deviceAddress)) return null;
|
||||
|
||||
// "p2p_peer deviceAddress" returns a multi-line result containing
|
||||
// intended_addr=fa:7b:7a:42:82:13
|
||||
String peerInfo = p2pPeer(deviceAddress);
|
||||
if (TextUtils.isEmpty(peerInfo)) return null;
|
||||
String[] tokens= peerInfo.split("\n");
|
||||
|
||||
for (String token : tokens) {
|
||||
//TODO: update from interface_addr when wpa_supplicant implementation is fixed
|
||||
if (token.startsWith("intended_addr=")) {
|
||||
String[] nameValue = token.split("=");
|
||||
if (nameValue.length != 2) break;
|
||||
return nameValue[1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String p2pGetDeviceAddress() {
|
||||
String status = status();
|
||||
if (status == null) return "";
|
||||
@@ -612,6 +592,13 @@ public class WifiNative {
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isGroupOwner(String deviceAddress) {
|
||||
/* BSS returns details only for a GO */
|
||||
String bssInfo = doStringCommand("BSS p2p_dev_addr=" + deviceAddress);
|
||||
if (TextUtils.isEmpty(bssInfo)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public String p2pPeer(String deviceAddress) {
|
||||
return doStringCommand("P2P_PEER " + deviceAddress);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.os.Parcel;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* A class representing a Wi-Fi p2p device
|
||||
@@ -41,17 +42,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
*/
|
||||
public String deviceAddress = "";
|
||||
|
||||
/**
|
||||
* interfaceAddress
|
||||
*
|
||||
* This address is used during group owner negotiation as the Intended
|
||||
* P2P Interface Address and the group interface will be created with
|
||||
* address as the local address in case of successfully completed
|
||||
* negotiation.
|
||||
* @hide
|
||||
*/
|
||||
public String interfaceAddress;
|
||||
|
||||
/**
|
||||
* Primary device type identifies the type of device. For example, an application
|
||||
* could filter the devices discovered to only display printers if the purpose is to
|
||||
@@ -117,6 +107,43 @@ public class WifiP2pDevice implements Parcelable {
|
||||
/** Device connection status */
|
||||
public int status = UNAVAILABLE;
|
||||
|
||||
/** Detailed device string pattern
|
||||
* Example:
|
||||
* P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13
|
||||
* pri_dev_type=1-0050F204-1 name='p2p-TEST1' config_methods=0x188 dev_capab=0x27
|
||||
* group_capab=0x0
|
||||
*
|
||||
*/
|
||||
private static final Pattern detailedDevicePattern = Pattern.compile(
|
||||
"((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
|
||||
"(\\d+ )?" +
|
||||
"p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
|
||||
"pri_dev_type=(\\d+-[0-9a-fA-F]+-\\d+) " +
|
||||
"name='(.*)' " +
|
||||
"config_methods=(0x[0-9a-fA-F]+) " +
|
||||
"dev_capab=(0x[0-9a-fA-F]+) " +
|
||||
"group_capab=(0x[0-9a-fA-F]+)"
|
||||
);
|
||||
|
||||
/** 2 token device address pattern
|
||||
* Example:
|
||||
* P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
|
||||
* AP-STA-DISCONNECTED 42:fc:89:a8:96:09
|
||||
*/
|
||||
private static final Pattern twoTokenPattern = Pattern.compile(
|
||||
"(p2p_dev_addr=)?((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
|
||||
);
|
||||
|
||||
/** 3 token device address pattern
|
||||
* Example:
|
||||
* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
|
||||
* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
|
||||
*/
|
||||
private static final Pattern threeTokenPattern = Pattern.compile(
|
||||
"(?:[0-9a-f]{2}:){5}[0-9a-f]{2} p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
|
||||
);
|
||||
|
||||
|
||||
public WifiP2pDevice() {
|
||||
}
|
||||
|
||||
@@ -128,6 +155,10 @@ public class WifiP2pDevice implements Parcelable {
|
||||
*
|
||||
* P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
|
||||
*
|
||||
* AP-STA-CONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
|
||||
*
|
||||
* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
|
||||
*
|
||||
* fa:7b:7a:42:02:13
|
||||
*
|
||||
* Note: The events formats can be looked up in the wpa_supplicant code
|
||||
@@ -135,56 +166,44 @@ public class WifiP2pDevice implements Parcelable {
|
||||
*/
|
||||
public WifiP2pDevice(String string) throws IllegalArgumentException {
|
||||
String[] tokens = string.split("[ \n]");
|
||||
Matcher match;
|
||||
|
||||
if (tokens.length < 1) {
|
||||
throw new IllegalArgumentException("Malformed supplicant event");
|
||||
}
|
||||
|
||||
/* Just a device address */
|
||||
if (tokens.length == 1) {
|
||||
deviceAddress = string;
|
||||
return;
|
||||
}
|
||||
|
||||
for (String token : tokens) {
|
||||
String[] nameValue = token.split("=");
|
||||
if (nameValue.length != 2) {
|
||||
//mac address without key is device address
|
||||
if (token.matches("(([0-9a-f]{2}:){5}[0-9a-f]{2})")) {
|
||||
deviceAddress = token;
|
||||
switch (tokens.length) {
|
||||
case 1:
|
||||
/* Just a device address */
|
||||
deviceAddress = string;
|
||||
return;
|
||||
case 2:
|
||||
match = twoTokenPattern.matcher(string);
|
||||
if (!match.find()) {
|
||||
throw new IllegalArgumentException("Malformed supplicant event");
|
||||
}
|
||||
deviceAddress = match.group(2);
|
||||
return;
|
||||
case 3:
|
||||
match = threeTokenPattern.matcher(string);
|
||||
if (!match.find()) {
|
||||
throw new IllegalArgumentException("Malformed supplicant event");
|
||||
}
|
||||
deviceAddress = match.group(1);
|
||||
return;
|
||||
default:
|
||||
match = detailedDevicePattern.matcher(string);
|
||||
if (!match.find()) {
|
||||
throw new IllegalArgumentException("Malformed supplicant event");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("p2p_dev_addr")) {
|
||||
deviceAddress = nameValue[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("pri_dev_type")) {
|
||||
primaryDeviceType = nameValue[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("name") || nameValue[0].equals("device_name")) {
|
||||
deviceName = trimQuotes(nameValue[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("config_methods")) {
|
||||
wpsConfigMethodsSupported = parseHex(nameValue[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("dev_capab")) {
|
||||
deviceCapability = parseHex(nameValue[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("group_capab")) {
|
||||
groupCapability = parseHex(nameValue[1]);
|
||||
continue;
|
||||
}
|
||||
deviceAddress = match.group(3);
|
||||
primaryDeviceType = match.group(4);
|
||||
deviceName = match.group(5);
|
||||
wpsConfigMethodsSupported = parseHex(match.group(6));
|
||||
deviceCapability = parseHex(match.group(7));
|
||||
groupCapability = parseHex(match.group(8));
|
||||
break;
|
||||
}
|
||||
|
||||
if (tokens[0].startsWith("P2P-DEVICE-FOUND")) {
|
||||
@@ -233,7 +252,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
StringBuffer sbuf = new StringBuffer();
|
||||
sbuf.append("Device: ").append(deviceName);
|
||||
sbuf.append("\n deviceAddress: ").append(deviceAddress);
|
||||
sbuf.append("\n interfaceAddress: ").append(interfaceAddress);
|
||||
sbuf.append("\n primary type: ").append(primaryDeviceType);
|
||||
sbuf.append("\n secondary type: ").append(secondaryDeviceType);
|
||||
sbuf.append("\n wps: ").append(wpsConfigMethodsSupported);
|
||||
@@ -253,7 +271,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
if (source != null) {
|
||||
deviceName = source.deviceName;
|
||||
deviceAddress = source.deviceAddress;
|
||||
interfaceAddress = source.interfaceAddress;
|
||||
primaryDeviceType = source.primaryDeviceType;
|
||||
secondaryDeviceType = source.secondaryDeviceType;
|
||||
wpsConfigMethodsSupported = source.wpsConfigMethodsSupported;
|
||||
@@ -267,7 +284,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(deviceName);
|
||||
dest.writeString(deviceAddress);
|
||||
dest.writeString(interfaceAddress);
|
||||
dest.writeString(primaryDeviceType);
|
||||
dest.writeString(secondaryDeviceType);
|
||||
dest.writeInt(wpsConfigMethodsSupported);
|
||||
@@ -283,7 +299,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
WifiP2pDevice device = new WifiP2pDevice();
|
||||
device.deviceName = in.readString();
|
||||
device.deviceAddress = in.readString();
|
||||
device.interfaceAddress = in.readString();
|
||||
device.primaryDeviceType = in.readString();
|
||||
device.secondaryDeviceType = in.readString();
|
||||
device.wpsConfigMethodsSupported = in.readInt();
|
||||
@@ -298,15 +313,6 @@ public class WifiP2pDevice implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
private String trimQuotes(String str) {
|
||||
str = str.trim();
|
||||
if (str.startsWith("'") && str.endsWith("'")) {
|
||||
if (str.length() <= 2) return "";
|
||||
else return str.substring(1, str.length()-1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//supported formats: 0x1abc, 0X1abc, 1abc
|
||||
private int parseHex(String hexString) {
|
||||
int num = 0;
|
||||
|
||||
@@ -79,19 +79,6 @@ public class WifiP2pDeviceList implements Parcelable {
|
||||
mDevices.add(device);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void updateInterfaceAddress(WifiP2pDevice device) {
|
||||
for (WifiP2pDevice d : mDevices) {
|
||||
//Found, update interface address
|
||||
if (d.equals(device)) {
|
||||
d.interfaceAddress = device.interfaceAddress;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Not found, add a new one
|
||||
mDevices.add(device);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public boolean remove(WifiP2pDevice device) {
|
||||
if (device == null) return false;
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* A class representing a Wi-Fi P2p group
|
||||
@@ -48,6 +50,15 @@ public class WifiP2pGroup implements Parcelable {
|
||||
|
||||
private String mInterface;
|
||||
|
||||
/** P2P group started string pattern */
|
||||
private static final Pattern groupStartedPattern = Pattern.compile(
|
||||
"ssid=\"(.+)\" " +
|
||||
"freq=(\\d+) " +
|
||||
"(?:psk=)?([0-9a-fA-F]{64})?" +
|
||||
"(?:passphrase=)?(?:\"(.{8,63})\")? " +
|
||||
"go_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
|
||||
);
|
||||
|
||||
public WifiP2pGroup() {
|
||||
}
|
||||
|
||||
@@ -78,24 +89,18 @@ public class WifiP2pGroup implements Parcelable {
|
||||
mInterface = tokens[1];
|
||||
mIsGroupOwner = tokens[2].equals("GO");
|
||||
|
||||
for (String token : tokens) {
|
||||
String[] nameValue = token.split("=");
|
||||
if (nameValue.length != 2) continue;
|
||||
|
||||
if (nameValue[0].equals("ssid")) {
|
||||
mNetworkName = nameValue[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("passphrase")) {
|
||||
mPassphrase = nameValue[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nameValue[0].equals("go_dev_addr")) {
|
||||
mOwner = new WifiP2pDevice(nameValue[1]);
|
||||
}
|
||||
Matcher match = groupStartedPattern.matcher(supplicantEvent);
|
||||
if (!match.find()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mNetworkName = match.group(1);
|
||||
//freq and psk are unused right now
|
||||
//int freq = Integer.parseInt(match.group(2));
|
||||
//String psk = match.group(3);
|
||||
mPassphrase = match.group(4);
|
||||
mOwner = new WifiP2pDevice(match.group(5));
|
||||
|
||||
} else if (tokens[0].equals("P2P-INVITATION-RECEIVED")) {
|
||||
for (String token : tokens) {
|
||||
String[] nameValue = token.split("=");
|
||||
|
||||
@@ -541,8 +541,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
case WifiP2pManager.CONNECT:
|
||||
if (DBG) logd(getName() + " sending connect");
|
||||
mSavedPeerConfig = (WifiP2pConfig) message.obj;
|
||||
String updatedPeerDetails = mWifiNative.p2pPeer(mSavedPeerConfig.deviceAddress);
|
||||
mPeers.update(new WifiP2pDevice(updatedPeerDetails));
|
||||
mPersistGroup = false;
|
||||
int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
|
||||
if (netId >= 0) {
|
||||
@@ -553,7 +551,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
mWifiNative.p2pStopFind();
|
||||
//If peer is a GO, we do not need to send provisional discovery,
|
||||
//the supplicant takes care of it.
|
||||
if (isGroupOwner(mSavedPeerConfig.deviceAddress)) {
|
||||
if (mWifiNative.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
|
||||
p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
|
||||
transitionTo(mGroupNegotiationState);
|
||||
} else {
|
||||
@@ -683,7 +681,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
switch (message.what) {
|
||||
case PEER_CONNECTION_USER_ACCEPT:
|
||||
//TODO: handle persistence
|
||||
if (isGroupOwner(mSavedPeerConfig.deviceAddress)) {
|
||||
if (mWifiNative.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
|
||||
p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
|
||||
} else {
|
||||
p2pConnectWithPinDisplay(mSavedPeerConfig, FORM_GROUP);
|
||||
@@ -842,7 +840,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
String deviceAddress = device.deviceAddress;
|
||||
if (deviceAddress != null) {
|
||||
mGroup.addClient(deviceAddress);
|
||||
mPeers.updateInterfaceAddress(device);
|
||||
updateDeviceStatus(deviceAddress, WifiP2pDevice.CONNECTED);
|
||||
if (DBG) logd(getName() + " ap sta connected");
|
||||
sendP2pPeersChangedBroadcast();
|
||||
@@ -851,10 +848,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
break;
|
||||
case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
|
||||
//TODO: the disconnection event is still inconsistent and reports
|
||||
//interface address. Fix this after wpa_supplicant is fixed.
|
||||
String interfaceAddress = (String) message.obj;
|
||||
deviceAddress = getDeviceAddress(interfaceAddress);
|
||||
device = (WifiP2pDevice) message.obj;
|
||||
deviceAddress = device.deviceAddress;
|
||||
if (deviceAddress != null) {
|
||||
updateDeviceStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
|
||||
if (mGroup.removeClient(deviceAddress)) {
|
||||
@@ -872,7 +867,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
sendP2pPeersChangedBroadcast();
|
||||
if (DBG) loge(getName() + " ap sta disconnected");
|
||||
} else {
|
||||
loge("Disconnect on unknown interface address : " + interfaceAddress);
|
||||
loge("Disconnect on unknown device: " + device);
|
||||
}
|
||||
break;
|
||||
case DhcpStateMachine.CMD_POST_DHCP_ACTION:
|
||||
@@ -883,6 +878,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
|
||||
sendP2pConnectionChangedBroadcast();
|
||||
} else {
|
||||
loge("DHCP failed");
|
||||
mWifiNative.p2pGroupRemove(mGroup.getInterface());
|
||||
}
|
||||
break;
|
||||
@@ -916,6 +912,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
|
||||
mGroup = null;
|
||||
mWifiNative.p2pFlush();
|
||||
if (changed) sendP2pPeersChangedBroadcast();
|
||||
transitionTo(mInactiveState);
|
||||
break;
|
||||
@@ -1183,15 +1180,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGroupOwner(String deviceAddress) {
|
||||
for (WifiP2pDevice d : mPeers.getDeviceList()) {
|
||||
if (d.deviceAddress.equals(deviceAddress)) {
|
||||
return d.isGroupOwner();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: implement when wpa_supplicant is fixed
|
||||
private int configuredNetworkId(String deviceAddress) {
|
||||
return -1;
|
||||
@@ -1219,15 +1207,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
return deviceAddress;
|
||||
}
|
||||
|
||||
private String getDeviceAddress(String interfaceAddress) {
|
||||
for (WifiP2pDevice d : mPeers.getDeviceList()) {
|
||||
if (interfaceAddress.equals(d.interfaceAddress)) {
|
||||
return d.deviceAddress;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private WifiP2pDevice getDeviceFromPeerList(String deviceAddress) {
|
||||
for (WifiP2pDevice d : mPeers.getDeviceList()) {
|
||||
if (d.deviceAddress.equals(deviceAddress)) {
|
||||
|
||||
Reference in New Issue
Block a user