1# Copyright (C) 2024 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# Lint as: python3 16"""Wi-Fi Aware Discovery test reimplemented in Mobly.""" 17import enum 18import logging 19import random 20import string 21import sys 22import time 23from typing import Any, Dict, Union 24 25from aware import aware_lib_utils as autils 26from aware import constants 27from mobly import asserts 28from mobly import base_test 29from mobly import records 30from mobly import test_runner 31from mobly import utils 32from mobly.controllers import android_device 33from mobly.controllers.android_device_lib import callback_handler_v2 34 35RUNTIME_PERMISSIONS = ( 36 'android.permission.ACCESS_FINE_LOCATION', 37 'android.permission.ACCESS_COARSE_LOCATION', 38 'android.permission.NEARBY_WIFI_DEVICES', 39) 40PACKAGE_NAME = constants.WIFI_AWARE_SNIPPET_PACKAGE_NAME 41_DEFAULT_TIMEOUT = constants.WAIT_WIFI_STATE_TIME_OUT.total_seconds() 42_MSG_ID_SUB_TO_PUB = random.randint(1000, 5000) 43_MSG_ID_PUB_TO_SUB = random.randint(5001, 9999) 44_MSG_SUB_TO_PUB = "Let's talk [Random Identifier: %s]" % utils.rand_ascii_str(5) 45_MSG_PUB_TO_SUB = 'Ready [Random Identifier: %s]' % utils.rand_ascii_str(5) 46_CALLBACK_NAME = constants.DiscoverySessionCallbackParamsType.CALLBACK_NAME 47_IS_SESSION_INIT = constants.DiscoverySessionCallbackParamsType.IS_SESSION_INIT 48 49# Publish & Subscribe Config keys. 50_PAYLOAD_SIZE_MIN = 0 51_PAYLOAD_SIZE_TYPICAL = 1 52_PAYLOAD_SIZE_MAX = 2 53_PUBLISH_TYPE_UNSOLICITED = 0 54_PUBLISH_TYPE_SOLICITED = 1 55_SUBSCRIBE_TYPE_PASSIVE = 0 56_SUBSCRIBE_TYPE_ACTIVE = 1 57 58 59class WifiAwareDiscoveryTest(base_test.BaseTestClass): 60 """Wi-Fi Aware test class.""" 61 62 ads: list[android_device.AndroidDevice] 63 publisher: android_device.AndroidDevice 64 subscriber: android_device.AndroidDevice 65 66 def setup_class(self): 67 # Register two Android devices. 68 self.ads = self.register_controller(android_device, min_number=2) 69 self.publisher = self.ads[0] 70 self.subscriber = self.ads[1] 71 72 def setup_device(device: android_device.AndroidDevice): 73 device.load_snippet( 74 'wifi_aware_snippet', PACKAGE_NAME 75 ) 76 for permission in RUNTIME_PERMISSIONS: 77 device.adb.shell(['pm', 'grant', PACKAGE_NAME, permission]) 78 asserts.abort_all_if( 79 not device.wifi_aware_snippet.wifiAwareIsAvailable(), 80 f'{device} Wi-Fi Aware is not available.', 81 ) 82 83 # Set up devices in parallel. 84 utils.concurrent_exec( 85 setup_device, 86 ((self.publisher,), (self.subscriber,)), 87 max_workers=2, 88 raise_on_exception=True, 89 ) 90 91 def setup_test(self): 92 for ad in self.ads: 93 autils.control_wifi(ad, True) 94 aware_avail = ad.wifi_aware_snippet.wifiAwareIsAvailable() 95 if not aware_avail: 96 ad.log.info('Aware not available. Waiting ...') 97 state_handler = ad.wifi_aware_snippet.wifiAwareMonitorStateChange() 98 state_handler.waitAndGet( 99 constants.WifiAwareBroadcast.WIFI_AWARE_AVAILABLE) 100 101 def teardown_test(self): 102 utils.concurrent_exec( 103 self._teardown_test_on_device, 104 ((self.publisher,), (self.subscriber,)), 105 max_workers=2, 106 raise_on_exception=True, 107 ) 108 utils.concurrent_exec( 109 lambda d: d.services.create_output_excerpts_all( 110 self.current_test_info), 111 param_list=[[ad] for ad in self.ads], 112 raise_on_exception=True, 113 ) 114 115 def _teardown_test_on_device(self, ad: android_device.AndroidDevice) -> None: 116 ad.wifi_aware_snippet.wifiAwareCloseAllWifiAwareSession() 117 autils.reset_device_parameters(ad) 118 autils.reset_device_statistics(ad) 119 120 def on_fail(self, record: records.TestResult) -> None: 121 android_device.take_bug_reports(self.ads, 122 destination = 123 self.current_test_info.output_path) 124 125 def _start_attach(self, ad: android_device.AndroidDevice) -> str: 126 """Starts the attach process on the provided device.""" 127 handler = ad.wifi_aware_snippet.wifiAwareAttach() 128 attach_event = handler.waitAndGet( 129 event_name=constants.AttachCallBackMethodType.ATTACHED, 130 timeout=_DEFAULT_TIMEOUT, 131 ) 132 asserts.assert_true( 133 ad.wifi_aware_snippet.wifiAwareIsSessionAttached(handler.callback_id), 134 f'{ad} attach succeeded, but Wi-Fi Aware session is still null.' 135 ) 136 ad.log.info('Attach Wi-Fi Aware session succeeded.') 137 return attach_event.callback_id 138 139 def _send_msg_and_check_received( 140 self, 141 *, 142 sender: android_device.AndroidDevice, 143 sender_aware_session_cb_handler: callback_handler_v2.CallbackHandlerV2, 144 receiver: android_device.AndroidDevice, 145 receiver_aware_session_cb_handler: callback_handler_v2.CallbackHandlerV2, 146 discovery_session: str, 147 peer: int, 148 send_message: str, 149 send_message_id: int, 150 ) -> int: 151 sender.wifi_aware_snippet.wifiAwareSendMessage( 152 discovery_session, peer, send_message_id, send_message 153 ) 154 message_send_result = sender_aware_session_cb_handler.waitAndGet( 155 event_name = 156 constants.DiscoverySessionCallbackMethodType.MESSAGE_SEND_RESULT, 157 timeout =_DEFAULT_TIMEOUT, 158 ) 159 callback_name = message_send_result.data[ 160 constants.DiscoverySessionCallbackParamsType.CALLBACK_NAME 161 ] 162 asserts.assert_equal( 163 callback_name, 164 constants.DiscoverySessionCallbackMethodType.MESSAGE_SEND_SUCCEEDED, 165 f'{sender} failed to send message with an unexpected callback.', 166 ) 167 actual_send_message_id = message_send_result.data[ 168 constants.DiscoverySessionCallbackParamsType.MESSAGE_ID 169 ] 170 asserts.assert_equal( 171 actual_send_message_id, 172 send_message_id, 173 f'{sender} send message succeeded but message ID mismatched.' 174 ) 175 receive_message_event = receiver_aware_session_cb_handler.waitAndGet( 176 event_name = constants.DiscoverySessionCallbackMethodType.MESSAGE_RECEIVED, 177 timeout = _DEFAULT_TIMEOUT, 178 ) 179 received_message_raw = receive_message_event.data[ 180 constants.WifiAwareSnippetParams.RECEIVED_MESSAGE 181 ] 182 received_message = bytes(received_message_raw).decode('utf-8') 183 asserts.assert_equal( 184 received_message, 185 send_message, 186 f'{receiver} received the message but message content mismatched.' 187 ) 188 return receive_message_event.data[ 189 constants.WifiAwareSnippetParams.PEER_ID] 190 191 def create_base_config(self, 192 caps: Dict[str, Union[bool, int, str]], 193 is_publish: bool, 194 ptype: Union[int, None], 195 stype: Union[int, None], 196 payload_size: int, 197 ttl: int, 198 term_ind_on: bool, 199 null_match: bool) -> Dict[str, Any]: 200 config = {} 201 if is_publish: 202 config[constants.PUBLISH_TYPE] = ptype 203 else: 204 config[constants.SUBSCRIBE_TYPE] = stype 205 config[constants.TTL_SEC] = ttl 206 config[constants.TERMINATE_NOTIFICATION_ENABLED] = term_ind_on 207 if payload_size == _PAYLOAD_SIZE_MIN: 208 config[constants.SERVICE_NAME] = "a" 209 config[constants.SERVICE_SPECIFIC_INFO] = None 210 config[constants.MATCH_FILTER] = [] 211 elif payload_size == _PAYLOAD_SIZE_TYPICAL: 212 config[constants.SERVICE_NAME] = "GoogleTestServiceX" 213 if is_publish: 214 config[constants.SERVICE_SPECIFIC_INFO] = string.ascii_letters 215 else: 216 config[constants.SERVICE_SPECIFIC_INFO] = string.ascii_letters[ 217 ::-1] 218 config[constants.MATCH_FILTER] = autils.encode_list( 219 [(10).to_bytes(1, byteorder="big"),"hello there string" 220 if not null_match else None,bytes(range(40))]) 221 else: # aware_constant.PAYLOAD_SIZE_MAX 222 config[constants.SERVICE_NAME] = "VeryLong" + "X" * ( 223 len("maxServiceNameLen") - 8) 224 config[constants.SERVICE_SPECIFIC_INFO] = ( 225 "P" if is_publish else "S") * len("maxServiceSpecificInfoLen") 226 mf = autils.construct_max_match_filter(len("maxMatchFilterLen")) 227 if null_match: 228 mf[2] = None 229 config[constants.MATCH_FILTER] = autils.encode_list(mf) 230 return config 231 232 def create_publish_config(self, caps: Dict[str, Union[bool, int, str]], 233 ptype: int, payload_size: int, ttl: int, 234 term_ind_on: bool, 235 null_match: bool) -> Dict[str, Any]: 236 return self.create_base_config(caps, True, ptype, None, payload_size, 237 ttl, term_ind_on, null_match) 238 239 def create_subscribe_config(self, caps: Dict[str, Union[bool, int, str]], 240 stype: int, payload_size: int, ttl: int, 241 term_ind_on: bool, 242 null_match: bool) -> Dict[str, Any]: 243 return self.create_base_config(caps, False, None, stype, payload_size, 244 ttl, term_ind_on, null_match) 245 246 def _positive_discovery_logic(self, ptype: int, stype: int, 247 payload_size: int) -> None: 248 """Utility function for positive discovery test. 249 250 1. Attach both publisher + subscriber to WiFi Aware service. 251 2. Publisher publishes a service. 252 3. Subscriber discoveries service(s) from publisher. 253 4. Exchange messages both publisher + subscriber. 254 5. Update publish/subscribe. 255 6. Terminate publish/subscribe. 256 257 Args: 258 ptype: Publish discovery type. 259 stype: Subscribe discovery type. 260 payload_size: One of PAYLOAD_SIZE_* constants - MIN, TYPICAL, MAX. 261 262 """ 263 pid = self._start_attach(self.publisher) 264 sid = self._start_attach(self.subscriber) 265 p_config = self.create_publish_config( 266 self.publisher.wifi_aware_snippet.getCharacteristics(), 267 ptype, 268 payload_size, 269 ttl=0, 270 term_ind_on=False, 271 null_match=False, 272 ) 273 p_disc_id = self.publisher.wifi_aware_snippet.wifiAwarePublish( 274 pid, p_config 275 ) 276 self.publisher.log.info('Created the publish session.') 277 p_discovery = p_disc_id.waitAndGet( 278 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 279 callback_name = p_discovery.data[_CALLBACK_NAME] 280 asserts.assert_equal( 281 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 282 callback_name, 283 f'{self.publisher} publish failed, got callback: {callback_name}.', 284 ) 285 s_config = self.create_subscribe_config( 286 self.subscriber.wifi_aware_snippet.getCharacteristics(), 287 stype, 288 payload_size, 289 ttl=0, 290 term_ind_on=False, 291 null_match=True, 292 ) 293 s_disc_id = self.subscriber.wifi_aware_snippet.wifiAwareSubscribe( 294 sid, s_config 295 ) 296 s_discovery = s_disc_id.waitAndGet( 297 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 298 callback_name = s_discovery.data[_CALLBACK_NAME] 299 asserts.assert_equal( 300 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 301 callback_name, 302 f'{self.subscriber} subscribe failed, got callback: {callback_name}.' 303 ) 304 is_session_init = s_discovery.data[_IS_SESSION_INIT] 305 asserts.assert_true( 306 is_session_init, 307 f'{self.subscriber} subscribe succeeded, but null session returned.' 308 ) 309 discovered_event = s_disc_id.waitAndGet( 310 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 311 subscriber_peer = discovered_event.data[constants.WifiAwareSnippetParams.PEER_ID] 312 if p_config[constants.SERVICE_SPECIFIC_INFO] == None: 313 p_ssi_1st_disc = "null" 314 else: 315 p_ssi_1st_disc = p_config[constants.SERVICE_SPECIFIC_INFO] 316 s_ssi_1st_disc = bytes( 317 discovered_event.data[ 318 constants.WifiAwareSnippetParams.SERVICE_SPECIFIC_INFO] 319 ).decode("utf-8") 320 asserts.assert_equal(s_ssi_1st_disc, p_ssi_1st_disc, 321 "Discovery mismatch: service specific info (SSI)") 322 p_filter_list_1 = autils.decode_list(p_config[constants.MATCH_FILTER]) 323 s_filter_list_1 = discovered_event.data[ 324 constants.WifiAwareSnippetParams.MATCH_FILTER] 325 s_filter_list_1 = [bytes(filter[ 326 constants.WifiAwareSnippetParams.MATCH_FILTER_VALUE 327 ]).decode("utf-8") 328 for filter in s_filter_list_1] 329 s_filter_list_1 = autils.decode_list(s_filter_list_1) 330 asserts.assert_equal(s_filter_list_1, 331 p_filter_list_1 if ptype == _PUBLISH_TYPE_UNSOLICITED 332 else autils.decode_list(s_config[constants.MATCH_FILTER]), 333 "Discovery mismatch: match filter") 334 # Subscriber sends a message to publisher. 335 publisher_peer = self._send_msg_and_check_received( 336 sender=self.subscriber, 337 sender_aware_session_cb_handler=s_disc_id, 338 receiver=self.publisher, 339 receiver_aware_session_cb_handler=p_disc_id, 340 discovery_session=s_disc_id.callback_id, 341 peer=subscriber_peer, 342 send_message=_MSG_SUB_TO_PUB, 343 send_message_id=_MSG_ID_SUB_TO_PUB, 344 ) 345 logging.info( 346 'The subscriber sent a message and the publisher received it.' 347 ) 348 # Publisher sends a message to subscriber. 349 self._send_msg_and_check_received( 350 sender=self.publisher, 351 sender_aware_session_cb_handler=p_disc_id, 352 receiver=self.subscriber, 353 receiver_aware_session_cb_handler=s_disc_id, 354 discovery_session=p_disc_id.callback_id, 355 peer=publisher_peer, 356 send_message=_MSG_PUB_TO_SUB, 357 send_message_id=_MSG_ID_PUB_TO_SUB, 358 ) 359 logging.info( 360 'The publisher sent a message and the subscriber received it.' 361 ) 362 p_config[constants.SERVICE_SPECIFIC_INFO] = "something else" 363 self.publisher.wifi_aware_snippet.wifiAwareUpdatePublish( 364 p_disc_id.callback_id, p_config 365 ) 366 p_disc_id.waitAndGet( 367 constants.DiscoverySessionCallbackMethodType.SESSION_CONFIG_UPDATED) 368 discovered_event_1 = s_disc_id.waitAndGet( 369 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 370 p_ssi_2st_disc = p_config[constants.SERVICE_SPECIFIC_INFO] 371 s_ssi_2st_disc = bytes( 372 discovered_event_1.data[ 373 constants.WifiAwareSnippetParams.SERVICE_SPECIFIC_INFO] 374 ).decode("utf-8") 375 asserts.assert_equal(s_ssi_2st_disc, p_ssi_2st_disc, 376 "Discovery mismatch (after pub update): service specific info (SSI") 377 p_filter_list_2 = autils.decode_list(p_config[constants.MATCH_FILTER]) 378 s_filter_list_2 = discovered_event_1.data[ 379 constants.WifiAwareSnippetParams.MATCH_FILTER] 380 s_filter_list_2 = [bytes(filter[ 381 constants.WifiAwareSnippetParams.MATCH_FILTER_VALUE]).decode("utf-8") 382 for filter in s_filter_list_2] 383 s_filter_list_2 = autils.decode_list(s_filter_list_2) 384 asserts.assert_equal(s_filter_list_2, 385 p_filter_list_2 if ptype == _PUBLISH_TYPE_UNSOLICITED 386 else autils.decode_list(s_config[constants.MATCH_FILTER]), 387 "Discovery mismatch: match filter") 388 disc_peer_id = discovered_event_1.data[ 389 constants.WifiAwareSnippetParams.PEER_ID] 390 asserts.assert_equal(subscriber_peer, disc_peer_id, 391 "Peer ID changed when publish was updated!?") 392 s_config = self.create_subscribe_config( 393 self.subscriber.wifi_aware_snippet.getCharacteristics(), 394 stype, 395 payload_size, 396 ttl=0, 397 term_ind_on=False, 398 null_match=False, 399 ) 400 s_disc_id_1 = self.subscriber.wifi_aware_snippet.wifiAwareUpdateSubscribe( 401 discovered_event_1.callback_id, s_config 402 ) 403 s_disc_id.waitAndGet( 404 constants.DiscoverySessionCallbackMethodType.SESSION_CONFIG_UPDATED) 405 self.publisher.wifi_aware_snippet.wifiAwareCloseDiscoverSession( 406 p_disc_id.callback_id) 407 self.subscriber.wifi_aware_snippet.wifiAwareCloseDiscoverSession( 408 s_disc_id.callback_id) 409 p_disc_id.waitAndGet( 410 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED) 411 s_disc_id.waitAndGet( 412 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED) 413 time.sleep(10) 414 if self.publisher.is_adb_root: 415 # Verify that forbidden callbacks aren't called. 416 autils.validate_forbidden_callbacks(self.publisher, {"4": 0}) 417 self.publisher.wifi_aware_snippet.wifiAwareDetach(pid) 418 self.subscriber.wifi_aware_snippet.wifiAwareDetach(sid) 419 420 def verify_discovery_session_term(self, dut, disc_id, config, is_publish, 421 term_ind_on): 422 """Utility to verify that the specified discovery session has terminated. 423 (by waiting for the TTL and then attempting to reconfigure). 424 425 Args: 426 dut: device under test 427 disc_id: discovery id for the existing session 428 config: configuration of the existing session 429 is_publish: True if the configuration was publish, False if subscribe 430 term_ind_on: True if a termination indication is expected, False otherwise 431 """ 432 # Wait for session termination 433 if term_ind_on: 434 disc_id.waitAndGet( 435 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED, 436 timeout = _DEFAULT_TIMEOUT) 437 else: 438 autils.callback_no_response( 439 disc_id, 440 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED, 441 timeout = _DEFAULT_TIMEOUT) 442 config[constants.SERVICE_SPECIFIC_INFO] = "something else" 443 if is_publish: 444 dut.wifi_aware_snippet.wifiAwareUpdatePublish( 445 disc_id.callback_id, config 446 ) 447 else: 448 dut.wifi_aware_snippet.wifiAwareUpdateSubscribe( 449 disc_id.callback_id, config 450 ) 451 if not term_ind_on: 452 disc_id.waitAndGet( 453 constants.DiscoverySessionCallbackMethodType.SESSION_CONFIG_FAILED, 454 timeout =_DEFAULT_TIMEOUT 455 ) 456 457 def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): 458 """Utility which runs a positive discovery session TTL configuration test. 459 460 Iteration 1: Verify session started with TTL 461 Iteration 2: Verify session started without TTL and reconfigured with TTL 462 Iteration 3: Verify session started with (long) TTL and reconfigured with 463 (short) TTL 464 465 Args: 466 is_publish: True if testing publish, False if testing subscribe 467 ptype: Publish discovery type (used if is_publish is True) 468 stype: Subscribe discovery type (used if is_publish is False) 469 term_ind_on: Configuration of termination indication 470 """ 471 SHORT_TTL = 5 # 5 seconds 472 LONG_TTL = 100 # 100 seconds 473 dut = self.ads[0] 474 id = self._start_attach(dut) 475 # Iteration 1: Start discovery session with TTL 476 config = self.create_base_config( 477 dut.wifi_aware_snippet.getCharacteristics(), 478 is_publish, 479 ptype, stype, 480 _PAYLOAD_SIZE_TYPICAL, 481 SHORT_TTL, 482 term_ind_on, 483 False) 484 if is_publish: 485 disc_id = dut.wifi_aware_snippet.wifiAwarePublish( 486 id, config 487 ) 488 p_discovery = disc_id.waitAndGet( 489 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 490 timeout=_DEFAULT_TIMEOUT) 491 callback_name = p_discovery.data[_CALLBACK_NAME] 492 asserts.assert_equal( 493 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 494 callback_name, 495 f'{dut} publish failed, got callback: {callback_name}.', 496 ) 497 else: 498 disc_id = dut.wifi_aware_snippet.wifiAwareSubscribe( 499 id, config 500 ) 501 s_discovery = disc_id.waitAndGet( 502 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 503 timeout=_DEFAULT_TIMEOUT) 504 callback_name = s_discovery.data[_CALLBACK_NAME] 505 asserts.assert_equal( 506 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 507 callback_name, 508 f'{dut} subscribe failed, got callback: {callback_name}.', 509 ) 510 # Wait for session termination & verify 511 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 512 term_ind_on) 513 # Iteration 2: Start a discovery session without TTL 514 config = self.create_base_config( 515 dut.wifi_aware_snippet.getCharacteristics(), 516 is_publish, 517 ptype, stype, 518 _PAYLOAD_SIZE_TYPICAL, 519 0, 520 term_ind_on, 521 False) 522 if is_publish: 523 disc_id = dut.wifi_aware_snippet.wifiAwarePublish( 524 id, config 525 ) 526 p_discovery = disc_id.waitAndGet( 527 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 528 timeout=_DEFAULT_TIMEOUT) 529 callback_name = p_discovery.data[_CALLBACK_NAME] 530 asserts.assert_equal( 531 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 532 callback_name, 533 f'{dut} publish failed, got callback: {callback_name}.', 534 ) 535 else: 536 disc_id = dut.wifi_aware_snippet.wifiAwareSubscribe( 537 id, config 538 ) 539 s_discovery = disc_id.waitAndGet( 540 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 541 timeout=_DEFAULT_TIMEOUT) 542 callback_name = s_discovery.data[_CALLBACK_NAME] 543 asserts.assert_equal( 544 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 545 callback_name, 546 f'{dut} subscribe failed, got callback: {callback_name}.', 547 ) 548 # Update with a TTL 549 config = self.create_base_config( 550 dut.wifi_aware_snippet.getCharacteristics(), 551 is_publish, 552 ptype, stype, 553 _PAYLOAD_SIZE_TYPICAL, 554 SHORT_TTL, 555 term_ind_on, 556 False) 557 if is_publish: 558 disc_id = dut.wifi_aware_snippet.wifiAwarePublish( 559 id, config 560 ) 561 p_discovery = disc_id.waitAndGet( 562 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 563 timeout=_DEFAULT_TIMEOUT) 564 callback_name = p_discovery.data[_CALLBACK_NAME] 565 asserts.assert_equal( 566 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 567 callback_name, 568 f'{dut} publish failed, got callback: {callback_name}.', 569 ) 570 else: 571 disc_id = dut.wifi_aware_snippet.wifiAwareSubscribe( 572 id, config 573 ) 574 s_discovery = disc_id.waitAndGet( 575 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 576 timeout=_DEFAULT_TIMEOUT) 577 callback_name = s_discovery.data[_CALLBACK_NAME] 578 asserts.assert_equal( 579 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 580 callback_name, 581 f'{dut} subscribe failed, got callback: {callback_name}.', 582 ) 583 # Wait for session termination & verify 584 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 585 term_ind_on) 586 # Iteration 3: Start a discovery session with (long) TTL 587 config = self.create_base_config( 588 dut.wifi_aware_snippet.getCharacteristics(), 589 is_publish, 590 ptype, stype, 591 _PAYLOAD_SIZE_TYPICAL, 592 LONG_TTL, 593 term_ind_on, 594 False) 595 if is_publish: 596 disc_id = dut.wifi_aware_snippet.wifiAwarePublish( 597 id, config 598 ) 599 p_discovery = disc_id.waitAndGet( 600 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 601 timeout=_DEFAULT_TIMEOUT) 602 callback_name = p_discovery.data[_CALLBACK_NAME] 603 asserts.assert_equal( 604 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 605 callback_name, 606 f'{dut} publish failed, got callback: {callback_name}.', 607 ) 608 else: 609 disc_id = dut.wifi_aware_snippet.wifiAwareSubscribe( 610 id, config 611 ) 612 s_discovery = disc_id.waitAndGet( 613 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 614 timeout=_DEFAULT_TIMEOUT) 615 callback_name = s_discovery.data[_CALLBACK_NAME] 616 asserts.assert_equal( 617 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 618 callback_name, 619 f'{dut} subscribe failed, got callback: {callback_name}.', 620 ) 621 # Update with a TTL 622 config = self.create_base_config( 623 dut.wifi_aware_snippet.getCharacteristics(), 624 is_publish, 625 ptype, stype, 626 _PAYLOAD_SIZE_TYPICAL, 627 SHORT_TTL, 628 term_ind_on, 629 False) 630 if is_publish: 631 disc_id = dut.wifi_aware_snippet.wifiAwarePublish( 632 id, config 633 ) 634 p_discovery = disc_id.waitAndGet( 635 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 636 timeout=_DEFAULT_TIMEOUT) 637 callback_name = p_discovery.data[_CALLBACK_NAME] 638 asserts.assert_equal( 639 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 640 callback_name, 641 f'{dut} publish failed, got callback: {callback_name}.', 642 ) 643 else: 644 disc_id = dut.wifi_aware_snippet.wifiAwareSubscribe( 645 id, config 646 ) 647 s_discovery = disc_id.waitAndGet( 648 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 649 timeout=_DEFAULT_TIMEOUT) 650 callback_name = s_discovery.data[_CALLBACK_NAME] 651 asserts.assert_equal( 652 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 653 callback_name, 654 f'{dut} subscribe failed, got callback: {callback_name}.', 655 ) 656 # Wait for session termination & verify 657 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 658 term_ind_on) 659 # verify that forbidden callbacks aren't called 660 if not term_ind_on: 661 autils.validate_forbidden_callbacks( 662 dut,{ 663 "2": 0, 664 "3": 0}) 665 666 def discovery_mismatch_test_utility(self, 667 is_expected_to_pass, 668 p_type, 669 s_type, 670 p_service_name=None, 671 s_service_name=None, 672 p_mf_1=None, 673 s_mf_1=None): 674 """Utility which runs the negative discovery test for mismatched service 675 configs. 676 677 Args: 678 is_expected_to_pass: True if positive test, False if negative 679 p_type: Publish discovery type 680 s_type: Subscribe discovery type 681 p_service_name: Publish service name (or None to leave unchanged) 682 s_service_name: Subscribe service name (or None to leave unchanged) 683 p_mf_1: Publish match filter element [1] (or None to leave unchanged) 684 s_mf_1: Subscribe match filter element [1] (or None to leave unchanged) 685 """ 686 p_dut = self.ads[0] 687 s_dut = self.ads[1] 688 # create configurations 689 p_config = self.create_publish_config( 690 p_dut.wifi_aware_snippet.getCharacteristics(), 691 p_type, 692 _PAYLOAD_SIZE_TYPICAL, 693 ttl=0, 694 term_ind_on=False, 695 null_match=False) 696 if p_service_name is not None: 697 p_config[constants.SERVICE_NAME] = p_service_name 698 if p_mf_1 is not None: 699 # p_config[constants.MATCH_FILTER] = p_mf_1.encode("utf-8") 700 p_config[constants.MATCH_FILTER] = autils.encode_list( 701 [(10).to_bytes(1, byteorder="big"), p_mf_1 , bytes(range(40))]) 702 s_config = self.create_subscribe_config( 703 s_dut.wifi_aware_snippet.getCharacteristics(), 704 s_type, 705 _PAYLOAD_SIZE_TYPICAL, 706 ttl=0, 707 term_ind_on=False, 708 null_match=False) 709 if s_service_name is not None: 710 s_config[constants.SERVICE_NAME] = s_service_name 711 if s_mf_1 is not None: 712 s_config[constants.MATCH_FILTER] = autils.encode_list( 713 [(10).to_bytes(1, byteorder="big"), s_mf_1 , bytes(range(40))]) 714 p_id = self._start_attach(p_dut) 715 s_id = self._start_attach(s_dut) 716 # Publisher: start publish and wait for confirmation 717 p_disc_id = p_dut.wifi_aware_snippet.wifiAwarePublish( 718 p_id, p_config 719 ) 720 p_dut.log.info('Created the publish session.') 721 p_discovery = p_disc_id.waitAndGet( 722 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 723 callback_name = p_discovery.data[_CALLBACK_NAME] 724 asserts.assert_equal( 725 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 726 callback_name, 727 f'{p_dut} publish failed, got callback: {callback_name}.', 728 ) 729 s_disc_id = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 730 s_id, s_config 731 ) 732 s_discovery = s_disc_id.waitAndGet( 733 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 734 timeout=_DEFAULT_TIMEOUT) 735 callback_name = s_discovery.data[_CALLBACK_NAME] 736 asserts.assert_equal( 737 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 738 callback_name, 739 f'{s_dut} subscribe failed, got callback: {callback_name}.', 740 ) 741 # Subscriber: fail on service discovery 742 if is_expected_to_pass: 743 s_disc_id.waitAndGet( 744 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 745 else: 746 autils.callback_no_response( 747 s_disc_id, 748 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED, 749 timeout = _DEFAULT_TIMEOUT) 750 # Publisher+Subscriber: Terminate sessions 751 p_dut.wifi_aware_snippet.wifiAwareCloseDiscoverSession( 752 p_disc_id.callback_id) 753 s_dut.wifi_aware_snippet.wifiAwareCloseDiscoverSession( 754 s_disc_id.callback_id) 755 p_disc_id.waitAndGet( 756 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED) 757 s_disc_id.waitAndGet( 758 constants.DiscoverySessionCallbackMethodType.SESSION_TERMINATED) 759 760 def create_discovery_pair( 761 self, p_dut, s_dut, p_config, s_config, msg_id=None): 762 """Creates a discovery session (publish and subscribe), and waits for 763 service discovery - at that point the sessions are connected and ready for 764 further messaging of data-path setup. 765 766 Args: 767 p_dut: Device to use as publisher. 768 s_dut: Device to use as subscriber. 769 p_config: Publish configuration. 770 s_config: Subscribe configuration. 771 device_startup_offset: Number of seconds to offset the enabling of NAN on 772 the two devices. 773 msg_id: Controls whether a message is sent from Subscriber to Publisher 774 (so that publisher has the sub's peer ID). If None then not sent, 775 otherwise should be an int for the message id. 776 Returns: variable size list of: 777 p_id: Publisher attach session id 778 s_id: Subscriber attach session id 779 p_disc_id: Publisher discovery session id 780 s_disc_id: Subscriber discovery session id 781 peer_id_on_sub: Peer ID of the Publisher as seen on the Subscriber 782 peer_id_on_pub: Peer ID of the Subscriber as seen on the Publisher. Only 783 included if |msg_id| is not None. 784 """ 785 786 p_dut = self.ads[0] 787 s_dut = self.ads[1] 788 # attach and wait for confirmation 789 p_id = self._start_attach(p_dut) 790 s_id = self._start_attach(s_dut) 791 p_disc_id = p_dut.wifi_aware_snippet.wifiAwarePublish( 792 p_id, p_config 793 ) 794 p_dut.log.info('Created the publish session.') 795 p_discovery = p_disc_id.waitAndGet( 796 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 797 callback_name = p_discovery.data[_CALLBACK_NAME] 798 asserts.assert_equal( 799 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 800 callback_name, 801 f'{p_dut} publish failed, got callback: {callback_name}.', 802 ) 803 # Subscriber: start subscribe and wait for confirmation 804 s_disc_id = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 805 s_id, s_config 806 ) 807 s_dut.log.info('Created the subscribe session.') 808 s_discovery = s_disc_id.waitAndGet( 809 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 810 callback_name = s_discovery.data[_CALLBACK_NAME] 811 asserts.assert_equal( 812 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 813 callback_name, 814 f'{s_dut} subscribe failed, got callback: {callback_name}.', 815 ) 816 # Subscriber: wait for service discovery 817 discovery_event = s_disc_id.waitAndGet( 818 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 819 peer_id_on_sub = discovery_event.data[constants.WifiAwareSnippetParams.PEER_ID] 820 # Optionally send a message from Subscriber to Publisher 821 if msg_id is not None: 822 ping_msg = 'PING' 823 # Subscriber: send message to peer (Publisher) 824 s_dut.sender.wifi_aware_snippet.wifiAwareSendMessage( 825 s_disc_id, peer_id_on_sub, _MSG_ID_SUB_TO_PUB, ping_msg 826 ) 827 message_send_result = s_disc_id.waitAndGet( 828 event_name = 829 constants.DiscoverySessionCallbackMethodType.MESSAGE_SEND_RESULT, 830 timeout =_DEFAULT_TIMEOUT, 831 ) 832 actual_send_message_id = message_send_result.data[ 833 constants.DiscoverySessionCallbackParamsType.MESSAGE_ID 834 ] 835 asserts.assert_equal( 836 actual_send_message_id, 837 _MSG_ID_SUB_TO_PUB, 838 f'{s_dut} send message succeeded but message ID mismatched.' 839 ) 840 pub_rx_msg_event = p_disc_id.waitAndGet( 841 event_name = constants.DiscoverySessionCallbackMethodType.MESSAGE_RECEIVED, 842 timeout = _DEFAULT_TIMEOUT, 843 ) 844 peer_id_on_pub = pub_rx_msg_event.data[constants.WifiAwareSnippetParams.PEER_ID] 845 received_message_raw = pub_rx_msg_event.data[ 846 constants.WifiAwareSnippetParams.RECEIVED_MESSAGE 847 ] 848 received_message = bytes(received_message_raw).decode('utf-8') 849 asserts.assert_equal( 850 received_message, 851 ping_msg, 852 f'{p_dut} Subscriber -> Publisher message corrupted.' 853 ) 854 return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, peer_id_on_pub 855 return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub 856 857 def exchange_messages(self, p_dut, p_disc_id, s_dut, s_disc_id, peer_id_on_sub, session_name): 858 """ 859 Exchange message between Publisher and Subscriber on target discovery session 860 861 Args: 862 p_dut: Publisher device 863 p_disc_id: Publish discovery session id 864 s_dut: Subscriber device 865 s_disc_id: Subscribe discovery session id 866 peer_id_on_sub: Peer ID of the Publisher as seen on the Subscriber 867 session_name: dictionary of discovery session name base on role("pub" or "sub") 868 {role: {disc_id: name}} 869 """ 870 871 msg_template = "Hello {} from {} !" 872 # Message send from Subscriber to Publisher 873 s_to_p_msg = msg_template.format(session_name["pub"][p_disc_id], 874 session_name["sub"][s_disc_id]) 875 publisher_peer = self._send_msg_and_check_received( 876 sender = s_dut, 877 sender_aware_session_cb_handler= s_disc_id, 878 receiver = p_dut, 879 receiver_aware_session_cb_handler= p_disc_id, 880 discovery_session = s_disc_id.callback_id, 881 peer=peer_id_on_sub, 882 send_message =s_to_p_msg, 883 send_message_id = _MSG_ID_SUB_TO_PUB, 884 ) 885 logging.info( 886 'The subscriber sent a message and the publisher received it.' 887 ) 888 889 # Publisher sends a message to subscriber. 890 p_to_s_msg = msg_template.format(session_name["sub"][s_disc_id], 891 session_name["pub"][p_disc_id]) 892 self._send_msg_and_check_received( 893 sender=p_dut, 894 sender_aware_session_cb_handler=p_disc_id, 895 receiver=s_dut, 896 receiver_aware_session_cb_handler=s_disc_id, 897 discovery_session=p_disc_id.callback_id, 898 peer=publisher_peer, 899 send_message=p_to_s_msg, 900 send_message_id=_MSG_ID_PUB_TO_SUB, 901 ) 902 logging.info( 903 'The publisher sent a message and the subscriber received it.' 904 ) 905 906 def run_multiple_concurrent_services(self, type_x, type_y): 907 """Validate same service name with multiple service specific info on publisher 908 and subscriber can see all service 909 910 - p_dut running Publish X and Y 911 - s_dut running subscribe A and B 912 - subscribe A find X and Y 913 - subscribe B find X and Y 914 915 Message exchanges: 916 - A to X and X to A 917 - B to X and X to B 918 - A to Y and Y to A 919 - B to Y and Y to B 920 921 Note: test requires that publisher device support 2 publish sessions concurrently, 922 and subscriber device support 2 subscribe sessions concurrently. 923 The test will be skipped if the devices are not capable. 924 925 Args: 926 type_x, type_y: A list of [ptype, stype] of the publish and subscribe 927 types for services X and Y respectively. 928 """ 929 930 p_dut = self.ads[0] 931 s_dut = self.ads[1] 932 X_SERVICE_NAME = "ServiceXXX" 933 Y_SERVICE_NAME = "ServiceYYY" 934 asserts.skip_if( 935 autils.get_aware_capabilities(p_dut)["maxPublishes"] < 2 936 or autils.get_aware_capabilities(s_dut)["maxPublishes"] < 2 937 ,"Devices do not support 2 publish sessions" 938 ) 939 # attach and wait for confirmation 940 p_id = self._start_attach(p_dut) 941 s_id = self._start_attach(s_dut) 942 # DUT1 & DUT2: start publishing both X & Y services and wait for 943 # confirmations 944 dut1_x_pid = p_dut.wifi_aware_snippet.wifiAwarePublish( 945 p_id, autils.create_discovery_config(X_SERVICE_NAME, type_x[0], None) 946 ) 947 p_dut.log.info('Created the DUT1 X publish session.') 948 p_discovery = dut1_x_pid.waitAndGet( 949 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 950 callback_name = p_discovery.data[_CALLBACK_NAME] 951 asserts.assert_equal( 952 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 953 callback_name, 954 f'{p_dut} DUT1 X publish failed, got callback: {callback_name}.', 955 ) 956 dut1_y_pid = p_dut.wifi_aware_snippet.wifiAwarePublish( 957 p_id, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0], None) 958 ) 959 p_dut.log.info('Created the DUT1 Y publish session.') 960 p_discovery = dut1_y_pid.waitAndGet( 961 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 962 callback_name = p_discovery.data[_CALLBACK_NAME] 963 asserts.assert_equal( 964 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 965 callback_name, 966 f'{p_dut} DUT1 Y publish failed, got callback: {callback_name}.', 967 ) 968 dut2_x_pid = s_dut.wifi_aware_snippet.wifiAwarePublish( 969 s_id, autils.create_discovery_config(X_SERVICE_NAME, type_x[0], None) 970 ) 971 s_dut.log.info('Created the DUT2 X publish session.') 972 p_discovery = dut2_x_pid.waitAndGet( 973 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 974 callback_name = p_discovery.data[_CALLBACK_NAME] 975 asserts.assert_equal( 976 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 977 callback_name, 978 f'{s_dut} DUT2 X publish failed, got callback: {callback_name}.', 979 ) 980 dut2_y_pid = s_dut.wifi_aware_snippet.wifiAwarePublish( 981 s_id, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0], None) 982 ) 983 s_dut.log.info('Created the DUT2 Y publish session.') 984 p_discovery = dut2_y_pid.waitAndGet( 985 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 986 callback_name = p_discovery.data[_CALLBACK_NAME] 987 asserts.assert_equal( 988 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 989 callback_name, 990 f'{s_dut} DUT1 Y publish failed, got callback: {callback_name}.', 991 ) 992 # DUT1: start subscribing for X 993 dut1_x_sid = p_dut.wifi_aware_snippet.wifiAwareSubscribe( 994 p_id, autils.create_discovery_config(X_SERVICE_NAME, None, type_x[1]) 995 ) 996 p_dut.log.info('Created the DUT1 X subscribe session.') 997 s_discovery = dut1_x_sid.waitAndGet( 998 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 999 timeout=_DEFAULT_TIMEOUT) 1000 callback_name = s_discovery.data[_CALLBACK_NAME] 1001 asserts.assert_equal( 1002 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1003 callback_name, 1004 f'{p_dut} DUT1 X subscribe failed, got callback: {callback_name}.', 1005 ) 1006 # DUT1: start subscribing for Y 1007 dut1_y_sid = p_dut.wifi_aware_snippet.wifiAwareSubscribe( 1008 p_id, autils.create_discovery_config(Y_SERVICE_NAME, None, type_y[1]) 1009 ) 1010 p_dut.log.info('Created the DUT1 Y subscribe session.') 1011 s_discovery = dut1_y_sid.waitAndGet( 1012 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1013 callback_name = s_discovery.data[_CALLBACK_NAME] 1014 asserts.assert_equal( 1015 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1016 callback_name, 1017 f'{p_dut} DUT1 Y subscribe failed, got callback: {callback_name}.', 1018 ) 1019 # DUT2: start subscribing for X 1020 dut2_x_sid = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 1021 s_id, autils.create_discovery_config(X_SERVICE_NAME, None, type_x[1]) 1022 ) 1023 s_dut.log.info('Created the DUT2 X subscribe session.') 1024 s_discovery = dut2_x_sid.waitAndGet( 1025 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 1026 timeout=_DEFAULT_TIMEOUT) 1027 callback_name = s_discovery.data[_CALLBACK_NAME] 1028 asserts.assert_equal( 1029 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1030 callback_name, 1031 f'{s_dut} DUT2 X subscribe failed, got callback: {callback_name}.', 1032 ) 1033 # DUT2: start subscribing for Y 1034 dut2_y_sid = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 1035 s_id, autils.create_discovery_config(Y_SERVICE_NAME, None, type_y[1]) 1036 ) 1037 s_dut.log.info('Created the DUT2 Y subscribe session.') 1038 s_discovery = dut2_y_sid.waitAndGet( 1039 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1040 callback_name = s_discovery.data[_CALLBACK_NAME] 1041 asserts.assert_equal( 1042 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1043 callback_name, 1044 f'{s_dut} DUT2 Y subscribe failed, got callback: {callback_name}.', 1045 ) 1046 dut1_x_sid_event = dut1_x_sid.waitAndGet( 1047 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 1048 dut1_peer_id_for_dut2_x = dut1_x_sid_event.data[constants.WifiAwareSnippetParams.PEER_ID] 1049 1050 dut2_y_sid_event = dut2_y_sid.waitAndGet( 1051 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 1052 dut2_peer_id_for_dut1_y = dut2_y_sid_event.data[constants.WifiAwareSnippetParams.PEER_ID] 1053 1054 # DUT1.X send message to DUT2 1055 x_msg = "Hello X on DUT2!" 1056 publisher_peer = self._send_msg_and_check_received( 1057 sender = p_dut, 1058 sender_aware_session_cb_handler= dut1_x_sid, 1059 receiver = s_dut, 1060 receiver_aware_session_cb_handler= dut2_x_pid, 1061 discovery_session = dut1_x_sid.callback_id, 1062 peer=dut1_peer_id_for_dut2_x, 1063 send_message =x_msg, 1064 send_message_id = _MSG_ID_PUB_TO_SUB, 1065 ) 1066 logging.info( 1067 'The DUT1.X sent a message and the DUT2 received it.' 1068 ) 1069 1070 # DUT2.Y send message to DUT1 1071 y_msg = "Hello Y on DUT1!" 1072 self._send_msg_and_check_received( 1073 sender = s_dut, 1074 sender_aware_session_cb_handler= dut2_y_sid, 1075 receiver = p_dut, 1076 receiver_aware_session_cb_handler= dut1_y_pid, 1077 discovery_session = dut2_y_sid.callback_id, 1078 peer=dut2_peer_id_for_dut1_y, 1079 send_message =y_msg, 1080 send_message_id = _MSG_ID_SUB_TO_PUB, 1081 ) 1082 logging.info( 1083 'The DUT2.Y sent a message and the DUT1 received it.' 1084 ) 1085 1086 def run_multiple_concurrent_services_same_name_diff_ssi(self, type_x, type_y): 1087 """Validate same service name with multiple service specific info on publisher 1088 and subscriber can see all service 1089 1090 - p_dut running Publish X and Y 1091 - s_dut running subscribe A and B 1092 - subscribe A find X and Y 1093 - subscribe B find X and Y 1094 1095 Message exchanges: 1096 - A to X and X to A 1097 - B to X and X to B 1098 - A to Y and Y to A 1099 - B to Y and Y to B 1100 1101 Note: test requires that publisher device support 2 publish sessions concurrently, 1102 and subscriber device support 2 subscribe sessions concurrently. 1103 The test will be skipped if the devices are not capable. 1104 1105 Args: 1106 type_x, type_y: A list of [ptype, stype] of the publish and subscribe 1107 types for services X and Y respectively. 1108 """ 1109 p_dut = self.ads[0] 1110 s_dut = self.ads[1] 1111 asserts.skip_if( 1112 autils.get_aware_capabilities(p_dut)["maxPublishes"] < 2 1113 or autils.get_aware_capabilities(s_dut)["maxPublishes"] < 2 1114 ,"Devices do not support 2 publish sessions" 1115 ) 1116 SERVICE_NAME = "ServiceName" 1117 X_SERVICE_SSI = "ServiceSpecificInfoXXX" 1118 Y_SERVICE_SSI = "ServiceSpecificInfoYYY" 1119 # use_id = True 1120 # attach and wait for confirmation 1121 p_id = self._start_attach(p_dut) 1122 s_id = self._start_attach(s_dut) 1123 p_disc_id_x = p_dut.wifi_aware_snippet.wifiAwarePublish( 1124 p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], None, X_SERVICE_SSI) 1125 ) 1126 p_dut.log.info('Created the DUT1 X publish session.') 1127 p_discovery = p_disc_id_x.waitAndGet( 1128 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1129 callback_name = p_discovery.data[_CALLBACK_NAME] 1130 asserts.assert_equal( 1131 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 1132 callback_name, 1133 f'{p_dut} DUT1 X publish failed, got callback: {callback_name}.', 1134 ) 1135 p_disc_id_y = p_dut.wifi_aware_snippet.wifiAwarePublish( 1136 p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], None, Y_SERVICE_SSI) 1137 ) 1138 p_dut.log.info('Created the DUT1 Y publish session.') 1139 p_discovery = p_disc_id_y.waitAndGet( 1140 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1141 callback_name = p_discovery.data[_CALLBACK_NAME] 1142 asserts.assert_equal( 1143 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 1144 callback_name, 1145 f'{p_dut} DUT1 Y publish failed, got callback: {callback_name}.', 1146 ) 1147 # Subscriber: start subscribe session A 1148 s_disc_id_a = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 1149 s_id, autils.create_discovery_config(SERVICE_NAME, None, type_x[1] ) 1150 ) 1151 s_dut.log.info('Created the DUT2 X subscribe session.') 1152 s_discovery = s_disc_id_a.waitAndGet( 1153 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT, 1154 timeout=_DEFAULT_TIMEOUT) 1155 callback_name = s_discovery.data[_CALLBACK_NAME] 1156 asserts.assert_equal( 1157 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1158 callback_name, 1159 f'{s_dut} DUT2 X subscribe failed, got callback: {callback_name}.', 1160 ) 1161 # Subscriber: start subscribe session B 1162 s_disc_id_b = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 1163 s_id, autils.create_discovery_config(SERVICE_NAME, None, type_y[1]) 1164 ) 1165 s_dut.log.info('Created the DUT2 Y subscribe session.') 1166 s_discovery = s_disc_id_b.waitAndGet( 1167 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1168 callback_name = s_discovery.data[_CALLBACK_NAME] 1169 asserts.assert_equal( 1170 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1171 callback_name, 1172 f'{s_dut} DUT2 Y subscribe failed, got callback: {callback_name}.', 1173 ) 1174 session_name = {"pub": {p_disc_id_x: "X", p_disc_id_y: "Y"}, 1175 "sub": {s_disc_id_a: "A", s_disc_id_b: "B"}} 1176 # Subscriber: subscribe session A & B wait for service discovery 1177 # Number of results on each session should be exactly 2 1178 results_a = {} 1179 for i in range(2): 1180 event = s_disc_id_a.waitAndGet( 1181 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 1182 results_a[ 1183 bytes(event.data[constants.WifiAwareSnippetParams.SERVICE_SPECIFIC_INFO]).decode("utf-8")] = event 1184 autils.callback_no_response( 1185 s_disc_id_a, constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED, 10, True 1186 ) 1187 results_b = {} 1188 for i in range(2): 1189 event = s_disc_id_b.waitAndGet( 1190 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 1191 results_b[ 1192 bytes(event.data[constants.WifiAwareSnippetParams.SERVICE_SPECIFIC_INFO]).decode("utf-8")] = event 1193 autils.callback_no_response( 1194 s_disc_id_b, constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED, 10, True 1195 ) 1196 s_a_peer_id_for_p_x = results_a[X_SERVICE_SSI].data[constants.WifiAwareSnippetParams.PEER_ID] 1197 s_a_peer_id_for_p_y = results_a[Y_SERVICE_SSI].data[constants.WifiAwareSnippetParams.PEER_ID] 1198 s_b_peer_id_for_p_x = results_b[X_SERVICE_SSI].data[constants.WifiAwareSnippetParams.PEER_ID] 1199 s_b_peer_id_for_p_y = results_b[Y_SERVICE_SSI].data[constants.WifiAwareSnippetParams.PEER_ID] 1200 1201 # Message exchange between Publisher and Subscribe 1202 self.exchange_messages(p_dut, p_disc_id_x, 1203 s_dut, s_disc_id_a, s_a_peer_id_for_p_x, session_name) 1204 1205 self.exchange_messages(p_dut, p_disc_id_x, 1206 s_dut, s_disc_id_b, s_b_peer_id_for_p_x, session_name) 1207 1208 self.exchange_messages(p_dut, p_disc_id_y, 1209 s_dut, s_disc_id_a, s_a_peer_id_for_p_y, session_name) 1210 1211 self.exchange_messages(p_dut, p_disc_id_y, 1212 s_dut, s_disc_id_b, s_b_peer_id_for_p_y, session_name) 1213 1214 def run_service_discovery_on_service_lost(self, p_type, s_type): 1215 """ 1216 Validate service lost callback will be receive on subscriber, when publisher stopped publish 1217 - p_dut running Publish 1218 - s_dut running subscribe 1219 - s_dut discover p_dut 1220 - p_dut stop publish 1221 - s_dut receive service lost callback 1222 1223 Args: 1224 p_type: Publish discovery type 1225 s_type: Subscribe discovery type 1226 """ 1227 p_dut = self.ads[0] 1228 s_dut = self.ads[1] 1229 # attach and wait for confirmation 1230 p_id = self._start_attach(p_dut) 1231 s_id = self._start_attach(s_dut) 1232 p_config = self.create_publish_config( 1233 p_dut.wifi_aware_snippet.getCharacteristics(), 1234 p_type, 1235 _PAYLOAD_SIZE_TYPICAL, 1236 ttl=0, 1237 term_ind_on=False, 1238 null_match=False, 1239 ) 1240 p_disc_id = p_dut.wifi_aware_snippet.wifiAwarePublish( 1241 p_id, p_config 1242 ) 1243 p_dut.log.info('Created the publish session.') 1244 p_discovery = p_disc_id.waitAndGet( 1245 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1246 callback_name = p_discovery.data[_CALLBACK_NAME] 1247 asserts.assert_equal( 1248 constants.DiscoverySessionCallbackMethodType.PUBLISH_STARTED, 1249 callback_name, 1250 f'{p_dut} publish failed, got callback: {callback_name}.', 1251 ) 1252 s_config = self.create_subscribe_config( 1253 s_dut.wifi_aware_snippet.getCharacteristics(), 1254 s_type, 1255 _PAYLOAD_SIZE_TYPICAL, 1256 ttl=0, 1257 term_ind_on=False, 1258 null_match=True, 1259 ) 1260 s_disc_id = s_dut.wifi_aware_snippet.wifiAwareSubscribe( 1261 s_id, s_config 1262 ) 1263 s_dut.log.info('Created the subscribe session.') 1264 s_discovery = s_disc_id.waitAndGet( 1265 constants.DiscoverySessionCallbackMethodType.DISCOVER_RESULT) 1266 callback_name = s_discovery.data[_CALLBACK_NAME] 1267 asserts.assert_equal( 1268 constants.DiscoverySessionCallbackMethodType.SUBSCRIBE_STARTED, 1269 callback_name, 1270 f'{s_dut} subscribe failed, got callback: {callback_name}.' 1271 ) 1272 discovered_event = s_disc_id.waitAndGet( 1273 constants.DiscoverySessionCallbackMethodType.SERVICE_DISCOVERED) 1274 peer_id_on_sub = discovered_event.data[ 1275 constants.WifiAwareSnippetParams.PEER_ID] 1276 # Publisher+Subscriber: Terminate sessions 1277 p_dut.wifi_aware_snippet.wifiAwareCloseDiscoverSession( 1278 p_disc_id.callback_id) 1279 time.sleep(10) 1280 # service_lost_event = s_disc_id.waitAndGet("WifiAwareSessionOnServiceLost") 1281 service_lost_event = s_disc_id.waitAndGet( 1282 constants.DiscoverySessionCallbackMethodType.SESSION_CB_ON_SERVICE_LOST) 1283 asserts.assert_equal(peer_id_on_sub, 1284 service_lost_event.data[constants.WifiAwareSnippetParams.PEER_ID]) 1285 asserts.assert_equal( 1286 constants.EASON_PEER_NOT_VISIBLE, 1287 service_lost_event.data[constants.DiscoverySessionCallbackMethodType.SESSION_CB_KEY_LOST_REASON] 1288 ) 1289 1290 def test_positive_unsolicited_passive_typical(self)-> None: 1291 """Functional test case / Discovery test cases / positive test case: 1292 - Unsolicited publish + passive subscribe 1293 - Typical payload fields size 1294 1295 Verifies that discovery and message exchange succeeds. 1296 """ 1297 self._positive_discovery_logic( 1298 _PUBLISH_TYPE_UNSOLICITED, 1299 _SUBSCRIBE_TYPE_PASSIVE, 1300 _PAYLOAD_SIZE_TYPICAL 1301 ) 1302 1303 def test_positive_unsolicited_passive_min(self)-> None: 1304 """Functional test case / Discovery test cases / positive test case: 1305 - Unsolicited publish + passive subscribe 1306 - Minimal payload fields size 1307 1308 Verifies that discovery and message exchange succeeds. 1309 """ 1310 self._positive_discovery_logic( 1311 _PUBLISH_TYPE_UNSOLICITED, 1312 _SUBSCRIBE_TYPE_PASSIVE, 1313 _PAYLOAD_SIZE_MIN 1314 ) 1315 1316 def test_positive_unsolicited_passive_max(self)-> None: 1317 """Functional test case / Discovery test cases / positive test case: 1318 - Unsolicited publish + passive subscribe 1319 - Maximal payload fields size 1320 1321 Verifies that discovery and message exchange succeeds. 1322 """ 1323 self._positive_discovery_logic( 1324 _PUBLISH_TYPE_UNSOLICITED, 1325 _SUBSCRIBE_TYPE_PASSIVE, 1326 _PAYLOAD_SIZE_MAX 1327 ) 1328 1329 def test_positive_solicited_active_typical(self)-> None: 1330 """Functional test case / Discovery test cases / positive test case: 1331 - Solicited publish + active subscribe 1332 - Typical payload fields size 1333 1334 Verifies that discovery and message exchange succeeds. 1335 """ 1336 self._positive_discovery_logic( 1337 _PUBLISH_TYPE_SOLICITED, 1338 _SUBSCRIBE_TYPE_ACTIVE, 1339 _PAYLOAD_SIZE_TYPICAL 1340 ) 1341 1342 def test_positive_solicited_active_min(self)-> None: 1343 """Functional test case / Discovery test cases / positive test case: 1344 - Solicited publish + active subscribe 1345 - Minimal payload fields size 1346 1347 Verifies that discovery and message exchange succeeds. 1348 """ 1349 self._positive_discovery_logic( 1350 _PUBLISH_TYPE_SOLICITED, 1351 _SUBSCRIBE_TYPE_ACTIVE, 1352 _PAYLOAD_SIZE_MIN 1353 ) 1354 1355 def test_positive_solicited_active_max(self)-> None: 1356 """Functional test case / Discovery test cases / positive test case: 1357 - Solicited publish + active subscribe 1358 - Maximal payload fields size 1359 1360 Verifies that discovery and message exchange succeeds. 1361 """ 1362 self._positive_discovery_logic( 1363 _PUBLISH_TYPE_SOLICITED, 1364 _SUBSCRIBE_TYPE_ACTIVE, 1365 _PAYLOAD_SIZE_MAX 1366 ) 1367 1368 ####################################### 1369 # TTL tests key: 1370 # 1371 # names is: test_ttl_<pub_type|sub_type>_<term_ind> 1372 # where: 1373 # 1374 # pub_type: Type of publish discovery session: unsolicited or solicited. 1375 # sub_type: Type of subscribe discovery session: passive or active. 1376 # term_ind: ind_on or ind_off 1377 ####################################### 1378 1379 def test_ttl_unsolicited_ind_on(self)-> None: 1380 """Functional test case / Discovery test cases / TTL test case: 1381 - Unsolicited publish 1382 - Termination indication enabled 1383 """ 1384 self.positive_ttl_test_utility( 1385 is_publish=True, 1386 ptype=_PUBLISH_TYPE_UNSOLICITED, 1387 stype=None, 1388 term_ind_on=True) 1389 1390 def test_ttl_unsolicited_ind_off(self)-> None: 1391 """Functional test case / Discovery test cases / TTL test case: 1392 - Unsolicited publish 1393 - Termination indication disabled 1394 """ 1395 self.positive_ttl_test_utility( 1396 is_publish=True, 1397 ptype=_PUBLISH_TYPE_UNSOLICITED, 1398 stype=None, 1399 term_ind_on=False) 1400 1401 def test_ttl_solicited_ind_on(self)-> None: 1402 """Functional test case / Discovery test cases / TTL test case: 1403 - Solicited publish 1404 - Termination indication enabled 1405 """ 1406 self.positive_ttl_test_utility( 1407 is_publish=True, 1408 ptype=_PUBLISH_TYPE_SOLICITED, 1409 stype=None, 1410 term_ind_on=True) 1411 1412 def test_ttl_solicited_ind_off(self)-> None: 1413 """Functional test case / Discovery test cases / TTL test case: 1414 - Solicited publish 1415 - Termination indication disabled 1416 """ 1417 self.positive_ttl_test_utility( 1418 is_publish=True, 1419 ptype=_PUBLISH_TYPE_SOLICITED, 1420 stype=None, 1421 term_ind_on=False) 1422 1423 def test_ttl_passive_ind_on(self)-> None: 1424 """Functional test case / Discovery test cases / TTL test case: 1425 - Passive subscribe 1426 - Termination indication enabled 1427 """ 1428 self.positive_ttl_test_utility( 1429 is_publish=False, 1430 ptype=None, 1431 stype=_SUBSCRIBE_TYPE_PASSIVE, 1432 term_ind_on=True) 1433 1434 def test_ttl_passive_ind_off(self)-> None: 1435 """Functional test case / Discovery test cases / TTL test case: 1436 - Passive subscribe 1437 - Termination indication disabled 1438 """ 1439 self.positive_ttl_test_utility( 1440 is_publish=False, 1441 ptype=None, 1442 stype=_SUBSCRIBE_TYPE_PASSIVE, 1443 term_ind_on=False) 1444 1445 def test_ttl_active_ind_on(self)-> None: 1446 """Functional test case / Discovery test cases / TTL test case: 1447 - Active subscribe 1448 - Termination indication enabled 1449 """ 1450 self.positive_ttl_test_utility( 1451 is_publish=False, 1452 ptype=None, 1453 stype=_SUBSCRIBE_TYPE_ACTIVE, 1454 term_ind_on=True) 1455 1456 def test_ttl_active_ind_off(self)-> None: 1457 """Functional test case / Discovery test cases / TTL test case: 1458 - Active subscribe 1459 - Termination indication disabled 1460 """ 1461 self.positive_ttl_test_utility( 1462 is_publish=False, 1463 ptype=None, 1464 stype=_SUBSCRIBE_TYPE_ACTIVE, 1465 term_ind_on=False) 1466 1467 ####################################### 1468 # Mismatched discovery session type tests key: 1469 # 1470 # names is: test_mismatch_service_type_<pub_type>_<sub_type> 1471 # where: 1472 # 1473 # pub_type: Type of publish discovery session: unsolicited or solicited. 1474 # sub_type: Type of subscribe discovery session: passive or active. 1475 ####################################### 1476 1477 def test_mismatch_service_type_unsolicited_active(self): 1478 """Functional test case / Discovery test cases / Mismatch service name 1479 - Unsolicited publish 1480 - Active subscribe 1481 """ 1482 self.discovery_mismatch_test_utility( 1483 is_expected_to_pass=True, 1484 p_type=_PUBLISH_TYPE_UNSOLICITED, 1485 s_type=_SUBSCRIBE_TYPE_ACTIVE) 1486 1487 def test_mismatch_service_type_solicited_passive(self): 1488 """Functional test case / Discovery test cases / Mismatch service name 1489 - Unsolicited publish 1490 - Active subscribe 1491 """ 1492 self.discovery_mismatch_test_utility( 1493 is_expected_to_pass=False, 1494 p_type = _PUBLISH_TYPE_SOLICITED, 1495 s_type = _SUBSCRIBE_TYPE_PASSIVE) 1496 1497 ###################################### 1498 # Mismatched service name tests key: 1499 # 1500 # names is: test_mismatch_service_name_<pub_type>_<sub_type> 1501 # where: 1502 # 1503 # pub_type: Type of publish discovery session: unsolicited or solicited. 1504 # sub_type: Type of subscribe discovery session: passive or active. 1505 ####################################### 1506 1507 def test_mismatch_service_name_unsolicited_passive(self): 1508 """Functional test case / Discovery test cases / Mismatch service name 1509 - Unsolicited publish 1510 - Passive subscribe 1511 """ 1512 self.discovery_mismatch_test_utility( 1513 is_expected_to_pass=False, 1514 p_type=_PUBLISH_TYPE_UNSOLICITED, 1515 s_type=_SUBSCRIBE_TYPE_PASSIVE, 1516 p_service_name="GoogleTestServiceXXX", 1517 s_service_name="GoogleTestServiceYYY") 1518 1519 def test_mismatch_service_name_solicited_active(self): 1520 """Functional test case / Discovery test cases / Mismatch service name 1521 - Solicited publish 1522 - Active subscribe 1523 """ 1524 self.discovery_mismatch_test_utility( 1525 is_expected_to_pass=False, 1526 p_type=_PUBLISH_TYPE_SOLICITED, 1527 s_type=_SUBSCRIBE_TYPE_ACTIVE, 1528 p_service_name="GoogleTestServiceXXX", 1529 s_service_name="GoogleTestServiceYYY") 1530 1531 ####################################### 1532 # Mismatched discovery match filter tests key: 1533 # 1534 # names is: test_mismatch_match_filter_<pub_type>_<sub_type> 1535 # where: 1536 # 1537 # pub_type: Type of publish discovery session: unsolicited or solicited. 1538 # sub_type: Type of subscribe discovery session: passive or active. 1539 ####################################### 1540 1541 def test_mismatch_match_filter_unsolicited_passive(self): 1542 """Functional test case / Discovery test cases / Mismatch match filter 1543 - Unsolicited publish 1544 - Passive subscribe 1545 """ 1546 self.discovery_mismatch_test_utility( 1547 is_expected_to_pass=False, 1548 p_type=_PUBLISH_TYPE_UNSOLICITED, 1549 s_type=_SUBSCRIBE_TYPE_PASSIVE, 1550 p_mf_1="hello there string", 1551 s_mf_1="goodbye there string") 1552 1553 def test_mismatch_match_filter_solicited_active(self): 1554 """Functional test case / Discovery test cases / Mismatch match filter 1555 - Solicited publish 1556 - Active subscribe 1557 """ 1558 self.discovery_mismatch_test_utility( 1559 is_expected_to_pass=False, 1560 p_type=_PUBLISH_TYPE_SOLICITED, 1561 s_type=_SUBSCRIBE_TYPE_ACTIVE, 1562 p_mf_1="hello there string", 1563 s_mf_1="goodbye there string") 1564 1565 ######################################################### 1566 # Multiple concurrent services 1567 ####################################### 1568 1569 def test_multiple_concurrent_services_both_unsolicited_passive(self): 1570 """Validate multiple concurrent discovery sessions running on both devices. 1571 - DUT1 & DUT2 running Publish for X 1572 - DUT1 & DUT2 running Publish for Y 1573 - DUT1 Subscribes for X 1574 - DUT2 Subscribes for Y 1575 Message exchanges. 1576 1577 Both sessions are Unsolicited/Passive. 1578 1579 Note: test requires that devices support 2 publish sessions concurrently. 1580 The test will be skipped if the devices are not capable. 1581 """ 1582 self.run_multiple_concurrent_services( 1583 type_x=[ 1584 _PUBLISH_TYPE_UNSOLICITED, 1585 _SUBSCRIBE_TYPE_PASSIVE 1586 ], 1587 type_y=[ 1588 _PUBLISH_TYPE_UNSOLICITED, 1589 _SUBSCRIBE_TYPE_PASSIVE 1590 ]) 1591 1592 def test_multiple_concurrent_services_both_solicited_active(self): 1593 """Validate multiple concurrent discovery sessions running on both devices. 1594 - DUT1 & DUT2 running Publish for X 1595 - DUT1 & DUT2 running Publish for Y 1596 - DUT1 Subscribes for X 1597 - DUT2 Subscribes for Y 1598 Message exchanges. 1599 1600 Both sessions are Solicited/Active. 1601 1602 Note: test requires that devices support 2 publish sessions concurrently. 1603 The test will be skipped if the devices are not capable. 1604 """ 1605 self.run_multiple_concurrent_services( 1606 type_x=[ 1607 _PUBLISH_TYPE_SOLICITED, 1608 _SUBSCRIBE_TYPE_ACTIVE 1609 ], 1610 type_y=[ 1611 _PUBLISH_TYPE_SOLICITED, _SUBSCRIBE_TYPE_ACTIVE 1612 ]) 1613 1614 def test_multiple_concurrent_services_mix_unsolicited_solicited(self): 1615 """Validate multiple concurrent discovery sessions running on both devices. 1616 - DUT1 & DUT2 running Publish for X 1617 - DUT1 & DUT2 running Publish for Y 1618 - DUT1 Subscribes for X 1619 - DUT2 Subscribes for Y 1620 Message exchanges. 1621 1622 Session A is Unsolicited/Passive. 1623 Session B is Solicited/Active. 1624 1625 Note: test requires that devices support 2 publish sessions concurrently. 1626 The test will be skipped if the devices are not capable. 1627 """ 1628 self.run_multiple_concurrent_services( 1629 type_x=[ 1630 _PUBLISH_TYPE_UNSOLICITED, 1631 _SUBSCRIBE_TYPE_PASSIVE 1632 ], 1633 type_y=[ 1634 _PUBLISH_TYPE_SOLICITED, _SUBSCRIBE_TYPE_ACTIVE 1635 ]) 1636 1637 ######################################################### 1638 # Multiple concurrent services with diff ssi 1639 ######################################################### 1640 1641 def test_multiple_concurrent_services_diff_ssi_unsolicited_passive(self): 1642 """Multi service test on same service name but different Service Specific Info 1643 - Unsolicited publish 1644 - Passive subscribe 1645 """ 1646 self.run_multiple_concurrent_services_same_name_diff_ssi( 1647 type_x=[_PUBLISH_TYPE_UNSOLICITED, _SUBSCRIBE_TYPE_PASSIVE], 1648 type_y=[_PUBLISH_TYPE_UNSOLICITED, _SUBSCRIBE_TYPE_PASSIVE]) 1649 1650 def test_multiple_concurrent_services_diff_ssi_solicited_active(self): 1651 """Multi service test on same service name but different Service Specific Info 1652 - Solicited publish 1653 - Active subscribe 1654 """ 1655 self.run_multiple_concurrent_services_same_name_diff_ssi( 1656 type_x=[_PUBLISH_TYPE_SOLICITED, _SUBSCRIBE_TYPE_ACTIVE], 1657 type_y=[_PUBLISH_TYPE_SOLICITED, _SUBSCRIBE_TYPE_ACTIVE]) 1658 1659 ######################################################### 1660 1661 def test_upper_lower_service_name_equivalence(self): 1662 """Validate that Service Name is case-insensitive. Publish a service name 1663 with mixed case, subscribe to the same service name with alternative case 1664 and verify that discovery happens.""" 1665 p_dut = self.ads[0] 1666 s_dut = self.ads[1] 1667 1668 pub_service_name = "GoogleAbCdEf" 1669 sub_service_name = "GoogleaBcDeF" 1670 p_config = autils.create_discovery_config(pub_service_name) 1671 p_config[constants.PUBLISH_TYPE] = _PUBLISH_TYPE_UNSOLICITED 1672 s_config = autils.create_discovery_config(sub_service_name) 1673 s_config[constants.SUBSCRIBE_TYPE] = _SUBSCRIBE_TYPE_PASSIVE 1674 self.create_discovery_pair( 1675 p_dut, 1676 s_dut, 1677 p_config, 1678 s_config) 1679 1680 ######################################################### 1681 # service discovery on service lost 1682 ######################################################### 1683 1684 def test_service_discovery_on_service_lost_unsolicited_passive(self): 1685 """ 1686 Test service discovery lost with unsolicited publish and passive subscribe 1687 """ 1688 self.run_service_discovery_on_service_lost(_PUBLISH_TYPE_UNSOLICITED, 1689 _SUBSCRIBE_TYPE_PASSIVE) 1690 1691 def test_service_discovery_on_service_lost_solicited_active(self): 1692 """ 1693 Test service discovery lost with solicited publish and active subscribe 1694 """ 1695 self.run_service_discovery_on_service_lost(_PUBLISH_TYPE_SOLICITED, 1696 _SUBSCRIBE_TYPE_ACTIVE) 1697 1698if __name__ == '__main__': 1699 # Take test args 1700 if '--' in sys.argv: 1701 index = sys.argv.index('--') 1702 sys.argv = sys.argv[:1] + sys.argv[index + 1:] 1703 1704 test_runner.main() 1705