1#!/usr/bin/env python3
2#
3#   Copyright 2018 Google, Inc.
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import logging
18import os
19import time
20
21from queue import Empty
22
23from acts import asserts
24from acts import utils
25from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts
26import acts.utils
27
28
29def is_discovered(event, ad):
30    """Check an Android device exist in WifiP2pOnPeersAvailable event or not.
31
32    Args:
33        event: WifiP2pOnPeersAvailable which include all of p2p devices.
34        ad: The android device
35    Returns:
36        True: if an Android device exist in p2p list
37        False: if not exist
38    """
39    for device in event['data']['Peers']:
40        if device['Name'] == ad.name:
41            ad.deviceAddress = device['Address']
42            return True
43    return False
44
45
46def check_disconnect(ad, timeout=p2pconsts.DEFAULT_TIMEOUT):
47    """Check an Android device disconnect or not
48
49    Args:
50        ad: The android device
51    """
52    ad.droid.wifiP2pRequestConnectionInfo()
53    # wait disconnect event
54    ad.ed.pop_event(p2pconsts.DISCONNECTED_EVENT, timeout)
55
56
57def p2p_disconnect(ad):
58    """Invoke an Android device removeGroup to trigger p2p disconnect
59
60    Args:
61        ad: The android device
62    """
63    ad.log.debug("Disconnect")
64    ad.droid.wifiP2pRemoveGroup()
65    check_disconnect(ad)
66
67
68def p2p_connection_ping_test(ad, target_ip_address):
69    """Let an Android device to start ping target_ip_address
70
71    Args:
72        ad: The android device
73        target_ip_address: ip address which would like to ping
74    """
75    ad.log.debug("Run Ping Test, %s ping %s " % (ad.serial, target_ip_address))
76    asserts.assert_true(
77        acts.utils.adb_shell_ping(ad,
78                                  count=6,
79                                  dest_ip=target_ip_address,
80                                  timeout=20), "%s ping failed" % (ad.serial))
81
82
83def is_go(ad):
84    """Check an Android p2p role is Go or not
85
86    Args:
87        ad: The android device
88    Return:
89        True: An Android device is p2p  go
90        False: An Android device is p2p gc
91    """
92    ad.log.debug("is go check")
93    ad.droid.wifiP2pRequestConnectionInfo()
94    ad_connect_info_event = ad.ed.pop_event(
95        p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, p2pconsts.DEFAULT_TIMEOUT)
96    if ad_connect_info_event['data']['isGroupOwner']:
97        return True
98    return False
99
100
101def p2p_go_ip(ad):
102    """Get GO IP address
103
104    Args:
105        ad: The android device
106    Return:
107        GO IP address
108    """
109    ad.log.debug("p2p go ip")
110    ad.droid.wifiP2pRequestConnectionInfo()
111    ad_connect_info_event = ad.ed.pop_event(
112        p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, p2pconsts.DEFAULT_TIMEOUT)
113    ad.log.debug("p2p go ip: %s" %
114                 ad_connect_info_event['data']['groupOwnerHostAddress'])
115    return ad_connect_info_event['data']['groupOwnerHostAddress']
116
117
118def p2p_get_current_group(ad):
119    """Get current group information
120
121    Args:
122        ad: The android device
123    Return:
124        p2p group information
125    """
126    ad.log.debug("get current group")
127    ad.droid.wifiP2pRequestGroupInfo()
128    ad_group_info_event = ad.ed.pop_event(p2pconsts.GROUP_INFO_AVAILABLE_EVENT,
129                                          p2pconsts.DEFAULT_TIMEOUT)
130    ad.log.debug(
131        "p2p group: SSID:%s, password:%s, owner address: %s, interface: %s" %
132        (ad_group_info_event['data']['NetworkName'],
133         ad_group_info_event['data']['Passphrase'],
134         ad_group_info_event['data']['OwnerAddress'],
135         ad_group_info_event['data']['Interface']))
136    return ad_group_info_event['data']
137
138
139#trigger p2p connect to ad2 from ad1
140def p2p_connect(ad1,
141                ad2,
142                isReconnect,
143                wpsSetup,
144                p2p_connect_type=p2pconsts.P2P_CONNECT_NEGOTIATION,
145                go_ad=None):
146    """trigger p2p connect to ad2 from ad1
147
148    Args:
149        ad1: The android device
150        ad2: The android device
151        isReconnect: boolean, if persist group is exist,
152                isReconnect is true, otherswise is false.
153        wpsSetup: which wps connection would like to use
154        p2p_connect_type: enumeration, which type this p2p connection is
155        go_ad: The group owner android device which is used for the invitation connection
156    """
157    ad1.log.info("Create p2p connection from %s to %s via wps: %s type %d" %
158                 (ad1.name, ad2.name, wpsSetup, p2p_connect_type))
159    if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION:
160        if go_ad is None:
161            go_ad = ad1
162        find_p2p_device(ad1, ad2)
163        find_p2p_group_owner(ad2, go_ad)
164    elif p2p_connect_type == p2pconsts.P2P_CONNECT_JOIN:
165        find_p2p_group_owner(ad1, ad2)
166    else:
167        find_p2p_device(ad1, ad2)
168    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
169    wifi_p2p_config = {
170        WifiP2PEnums.WifiP2pConfig.DEVICEADDRESS_KEY: ad2.deviceAddress,
171        WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: {
172            WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: wpsSetup
173        }
174    }
175    ad1.droid.wifiP2pConnect(wifi_p2p_config)
176    ad1.ed.pop_event(p2pconsts.CONNECT_SUCCESS_EVENT,
177                     p2pconsts.DEFAULT_TIMEOUT)
178    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
179    if not isReconnect:
180        ad1.droid.requestP2pPeerConfigure()
181        ad1_peerConfig = ad1.ed.pop_event(
182            p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT,
183            p2pconsts.DEFAULT_TIMEOUT)
184        ad1.log.debug(ad1_peerConfig['data'])
185        ad2.droid.requestP2pPeerConfigure()
186        ad2_peerConfig = ad2.ed.pop_event(
187            p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT,
188            p2pconsts.DEFAULT_TIMEOUT)
189        ad2.log.debug(ad2_peerConfig['data'])
190        if wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY:
191            asserts.assert_true(
192                WifiP2PEnums.WpsInfo.WPS_PIN_KEY in ad1_peerConfig['data'][
193                    WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY],
194                "Can't get pin value")
195            ad2_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][
196                WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad1_peerConfig['data'][
197                    WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][
198                        WifiP2PEnums.WpsInfo.WPS_PIN_KEY]
199            ad2.droid.setP2pPeerConfigure(ad2_peerConfig['data'])
200            ad2.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT,
201                             p2pconsts.DEFAULT_TIMEOUT)
202            ad2.droid.wifiP2pAcceptConnection()
203        elif wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD:
204            asserts.assert_true(
205                WifiP2PEnums.WpsInfo.WPS_PIN_KEY in ad2_peerConfig['data'][
206                    WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY],
207                "Can't get pin value")
208            ad1_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][
209                WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad2_peerConfig['data'][
210                    WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][
211                        WifiP2PEnums.WpsInfo.WPS_PIN_KEY]
212            ad1.droid.setP2pPeerConfigure(ad1_peerConfig['data'])
213            ad1.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT,
214                             p2pconsts.DEFAULT_TIMEOUT)
215            #Need to Accept first in ad1 to avoid connect time out in ad2,
216            #the timeout just 1 sec in ad2
217            ad1.droid.wifiP2pAcceptConnection()
218            time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
219            ad2.droid.wifiP2pConfirmConnection()
220        elif wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC:
221            ad2.droid.wifiP2pAcceptConnection()
222            if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION:
223                time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
224                go_ad.droid.wifiP2pAcceptConnection()
225
226    #wait connected event
227    if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION:
228        go_ad.ed.pop_event(p2pconsts.CONNECTED_EVENT,
229                           p2pconsts.DEFAULT_TIMEOUT)
230    else:
231        ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT)
232    ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT)
233
234
235def p2p_connect_with_config(ad1, ad2, network_name, passphrase, band):
236    """trigger p2p connect to ad2 from ad1 with config
237
238    Args:
239        ad1: The android device
240        ad2: The android device
241        network_name: the network name of the desired group.
242        passphrase: the passphrase of the desired group.
243        band: the operating band of the desired group.
244    """
245    ad1.log.info("Create p2p connection from %s to %s" % (ad1.name, ad2.name))
246    find_p2p_device(ad1, ad2)
247    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
248    wifi_p2p_config = {
249        WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name,
250        WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase,
251        WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band,
252        WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: {
253            WifiP2PEnums.WpsInfo.WPS_SETUP_KEY:
254            WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC
255        }
256    }
257    ad1.droid.wifiP2pConnect(wifi_p2p_config)
258    ad1.ed.pop_event(p2pconsts.CONNECT_SUCCESS_EVENT,
259                     p2pconsts.DEFAULT_TIMEOUT)
260    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
261
262    #wait connected event
263    ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT)
264    ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT)
265
266
267def find_p2p_device(ad1, ad2):
268    """Check an Android device ad1 can discover an Android device ad2
269
270    Args:
271        ad1: The android device
272        ad2: The android device
273    """
274    ad1.droid.wifiP2pDiscoverPeers()
275    ad2.droid.wifiP2pDiscoverPeers()
276    p2p_find_result = False
277    while not p2p_find_result:
278        ad1_event = ad1.ed.pop_event(p2pconsts.PEER_AVAILABLE_EVENT,
279                                     p2pconsts.P2P_FIND_TIMEOUT)
280        ad1.log.debug(ad1_event['data'])
281        p2p_find_result = is_discovered(ad1_event, ad2)
282    asserts.assert_true(p2p_find_result,
283                        "DUT didn't discovered peer:%s device" % (ad2.name))
284
285
286def find_p2p_group_owner(ad1, ad2):
287    """Check an Android device ad1 can discover an Android device ad2 which
288       is a group owner
289
290    Args:
291        ad1: The android device
292        ad2: The android device which is a group owner
293    """
294    ad2.droid.wifiP2pStopPeerDiscovery()
295    time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME)
296    ad1.droid.wifiP2pDiscoverPeers()
297    p2p_find_result = False
298    while not p2p_find_result:
299        ad1_event = ad1.ed.pop_event(p2pconsts.PEER_AVAILABLE_EVENT,
300                                     p2pconsts.P2P_FIND_TIMEOUT)
301        ad1.log.debug(ad1_event['data'])
302        for device in ad1_event['data']['Peers']:
303            if (device['Name'] == ad2.name and int(device['GroupCapability'])
304                    & p2pconsts.P2P_GROUP_CAPAB_GROUP_OWNER):
305                ad2.deviceAddress = device['Address']
306                p2p_find_result = True
307    asserts.assert_true(
308        p2p_find_result,
309        "DUT didn't discovered group owner peer:%s device" % (ad2.name))
310
311
312def createP2pLocalService(ad, serviceCategory):
313    """Based on serviceCategory to create p2p local service
314            on an Android device ad
315
316    Args:
317        ad: The android device
318        serviceCategory: p2p local service type, UPNP / IPP / AFP,
319    """
320    testData = genTestData(serviceCategory)
321    if serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_UPNP:
322        ad.droid.wifiP2pCreateUpnpServiceInfo(testData[0], testData[1],
323                                              testData[2])
324    elif (serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_IPP
325          or serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_AFP):
326        ad.droid.wifiP2pCreateBonjourServiceInfo(testData[0], testData[1],
327                                                 testData[2])
328    ad.droid.wifiP2pAddLocalService()
329
330
331def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver,
332                                 serviceType, queryString1, queryString2):
333    """Based on serviceType and query info, check service request result
334            same as expect or not on an Android device ad_serviceReceiver.
335            And remove p2p service request after result check.
336
337    Args:
338        ad_serviceProvider: The android device which provide p2p local service
339        ad_serviceReceiver: The android device which query p2p local service
340        serviceType: P2p local service type, Upnp or Bonjour
341        queryString1: Query String, NonNull
342        queryString2: Query String, used for Bonjour, Nullable
343    """
344    expectData = genExpectTestData(serviceType, queryString1, queryString2)
345    find_p2p_device(ad_serviceReceiver, ad_serviceProvider)
346    ad_serviceReceiver.droid.wifiP2pStopPeerDiscovery()
347    ad_serviceReceiver.droid.wifiP2pClearServiceRequests()
348    time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME)
349
350    ad_serviceReceiver.droid.wifiP2pDiscoverServices()
351    serviceData = {}
352    service_id = 0
353    if (serviceType ==
354            WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR):
355        ad_serviceReceiver.log.info(
356            "Request bonjour service in \
357                %s with Query String %s and %s " %
358            (ad_serviceReceiver.name, queryString1, queryString2))
359        ad_serviceReceiver.log.info("expectData %s" % expectData)
360        if queryString1 != None:
361            service_id = ad_serviceReceiver.droid.wifiP2pAddDnssdServiceRequest(
362                queryString1, queryString2)
363        else:
364            service_id = ad_serviceReceiver.droid.wifiP2pAddServiceRequest(
365                serviceType)
366            ad_serviceReceiver.log.info("request bonjour service id %s" %
367                                        service_id)
368        ad_serviceReceiver.droid.wifiP2pSetDnsSdResponseListeners()
369        ad_serviceReceiver.droid.wifiP2pDiscoverServices()
370        ad_serviceReceiver.log.info("Check Service Listener")
371        time.sleep(p2pconsts.DEFAULT_SERVICE_WAITING_TIME)
372        try:
373            dnssd_events = ad_serviceReceiver.ed.pop_all(p2pconsts.DNSSD_EVENT)
374            dnssd_txrecord_events = ad_serviceReceiver.ed.pop_all(
375                p2pconsts.DNSSD_TXRECORD_EVENT)
376            dns_service = WifiP2PEnums.WifiP2pDnsSdServiceResponse()
377            for dnssd_event in dnssd_events:
378                if dnssd_event['data'][
379                        'SourceDeviceAddress'] == ad_serviceProvider.deviceAddress:
380                    dns_service.InstanceName = dnssd_event['data'][
381                        p2pconsts.DNSSD_EVENT_INSTANCENAME_KEY]
382                    dns_service.RegistrationType = dnssd_event['data'][
383                        p2pconsts.DNSSD_EVENT_REGISTRATIONTYPE_KEY]
384                    dns_service.FullDomainName = ""
385                    dns_service.TxtRecordMap = ""
386                    serviceData[dns_service.toString()] = 1
387            for dnssd_txrecord_event in dnssd_txrecord_events:
388                if dnssd_txrecord_event['data'][
389                        'SourceDeviceAddress'] == ad_serviceProvider.deviceAddress:
390                    dns_service.InstanceName = ""
391                    dns_service.RegistrationType = ""
392                    dns_service.FullDomainName = dnssd_txrecord_event['data'][
393                        p2pconsts.DNSSD_TXRECORD_EVENT_FULLDOMAINNAME_KEY]
394                    dns_service.TxtRecordMap = dnssd_txrecord_event['data'][
395                        p2pconsts.DNSSD_TXRECORD_EVENT_TXRECORDMAP_KEY]
396                    serviceData[dns_service.toString()] = 1
397            ad_serviceReceiver.log.info("serviceData %s" % serviceData)
398            if len(serviceData) == 0:
399                ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(
400                    service_id)
401                return -1
402        except queue.Empty as error:
403            ad_serviceReceiver.log.info("dnssd event is empty", )
404    elif (serviceType ==
405          WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP):
406        ad_serviceReceiver.log.info(
407            "Request upnp service in %s with Query String %s " %
408            (ad_serviceReceiver.name, queryString1))
409        ad_serviceReceiver.log.info("expectData %s" % expectData)
410        if queryString1 != None:
411            service_id = ad_serviceReceiver.droid.wifiP2pAddUpnpServiceRequest(
412                queryString1)
413        else:
414            service_id = ad_serviceReceiver.droid.wifiP2pAddServiceRequest(
415                WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP)
416        ad_serviceReceiver.droid.wifiP2pSetUpnpResponseListeners()
417        ad_serviceReceiver.droid.wifiP2pDiscoverServices()
418        ad_serviceReceiver.log.info("Check Service Listener")
419        time.sleep(p2pconsts.DEFAULT_SERVICE_WAITING_TIME)
420        try:
421            upnp_events = ad_serviceReceiver.ed.pop_all(p2pconsts.UPNP_EVENT)
422            for upnp_event in upnp_events:
423                if upnp_event['data']['Device'][
424                        'Address'] == ad_serviceProvider.deviceAddress:
425                    for service in upnp_event['data'][
426                            p2pconsts.UPNP_EVENT_SERVICELIST_KEY]:
427                        serviceData[service] = 1
428            ad_serviceReceiver.log.info("serviceData %s" % serviceData)
429            if len(serviceData) == 0:
430                ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(
431                    service_id)
432                return -1
433        except queue.Empty as error:
434            ad_serviceReceiver.log.info("p2p upnp event is empty", )
435
436    ad_serviceReceiver.log.info("Check ServiceList")
437    asserts.assert_true(checkServiceQueryResult(serviceData, expectData),
438                        "ServiceList not same as Expect")
439    # After service checked, remove the service_id
440    ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(service_id)
441    return 0
442
443
444def requestServiceAndCheckResultWithRetry(ad_serviceProvider,
445                                          ad_serviceReceiver,
446                                          serviceType,
447                                          queryString1,
448                                          queryString2,
449                                          retryCount=3):
450    """ allow failures for requestServiceAndCheckResult. Service
451        discovery might fail unexpectedly because the request packet might not be
452        recevied by the service responder due to p2p state switch.
453
454    Args:
455        ad_serviceProvider: The android device which provide p2p local service
456        ad_serviceReceiver: The android device which query p2p local service
457        serviceType: P2p local service type, Upnp or Bonjour
458        queryString1: Query String, NonNull
459        queryString2: Query String, used for Bonjour, Nullable
460        retryCount: maximum retry count, default is 3
461    """
462    ret = 0
463    while retryCount > 0:
464        ret = requestServiceAndCheckResult(ad_serviceProvider,
465                                           ad_serviceReceiver, serviceType,
466                                           queryString1, queryString2)
467        if (ret == 0):
468            break
469        retryCount -= 1
470
471    asserts.assert_equal(0, ret, "cannot find any services with retries.")
472
473
474def checkServiceQueryResult(serviceList, expectServiceList):
475    """Check serviceList same as expectServiceList or not
476
477    Args:
478        serviceList: ServiceList which get from query result
479        expectServiceList: ServiceList which hardcode in genExpectTestData
480    Return:
481        True: serviceList  same as expectServiceList
482        False:Exist discrepancy between serviceList and expectServiceList
483    """
484    tempServiceList = serviceList.copy()
485    tempExpectServiceList = expectServiceList.copy()
486    for service in serviceList.keys():
487        if service in expectServiceList:
488            del tempServiceList[service]
489            del tempExpectServiceList[service]
490    return len(tempExpectServiceList) == 0 and len(tempServiceList) == 0
491
492
493def genTestData(serviceCategory):
494    """Based on serviceCategory to generator Test Data
495
496    Args:
497        serviceCategory: P2p local service type, Upnp or Bonjour
498    Return:
499        TestData
500    """
501    testData = []
502    if serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_UPNP:
503        testData.append(p2pconsts.UpnpTestData.uuid)
504        testData.append(p2pconsts.UpnpTestData.serviceType)
505        testData.append([
506            p2pconsts.UpnpTestData.AVTransport,
507            p2pconsts.UpnpTestData.ConnectionManager
508        ])
509    elif serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_IPP:
510        testData.append(p2pconsts.IppTestData.ippInstanceName)
511        testData.append(p2pconsts.IppTestData.ippRegistrationType)
512        testData.append(p2pconsts.IppTestData.ipp_txtRecord)
513    elif serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_AFP:
514        testData.append(p2pconsts.AfpTestData.afpInstanceName)
515        testData.append(p2pconsts.AfpTestData.afpRegistrationType)
516        testData.append(p2pconsts.AfpTestData.afp_txtRecord)
517
518    return testData
519
520
521def genExpectTestData(serviceType, queryString1, queryString2):
522    """Based on serviceCategory to generator expect serviceList
523
524    Args:
525        serviceType: P2p local service type, Upnp or Bonjour
526        queryString1: Query String, NonNull
527        queryString2: Query String, used for Bonjour, Nullable
528    Return:
529        expectServiceList
530    """
531    expectServiceList = {}
532    if (serviceType ==
533            WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR):
534        ipp_service = WifiP2PEnums.WifiP2pDnsSdServiceResponse()
535        afp_service = WifiP2PEnums.WifiP2pDnsSdServiceResponse()
536        if queryString1 == p2pconsts.IppTestData.ippRegistrationType:
537            if queryString2 == p2pconsts.IppTestData.ippInstanceName:
538                ipp_service.InstanceName = ""
539                ipp_service.RegistrationType = ""
540                ipp_service.FullDomainName = p2pconsts.IppTestData.ippDomainName
541                ipp_service.TxtRecordMap = p2pconsts.IppTestData.ipp_txtRecord
542                expectServiceList[ipp_service.toString()] = 1
543                return expectServiceList
544            ipp_service.InstanceName = p2pconsts.IppTestData.ippInstanceName
545            ipp_service.RegistrationType = (
546                p2pconsts.IppTestData.ippRegistrationType + ".local.")
547            ipp_service.FullDomainName = ""
548            ipp_service.TxtRecordMap = ""
549            expectServiceList[ipp_service.toString()] = 1
550            return expectServiceList
551        elif queryString1 == p2pconsts.AfpTestData.afpRegistrationType:
552            if queryString2 == p2pconsts.AfpTestData.afpInstanceName:
553                afp_service.InstanceName = ""
554                afp_service.RegistrationType = ""
555                afp_service.FullDomainName = p2pconsts.AfpTestData.afpDomainName
556                afp_service.TxtRecordMap = p2pconsts.AfpTestData.afp_txtRecord
557                expectServiceList[afp_service.toString()] = 1
558                return expectServiceList
559        ipp_service.InstanceName = p2pconsts.IppTestData.ippInstanceName
560        ipp_service.RegistrationType = (
561            p2pconsts.IppTestData.ippRegistrationType + ".local.")
562        ipp_service.FullDomainName = ""
563        ipp_service.TxtRecordMap = ""
564        expectServiceList[ipp_service.toString()] = 1
565
566        ipp_service.InstanceName = ""
567        ipp_service.RegistrationType = ""
568        ipp_service.FullDomainName = p2pconsts.IppTestData.ippDomainName
569        ipp_service.TxtRecordMap = p2pconsts.IppTestData.ipp_txtRecord
570        expectServiceList[ipp_service.toString()] = 1
571
572        afp_service.InstanceName = p2pconsts.AfpTestData.afpInstanceName
573        afp_service.RegistrationType = (
574            p2pconsts.AfpTestData.afpRegistrationType + ".local.")
575        afp_service.FullDomainName = ""
576        afp_service.TxtRecordMap = ""
577        expectServiceList[afp_service.toString()] = 1
578
579        afp_service.InstanceName = ""
580        afp_service.RegistrationType = ""
581        afp_service.FullDomainName = p2pconsts.AfpTestData.afpDomainName
582        afp_service.TxtRecordMap = p2pconsts.AfpTestData.afp_txtRecord
583        expectServiceList[afp_service.toString()] = 1
584
585        return expectServiceList
586    elif serviceType == WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP:
587        upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + "::" + (
588            p2pconsts.UpnpTestData.rootdevice)
589        expectServiceList[upnp_service] = 1
590        if queryString1 != "upnp:rootdevice":
591            upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + (
592                "::" + p2pconsts.UpnpTestData.AVTransport)
593            expectServiceList[upnp_service] = 1
594            upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + (
595                "::" + p2pconsts.UpnpTestData.ConnectionManager)
596            expectServiceList[upnp_service] = 1
597            upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + (
598                "::" + p2pconsts.UpnpTestData.serviceType)
599            expectServiceList[upnp_service] = 1
600            upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid
601            expectServiceList[upnp_service] = 1
602
603    return expectServiceList
604
605
606def p2p_create_group(ad):
607    """Create a group as Group Owner
608
609    Args:
610        ad: The android device
611    """
612    ad.droid.wifiP2pCreateGroup()
613    ad.ed.pop_event(p2pconsts.CREATE_GROUP_SUCCESS_EVENT,
614                    p2pconsts.DEFAULT_TIMEOUT)
615    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
616
617
618def p2p_create_group_with_config(ad, network_name, passphrase, band):
619    """Create a group as Group Owner
620
621    Args:
622        ad: The android device
623    """
624    wifi_p2p_config = {
625        WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name,
626        WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase,
627        WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band,
628        WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: {
629            WifiP2PEnums.WpsInfo.WPS_SETUP_KEY:
630            WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC
631        }
632    }
633    ad.droid.wifiP2pCreateGroupWithConfig(wifi_p2p_config)
634    ad.ed.pop_event(p2pconsts.CREATE_GROUP_SUCCESS_EVENT,
635                    p2pconsts.DEFAULT_TIMEOUT)
636    time.sleep(p2pconsts.DEFAULT_SLEEPTIME)
637
638
639def wifi_p2p_set_channels_for_current_group(ad, listening_chan,
640                                            operating_chan):
641    """Sets the listening channel and operating channel of the current group
642       created with initialize.
643
644    Args:
645        ad: The android device
646        listening_chan: Integer, the listening channel
647        operating_chan: Integer, the operating channel
648    """
649    ad.droid.wifiP2pSetChannelsForCurrentGroup(listening_chan, operating_chan)
650    ad.ed.pop_event(p2pconsts.SET_CHANNEL_SUCCESS_EVENT,
651                    p2pconsts.DEFAULT_TIMEOUT)
652
653
654class WifiP2PEnums():
655    class WifiP2pConfig():
656        DEVICEADDRESS_KEY = "deviceAddress"
657        WPSINFO_KEY = "wpsInfo"
658        GO_INTENT_KEY = "groupOwnerIntent"
659        NETID_KEY = "netId"
660        NETWORK_NAME = "networkName"
661        PASSPHRASE = "passphrase"
662        GROUP_BAND = "groupOwnerBand"
663
664    class WpsInfo():
665        WPS_SETUP_KEY = "setup"
666        BSSID_KEY = "BSSID"
667        WPS_PIN_KEY = "pin"
668        #TODO: remove it from wifi_test_utils.py
669        WIFI_WPS_INFO_PBC = 0
670        WIFI_WPS_INFO_DISPLAY = 1
671        WIFI_WPS_INFO_KEYPAD = 2
672        WIFI_WPS_INFO_LABEL = 3
673        WIFI_WPS_INFO_INVALID = 4
674
675    class WifiP2pServiceInfo():
676        #TODO: remove it from wifi_test_utils.py
677        # Macros for wifi p2p.
678        WIFI_P2P_SERVICE_TYPE_ALL = 0
679        WIFI_P2P_SERVICE_TYPE_BONJOUR = 1
680        WIFI_P2P_SERVICE_TYPE_UPNP = 2
681        WIFI_P2P_SERVICE_TYPE_VENDOR_SPECIFIC = 255
682
683    class WifiP2pDnsSdServiceResponse():
684        def __init__(self):
685            pass
686
687        InstanceName = ""
688        RegistrationType = ""
689        FullDomainName = ""
690        TxtRecordMap = {}
691
692        def toString(self):
693            return self.InstanceName + self.RegistrationType + (
694                self.FullDomainName + str(self.TxtRecordMap))
695