1#!/usr/bin/python3.4
2#
3#   Copyright 2017 - The Android Open Source Project
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 time
18
19from acts import asserts
20from acts.test_decorators import test_tracker_info
21from acts_contrib.test_utils.net import connectivity_const as cconsts
22from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
23from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
24from acts_contrib.test_utils.wifi.aware import aware_const as aconsts
25from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils
26from acts_contrib.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest
27
28
29class DataPathTest(AwareBaseTest):
30    """Set of tests for Wi-Fi Aware data-path."""
31
32    # configuration parameters used by tests
33    ENCR_TYPE_OPEN = 0
34    ENCR_TYPE_PASSPHRASE = 1
35    ENCR_TYPE_PMK = 2
36
37    PASSPHRASE = "This is some random passphrase - very very secure!!"
38    PASSPHRASE_MIN = "01234567"
39    PASSPHRASE_MAX = "012345678901234567890123456789012345678901234567890123456789012"
40    PMK = "ODU0YjE3YzdmNDJiNWI4NTQ2NDJjNDI3M2VkZTQyZGU="
41    PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!"
42    PMK2 = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="
43
44    PING_MSG = "ping"
45
46    # message re-transmit counter (increases reliability in open-environment)
47    # Note: reliability of message transmission is tested elsewhere
48    MSG_RETX_COUNT = 5  # hard-coded max value, internal API
49
50    # number of second to 'reasonably' wait to make sure that devices synchronize
51    # with each other - useful for OOB test cases, where the OOB discovery would
52    # take some time
53    WAIT_FOR_CLUSTER = 5
54
55    def create_config(self, dtype):
56        """Create a base configuration based on input parameters.
57
58    Args:
59      dtype: Publish or Subscribe discovery type
60
61    Returns:
62      Discovery configuration object.
63    """
64        config = {}
65        config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype
66        config[
67            aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceDataPath"
68        return config
69
70    def request_network(self, dut, ns):
71        """Request a Wi-Fi Aware network.
72
73    Args:
74      dut: Device
75      ns: Network specifier
76    Returns: the request key
77    """
78        network_req = {"TransportType": 5, "NetworkSpecifier": ns}
79        return dut.droid.connectivityRequestWifiAwareNetwork(network_req)
80
81    def set_up_discovery(self,
82                         ptype,
83                         stype,
84                         get_peer_id,
85                         pub_on_both=False,
86                         pub_on_both_same=True):
87        """Set up discovery sessions and wait for service discovery.
88
89    Args:
90      ptype: Publish discovery type
91      stype: Subscribe discovery type
92      get_peer_id: Send a message across to get the peer's id
93      pub_on_both: If True then set up a publisher on both devices. The second
94                   publisher isn't used (existing to test use-case).
95      pub_on_both_same: If True then the second publish uses an identical
96                        service name, otherwise a different service name.
97    """
98        p_dut = self.android_devices[0]
99        p_dut.pretty_name = "Publisher"
100        s_dut = self.android_devices[1]
101        s_dut.pretty_name = "Subscriber"
102
103        # Publisher+Subscriber: attach and wait for confirmation
104        p_id = p_dut.droid.wifiAwareAttach()
105        autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED)
106        time.sleep(self.device_startup_offset)
107        s_id = s_dut.droid.wifiAwareAttach()
108        autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED)
109
110        # Publisher: start publish and wait for confirmation
111        p_disc_id = p_dut.droid.wifiAwarePublish(p_id,
112                                                 self.create_config(ptype))
113        autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED)
114
115        # Optionally set up a publish session on the Subscriber device
116        if pub_on_both:
117            p2_config = self.create_config(ptype)
118            if not pub_on_both_same:
119                p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = (
120                        p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] + "-XYZXYZ")
121            s_dut.droid.wifiAwarePublish(s_id, p2_config)
122            autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED)
123
124        # Subscriber: start subscribe and wait for confirmation
125        s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id,
126                                                   self.create_config(stype))
127        autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED)
128
129        # Subscriber: wait for service discovery
130        discovery_event = autils.wait_for_event(
131            s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED)
132        peer_id_on_sub = discovery_event["data"][
133            aconsts.SESSION_CB_KEY_PEER_ID]
134
135        peer_id_on_pub = None
136        if get_peer_id:  # only need message to receive peer ID
137            # Subscriber: send message to peer (Publisher - so it knows our address)
138            s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub,
139                                             self.get_next_msg_id(),
140                                             self.PING_MSG,
141                                             self.MSG_RETX_COUNT)
142            autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT)
143
144            # Publisher: wait for received message
145            pub_rx_msg_event = autils.wait_for_event(
146                p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED)
147            peer_id_on_pub = pub_rx_msg_event["data"][
148                aconsts.SESSION_CB_KEY_PEER_ID]
149
150        return (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub,
151                peer_id_on_pub)
152
153    def run_ib_data_path_test(self,
154                              ptype,
155                              stype,
156                              encr_type,
157                              use_peer_id,
158                              passphrase_to_use=None,
159                              pub_on_both=False,
160                              pub_on_both_same=True,
161                              expect_failure=False):
162        """Runs the in-band data-path tests.
163
164    Args:
165      ptype: Publish discovery type
166      stype: Subscribe discovery type
167      encr_type: Encryption type, one of ENCR_TYPE_*
168      use_peer_id: On Responder (publisher): True to use peer ID, False to
169                   accept any request
170      passphrase_to_use: The passphrase to use if encr_type=ENCR_TYPE_PASSPHRASE
171                         If None then use self.PASSPHRASE
172      pub_on_both: If True then set up a publisher on both devices. The second
173                   publisher isn't used (existing to test use-case).
174      pub_on_both_same: If True then the second publish uses an identical
175                        service name, otherwise a different service name.
176      expect_failure: If True then don't expect NDP formation, otherwise expect
177                      NDP setup to succeed.
178    """
179        (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub,
180         peer_id_on_pub) = self.set_up_discovery(
181            ptype,
182            stype,
183            use_peer_id,
184            pub_on_both=pub_on_both,
185            pub_on_both_same=pub_on_both_same)
186
187        passphrase = None
188        pmk = None
189        if encr_type == self.ENCR_TYPE_PASSPHRASE:
190            passphrase = (self.PASSPHRASE
191                          if passphrase_to_use == None else passphrase_to_use)
192        elif encr_type == self.ENCR_TYPE_PMK:
193            pmk = self.PMK
194
195        port = 1234
196        transport_protocol = 6  # TCP/IP
197
198        # Publisher: request network
199        if encr_type == self.ENCR_TYPE_OPEN:
200            p_req_key = self.request_network(
201                p_dut,
202                p_dut.droid.wifiAwareCreateNetworkSpecifier(
203                    p_disc_id, peer_id_on_pub
204                    if use_peer_id else None, passphrase, pmk))
205        else:
206            p_req_key = self.request_network(
207                p_dut,
208                p_dut.droid.wifiAwareCreateNetworkSpecifier(
209                    p_disc_id, peer_id_on_pub if use_peer_id else None,
210                    passphrase, pmk, port, transport_protocol))
211
212        # Subscriber: request network
213        s_req_key = self.request_network(
214            s_dut,
215            s_dut.droid.wifiAwareCreateNetworkSpecifier(
216                s_disc_id, peer_id_on_sub, passphrase, pmk))
217
218        if expect_failure:
219            # Publisher & Subscriber: expect unavailable callbacks
220            autils.wait_for_event_with_keys(
221                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
222                autils.EVENT_NDP_TIMEOUT,
223                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
224            autils.wait_for_event_with_keys(
225                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
226                autils.EVENT_NDP_TIMEOUT,
227                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
228        else:
229            # Publisher & Subscriber: wait for network formation
230            p_net_event_nc = autils.wait_for_event_with_keys(
231                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
232                autils.EVENT_NDP_TIMEOUT,
233                (cconsts.NETWORK_CB_KEY_EVENT,
234                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
235                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
236            s_net_event_nc = autils.wait_for_event_with_keys(
237                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
238                autils.EVENT_NDP_TIMEOUT,
239                (cconsts.NETWORK_CB_KEY_EVENT,
240                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
241                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
242
243            # validate no leak of information
244            asserts.assert_false(
245                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[
246                    "data"], "Network specifier leak!")
247            asserts.assert_false(
248                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[
249                    "data"], "Network specifier leak!")
250
251            # note that Pub <-> Sub since IPv6 are of peer's!
252            s_ipv6 = p_net_event_nc["data"][aconsts.NET_CAP_IPV6]
253            p_ipv6 = s_net_event_nc["data"][aconsts.NET_CAP_IPV6]
254
255            self.verify_network_info(
256                p_net_event_nc["data"], s_net_event_nc["data"],
257                encr_type == self.ENCR_TYPE_OPEN, port, transport_protocol)
258
259            p_net_event_lp = autils.wait_for_event_with_keys(
260                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
261                autils.EVENT_NDP_TIMEOUT,
262                (cconsts.NETWORK_CB_KEY_EVENT,
263                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
264                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
265            s_net_event_lp = autils.wait_for_event_with_keys(
266                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
267                autils.EVENT_NDP_TIMEOUT,
268                (cconsts.NETWORK_CB_KEY_EVENT,
269                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
270                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
271
272            p_aware_if = p_net_event_lp["data"][
273                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
274            s_aware_if = s_net_event_lp["data"][
275                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
276
277            self.log.info("Interface names: p=%s, s=%s", p_aware_if,
278                          s_aware_if)
279            self.log.info("Interface addresses (IPv6): p=%s, s=%s", p_ipv6,
280                          s_ipv6)
281
282            # open sockets to test connection
283            asserts.assert_true(
284                autils.verify_socket_connect(p_dut, s_dut, p_ipv6, s_ipv6, 0),
285                "Failed socket link with Pub as Server")
286            asserts.assert_true(
287                autils.verify_socket_connect(s_dut, p_dut, s_ipv6, p_ipv6, 0),
288                "Failed socket link with Sub as Server")
289
290            # terminate sessions and wait for ON_LOST callbacks
291            p_dut.droid.wifiAwareDestroy(p_id)
292            s_dut.droid.wifiAwareDestroy(s_id)
293
294            autils.wait_for_event_with_keys(
295                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
296                autils.EVENT_NDP_TIMEOUT,
297                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST),
298                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
299            autils.wait_for_event_with_keys(
300                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
301                autils.EVENT_NDP_TIMEOUT,
302                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST),
303                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
304
305        # clean-up
306        p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key)
307        s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key)
308
309    def run_oob_data_path_test(self,
310                               encr_type,
311                               use_peer_id,
312                               setup_discovery_sessions=False,
313                               expect_failure=False):
314        """Runs the out-of-band data-path tests.
315
316    Args:
317      encr_type: Encryption type, one of ENCR_TYPE_*
318      use_peer_id: On Responder: True to use peer ID, False to accept any
319                   request
320      setup_discovery_sessions: If True also set up a (spurious) discovery
321        session (pub on both sides, sub on Responder side). Validates a corner
322        case.
323      expect_failure: If True then don't expect NDP formation, otherwise expect
324                      NDP setup to succeed.
325    """
326        init_dut = self.android_devices[0]
327        init_dut.pretty_name = "Initiator"
328        resp_dut = self.android_devices[1]
329        resp_dut.pretty_name = "Responder"
330
331        # Initiator+Responder: attach and wait for confirmation & identity
332        init_id = init_dut.droid.wifiAwareAttach(True)
333        autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED)
334        init_ident_event = autils.wait_for_event(
335            init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
336        init_mac = init_ident_event["data"]["mac"]
337        time.sleep(self.device_startup_offset)
338        resp_id = resp_dut.droid.wifiAwareAttach(True)
339        autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED)
340        resp_ident_event = autils.wait_for_event(
341            resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
342        resp_mac = resp_ident_event["data"]["mac"]
343
344        # wait for for devices to synchronize with each other - there are no other
345        # mechanisms to make sure this happens for OOB discovery (except retrying
346        # to execute the data-path request)
347        time.sleep(self.WAIT_FOR_CLUSTER)
348
349        if setup_discovery_sessions:
350            init_dut.droid.wifiAwarePublish(
351                init_id, self.create_config(aconsts.PUBLISH_TYPE_UNSOLICITED))
352            autils.wait_for_event(init_dut,
353                                  aconsts.SESSION_CB_ON_PUBLISH_STARTED)
354            resp_dut.droid.wifiAwarePublish(
355                resp_id, self.create_config(aconsts.PUBLISH_TYPE_UNSOLICITED))
356            autils.wait_for_event(resp_dut,
357                                  aconsts.SESSION_CB_ON_PUBLISH_STARTED)
358            resp_dut.droid.wifiAwareSubscribe(
359                resp_id, self.create_config(aconsts.SUBSCRIBE_TYPE_PASSIVE))
360            autils.wait_for_event(resp_dut,
361                                  aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED)
362            autils.wait_for_event(resp_dut,
363                                  aconsts.SESSION_CB_ON_SERVICE_DISCOVERED)
364
365        passphrase = None
366        pmk = None
367        if encr_type == self.ENCR_TYPE_PASSPHRASE:
368            passphrase = self.PASSPHRASE
369        elif encr_type == self.ENCR_TYPE_PMK:
370            pmk = self.PMK
371
372        # Responder: request network
373        resp_req_key = self.request_network(
374            resp_dut,
375            resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
376                resp_id, aconsts.DATA_PATH_RESPONDER, init_mac
377                if use_peer_id else None, passphrase, pmk))
378
379        # Initiator: request network
380        init_req_key = self.request_network(
381            init_dut,
382            init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
383                init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase,
384                pmk))
385
386        if expect_failure:
387            # Initiator & Responder: expect unavailable callbacks
388            autils.wait_for_event_with_keys(
389                init_dut, cconsts.EVENT_NETWORK_CALLBACK,
390                autils.EVENT_NDP_TIMEOUT,
391                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
392            autils.wait_for_event_with_keys(
393                resp_dut, cconsts.EVENT_NETWORK_CALLBACK,
394                autils.EVENT_NDP_TIMEOUT,
395                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
396        else:
397            # Initiator & Responder: wait for network formation
398            init_net_event_nc = autils.wait_for_event_with_keys(
399                init_dut, cconsts.EVENT_NETWORK_CALLBACK,
400                autils.EVENT_NDP_TIMEOUT,
401                (cconsts.NETWORK_CB_KEY_EVENT,
402                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
403                (cconsts.NETWORK_CB_KEY_ID, init_req_key))
404            resp_net_event_nc = autils.wait_for_event_with_keys(
405                resp_dut, cconsts.EVENT_NETWORK_CALLBACK,
406                autils.EVENT_NDP_TIMEOUT,
407                (cconsts.NETWORK_CB_KEY_EVENT,
408                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
409                (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
410
411            # validate no leak of information
412            asserts.assert_false(
413                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in init_net_event_nc[
414                    "data"], "Network specifier leak!")
415            asserts.assert_false(
416                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in resp_net_event_nc[
417                    "data"], "Network specifier leak!")
418
419            # note that Init <-> Resp since IPv6 are of peer's!
420            init_ipv6 = resp_net_event_nc["data"][aconsts.NET_CAP_IPV6]
421            resp_ipv6 = init_net_event_nc["data"][aconsts.NET_CAP_IPV6]
422
423            init_net_event_lp = autils.wait_for_event_with_keys(
424                init_dut, cconsts.EVENT_NETWORK_CALLBACK,
425                autils.EVENT_NDP_TIMEOUT,
426                (cconsts.NETWORK_CB_KEY_EVENT,
427                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
428                (cconsts.NETWORK_CB_KEY_ID, init_req_key))
429            resp_net_event_lp = autils.wait_for_event_with_keys(
430                resp_dut, cconsts.EVENT_NETWORK_CALLBACK,
431                autils.EVENT_NDP_TIMEOUT,
432                (cconsts.NETWORK_CB_KEY_EVENT,
433                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
434                (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
435
436            init_aware_if = init_net_event_lp["data"][
437                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
438            resp_aware_if = resp_net_event_lp["data"][
439                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
440
441            self.log.info("Interface names: I=%s, R=%s", init_aware_if,
442                          resp_aware_if)
443            self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6,
444                          resp_ipv6)
445
446            # open sockets to test connection
447            asserts.assert_true(
448                autils.verify_socket_connect(init_dut, resp_dut, init_ipv6,
449                                             resp_ipv6, 0),
450                "Failed socket link with Initiator as Server")
451            asserts.assert_true(
452                autils.verify_socket_connect(resp_dut, init_dut, resp_ipv6,
453                                             init_ipv6, 0),
454                "Failed socket link with Responder as Server")
455
456            # terminate sessions and wait for ON_LOST callbacks
457            init_dut.droid.wifiAwareDestroy(init_id)
458            resp_dut.droid.wifiAwareDestroy(resp_id)
459
460            autils.wait_for_event_with_keys(
461                init_dut, cconsts.EVENT_NETWORK_CALLBACK,
462                autils.EVENT_NDP_TIMEOUT,
463                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST),
464                (cconsts.NETWORK_CB_KEY_ID, init_req_key))
465            autils.wait_for_event_with_keys(
466                resp_dut, cconsts.EVENT_NETWORK_CALLBACK,
467                autils.EVENT_NDP_TIMEOUT,
468                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST),
469                (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
470
471        # clean-up
472        resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
473        init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
474
475    def run_mismatched_ib_data_path_test(self, pub_mismatch, sub_mismatch):
476        """Runs the negative in-band data-path tests: mismatched peer ID.
477
478    Args:
479      pub_mismatch: Mismatch the publisher's ID
480      sub_mismatch: Mismatch the subscriber's ID
481    """
482        (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub,
483         peer_id_on_pub) = self.set_up_discovery(
484            aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE,
485            True)
486
487        if pub_mismatch:
488            peer_id_on_pub = peer_id_on_pub - 1
489        if sub_mismatch:
490            peer_id_on_sub = peer_id_on_sub - 1
491
492        # Publisher: request network
493        p_req_key = self.request_network(
494            p_dut,
495            p_dut.droid.wifiAwareCreateNetworkSpecifier(
496                p_disc_id, peer_id_on_pub, None))
497
498        # Subscriber: request network
499        s_req_key = self.request_network(
500            s_dut,
501            s_dut.droid.wifiAwareCreateNetworkSpecifier(
502                s_disc_id, peer_id_on_sub, None))
503
504        # Publisher & Subscriber:
505        # - expect unavailable callbacks on the party with the bad ID
506        # - also expect unavailable on the Initiator party (i.e. the
507        #   Subscriber) if the Publisher has a bad ID
508        # - but a Publisher with a valid ID will keep waiting ...
509        autils.wait_for_event_with_keys(
510            s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
511            (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
512        if pub_mismatch:
513            autils.wait_for_event_with_keys(
514                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
515                autils.EVENT_NDP_TIMEOUT,
516                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
517        else:
518            time.sleep(autils.EVENT_NDP_TIMEOUT)
519            autils.fail_on_event_with_keys(
520                p_dut, cconsts.EVENT_NETWORK_CALLBACK, 0,
521                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
522
523        # clean-up
524        p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key)
525        s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key)
526
527    def run_mismatched_oob_data_path_test(self,
528                                          init_mismatch_mac=False,
529                                          resp_mismatch_mac=False,
530                                          init_encr_type=ENCR_TYPE_OPEN,
531                                          resp_encr_type=ENCR_TYPE_OPEN):
532        """Runs the negative out-of-band data-path tests: mismatched information
533    between Responder and Initiator.
534
535    Args:
536      init_mismatch_mac: True to mismatch the Initiator MAC address
537      resp_mismatch_mac: True to mismatch the Responder MAC address
538      init_encr_type: Encryption type of Initiator - ENCR_TYPE_*
539      resp_encr_type: Encryption type of Responder - ENCR_TYPE_*
540    """
541        init_dut = self.android_devices[0]
542        init_dut.pretty_name = "Initiator"
543        resp_dut = self.android_devices[1]
544        resp_dut.pretty_name = "Responder"
545
546        # Initiator+Responder: attach and wait for confirmation & identity
547        init_id = init_dut.droid.wifiAwareAttach(True)
548        autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED)
549        init_ident_event = autils.wait_for_event(
550            init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
551        init_mac = init_ident_event["data"]["mac"]
552        time.sleep(self.device_startup_offset)
553        resp_id = resp_dut.droid.wifiAwareAttach(True)
554        autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED)
555        resp_ident_event = autils.wait_for_event(
556            resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
557        resp_mac = resp_ident_event["data"]["mac"]
558
559        if init_mismatch_mac:  # assumes legit ones don't start with "00"
560            init_mac = "00" + init_mac[2:]
561        if resp_mismatch_mac:
562            resp_mac = "00" + resp_mac[2:]
563
564        # wait for for devices to synchronize with each other - there are no other
565        # mechanisms to make sure this happens for OOB discovery (except retrying
566        # to execute the data-path request)
567        time.sleep(self.WAIT_FOR_CLUSTER)
568
569        # set up separate keys: even if types are the same we want a mismatch
570        init_passphrase = None
571        init_pmk = None
572        if init_encr_type == self.ENCR_TYPE_PASSPHRASE:
573            init_passphrase = self.PASSPHRASE
574        elif init_encr_type == self.ENCR_TYPE_PMK:
575            init_pmk = self.PMK
576
577        resp_passphrase = None
578        resp_pmk = None
579        if resp_encr_type == self.ENCR_TYPE_PASSPHRASE:
580            resp_passphrase = self.PASSPHRASE2
581        elif resp_encr_type == self.ENCR_TYPE_PMK:
582            resp_pmk = self.PMK2
583
584        # Responder: request network
585        resp_req_key = self.request_network(
586            resp_dut,
587            resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
588                resp_id, aconsts.DATA_PATH_RESPONDER, init_mac,
589                resp_passphrase, resp_pmk))
590
591        # Initiator: request network
592        init_req_key = self.request_network(
593            init_dut,
594            init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
595                init_id, aconsts.DATA_PATH_INITIATOR, resp_mac,
596                init_passphrase, init_pmk))
597
598        # Initiator & Responder:
599        # - expect unavailable on the Initiator party if the
600        #   Initiator and Responder with mac or encryption mismatch
601        # - For responder:
602        #   - If mac mismatch, responder will keep waiting ...
603        #   - If encryption mismatch, responder expect unavailable
604        autils.wait_for_event_with_keys(
605            init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
606            (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
607        time.sleep(autils.EVENT_NDP_TIMEOUT)
608        if init_mismatch_mac or resp_mismatch_mac:
609            autils.fail_on_event_with_keys(
610                resp_dut, cconsts.EVENT_NETWORK_CALLBACK, 0,
611                (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
612        else:
613            autils.wait_for_event_with_keys(
614                resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
615                (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE))
616
617        # clean-up
618        resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
619        init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
620
621    def verify_network_info(self, p_data, s_data, open, port,
622                            transport_protocol):
623        """Verify that the port and transport protocol information is correct.
624            - should only exist on subscriber (received from publisher)
625              and match transmitted values
626            - should only exist on an encrypted NDP
627
628        Args:
629            p_data, s_data: Pub and Sub (respectively) net cap event data.
630            open: True if NDP unencrypted, False if encrypted.
631            port: Expected port value.
632            transport_protocol: Expected transport protocol value.
633        """
634        asserts.assert_true(aconsts.NET_CAP_PORT not in p_data,
635                            "port info not expected on Pub")
636        asserts.assert_true(aconsts.NET_CAP_TRANSPORT_PROTOCOL not in p_data,
637                            "transport protocol info not expected on Pub")
638        if open:
639            asserts.assert_true(aconsts.NET_CAP_PORT not in s_data,
640                                "port info not expected on Sub (open NDP)")
641            asserts.assert_true(
642                aconsts.NET_CAP_TRANSPORT_PROTOCOL not in s_data,
643                "transport protocol info not expected on Sub (open NDP)")
644        else:
645            asserts.assert_equal(s_data[aconsts.NET_CAP_PORT], port,
646                                 "Port info does not match on Sub (from Pub)")
647            asserts.assert_equal(
648                s_data[aconsts.NET_CAP_TRANSPORT_PROTOCOL], transport_protocol,
649                "Transport protocol info does not match on Sub (from Pub)")
650
651    #######################################
652    # Positive In-Band (IB) tests key:
653    #
654    # names is: test_ib_<pub_type>_<sub_type>_<encr_type>_<peer_spec>
655    # where:
656    #
657    # pub_type: Type of publish discovery session: unsolicited or solicited.
658    # sub_type: Type of subscribe discovery session: passive or active.
659    # encr_type: Encription type: open, passphrase
660    # peer_spec: Peer specification method: any or specific
661    #
662    # Note: In-Band means using Wi-Fi Aware for discovery and referring to the
663    # peer using the Aware-provided peer handle (as opposed to a MAC address).
664    #######################################
665
666    @test_tracker_info(uuid="fa30bedc-d1de-4440-bf25-ec00d10555af")
667    @WifiBaseTest.wifi_test_wrap
668    def test_ib_unsolicited_passive_open_specific(self):
669        """Data-path: in-band, unsolicited/passive, open encryption, specific peer
670
671    Verifies end-to-end discovery + data-path creation.
672    """
673        self.run_ib_data_path_test(
674            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
675            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
676            encr_type=self.ENCR_TYPE_OPEN,
677            use_peer_id=True)
678
679    @test_tracker_info(uuid="57fc9d53-32ae-470f-a8b1-2fe37893687d")
680    @WifiBaseTest.wifi_test_wrap
681    def test_ib_unsolicited_passive_open_any(self):
682        """Data-path: in-band, unsolicited/passive, open encryption, any peer
683
684    Verifies end-to-end discovery + data-path creation.
685    """
686        self.run_ib_data_path_test(
687            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
688            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
689            encr_type=self.ENCR_TYPE_OPEN,
690            use_peer_id=False)
691
692    @test_tracker_info(uuid="93b2a23d-8579-448a-936c-7812929464cf")
693    @WifiBaseTest.wifi_test_wrap
694    def test_ib_unsolicited_passive_passphrase_specific(self):
695        """Data-path: in-band, unsolicited/passive, passphrase, specific peer
696
697    Verifies end-to-end discovery + data-path creation.
698    """
699        self.run_ib_data_path_test(
700            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
701            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
702            encr_type=self.ENCR_TYPE_PASSPHRASE,
703            use_peer_id=True)
704
705    @test_tracker_info(uuid="1736126f-a0ff-4712-acc4-f89b4eef5716")
706    @WifiBaseTest.wifi_test_wrap
707    def test_ib_unsolicited_passive_passphrase_any(self):
708        """Data-path: in-band, unsolicited/passive, passphrase, any peer
709
710    Verifies end-to-end discovery + data-path creation.
711    """
712        self.run_ib_data_path_test(
713            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
714            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
715            encr_type=self.ENCR_TYPE_PASSPHRASE,
716            use_peer_id=False)
717
718    @test_tracker_info(uuid="b9353d5b-3f77-46bf-bfd9-65d56a7c939a")
719    @WifiBaseTest.wifi_test_wrap
720    def test_ib_unsolicited_passive_pmk_specific(self):
721        """Data-path: in-band, unsolicited/passive, PMK, specific peer
722
723    Verifies end-to-end discovery + data-path creation.
724    """
725        self.run_ib_data_path_test(
726            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
727            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
728            encr_type=self.ENCR_TYPE_PMK,
729            use_peer_id=True)
730
731    @test_tracker_info(uuid="06f3b2ab-4a10-4398-83a4-6a23851b1662")
732    @WifiBaseTest.wifi_test_wrap
733    def test_ib_unsolicited_passive_pmk_any(self):
734        """Data-path: in-band, unsolicited/passive, PMK, any peer
735
736    Verifies end-to-end discovery + data-path creation.
737    """
738        self.run_ib_data_path_test(
739            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
740            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
741            encr_type=self.ENCR_TYPE_PMK,
742            use_peer_id=False)
743
744    @test_tracker_info(uuid="0ed7d8b3-a69e-46ba-aeb7-13e507ecf290")
745    @WifiBaseTest.wifi_test_wrap
746    def test_ib_solicited_active_open_specific(self):
747        """Data-path: in-band, solicited/active, open encryption, specific peer
748
749    Verifies end-to-end discovery + data-path creation.
750    """
751        self.run_ib_data_path_test(
752            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
753            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
754            encr_type=self.ENCR_TYPE_OPEN,
755            use_peer_id=True)
756
757    @test_tracker_info(uuid="c7ba6d28-5ef6-45d9-95d5-583ad6d981f3")
758    @WifiBaseTest.wifi_test_wrap
759    def test_ib_solicited_active_open_any(self):
760        """Data-path: in-band, solicited/active, open encryption, any peer
761
762    Verifies end-to-end discovery + data-path creation.
763    """
764        self.run_ib_data_path_test(
765            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
766            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
767            encr_type=self.ENCR_TYPE_OPEN,
768            use_peer_id=False)
769
770    @test_tracker_info(uuid="388cea99-0e2e-49ea-b00e-f3e56b6236e5")
771    @WifiBaseTest.wifi_test_wrap
772    def test_ib_solicited_active_passphrase_specific(self):
773        """Data-path: in-band, solicited/active, passphrase, specific peer
774
775    Verifies end-to-end discovery + data-path creation.
776    """
777        self.run_ib_data_path_test(
778            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
779            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
780            encr_type=self.ENCR_TYPE_PASSPHRASE,
781            use_peer_id=True)
782
783    @test_tracker_info(uuid="fcd3e28a-5eab-4169-8a0c-dc7204dcdc13")
784    @WifiBaseTest.wifi_test_wrap
785    def test_ib_solicited_active_passphrase_any(self):
786        """Data-path: in-band, solicited/active, passphrase, any peer
787
788    Verifies end-to-end discovery + data-path creation.
789    """
790        self.run_ib_data_path_test(
791            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
792            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
793            encr_type=self.ENCR_TYPE_PASSPHRASE,
794            use_peer_id=False)
795
796    @test_tracker_info(uuid="9d4eaad7-ba53-4a06-8ce0-e308daea3309")
797    @WifiBaseTest.wifi_test_wrap
798    def test_ib_solicited_active_pmk_specific(self):
799        """Data-path: in-band, solicited/active, PMK, specific peer
800
801    Verifies end-to-end discovery + data-path creation.
802    """
803        self.run_ib_data_path_test(
804            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
805            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
806            encr_type=self.ENCR_TYPE_PMK,
807            use_peer_id=True)
808
809    @test_tracker_info(uuid="129d850e-c312-4137-a67b-05ae95fe66cc")
810    @WifiBaseTest.wifi_test_wrap
811    def test_ib_solicited_active_pmk_any(self):
812        """Data-path: in-band, solicited/active, PMK, any peer
813
814    Verifies end-to-end discovery + data-path creation.
815    """
816        self.run_ib_data_path_test(
817            ptype=aconsts.PUBLISH_TYPE_SOLICITED,
818            stype=aconsts.SUBSCRIBE_TYPE_ACTIVE,
819            encr_type=self.ENCR_TYPE_PMK,
820            use_peer_id=False)
821
822    #######################################
823    # Positive In-Band (IB) with a publish session running on the subscriber
824    # tests key:
825    #
826    # names is: test_ib_extra_pub_<same|diff>_<pub_type>_<sub_type>
827    #                                          _<encr_type>_<peer_spec>
828    # where:
829    #
830    # same|diff: Whether the extra publish session (on the subscriber) is the same
831    #            or different from the primary session.
832    # pub_type: Type of publish discovery session: unsolicited or solicited.
833    # sub_type: Type of subscribe discovery session: passive or active.
834    # encr_type: Encryption type: open, passphrase
835    # peer_spec: Peer specification method: any or specific
836    #
837    # Note: In-Band means using Wi-Fi Aware for discovery and referring to the
838    # peer using the Aware-provided peer handle (as opposed to a MAC address).
839    #######################################
840
841    @test_tracker_info(uuid="e855dd81-45c8-4bb2-a204-7687c48ff843")
842    @WifiBaseTest.wifi_test_wrap
843    def test_ib_extra_pub_same_unsolicited_passive_open_specific(self):
844        """Data-path: in-band, unsolicited/passive, open encryption, specific peer.
845
846    Configuration contains a publisher (for the same service) running on *both*
847    devices.
848
849    Verifies end-to-end discovery + data-path creation.
850    """
851        self.run_ib_data_path_test(
852            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
853            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
854            encr_type=self.ENCR_TYPE_OPEN,
855            use_peer_id=True,
856            pub_on_both=True,
857            pub_on_both_same=True)
858
859    @test_tracker_info(uuid="228ea657-82e6-44bc-8369-a2c719a5e252")
860    @WifiBaseTest.wifi_test_wrap
861    def test_ib_extra_pub_same_unsolicited_passive_open_any(self):
862        """Data-path: in-band, unsolicited/passive, open encryption, any peer.
863
864    Configuration contains a publisher (for the same service) running on *both*
865    devices.
866
867    Verifies end-to-end discovery + data-path creation.
868    """
869        self.run_ib_data_path_test(
870            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
871            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
872            encr_type=self.ENCR_TYPE_OPEN,
873            use_peer_id=False,
874            pub_on_both=True,
875            pub_on_both_same=True)
876
877    @test_tracker_info(uuid="7a32f439-d745-4716-a75e-b54109aaaf82")
878    @WifiBaseTest.wifi_test_wrap
879    def test_ib_extra_pub_diff_unsolicited_passive_open_specific(self):
880        """Data-path: in-band, unsolicited/passive, open encryption, specific peer.
881
882    Configuration contains a publisher (for a different service) running on
883    *both* devices.
884
885    Verifies end-to-end discovery + data-path creation.
886    """
887        self.run_ib_data_path_test(
888            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
889            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
890            encr_type=self.ENCR_TYPE_OPEN,
891            use_peer_id=True,
892            pub_on_both=True,
893            pub_on_both_same=False)
894
895    @test_tracker_info(uuid="a14ddc66-88fd-4b49-ab37-225533867c63")
896    @WifiBaseTest.wifi_test_wrap
897    def test_ib_extra_pub_diff_unsolicited_passive_open_any(self):
898        """Data-path: in-band, unsolicited/passive, open encryption, any peer.
899
900    Configuration contains a publisher (for a different service) running on
901    *both* devices.
902
903    Verifies end-to-end discovery + data-path creation.
904    """
905        self.run_ib_data_path_test(
906            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
907            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
908            encr_type=self.ENCR_TYPE_OPEN,
909            use_peer_id=False,
910            pub_on_both=True,
911            pub_on_both_same=False)
912
913    #######################################
914    # Positive Out-of-Band (OOB) tests key:
915    #
916    # names is: test_oob_<encr_type>_<peer_spec>
917    # where:
918    #
919    # encr_type: Encryption type: open, passphrase
920    # peer_spec: Peer specification method: any or specific
921    #
922    # Optionally set up an extra discovery session to test coexistence. If so
923    # add "ib_coex" to test name.
924    #
925    # Note: Out-of-Band means using a non-Wi-Fi Aware mechanism for discovery and
926    # exchange of MAC addresses and then Wi-Fi Aware for data-path.
927    #######################################
928
929    @test_tracker_info(uuid="7db17d8c-1dce-4084-b695-215bbcfe7d41")
930    @WifiBaseTest.wifi_test_wrap
931    def test_oob_open_specific(self):
932        """Data-path: out-of-band, open encryption, specific peer
933
934    Verifies end-to-end discovery + data-path creation.
935    """
936        self.run_oob_data_path_test(
937            encr_type=self.ENCR_TYPE_OPEN, use_peer_id=True)
938
939    @test_tracker_info(uuid="ad416d89-cb95-4a07-8d29-ee213117450b")
940    @WifiBaseTest.wifi_test_wrap
941    def test_oob_open_any(self):
942        """Data-path: out-of-band, open encryption, any peer
943
944    Verifies end-to-end discovery + data-path creation.
945    """
946        self.run_oob_data_path_test(
947            encr_type=self.ENCR_TYPE_OPEN, use_peer_id=False)
948
949    @test_tracker_info(uuid="74937a3a-d524-43e2-8979-4449271cab52")
950    @WifiBaseTest.wifi_test_wrap
951    def test_oob_passphrase_specific(self):
952        """Data-path: out-of-band, passphrase, specific peer
953
954    Verifies end-to-end discovery + data-path creation.
955    """
956        self.run_oob_data_path_test(
957            encr_type=self.ENCR_TYPE_PASSPHRASE, use_peer_id=True)
958
959    @test_tracker_info(uuid="afcbdc7e-d3a9-465b-b1da-ce2e42e3941e")
960    @WifiBaseTest.wifi_test_wrap
961    def test_oob_passphrase_any(self):
962        """Data-path: out-of-band, passphrase, any peer
963
964    Verifies end-to-end discovery + data-path creation.
965    """
966        self.run_oob_data_path_test(
967            encr_type=self.ENCR_TYPE_PASSPHRASE, use_peer_id=False)
968
969    @test_tracker_info(uuid="0d095031-160a-4537-aab5-41b6ad5d55f8")
970    @WifiBaseTest.wifi_test_wrap
971    def test_oob_pmk_specific(self):
972        """Data-path: out-of-band, PMK, specific peer
973
974    Verifies end-to-end discovery + data-path creation.
975    """
976        self.run_oob_data_path_test(
977            encr_type=self.ENCR_TYPE_PMK, use_peer_id=True)
978
979    @test_tracker_info(uuid="e45477bd-66cc-4eb7-88dd-4518c8aa2a74")
980    @WifiBaseTest.wifi_test_wrap
981    def test_oob_pmk_any(self):
982        """Data-path: out-of-band, PMK, any peer
983
984    Verifies end-to-end discovery + data-path creation.
985    """
986        self.run_oob_data_path_test(
987            encr_type=self.ENCR_TYPE_PMK, use_peer_id=False)
988
989    @test_tracker_info(uuid="dd464f24-b404-4eea-955c-d10c9e8adefc")
990    @WifiBaseTest.wifi_test_wrap
991    def test_oob_ib_coex_open_specific(self):
992        """Data-path: out-of-band, open encryption, specific peer - in-band coex:
993    set up a concurrent discovery session to verify no impact. The session
994    consists of Publisher on both ends, and a Subscriber on the Responder.
995
996    Verifies end-to-end discovery + data-path creation.
997    """
998        self.run_oob_data_path_test(
999            encr_type=self.ENCR_TYPE_OPEN,
1000            use_peer_id=True,
1001            setup_discovery_sessions=True)
1002
1003    @test_tracker_info(uuid="088fcd3a-b015-4179-a9a5-91f782b03e3b")
1004    @WifiBaseTest.wifi_test_wrap
1005    def test_oob_ib_coex_open_any(self):
1006        """Data-path: out-of-band, open encryption, any peer - in-band coex:
1007    set up a concurrent discovery session to verify no impact. The session
1008    consists of Publisher on both ends, and a Subscriber on the Responder.
1009
1010    Verifies end-to-end discovery + data-path creation.
1011    """
1012        self.run_oob_data_path_test(
1013            encr_type=self.ENCR_TYPE_OPEN,
1014            use_peer_id=False,
1015            setup_discovery_sessions=True)
1016
1017    ##############################################################
1018
1019    @test_tracker_info(uuid="1c2c9805-dc1e-43b5-a1b8-315e8c9a4337")
1020    @WifiBaseTest.wifi_test_wrap
1021    def test_passphrase_min(self):
1022        """Data-path: minimum passphrase length
1023
1024    Use in-band, unsolicited/passive, any peer combination
1025    """
1026        self.run_ib_data_path_test(
1027            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
1028            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
1029            encr_type=self.ENCR_TYPE_PASSPHRASE,
1030            use_peer_id=False,
1031            passphrase_to_use=self.PASSPHRASE_MIN)
1032
1033    @test_tracker_info(uuid="e696e2b9-87a9-4521-b337-61b9efaa2057")
1034    @WifiBaseTest.wifi_test_wrap
1035    def test_passphrase_max(self):
1036        """Data-path: maximum passphrase length
1037
1038    Use in-band, unsolicited/passive, any peer combination
1039    """
1040        self.run_ib_data_path_test(
1041            ptype=aconsts.PUBLISH_TYPE_UNSOLICITED,
1042            stype=aconsts.SUBSCRIBE_TYPE_PASSIVE,
1043            encr_type=self.ENCR_TYPE_PASSPHRASE,
1044            use_peer_id=False,
1045            passphrase_to_use=self.PASSPHRASE_MAX)
1046
1047    @test_tracker_info(uuid="533cd44c-ff30-4283-ac28-f71fd7b4f02d")
1048    @WifiBaseTest.wifi_test_wrap
1049    def test_negative_mismatch_publisher_peer_id(self):
1050        """Data-path: failure when publisher peer ID is mismatched"""
1051        self.run_mismatched_ib_data_path_test(
1052            pub_mismatch=True, sub_mismatch=False)
1053
1054    @test_tracker_info(uuid="682f275e-722a-4f8b-85e7-0dcea9d25532")
1055    @WifiBaseTest.wifi_test_wrap
1056    def test_negative_mismatch_subscriber_peer_id(self):
1057        """Data-path: failure when subscriber peer ID is mismatched"""
1058        self.run_mismatched_ib_data_path_test(
1059            pub_mismatch=False, sub_mismatch=True)
1060
1061    @test_tracker_info(uuid="7fa82796-7fc9-4d9e-bbbb-84b751788943")
1062    @WifiBaseTest.wifi_test_wrap
1063    def test_negative_mismatch_init_mac(self):
1064        """Data-path: failure when Initiator MAC address mismatch"""
1065        self.run_mismatched_oob_data_path_test(
1066            init_mismatch_mac=True, resp_mismatch_mac=False)
1067
1068    @test_tracker_info(uuid="edeae959-4644-44f9-8d41-bdeb5216954e")
1069    @WifiBaseTest.wifi_test_wrap
1070    def test_negative_mismatch_resp_mac(self):
1071        """Data-path: failure when Responder MAC address mismatch"""
1072        self.run_mismatched_oob_data_path_test(
1073            init_mismatch_mac=False, resp_mismatch_mac=True)
1074
1075    @test_tracker_info(uuid="91f46949-c47f-49f9-a90f-6fae699613a7")
1076    @WifiBaseTest.wifi_test_wrap
1077    def test_negative_mismatch_passphrase(self):
1078        """Data-path: failure when passphrases mismatch"""
1079        self.run_mismatched_oob_data_path_test(
1080            init_encr_type=self.ENCR_TYPE_PASSPHRASE,
1081            resp_encr_type=self.ENCR_TYPE_PASSPHRASE)
1082
1083    @test_tracker_info(uuid="01c49c2e-dc92-4a27-bb47-c4fc67617c23")
1084    @WifiBaseTest.wifi_test_wrap
1085    def test_negative_mismatch_pmk(self):
1086        """Data-path: failure when PMK mismatch"""
1087        self.run_mismatched_oob_data_path_test(
1088            init_encr_type=self.ENCR_TYPE_PMK,
1089            resp_encr_type=self.ENCR_TYPE_PMK)
1090
1091    @test_tracker_info(uuid="4d651797-5fbb-408e-a4b6-a6e1944136da")
1092    @WifiBaseTest.wifi_test_wrap
1093    def test_negative_mismatch_open_passphrase(self):
1094        """Data-path: failure when initiator is open, and responder passphrase"""
1095        self.run_mismatched_oob_data_path_test(
1096            init_encr_type=self.ENCR_TYPE_OPEN,
1097            resp_encr_type=self.ENCR_TYPE_PASSPHRASE)
1098
1099    @test_tracker_info(uuid="1ae697f4-5987-4187-aeef-1e22d07d4a7c")
1100    @WifiBaseTest.wifi_test_wrap
1101    def test_negative_mismatch_open_pmk(self):
1102        """Data-path: failure when initiator is open, and responder PMK"""
1103        self.run_mismatched_oob_data_path_test(
1104            init_encr_type=self.ENCR_TYPE_OPEN,
1105            resp_encr_type=self.ENCR_TYPE_PMK)
1106
1107    @test_tracker_info(uuid="f027b1cc-0e7a-4075-b880-5e64b288afbd")
1108    @WifiBaseTest.wifi_test_wrap
1109    def test_negative_mismatch_pmk_passphrase(self):
1110        """Data-path: failure when initiator is pmk, and responder passphrase"""
1111        self.run_mismatched_oob_data_path_test(
1112            init_encr_type=self.ENCR_TYPE_PMK,
1113            resp_encr_type=self.ENCR_TYPE_PASSPHRASE)
1114
1115    @test_tracker_info(uuid="0819bbd4-72ae-49c4-bd46-5448db2b0a06")
1116    @WifiBaseTest.wifi_test_wrap
1117    def test_negative_mismatch_passphrase_open(self):
1118        """Data-path: failure when initiator is passphrase, and responder open"""
1119        self.run_mismatched_oob_data_path_test(
1120            init_encr_type=self.ENCR_TYPE_PASSPHRASE,
1121            resp_encr_type=self.ENCR_TYPE_OPEN)
1122
1123    @test_tracker_info(uuid="7ef24f62-8e6b-4732-88a3-80a43584dda4")
1124    @WifiBaseTest.wifi_test_wrap
1125    def test_negative_mismatch_pmk_open(self):
1126        """Data-path: failure when initiator is PMK, and responder open"""
1127        self.run_mismatched_oob_data_path_test(
1128            init_encr_type=self.ENCR_TYPE_PMK,
1129            resp_encr_type=self.ENCR_TYPE_OPEN)
1130
1131    @test_tracker_info(uuid="7b9c9efc-1c06-465e-8a5e-d6a22ac1da97")
1132    @WifiBaseTest.wifi_test_wrap
1133    def test_negative_mismatch_passphrase_pmk(self):
1134        """Data-path: failure when initiator is passphrase, and responder pmk"""
1135        self.run_mismatched_oob_data_path_test(
1136            init_encr_type=self.ENCR_TYPE_PASSPHRASE,
1137            resp_encr_type=self.ENCR_TYPE_OPEN)
1138
1139    ##########################################################################
1140
1141    def wait_for_request_responses(self, dut, req_keys, aware_ifs, aware_ipv6):
1142        """Wait for network request confirmation for all request keys.
1143
1144    Args:
1145      dut: Device under test
1146      req_keys: (in) A list of the network requests
1147      aware_ifs: (out) A list into which to append the network interface
1148      aware_ipv6: (out) A list into which to append the network ipv6 address
1149    """
1150        num_events = 0  # looking for 2 events per NDP: link-prop + net-cap
1151        while num_events != 2 * len(req_keys):
1152            event = autils.wait_for_event(
1153                dut,
1154                cconsts.EVENT_NETWORK_CALLBACK,
1155                timeout=autils.EVENT_NDP_TIMEOUT)
1156            if (event["data"][cconsts.NETWORK_CB_KEY_EVENT] ==
1157                    cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED):
1158                if event["data"][cconsts.NETWORK_CB_KEY_ID] in req_keys:
1159                    num_events = num_events + 1
1160                    aware_ifs.append(
1161                        event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME])
1162                else:
1163                    self.log.info(
1164                        "Received an unexpected connectivity, the revoked "
1165                        "network request probably went through -- %s", event)
1166            elif (event["data"][cconsts.NETWORK_CB_KEY_EVENT] ==
1167                  cconsts.NETWORK_CB_CAPABILITIES_CHANGED):
1168                if event["data"][cconsts.NETWORK_CB_KEY_ID] in req_keys:
1169                    num_events = num_events + 1
1170                    aware_ipv6.append(event["data"][aconsts.NET_CAP_IPV6])
1171                else:
1172                    self.log.info(
1173                        "Received an unexpected connectivity, the revoked "
1174                        "network request probably went through -- %s", event)
1175                # validate no leak of information
1176                asserts.assert_false(
1177                    cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in event["data"],
1178                    "Network specifier leak!")
1179
1180    @test_tracker_info(uuid="2e325e2b-d552-4890-b470-20b40284395d")
1181    @WifiBaseTest.wifi_test_wrap
1182    def test_multiple_identical_networks(self):
1183        """Validate that creating multiple networks between 2 devices, each network
1184    with identical configuration is supported over a single NDP.
1185
1186    Verify that the interface and IPv6 address is the same for all networks.
1187    """
1188        init_dut = self.android_devices[0]
1189        init_dut.pretty_name = "Initiator"
1190        resp_dut = self.android_devices[1]
1191        resp_dut.pretty_name = "Responder"
1192
1193        N = 2  # first iteration (must be 2 to give us a chance to cancel the first)
1194        M = 5  # second iteration
1195
1196        init_ids = []
1197        resp_ids = []
1198
1199        # Initiator+Responder: attach and wait for confirmation & identity
1200        # create N+M sessions to be used in the different (but identical) NDPs
1201        for i in range(N + M):
1202            id, init_mac = autils.attach_with_identity(init_dut)
1203            init_ids.append(id)
1204            id, resp_mac = autils.attach_with_identity(resp_dut)
1205            resp_ids.append(id)
1206
1207        # wait for for devices to synchronize with each other - there are no other
1208        # mechanisms to make sure this happens for OOB discovery (except retrying
1209        # to execute the data-path request)
1210        time.sleep(autils.WAIT_FOR_CLUSTER)
1211
1212        resp_req_keys = []
1213        init_req_keys = []
1214        resp_aware_ifs = []
1215        init_aware_ifs = []
1216        resp_aware_ipv6 = []
1217        init_aware_ipv6 = []
1218
1219        # issue N quick requests for identical NDPs - without waiting for result
1220        # tests whether pre-setup multiple NDP procedure
1221        for i in range(N):
1222            # Responder: request network
1223            resp_req_keys.append(
1224                autils.request_network(
1225                    resp_dut,
1226                    resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1227                        resp_ids[i], aconsts.DATA_PATH_RESPONDER, init_mac,
1228                        None)))
1229
1230            # Initiator: request network
1231            init_req_keys.append(
1232                autils.request_network(
1233                    init_dut,
1234                    init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1235                        init_ids[i], aconsts.DATA_PATH_INITIATOR, resp_mac,
1236                        None)))
1237
1238        # remove the first request (hopefully before completed) testing that NDP
1239        # is still created
1240        resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_keys[0])
1241        resp_req_keys.remove(resp_req_keys[0])
1242        init_dut.droid.connectivityUnregisterNetworkCallback(init_req_keys[0])
1243        init_req_keys.remove(init_req_keys[0])
1244
1245        # wait for network formation for all initial requests
1246        # note: for IPv6 Init <--> Resp since each reports the other's IPv6 address
1247        #       in it's transport-specific network info
1248        self.wait_for_request_responses(resp_dut, resp_req_keys,
1249                                        resp_aware_ifs, init_aware_ipv6)
1250        self.wait_for_request_responses(init_dut, init_req_keys,
1251                                        init_aware_ifs, resp_aware_ipv6)
1252
1253        # issue M more requests for the same NDPs - tests post-setup multiple NDP
1254        for i in range(M):
1255            # Responder: request network
1256            resp_req_keys.append(
1257                autils.request_network(
1258                    resp_dut,
1259                    resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1260                        resp_ids[N + i], aconsts.DATA_PATH_RESPONDER, init_mac,
1261                        None)))
1262
1263            # Initiator: request network
1264            init_req_keys.append(
1265                autils.request_network(
1266                    init_dut,
1267                    init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1268                        init_ids[N + i], aconsts.DATA_PATH_INITIATOR, resp_mac,
1269                        None)))
1270
1271        # wait for network formation for all subsequent requests
1272        self.wait_for_request_responses(resp_dut, resp_req_keys[N - 1:],
1273                                        resp_aware_ifs, init_aware_ipv6)
1274        self.wait_for_request_responses(init_dut, init_req_keys[N - 1:],
1275                                        init_aware_ifs, resp_aware_ipv6)
1276
1277        # determine whether all interfaces and ipv6 addresses are identical
1278        # (single NDP)
1279        init_aware_ifs = list(set(init_aware_ifs))
1280        resp_aware_ifs = list(set(resp_aware_ifs))
1281        init_aware_ipv6 = list(set(init_aware_ipv6))
1282        resp_aware_ipv6 = list(set(resp_aware_ipv6))
1283
1284        self.log.info("Interface names: I=%s, R=%s", init_aware_ifs,
1285                      resp_aware_ifs)
1286        self.log.info("Interface IPv6: I=%s, R=%s", init_aware_ipv6,
1287                      resp_aware_ipv6)
1288        self.log.info("Initiator requests: %s", init_req_keys)
1289        self.log.info("Responder requests: %s", resp_req_keys)
1290
1291        asserts.assert_equal(
1292            len(init_aware_ifs), 1, "Multiple initiator interfaces")
1293        asserts.assert_equal(
1294            len(resp_aware_ifs), 1, "Multiple responder interfaces")
1295        asserts.assert_equal(
1296            len(init_aware_ipv6), 1, "Multiple initiator IPv6 addresses")
1297        asserts.assert_equal(
1298            len(resp_aware_ipv6), 1, "Multiple responder IPv6 addresses")
1299
1300        for i in range(
1301                init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]):
1302            # note: using get_ipv6_addr (ifconfig method) since want to verify
1303            # that interfaces which do not have any NDPs on them do not have
1304            # an IPv6 link-local address.
1305            if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i)
1306            init_ipv6 = autils.get_ipv6_addr(init_dut, if_name)
1307            resp_ipv6 = autils.get_ipv6_addr(resp_dut, if_name)
1308
1309            asserts.assert_equal(
1310                init_ipv6 is None, if_name not in init_aware_ifs,
1311                "Initiator interface %s in unexpected state" % if_name)
1312            asserts.assert_equal(
1313                resp_ipv6 is None, if_name not in resp_aware_ifs,
1314                "Responder interface %s in unexpected state" % if_name)
1315
1316        # release requests
1317        for resp_req_key in resp_req_keys:
1318            resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
1319        for init_req_key in init_req_keys:
1320            init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
1321
1322    @test_tracker_info(uuid="34cf12e8-5df6-49bd-b384-e9935d89a5b7")
1323    @WifiBaseTest.wifi_test_wrap
1324    def test_identical_network_from_both_sides(self):
1325        """Validate that requesting two identical NDPs (Open) each being initiated
1326    from a different side, results in the same/single NDP.
1327
1328    Verify that the interface and IPv6 address is the same for all networks.
1329    """
1330        dut1 = self.android_devices[0]
1331        dut2 = self.android_devices[1]
1332
1333        id1, mac1 = autils.attach_with_identity(dut1)
1334        id2, mac2 = autils.attach_with_identity(dut2)
1335
1336        # wait for for devices to synchronize with each other - there are no other
1337        # mechanisms to make sure this happens for OOB discovery (except retrying
1338        # to execute the data-path request)
1339        time.sleep(autils.WAIT_FOR_CLUSTER)
1340
1341        # first NDP: DUT1 (Init) -> DUT2 (Resp)
1342        req_a_resp = autils.request_network(
1343            dut2,
1344            dut2.droid.wifiAwareCreateNetworkSpecifierOob(
1345                id2, aconsts.DATA_PATH_RESPONDER, mac1))
1346
1347        req_a_init = autils.request_network(
1348            dut1,
1349            dut1.droid.wifiAwareCreateNetworkSpecifierOob(
1350                id1, aconsts.DATA_PATH_INITIATOR, mac2))
1351
1352        req_a_resp_event_nc = autils.wait_for_event_with_keys(
1353            dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1354            (cconsts.NETWORK_CB_KEY_EVENT,
1355             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1356            (cconsts.NETWORK_CB_KEY_ID, req_a_resp))
1357        req_a_init_event_nc = autils.wait_for_event_with_keys(
1358            dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1359            (cconsts.NETWORK_CB_KEY_EVENT,
1360             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1361            (cconsts.NETWORK_CB_KEY_ID, req_a_init))
1362
1363        # validate no leak of information
1364        asserts.assert_false(
1365            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_a_resp_event_nc[
1366                "data"], "Network specifier leak!")
1367        asserts.assert_false(
1368            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_a_init_event_nc[
1369                "data"], "Network specifier leak!")
1370
1371        # note that Init <-> Resp since IPv6 are of peer's!
1372        req_a_ipv6_init = req_a_resp_event_nc["data"][aconsts.NET_CAP_IPV6]
1373        req_a_ipv6_resp = req_a_init_event_nc["data"][aconsts.NET_CAP_IPV6]
1374
1375        req_a_resp_event_lp = autils.wait_for_event_with_keys(
1376            dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1377            (cconsts.NETWORK_CB_KEY_EVENT,
1378             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1379            (cconsts.NETWORK_CB_KEY_ID, req_a_resp))
1380        req_a_init_event_lp = autils.wait_for_event_with_keys(
1381            dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1382            (cconsts.NETWORK_CB_KEY_EVENT,
1383             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1384            (cconsts.NETWORK_CB_KEY_ID, req_a_init))
1385
1386        req_a_if_resp = req_a_resp_event_lp["data"][
1387            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1388        req_a_if_init = req_a_init_event_lp["data"][
1389            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1390
1391        self.log.info("Interface names for A: I=%s, R=%s", req_a_if_init,
1392                      req_a_if_resp)
1393        self.log.info("Interface addresses (IPv6) for A: I=%s, R=%s",
1394                      req_a_ipv6_init, req_a_ipv6_resp)
1395
1396        # second NDP: DUT2 (Init) -> DUT1 (Resp)
1397        req_b_resp = autils.request_network(
1398            dut1,
1399            dut1.droid.wifiAwareCreateNetworkSpecifierOob(
1400                id1, aconsts.DATA_PATH_RESPONDER, mac2))
1401
1402        req_b_init = autils.request_network(
1403            dut2,
1404            dut2.droid.wifiAwareCreateNetworkSpecifierOob(
1405                id2, aconsts.DATA_PATH_INITIATOR, mac1))
1406
1407        req_b_resp_event_nc = autils.wait_for_event_with_keys(
1408            dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1409            (cconsts.NETWORK_CB_KEY_EVENT,
1410             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1411            (cconsts.NETWORK_CB_KEY_ID, req_b_resp))
1412        req_b_init_event_nc = autils.wait_for_event_with_keys(
1413            dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1414            (cconsts.NETWORK_CB_KEY_EVENT,
1415             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1416            (cconsts.NETWORK_CB_KEY_ID, req_b_init))
1417
1418        # validate no leak of information
1419        asserts.assert_false(
1420            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_b_resp_event_nc[
1421                "data"], "Network specifier leak!")
1422        asserts.assert_false(
1423            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_b_init_event_nc[
1424                "data"], "Network specifier leak!")
1425
1426        # note that Init <-> Resp since IPv6 are of peer's!
1427        req_b_ipv6_init = req_b_resp_event_nc["data"][aconsts.NET_CAP_IPV6]
1428        req_b_ipv6_resp = req_b_init_event_nc["data"][aconsts.NET_CAP_IPV6]
1429
1430        req_b_resp_event_lp = autils.wait_for_event_with_keys(
1431            dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1432            (cconsts.NETWORK_CB_KEY_EVENT,
1433             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1434            (cconsts.NETWORK_CB_KEY_ID, req_b_resp))
1435        req_b_init_event_lp = autils.wait_for_event_with_keys(
1436            dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1437            (cconsts.NETWORK_CB_KEY_EVENT,
1438             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1439            (cconsts.NETWORK_CB_KEY_ID, req_b_init))
1440
1441        req_b_if_resp = req_b_resp_event_lp["data"][
1442            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1443        req_b_if_init = req_b_init_event_lp["data"][
1444            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1445
1446        self.log.info("Interface names for B: I=%s, R=%s", req_b_if_init,
1447                      req_b_if_resp)
1448        self.log.info("Interface addresses (IPv6) for B: I=%s, R=%s",
1449                      req_b_ipv6_init, req_b_ipv6_resp)
1450
1451        # validate equality of NDPs (using interface names & ipv6)
1452        asserts.assert_equal(req_a_if_init, req_b_if_resp,
1453                             "DUT1 NDPs are on different interfaces")
1454        asserts.assert_equal(req_a_if_resp, req_b_if_init,
1455                             "DUT2 NDPs are on different interfaces")
1456        asserts.assert_equal(req_a_ipv6_init, req_b_ipv6_resp,
1457                             "DUT1 NDPs are using different IPv6 addresses")
1458        asserts.assert_equal(req_a_ipv6_resp, req_b_ipv6_init,
1459                             "DUT2 NDPs are using different IPv6 addresses")
1460
1461        # release requests
1462        dut1.droid.connectivityUnregisterNetworkCallback(req_a_init)
1463        dut1.droid.connectivityUnregisterNetworkCallback(req_b_resp)
1464        dut2.droid.connectivityUnregisterNetworkCallback(req_a_resp)
1465        dut2.droid.connectivityUnregisterNetworkCallback(req_b_init)
1466
1467    ########################################################################
1468
1469    def run_multiple_ndi(self, sec_configs, flip_init_resp=False):
1470        """Validate that the device can create and use multiple NDIs.
1471
1472    The security configuration can be:
1473    - None: open
1474    - String: passphrase
1475    - otherwise: PMK (byte array)
1476
1477    Args:
1478      sec_configs: list of security configurations
1479      flip_init_resp: if True the roles of Initiator and Responder are flipped
1480                      between the 2 devices, otherwise same devices are always
1481                      configured in the same role.
1482    """
1483        dut1 = self.android_devices[0]
1484        dut2 = self.android_devices[1]
1485
1486        asserts.skip_if(
1487            dut1.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] <
1488            len(sec_configs)
1489            or dut2.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] <
1490            len(sec_configs), "DUTs do not support enough NDIs")
1491
1492        id1, mac1 = autils.attach_with_identity(dut1)
1493        id2, mac2 = autils.attach_with_identity(dut2)
1494
1495        # wait for for devices to synchronize with each other - there are no other
1496        # mechanisms to make sure this happens for OOB discovery (except retrying
1497        # to execute the data-path request)
1498        time.sleep(autils.WAIT_FOR_CLUSTER)
1499
1500        dut2_req_keys = []
1501        dut1_req_keys = []
1502        dut2_aware_ifs = []
1503        dut1_aware_ifs = []
1504        dut2_aware_ipv6s = []
1505        dut1_aware_ipv6s = []
1506
1507        dut2_type = aconsts.DATA_PATH_RESPONDER
1508        dut1_type = aconsts.DATA_PATH_INITIATOR
1509        dut2_is_responder = True
1510        for sec in sec_configs:
1511            if dut2_is_responder:
1512                # DUT2 (Responder): request network
1513                dut2_req_key = autils.request_network(
1514                    dut2,
1515                    autils.get_network_specifier(dut2, id2, dut2_type, mac1,
1516                                                 sec))
1517                dut2_req_keys.append(dut2_req_key)
1518
1519                # DUT1 (Initiator): request network
1520                dut1_req_key = autils.request_network(
1521                    dut1,
1522                    autils.get_network_specifier(dut1, id1, dut1_type, mac2,
1523                                                 sec))
1524                dut1_req_keys.append(dut1_req_key)
1525            else:
1526                # DUT1 (Responder): request network
1527                dut1_req_key = autils.request_network(
1528                    dut1,
1529                    autils.get_network_specifier(dut1, id1, dut1_type, mac2,
1530                                                 sec))
1531                dut1_req_keys.append(dut1_req_key)
1532
1533                # DUT2 (Initiator): request network
1534                dut2_req_key = autils.request_network(
1535                    dut2,
1536                    autils.get_network_specifier(dut2, id2, dut2_type, mac1,
1537                                                 sec))
1538                dut2_req_keys.append(dut2_req_key)
1539
1540            # Wait for network
1541            dut1_net_event_nc = autils.wait_for_event_with_keys(
1542                dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1543                (cconsts.NETWORK_CB_KEY_EVENT,
1544                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1545                (cconsts.NETWORK_CB_KEY_ID, dut1_req_key))
1546            dut2_net_event_nc = autils.wait_for_event_with_keys(
1547                dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1548                (cconsts.NETWORK_CB_KEY_EVENT,
1549                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1550                (cconsts.NETWORK_CB_KEY_ID, dut2_req_key))
1551
1552            # validate no leak of information
1553            asserts.assert_false(
1554                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in dut1_net_event_nc[
1555                    "data"], "Network specifier leak!")
1556            asserts.assert_false(
1557                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in dut2_net_event_nc[
1558                    "data"], "Network specifier leak!")
1559
1560            # Note: dut1 <--> dut2 IPv6's addresses since it is peer's info
1561            dut2_aware_ipv6 = dut1_net_event_nc["data"][aconsts.NET_CAP_IPV6]
1562            dut1_aware_ipv6 = dut2_net_event_nc["data"][aconsts.NET_CAP_IPV6]
1563
1564            dut1_net_event_lp = autils.wait_for_event_with_keys(
1565                dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1566                (cconsts.NETWORK_CB_KEY_EVENT,
1567                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1568                (cconsts.NETWORK_CB_KEY_ID, dut1_req_key))
1569            dut2_net_event_lp = autils.wait_for_event_with_keys(
1570                dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1571                (cconsts.NETWORK_CB_KEY_EVENT,
1572                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1573                (cconsts.NETWORK_CB_KEY_ID, dut2_req_key))
1574
1575            dut2_aware_if = dut2_net_event_lp["data"][
1576                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1577            dut1_aware_if = dut1_net_event_lp["data"][
1578                cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
1579
1580            dut2_aware_ifs.append(dut2_aware_if)
1581            dut1_aware_ifs.append(dut1_aware_if)
1582            dut2_aware_ipv6s.append(dut2_aware_ipv6)
1583            dut1_aware_ipv6s.append(dut1_aware_ipv6)
1584
1585            if flip_init_resp:
1586                if dut2_is_responder:
1587                    dut2_type = aconsts.DATA_PATH_INITIATOR
1588                    dut1_type = aconsts.DATA_PATH_RESPONDER
1589                else:
1590                    dut2_type = aconsts.DATA_PATH_RESPONDER
1591                    dut1_type = aconsts.DATA_PATH_INITIATOR
1592                dut2_is_responder = not dut2_is_responder
1593
1594        # check that we are using 2 NDIs & that they have unique IPv6 addresses
1595        dut1_aware_ifs = list(set(dut1_aware_ifs))
1596        dut2_aware_ifs = list(set(dut2_aware_ifs))
1597        dut1_aware_ipv6s = list(set(dut1_aware_ipv6s))
1598        dut2_aware_ipv6s = list(set(dut2_aware_ipv6s))
1599
1600        self.log.info("Interface names: DUT1=%s, DUT2=%s", dut1_aware_ifs,
1601                      dut2_aware_ifs)
1602        self.log.info("IPv6 addresses: DUT1=%s, DUT2=%s", dut1_aware_ipv6s,
1603                      dut2_aware_ipv6s)
1604        self.log.info("DUT1 requests: %s", dut1_req_keys)
1605        self.log.info("DUT2 requests: %s", dut2_req_keys)
1606
1607        asserts.assert_equal(
1608            len(dut1_aware_ifs), len(sec_configs), "Multiple DUT1 interfaces")
1609        asserts.assert_equal(
1610            len(dut2_aware_ifs), len(sec_configs), "Multiple DUT2 interfaces")
1611        asserts.assert_equal(
1612            len(dut1_aware_ipv6s), len(sec_configs),
1613            "Multiple DUT1 IPv6 addresses")
1614        asserts.assert_equal(
1615            len(dut2_aware_ipv6s), len(sec_configs),
1616            "Multiple DUT2 IPv6 addresses")
1617
1618        for i in range(len(sec_configs)):
1619            # note: using get_ipv6_addr (ifconfig method) since want to verify
1620            # that the system information is the same as the reported information
1621            if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i)
1622            dut1_ipv6 = autils.get_ipv6_addr(dut1, if_name)
1623            dut2_ipv6 = autils.get_ipv6_addr(dut2, if_name)
1624
1625            asserts.assert_equal(
1626                dut1_ipv6 is None, if_name not in dut1_aware_ifs,
1627                "DUT1 interface %s in unexpected state" % if_name)
1628            asserts.assert_equal(
1629                dut2_ipv6 is None, if_name not in dut2_aware_ifs,
1630                "DUT2 interface %s in unexpected state" % if_name)
1631
1632        # release requests
1633        for dut2_req_key in dut2_req_keys:
1634            dut2.droid.connectivityUnregisterNetworkCallback(dut2_req_key)
1635        for dut1_req_key in dut1_req_keys:
1636            dut1.droid.connectivityUnregisterNetworkCallback(dut1_req_key)
1637
1638    @test_tracker_info(uuid="2d728163-11cc-46ba-a973-c8e1e71397fc")
1639    @WifiBaseTest.wifi_test_wrap
1640    def test_multiple_ndi_open_passphrase(self):
1641        """Verify that between 2 DUTs can create 2 NDPs with different security
1642    configuration (one open, one using passphrase). The result should use two
1643    different NDIs"""
1644        self.run_multiple_ndi([None, self.PASSPHRASE])
1645
1646    @test_tracker_info(uuid="5f2c32aa-20b2-41f0-8b1e-d0b68df73ada")
1647    @WifiBaseTest.wifi_test_wrap
1648    def test_multiple_ndi_open_pmk(self):
1649        """Verify that between 2 DUTs can create 2 NDPs with different security
1650    configuration (one open, one using pmk). The result should use two
1651    different NDIs"""
1652        self.run_multiple_ndi([None, self.PMK])
1653
1654    @test_tracker_info(uuid="34467659-bcfb-40cd-ba25-7e50560fca63")
1655    @WifiBaseTest.wifi_test_wrap
1656    def test_multiple_ndi_passphrase_pmk(self):
1657        """Verify that between 2 DUTs can create 2 NDPs with different security
1658    configuration (one using passphrase, one using pmk). The result should use
1659    two different NDIs"""
1660        self.run_multiple_ndi([self.PASSPHRASE, self.PMK])
1661
1662    @test_tracker_info(uuid="d9194ce6-45b6-41b1-9cc8-ada79968966d")
1663    @WifiBaseTest.wifi_test_wrap
1664    def test_multiple_ndi_passphrases(self):
1665        """Verify that between 2 DUTs can create 2 NDPs with different security
1666    configuration (using different passphrases). The result should use two
1667    different NDIs"""
1668        self.run_multiple_ndi([self.PASSPHRASE, self.PASSPHRASE2])
1669
1670    @test_tracker_info(uuid="879df795-62d2-40d4-a862-bd46d8f7e67f")
1671    @WifiBaseTest.wifi_test_wrap
1672    def test_multiple_ndi_pmks(self):
1673        """Verify that between 2 DUTs can create 2 NDPs with different security
1674    configuration (using different PMKS). The result should use two different
1675    NDIs"""
1676        self.run_multiple_ndi([self.PMK, self.PMK2])
1677
1678    @test_tracker_info(uuid="397d380a-8e41-466e-9ccb-cf8f413d83ba")
1679    @WifiBaseTest.wifi_test_wrap
1680    def test_multiple_ndi_open_passphrase_flip(self):
1681        """Verify that between 2 DUTs can create 2 NDPs with different security
1682    configuration (one open, one using passphrase). The result should use two
1683    different NDIs.
1684
1685    Flip Initiator and Responder roles.
1686    """
1687        self.run_multiple_ndi([None, self.PASSPHRASE], flip_init_resp=True)
1688
1689    @test_tracker_info(uuid="b3a4300b-1514-4cb8-a814-9c2baa449700")
1690    @WifiBaseTest.wifi_test_wrap
1691    def test_multiple_ndi_open_pmk_flip(self):
1692        """Verify that between 2 DUTs can create 2 NDPs with different security
1693    configuration (one open, one using pmk). The result should use two
1694    different NDIs
1695
1696    Flip Initiator and Responder roles.
1697    """
1698        self.run_multiple_ndi([None, self.PMK], flip_init_resp=True)
1699
1700    @test_tracker_info(uuid="0bfea9e4-e57d-417f-8db4-245741e9bbd5")
1701    @WifiBaseTest.wifi_test_wrap
1702    def test_multiple_ndi_passphrase_pmk_flip(self):
1703        """Verify that between 2 DUTs can create 2 NDPs with different security
1704    configuration (one using passphrase, one using pmk). The result should use
1705    two different NDIs
1706
1707    Flip Initiator and Responder roles.
1708    """
1709        self.run_multiple_ndi([self.PASSPHRASE, self.PMK], flip_init_resp=True)
1710
1711    @test_tracker_info(uuid="74023483-5417-431b-a362-991ad4a03ab8")
1712    @WifiBaseTest.wifi_test_wrap
1713    def test_multiple_ndi_passphrases_flip(self):
1714        """Verify that between 2 DUTs can create 2 NDPs with different security
1715    configuration (using different passphrases). The result should use two
1716    different NDIs
1717
1718    Flip Initiator and Responder roles.
1719    """
1720        self.run_multiple_ndi(
1721            [self.PASSPHRASE, self.PASSPHRASE2], flip_init_resp=True)
1722
1723    @test_tracker_info(uuid="873b2d91-28a1-403f-ae9c-d756bb2f59ee")
1724    @WifiBaseTest.wifi_test_wrap
1725    def test_multiple_ndi_pmks_flip(self):
1726        """Verify that between 2 DUTs can create 2 NDPs with different security
1727    configuration (using different PMKS). The result should use two different
1728    NDIs
1729
1730    Flip Initiator and Responder roles.
1731    """
1732        self.run_multiple_ndi([self.PMK, self.PMK2], flip_init_resp=True)
1733
1734    #######################################
1735
1736    def run_multiple_regulatory_domains(self, use_ib, init_domain,
1737                                        resp_domain):
1738        """Verify that a data-path setup with two conflicting regulatory domains
1739    works (the result should be run in Channel 6 - but that is not tested).
1740
1741    Args:
1742      use_ib: True to use in-band discovery, False to use out-of-band discovery.
1743      init_domain: The regulatory domain of the Initiator/Subscriber.
1744      resp_domain: The regulator domain of the Responder/Publisher.
1745    """
1746        init_dut = self.android_devices[0]
1747        resp_dut = self.android_devices[1]
1748
1749        wutils.set_wifi_country_code(init_dut, init_domain)
1750        wutils.set_wifi_country_code(resp_dut, resp_domain)
1751
1752        if use_ib:
1753            (resp_req_key, init_req_key, resp_aware_if, init_aware_if,
1754             resp_ipv6, init_ipv6) = autils.create_ib_ndp(
1755                resp_dut, init_dut,
1756                autils.create_discovery_config(
1757                    "GoogleTestXyz", aconsts.PUBLISH_TYPE_UNSOLICITED),
1758                autils.create_discovery_config(
1759                    "GoogleTestXyz", aconsts.SUBSCRIBE_TYPE_PASSIVE),
1760                self.device_startup_offset)
1761        else:
1762            (init_req_key, resp_req_key, init_aware_if, resp_aware_if,
1763             init_ipv6, resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut)
1764
1765        self.log.info("Interface names: I=%s, R=%s", init_aware_if,
1766                      resp_aware_if)
1767        self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6,
1768                      resp_ipv6)
1769
1770        # clean-up
1771        resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
1772        init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
1773
1774    @test_tracker_info(uuid="eff53739-35c5-47a6-81f0-d70b51d89c3b")
1775    @WifiBaseTest.wifi_test_wrap
1776    def test_multiple_regulator_domains_ib_us_jp(self):
1777        """Verify data-path setup across multiple regulator domains.
1778
1779    - Uses in-band discovery
1780    - Subscriber=US, Publisher=JP
1781    """
1782        self.run_multiple_regulatory_domains(
1783            use_ib=True,
1784            init_domain=wutils.WifiEnums.CountryCode.US,
1785            resp_domain=wutils.WifiEnums.CountryCode.JAPAN)
1786
1787    @test_tracker_info(uuid="19af47cc-3204-40ef-b50f-14cf7b89cf4a")
1788    @WifiBaseTest.wifi_test_wrap
1789    def test_multiple_regulator_domains_ib_jp_us(self):
1790        """Verify data-path setup across multiple regulator domains.
1791
1792    - Uses in-band discovery
1793    - Subscriber=JP, Publisher=US
1794    """
1795        self.run_multiple_regulatory_domains(
1796            use_ib=True,
1797            init_domain=wutils.WifiEnums.CountryCode.JAPAN,
1798            resp_domain=wutils.WifiEnums.CountryCode.US)
1799
1800    @test_tracker_info(uuid="65285ab3-977f-4dbd-b663-d5a02f4fc663")
1801    @WifiBaseTest.wifi_test_wrap
1802    def test_multiple_regulator_domains_oob_us_jp(self):
1803        """Verify data-path setup across multiple regulator domains.
1804
1805    - Uses out-f-band discovery
1806    - Initiator=US, Responder=JP
1807    """
1808        self.run_multiple_regulatory_domains(
1809            use_ib=False,
1810            init_domain=wutils.WifiEnums.CountryCode.US,
1811            resp_domain=wutils.WifiEnums.CountryCode.JAPAN)
1812
1813    @test_tracker_info(uuid="8a417e24-aaf6-44b9-a089-a07c3ba8d954")
1814    @WifiBaseTest.wifi_test_wrap
1815    def test_multiple_regulator_domains_oob_jp_us(self):
1816        """Verify data-path setup across multiple regulator domains.
1817
1818    - Uses out-of-band discovery
1819    - Initiator=JP, Responder=US
1820    """
1821        self.run_multiple_regulatory_domains(
1822            use_ib=False,
1823            init_domain=wutils.WifiEnums.CountryCode.JAPAN,
1824            resp_domain=wutils.WifiEnums.CountryCode.US)
1825
1826    ########################################################################
1827
1828    def run_mix_ib_oob(self, same_request, ib_first, inits_on_same_dut):
1829        """Validate that multiple network requests issued using both in-band and
1830    out-of-band discovery behave as expected.
1831
1832    The same_request parameter controls whether identical single NDP is
1833    expected, if True, or whether multiple NDPs on different NDIs are expected,
1834    if False.
1835
1836    Args:
1837      same_request: Issue canonically identical requests (same NMI peer, same
1838                    passphrase) if True, if False use different passphrases.
1839      ib_first: If True then the in-band network is requested first, otherwise
1840                (if False) then the out-of-band network is requested first.
1841      inits_on_same_dut: If True then the Initiators are run on the same device,
1842                         otherwise (if False) then the Initiators are run on
1843                         different devices. Note that Subscribe == Initiator.
1844    """
1845        if not same_request:
1846            asserts.skip_if(
1847                self.android_devices[0]
1848                .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2
1849                or self.android_devices[1]
1850                .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2,
1851                "DUTs do not support enough NDIs")
1852
1853        (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub,
1854         peer_id_on_pub) = self.set_up_discovery(
1855            aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE, True)
1856
1857        p_id2, p_mac = autils.attach_with_identity(p_dut)
1858        s_id2, s_mac = autils.attach_with_identity(s_dut)
1859
1860        if inits_on_same_dut:
1861            resp_dut = p_dut
1862            resp_id = p_id2
1863            resp_mac = p_mac
1864
1865            init_dut = s_dut
1866            init_id = s_id2
1867            init_mac = s_mac
1868        else:
1869            resp_dut = s_dut
1870            resp_id = s_id2
1871            resp_mac = s_mac
1872
1873            init_dut = p_dut
1874            init_id = p_id2
1875            init_mac = p_mac
1876
1877        passphrase = None if same_request else self.PASSPHRASE
1878
1879        if ib_first:
1880            # request in-band network (to completion)
1881            p_req_key = self.request_network(
1882                p_dut,
1883                p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub))
1884            s_req_key = self.request_network(
1885                s_dut,
1886                s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, peer_id_on_sub))
1887
1888            # Publisher & Subscriber: wait for network formation
1889            p_net_event_nc = autils.wait_for_event_with_keys(
1890                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
1891                autils.EVENT_NDP_TIMEOUT,
1892                (cconsts.NETWORK_CB_KEY_EVENT,
1893                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1894                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
1895            s_net_event_nc = autils.wait_for_event_with_keys(
1896                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
1897                autils.EVENT_NDP_TIMEOUT,
1898                (cconsts.NETWORK_CB_KEY_EVENT,
1899                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1900                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
1901            p_net_event_lp = autils.wait_for_event_with_keys(
1902                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
1903                autils.EVENT_NDP_TIMEOUT,
1904                (cconsts.NETWORK_CB_KEY_EVENT,
1905                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1906                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
1907            s_net_event_lp = autils.wait_for_event_with_keys(
1908                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
1909                autils.EVENT_NDP_TIMEOUT,
1910                (cconsts.NETWORK_CB_KEY_EVENT,
1911                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1912                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
1913
1914            # validate no leak of information
1915            asserts.assert_false(
1916                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[
1917                    "data"], "Network specifier leak!")
1918            asserts.assert_false(
1919                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[
1920                    "data"], "Network specifier leak!")
1921
1922        # request out-of-band network
1923        resp_req_key = autils.request_network(
1924            resp_dut,
1925            resp_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1926                resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, passphrase))
1927        init_req_key = autils.request_network(
1928            init_dut,
1929            init_dut.droid.wifiAwareCreateNetworkSpecifierOob(
1930                init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase))
1931
1932        resp_net_event_nc = autils.wait_for_event_with_keys(
1933            resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1934            (cconsts.NETWORK_CB_KEY_EVENT,
1935             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1936            (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
1937        init_net_event_nc = autils.wait_for_event_with_keys(
1938            init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1939            (cconsts.NETWORK_CB_KEY_EVENT,
1940             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1941            (cconsts.NETWORK_CB_KEY_ID, init_req_key))
1942        resp_net_event_lp = autils.wait_for_event_with_keys(
1943            resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1944            (cconsts.NETWORK_CB_KEY_EVENT,
1945             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1946            (cconsts.NETWORK_CB_KEY_ID, resp_req_key))
1947        init_net_event_lp = autils.wait_for_event_with_keys(
1948            init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT,
1949            (cconsts.NETWORK_CB_KEY_EVENT,
1950             cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1951            (cconsts.NETWORK_CB_KEY_ID, init_req_key))
1952
1953        # validate no leak of information
1954        asserts.assert_false(
1955            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in resp_net_event_nc[
1956                "data"], "Network specifier leak!")
1957        asserts.assert_false(
1958            cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in init_net_event_nc[
1959                "data"], "Network specifier leak!")
1960
1961        if not ib_first:
1962            # request in-band network (to completion)
1963            p_req_key = self.request_network(
1964                p_dut,
1965                p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub))
1966            s_req_key = self.request_network(
1967                s_dut,
1968                s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, peer_id_on_sub))
1969
1970            # Publisher & Subscriber: wait for network formation
1971            p_net_event_nc = autils.wait_for_event_with_keys(
1972                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
1973                autils.EVENT_NDP_TIMEOUT,
1974                (cconsts.NETWORK_CB_KEY_EVENT,
1975                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1976                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
1977            s_net_event_nc = autils.wait_for_event_with_keys(
1978                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
1979                autils.EVENT_NDP_TIMEOUT,
1980                (cconsts.NETWORK_CB_KEY_EVENT,
1981                 cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
1982                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
1983            p_net_event_lp = autils.wait_for_event_with_keys(
1984                p_dut, cconsts.EVENT_NETWORK_CALLBACK,
1985                autils.EVENT_NDP_TIMEOUT,
1986                (cconsts.NETWORK_CB_KEY_EVENT,
1987                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1988                (cconsts.NETWORK_CB_KEY_ID, p_req_key))
1989            s_net_event_lp = autils.wait_for_event_with_keys(
1990                s_dut, cconsts.EVENT_NETWORK_CALLBACK,
1991                autils.EVENT_NDP_TIMEOUT,
1992                (cconsts.NETWORK_CB_KEY_EVENT,
1993                 cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED),
1994                (cconsts.NETWORK_CB_KEY_ID, s_req_key))
1995
1996            # validate no leak of information
1997            asserts.assert_false(
1998                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[
1999                    "data"], "Network specifier leak!")
2000            asserts.assert_false(
2001                cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[
2002                    "data"], "Network specifier leak!")
2003
2004        # note that Init <-> Resp & Pub <--> Sub since IPv6 are of peer's!
2005        init_ipv6 = resp_net_event_nc["data"][aconsts.NET_CAP_IPV6]
2006        resp_ipv6 = init_net_event_nc["data"][aconsts.NET_CAP_IPV6]
2007        pub_ipv6 = s_net_event_nc["data"][aconsts.NET_CAP_IPV6]
2008        sub_ipv6 = p_net_event_nc["data"][aconsts.NET_CAP_IPV6]
2009
2010        # extract net info
2011        pub_interface = p_net_event_lp["data"][
2012            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
2013        sub_interface = s_net_event_lp["data"][
2014            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
2015        resp_interface = resp_net_event_lp["data"][
2016            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
2017        init_interface = init_net_event_lp["data"][
2018            cconsts.NETWORK_CB_KEY_INTERFACE_NAME]
2019
2020        self.log.info("Interface names: Pub=%s, Sub=%s, Resp=%s, Init=%s",
2021                      pub_interface, sub_interface, resp_interface,
2022                      init_interface)
2023        self.log.info(
2024            "Interface addresses (IPv6): Pub=%s, Sub=%s, Resp=%s, Init=%s",
2025            pub_ipv6, sub_ipv6, resp_ipv6, init_ipv6)
2026
2027        # validate NDP/NDI conditions (using interface names & ipv6)
2028        if same_request:
2029            asserts.assert_equal(
2030                pub_interface, resp_interface if inits_on_same_dut else
2031                init_interface, "NDP interfaces don't match on Pub/other")
2032            asserts.assert_equal(
2033                sub_interface, init_interface if inits_on_same_dut else
2034                resp_interface, "NDP interfaces don't match on Sub/other")
2035
2036            asserts.assert_equal(pub_ipv6, resp_ipv6
2037            if inits_on_same_dut else init_ipv6,
2038                                 "NDP IPv6 don't match on Pub/other")
2039            asserts.assert_equal(sub_ipv6, init_ipv6
2040            if inits_on_same_dut else resp_ipv6,
2041                                 "NDP IPv6 don't match on Sub/other")
2042        else:
2043            asserts.assert_false(
2044                pub_interface == (resp_interface
2045                                  if inits_on_same_dut else init_interface),
2046                "NDP interfaces match on Pub/other")
2047            asserts.assert_false(
2048                sub_interface == (init_interface
2049                                  if inits_on_same_dut else resp_interface),
2050                "NDP interfaces match on Sub/other")
2051
2052            asserts.assert_false(
2053                pub_ipv6 == (resp_ipv6 if inits_on_same_dut else init_ipv6),
2054                "NDP IPv6 match on Pub/other")
2055            asserts.assert_false(
2056                sub_ipv6 == (init_ipv6 if inits_on_same_dut else resp_ipv6),
2057                "NDP IPv6 match on Sub/other")
2058
2059        # release requests
2060        p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key)
2061        s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key)
2062        resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key)
2063        init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key)
2064
2065    @test_tracker_info(uuid="d8a0839d-4ba0-43f2-af93-3cf1382f9f16")
2066    @WifiBaseTest.wifi_test_wrap
2067    def test_identical_ndps_mix_ib_oob_ib_first_same_polarity(self):
2068        """Validate that a single NDP is created for multiple identical requests
2069    which are issued through either in-band (ib) or out-of-band (oob) APIs.
2070
2071    The in-band request is issued first. Both Initiators (Sub == Initiator) are
2072    run on the same device.
2073    """
2074        self.run_mix_ib_oob(
2075            same_request=True, ib_first=True, inits_on_same_dut=True)
2076
2077    @test_tracker_info(uuid="70bbb811-0bed-4a19-96b3-f2446e777c8a")
2078    @WifiBaseTest.wifi_test_wrap
2079    def test_identical_ndps_mix_ib_oob_oob_first_same_polarity(self):
2080        """Validate that a single NDP is created for multiple identical requests
2081    which are issued through either in-band (ib) or out-of-band (oob) APIs.
2082
2083    The out-of-band request is issued first. Both Initiators (Sub == Initiator)
2084    are run on the same device.
2085    """
2086        self.run_mix_ib_oob(
2087            same_request=True, ib_first=False, inits_on_same_dut=True)
2088
2089    @test_tracker_info(uuid="d9796da5-f96a-4a51-be0f-89d6f5bfe3ad")
2090    @WifiBaseTest.wifi_test_wrap
2091    def test_identical_ndps_mix_ib_oob_ib_first_diff_polarity(self):
2092        """Validate that a single NDP is created for multiple identical requests
2093    which are issued through either in-band (ib) or out-of-band (oob) APIs.
2094
2095    The in-band request is issued first. Initiators (Sub == Initiator) are
2096    run on different devices.
2097    """
2098        self.run_mix_ib_oob(
2099            same_request=True, ib_first=True, inits_on_same_dut=False)
2100
2101    @test_tracker_info(uuid="48b9005b-7851-4222-b41c-1fcbefbc704d")
2102    @WifiBaseTest.wifi_test_wrap
2103    def test_identical_ndps_mix_ib_oob_oob_first_diff_polarity(self):
2104        """Validate that a single NDP is created for multiple identical requests
2105    which are issued through either in-band (ib) or out-of-band (oob) APIs.
2106
2107    The out-of-band request is issued first. Initiators (Sub == Initiator) are
2108    run on different devices.
2109    """
2110        self.run_mix_ib_oob(
2111            same_request=True, ib_first=False, inits_on_same_dut=False)
2112
2113    @test_tracker_info(uuid="51f9581e-c5ee-48a7-84d2-adff4876c3d7")
2114    @WifiBaseTest.wifi_test_wrap
2115    def test_multiple_ndis_mix_ib_oob_ib_first_same_polarity(self):
2116        """Validate that multiple NDIs are created for NDPs which are requested with
2117    different security configurations. Use a mix of in-band and out-of-band APIs
2118    to request the different NDPs.
2119
2120    The in-band request is issued first. Initiators (Sub == Initiator) are
2121    run on the same device.
2122    """
2123        self.run_mix_ib_oob(
2124            same_request=False, ib_first=True, inits_on_same_dut=True)
2125
2126    @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853")
2127    @WifiBaseTest.wifi_test_wrap
2128    def test_multiple_ndis_mix_ib_oob_oob_first_same_polarity(self):
2129        """Validate that multiple NDIs are created for NDPs which are requested with
2130    different security configurations. Use a mix of in-band and out-of-band APIs
2131    to request the different NDPs.
2132
2133    The out-of-band request is issued first. Initiators (Sub == Initiator) are
2134    run on the same device.
2135    """
2136        self.run_mix_ib_oob(
2137            same_request=False, ib_first=False, inits_on_same_dut=True)
2138
2139    @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853")
2140    @WifiBaseTest.wifi_test_wrap
2141    def test_multiple_ndis_mix_ib_oob_ib_first_diff_polarity(self):
2142        """Validate that multiple NDIs are created for NDPs which are requested with
2143    different security configurations. Use a mix of in-band and out-of-band APIs
2144    to request the different NDPs.
2145
2146    The in-band request is issued first. Initiators (Sub == Initiator) are
2147    run on different devices.
2148    """
2149        self.run_mix_ib_oob(
2150            same_request=False, ib_first=True, inits_on_same_dut=False)
2151
2152    @test_tracker_info(uuid="596caadf-028e-494b-bbce-8304ccec2cbb")
2153    @WifiBaseTest.wifi_test_wrap
2154    def test_multiple_ndis_mix_ib_oob_oob_first_diff_polarity(self):
2155        """Validate that multiple NDIs are created for NDPs which are requested with
2156    different security configurations. Use a mix of in-band and out-of-band APIs
2157    to request the different NDPs.
2158
2159    The out-of-band request is issued first. Initiators (Sub == Initiator) are
2160    run on different devices.
2161    """
2162        self.run_mix_ib_oob(
2163            same_request=False, ib_first=False, inits_on_same_dut=False)
2164
2165    ########################################################################
2166
2167    @test_tracker_info(uuid="5ec10bf9-bfda-4093-8344-7ccc7764737e")
2168    def test_ndp_loop(self):
2169        """Validate that can create a loop (chain) of N NDPs between N devices,
2170    where N >= 3, e.g.
2171
2172    A - B
2173    B - C
2174    C - A
2175
2176    The NDPs are all OPEN (no encryption).
2177    """
2178        asserts.skip_if(
2179            len(self.android_devices) < 3,
2180            'A minimum of 3 devices is needed to run the test, have %d' % len(
2181                self.android_devices))
2182        asserts.skip_if(
2183            self.android_devices[0]
2184            .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2
2185            or self.android_devices[1]
2186            .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2
2187            or self.android_devices[2]
2188            .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2,
2189            "DUTs do not support enough NDIs")
2190
2191        duts = self.android_devices
2192        loop_len = len(duts)
2193        ids = []
2194        macs = []
2195        reqs = []
2196        ifs = []
2197        ipv6s = []
2198
2199        for i in range(loop_len):
2200            duts[i].pretty_name = chr(ord("A") + i)
2201            reqs.append([])
2202            ifs.append([])
2203            ipv6s.append([])
2204
2205        # start-up 3 devices (attach w/ identity)
2206        for i in range(loop_len):
2207            ids.append(duts[i].droid.wifiAwareAttach(True))
2208            autils.wait_for_event(duts[i], aconsts.EVENT_CB_ON_ATTACHED)
2209            ident_event = autils.wait_for_event(
2210                duts[i], aconsts.EVENT_CB_ON_IDENTITY_CHANGED)
2211            macs.append(ident_event['data']['mac'])
2212
2213        # wait for for devices to synchronize with each other - there are no other
2214        # mechanisms to make sure this happens for OOB discovery (except retrying
2215        # to execute the data-path request)
2216        time.sleep(autils.WAIT_FOR_CLUSTER)
2217
2218        # create the N NDPs: i to (i+1) % N
2219        for i in range(loop_len):
2220            peer_device = (i + 1) % loop_len
2221
2222            (init_req_key, resp_req_key, init_aware_if, resp_aware_if,
2223             init_ipv6, resp_ipv6) = autils.create_oob_ndp_on_sessions(
2224                duts[i], duts[peer_device], ids[i], macs[i], ids[peer_device],
2225                macs[peer_device])
2226
2227            reqs[i].append(init_req_key)
2228            reqs[peer_device].append(resp_req_key)
2229            ifs[i].append(init_aware_if)
2230            ifs[peer_device].append(resp_aware_if)
2231            ipv6s[i].append(init_ipv6)
2232            ipv6s[peer_device].append(resp_ipv6)
2233
2234        # clean-up
2235        for i in range(loop_len):
2236            for req in reqs[i]:
2237                duts[i].droid.connectivityUnregisterNetworkCallback(req)
2238
2239        # info
2240        self.log.info("MACs: %s", macs)
2241        self.log.info("Interface names: %s", ifs)
2242        self.log.info("IPv6 addresses: %s", ipv6s)
2243        asserts.explicit_pass(
2244            "NDP loop test", extras={
2245                "macs": macs,
2246                "ifs": ifs,
2247                "ipv6s": ipv6s
2248            })
2249
2250    @test_tracker_info(uuid="88cd288f-71ad-40fe-94d7-34e60fb6c962")
2251    def test_ndp_initiate_from_both_sides_with_accepts_any_responder(self):
2252        """Validate when two device both try to initiate a connection to each other, both NDP can be
2253        formed.
2254
2255        1. Device A and B both publish and file accept any request.
2256        2. Device A and B both subscribe to the peer
2257        3. When get a discovery match file a network request to the peer
2258        4. Wait for NDP setup finish.
2259        """
2260        asserts.skip_if(
2261            self.android_devices[0]
2262            .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2
2263            or self.android_devices[1]
2264            .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2,
2265            "DUTs do not support enough NDIs.")
2266        ptype = aconsts.PUBLISH_TYPE_UNSOLICITED
2267        stype = aconsts.SUBSCRIBE_TYPE_PASSIVE
2268        dut1 = self.android_devices[0]
2269        dut2 = self.android_devices[1]
2270
2271        # Publisher+Subscriber: attach and wait for confirmation
2272        dut1_id = dut1.droid.wifiAwareAttach()
2273        autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED)
2274        time.sleep(self.device_startup_offset)
2275        dut2_id = dut2.droid.wifiAwareAttach()
2276        autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED)
2277
2278        # Publisher: start publish and wait for confirmation
2279        dut1_p_disc_id = dut1.droid.wifiAwarePublish(dut1_id, self.create_config(ptype))
2280        autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED)
2281
2282        dut2_p_disc_id = dut2.droid.wifiAwarePublish(dut2_id, self.create_config(ptype))
2283        autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED)
2284
2285        # Publisher: file an accept any NetworkRequest
2286        dut1_p_req_key = self.request_network(
2287            dut1,
2288            dut1.droid.wifiAwareCreateNetworkSpecifier(
2289                dut1_p_disc_id, None, self.PASSPHRASE, None))
2290
2291        dut2_p_req_key = self.request_network(
2292            dut2,
2293            dut2.droid.wifiAwareCreateNetworkSpecifier(
2294                dut2_p_disc_id, None, self.PASSPHRASE, None))
2295
2296        # Subscriber: start subscribe and wait for discovery match
2297        dut2_s_disc_id = dut2.droid.wifiAwareSubscribe(dut2_id, self.create_config(stype))
2298        autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED)
2299
2300        dut1_s_disc_id = dut1.droid.wifiAwareSubscribe(dut1_id, self.create_config(stype))
2301        autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED)
2302
2303        discovery_event = autils.wait_for_event(
2304            dut2, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED)
2305        dut2_peer_id_on_sub = discovery_event["data"][
2306            aconsts.SESSION_CB_KEY_PEER_ID]
2307
2308        discovery_event = autils.wait_for_event(
2309            dut1, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED)
2310        dut1_peer_id_on_sub = discovery_event["data"][
2311            aconsts.SESSION_CB_KEY_PEER_ID]
2312
2313        # Subscriber: file a NetworkRequest with peer Id
2314        dut2_s_req_key = self.request_network(
2315            dut2,
2316            dut2.droid.wifiAwareCreateNetworkSpecifier(
2317                dut2_s_disc_id, dut2_peer_id_on_sub, self.PASSPHRASE, None))
2318
2319        # Avoid publisher and subscriber requests are handled in the same NDP
2320        time.sleep(1)
2321
2322        dut1_s_req_key = self.request_network(
2323            dut1,
2324            dut1.droid.wifiAwareCreateNetworkSpecifier(
2325                dut1_s_disc_id, dut1_peer_id_on_sub, self.PASSPHRASE, None))
2326
2327        # Publisher+Subscriber: wait and check the network callback.
2328        autils.wait_for_event_with_keys(
2329            dut1, cconsts.EVENT_NETWORK_CALLBACK,
2330            autils.EVENT_NDP_TIMEOUT,
2331            (cconsts.NETWORK_CB_KEY_EVENT,
2332             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
2333            (cconsts.NETWORK_CB_KEY_ID, dut1_p_req_key))
2334
2335        autils.wait_for_event_with_keys(
2336            dut2, cconsts.EVENT_NETWORK_CALLBACK,
2337            autils.EVENT_NDP_TIMEOUT,
2338            (cconsts.NETWORK_CB_KEY_EVENT,
2339             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
2340            (cconsts.NETWORK_CB_KEY_ID, dut2_s_req_key))
2341
2342        autils.wait_for_event_with_keys(
2343            dut2, cconsts.EVENT_NETWORK_CALLBACK,
2344            autils.EVENT_NDP_TIMEOUT,
2345            (cconsts.NETWORK_CB_KEY_EVENT,
2346             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
2347            (cconsts.NETWORK_CB_KEY_ID, dut2_p_req_key))
2348
2349        autils.wait_for_event_with_keys(
2350            dut1, cconsts.EVENT_NETWORK_CALLBACK,
2351            autils.EVENT_NDP_TIMEOUT,
2352            (cconsts.NETWORK_CB_KEY_EVENT,
2353             cconsts.NETWORK_CB_CAPABILITIES_CHANGED),
2354            (cconsts.NETWORK_CB_KEY_ID, dut1_s_req_key))
2355
2356