Skip to content

Commit d4fecc2

Browse files
isheriffAndroid (Google) Code Review
authored andcommitted
Merge "Pre-association service discovery support"
2 parents c8cbf5d + 21ba815 commit d4fecc2

19 files changed

+2932
-38
lines changed

core/java/android/net/nsd/DnsSdTxtRecord.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import android.os.Parcelable;
2525
import android.os.Parcel;
2626

27+
import java.util.Arrays;
28+
2729
/**
2830
* This class handles TXT record data for DNS based service discovery as specified at
2931
* http://tools.ietf.org/html/draft-cheshire-dnsext-dns-sd-11
@@ -160,7 +162,7 @@ public int size() {
160162

161163
/* Gets the raw data in bytes */
162164
public byte[] getRawData() {
163-
return mData;
165+
return (byte[]) mData.clone();
164166
}
165167

166168
private void insert(byte[] keyBytes, byte[] value, int index) {
@@ -279,6 +281,24 @@ public String toString() {
279281
return result != null ? result : "";
280282
}
281283

284+
@Override
285+
public boolean equals(Object o) {
286+
if (o == this) {
287+
return true;
288+
}
289+
if (!(o instanceof DnsSdTxtRecord)) {
290+
return false;
291+
}
292+
293+
DnsSdTxtRecord record = (DnsSdTxtRecord)o;
294+
return Arrays.equals(record.mData, mData);
295+
}
296+
297+
@Override
298+
public int hashCode() {
299+
return Arrays.hashCode(mData);
300+
}
301+
282302
/** Implement the Parcelable interface */
283303
public int describeContents() {
284304
return 0;

core/jni/android_net_wifi_Wifi.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
2929
#define BUF_SIZE 256
30+
#define EVENT_BUF_SIZE 2048
3031

3132
namespace android {
3233

@@ -140,7 +141,7 @@ static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jst
140141

141142
static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
142143
{
143-
char buf[BUF_SIZE];
144+
char buf[EVENT_BUF_SIZE];
144145
ScopedUtfChars ifname(env, jIface);
145146
int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
146147
if (nread > 0) {

wifi/java/android/net/wifi/WifiMonitor.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import android.net.wifi.p2p.WifiP2pDevice;
2222
import android.net.wifi.p2p.WifiP2pGroup;
2323
import android.net.wifi.p2p.WifiP2pProvDiscEvent;
24+
import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
2425
import android.net.wifi.StateChangeResult;
2526
import android.os.Message;
2627
import android.util.Log;
@@ -29,6 +30,7 @@
2930
import com.android.internal.util.Protocol;
3031
import com.android.internal.util.StateMachine;
3132

33+
import java.util.List;
3234
import java.util.regex.Pattern;
3335
import java.util.regex.Matcher;
3436

@@ -214,6 +216,52 @@ public class WifiMonitor {
214216
group_capab=0x0 */
215217
private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN";
216218

219+
/*
220+
* Protocol format is as follows.<br>
221+
* See the Table.62 in the WiFi Direct specification for the detail.
222+
* ______________________________________________________________
223+
* | Length(2byte) | Type(1byte) | TransId(1byte)}|
224+
* ______________________________________________________________
225+
* | status(1byte) | vendor specific(variable) |
226+
*
227+
* P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300000101
228+
* length=3, service type=0(ALL Service), transaction id=1,
229+
* status=1(service protocol type not available)<br>
230+
*
231+
* P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300020201
232+
* length=3, service type=2(UPnP), transaction id=2,
233+
* status=1(service protocol type not available)
234+
*
235+
* P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 990002030010757569643a3131323
236+
* 2646534652d383537342d353961622d393332322d3333333435363738393034343a3
237+
* a75726e3a736368656d61732d75706e702d6f72673a736572766963653a436f6e746
238+
* 56e744469726563746f72793a322c757569643a36383539646564652d383537342d3
239+
* 53961622d393333322d3132333435363738393031323a3a75706e703a726f6f74646
240+
* 576696365
241+
* length=153,type=2(UPnP),transaction id=3,status=0
242+
*
243+
* UPnP Protocol format is as follows.
244+
* ______________________________________________________
245+
* | Version (1) | USN (Variable) |
246+
*
247+
* version=0x10(UPnP1.0) data=usn:uuid:1122de4e-8574-59ab-9322-33345678
248+
* 9044::urn:schemas-upnp-org:service:ContentDirectory:2,usn:uuid:6859d
249+
* ede-8574-59ab-9332-123456789012::upnp:rootdevice
250+
*
251+
* P2P-SERV-DISC-RESP 58:17:0c:bc:dd:ca 21 1900010200045f6970
252+
* 70c00c000c01094d795072696e746572c027
253+
* length=25, type=1(Bonjour),transaction id=2,status=0
254+
*
255+
* Bonjour Protocol format is as follows.
256+
* __________________________________________________________
257+
* |DNS Name(Variable)|DNS Type(1)|Version(1)|RDATA(Variable)|
258+
*
259+
* DNS Name=_ipp._tcp.local.,DNS type=12(PTR), Version=1,
260+
* RDATA=MyPrinter._ipp._tcp.local.
261+
*
262+
*/
263+
private static final String P2P_SERV_DISC_RESP_STR = "P2P-SERV-DISC-RESP";
264+
217265
private static final String HOST_AP_EVENT_PREFIX_STR = "AP";
218266
/* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
219267
private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED";
@@ -268,6 +316,7 @@ public class WifiMonitor {
268316
public static final int P2P_PROV_DISC_ENTER_PIN_EVENT = BASE + 35;
269317
public static final int P2P_PROV_DISC_SHOW_PIN_EVENT = BASE + 36;
270318
public static final int P2P_FIND_STOPPED_EVENT = BASE + 37;
319+
public static final int P2P_SERV_DISC_RESP_EVENT = BASE + 38;
271320

272321
/* hostap events */
273322
public static final int AP_STA_DISCONNECTED_EVENT = BASE + 41;
@@ -558,6 +607,13 @@ private void handleP2pEvents(String dataString) {
558607
} else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
559608
mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
560609
new WifiP2pProvDiscEvent(dataString));
610+
} else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
611+
List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
612+
if (list != null) {
613+
mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
614+
} else {
615+
Log.e(TAG, "Null service resp " + dataString);
616+
}
561617
}
562618
}
563619

wifi/java/android/net/wifi/WifiNative.java

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
import android.net.wifi.p2p.WifiP2pConfig;
2020
import android.net.wifi.p2p.WifiP2pGroup;
2121
import android.net.wifi.p2p.WifiP2pDevice;
22-
import android.os.SystemProperties;
2322
import android.text.TextUtils;
23+
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
24+
import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
2425
import android.util.Log;
2526

2627
import java.io.InputStream;
@@ -644,4 +645,78 @@ public boolean isGroupOwner(String deviceAddress) {
644645
public String p2pPeer(String deviceAddress) {
645646
return doStringCommand("P2P_PEER " + deviceAddress);
646647
}
648+
649+
public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
650+
/*
651+
* P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
652+
* P2P_SERVICE_ADD upnp <version hex> <service>
653+
*
654+
* e.g)
655+
* [Bonjour]
656+
* # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
657+
* P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
658+
* # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
659+
* P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
660+
* 09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
661+
*
662+
* [UPnP]
663+
* P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
664+
* P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
665+
* P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
666+
* -org:device:InternetGatewayDevice:1
667+
* P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
668+
* -org:service:ContentDirectory:2
669+
*/
670+
for (String s : servInfo.getSupplicantQueryList()) {
671+
String command = "P2P_SERVICE_ADD";
672+
command += (" " + s);
673+
if (!doBooleanCommand(command)) {
674+
return false;
675+
}
676+
}
677+
return true;
678+
}
679+
680+
public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
681+
/*
682+
* P2P_SERVICE_DEL bonjour <query hexdump>
683+
* P2P_SERVICE_DEL upnp <version hex> <service>
684+
*/
685+
for (String s : servInfo.getSupplicantQueryList()) {
686+
String command = "P2P_SERVICE_DEL ";
687+
688+
String[] data = s.split(" ");
689+
if (data.length < 2) {
690+
return false;
691+
}
692+
if ("upnp".equals(data[0])) {
693+
command += s;
694+
} else if ("bonjour".equals(data[0])) {
695+
command += data[0];
696+
command += (" " + data[1]);
697+
} else {
698+
return false;
699+
}
700+
if (!doBooleanCommand(command)) {
701+
return false;
702+
}
703+
}
704+
return true;
705+
}
706+
707+
public boolean p2pServiceFlush() {
708+
return doBooleanCommand("P2P_SERVICE_FLUSH");
709+
}
710+
711+
public String p2pServDiscReq(String addr, String query) {
712+
String command = "P2P_SERV_DISC_REQ";
713+
command += (" " + addr);
714+
command += (" " + query);
715+
716+
return doStringCommand(command);
717+
}
718+
719+
public boolean p2pServDiscCancelReq(String id) {
720+
return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
721+
}
647722
}

wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.ArrayList;
2525
import java.util.Collection;
2626
import java.util.Collections;
27+
import java.util.HashMap;
2728

2829
/**
2930
* A class representing a Wi-Fi P2p device list
@@ -32,24 +33,28 @@
3233
*/
3334
public class WifiP2pDeviceList implements Parcelable {
3435

35-
private Collection<WifiP2pDevice> mDevices;
36+
private HashMap<String, WifiP2pDevice> mDevices;
3637

3738
public WifiP2pDeviceList() {
38-
mDevices = new ArrayList<WifiP2pDevice>();
39+
mDevices = new HashMap<String, WifiP2pDevice>();
3940
}
4041

4142
/** copy constructor */
4243
public WifiP2pDeviceList(WifiP2pDeviceList source) {
4344
if (source != null) {
44-
mDevices = source.getDeviceList();
45+
for (WifiP2pDevice d : source.getDeviceList()) {
46+
mDevices.put(d.deviceAddress, d);
47+
}
4548
}
4649
}
4750

4851
/** @hide */
4952
public WifiP2pDeviceList(ArrayList<WifiP2pDevice> devices) {
50-
mDevices = new ArrayList<WifiP2pDevice>();
53+
mDevices = new HashMap<String, WifiP2pDevice>();
5154
for (WifiP2pDevice device : devices) {
52-
mDevices.add(device);
55+
if (device.deviceAddress != null) {
56+
mDevices.put(device.deviceAddress, device);
57+
}
5358
}
5459
}
5560

@@ -62,37 +67,42 @@ public boolean clear() {
6267

6368
/** @hide */
6469
public void update(WifiP2pDevice device) {
65-
if (device == null) return;
66-
for (WifiP2pDevice d : mDevices) {
67-
//Found, update fields that can change
68-
if (d.equals(device)) {
69-
d.deviceName = device.deviceName;
70-
d.primaryDeviceType = device.primaryDeviceType;
71-
d.secondaryDeviceType = device.secondaryDeviceType;
72-
d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
73-
d.deviceCapability = device.deviceCapability;
74-
d.groupCapability = device.groupCapability;
75-
return;
76-
}
70+
if (device == null || device.deviceAddress == null) return;
71+
WifiP2pDevice d = mDevices.get(device.deviceAddress);
72+
if (d != null) {
73+
d.deviceName = device.deviceName;
74+
d.primaryDeviceType = device.primaryDeviceType;
75+
d.secondaryDeviceType = device.secondaryDeviceType;
76+
d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
77+
d.deviceCapability = device.deviceCapability;
78+
d.groupCapability = device.groupCapability;
79+
return;
7780
}
7881
//Not found, add a new one
79-
mDevices.add(device);
82+
mDevices.put(device.deviceAddress, device);
83+
}
84+
85+
/** @hide */
86+
public WifiP2pDevice get(String deviceAddress) {
87+
if (deviceAddress == null) return null;
88+
89+
return mDevices.get(deviceAddress);
8090
}
8191

8292
/** @hide */
8393
public boolean remove(WifiP2pDevice device) {
84-
if (device == null) return false;
85-
return mDevices.remove(device);
94+
if (device == null || device.deviceAddress == null) return false;
95+
return mDevices.remove(device.deviceAddress) != null;
8696
}
8797

8898
/** Get the list of devices */
8999
public Collection<WifiP2pDevice> getDeviceList() {
90-
return Collections.unmodifiableCollection(mDevices);
100+
return Collections.unmodifiableCollection(mDevices.values());
91101
}
92102

93103
public String toString() {
94104
StringBuffer sbuf = new StringBuffer();
95-
for (WifiP2pDevice device : mDevices) {
105+
for (WifiP2pDevice device : mDevices.values()) {
96106
sbuf.append("\n").append(device);
97107
}
98108
return sbuf.toString();
@@ -106,7 +116,7 @@ public int describeContents() {
106116
/** Implement the Parcelable interface */
107117
public void writeToParcel(Parcel dest, int flags) {
108118
dest.writeInt(mDevices.size());
109-
for(WifiP2pDevice device : mDevices) {
119+
for(WifiP2pDevice device : mDevices.values()) {
110120
dest.writeParcelable(device, flags);
111121
}
112122
}

0 commit comments

Comments
 (0)