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 queue 18import string 19import time 20 21from acts import asserts 22from acts.test_decorators import test_tracker_info 23from acts_contrib.test_utils.wifi.aware import aware_const as aconsts 24from acts_contrib.test_utils.wifi.aware import aware_test_utils as autils 25from acts_contrib.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest 26from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 27 28 29class DiscoveryTest(AwareBaseTest): 30 """Set of tests for Wi-Fi Aware discovery.""" 31 32 # configuration parameters used by tests 33 PAYLOAD_SIZE_MIN = 0 34 PAYLOAD_SIZE_TYPICAL = 1 35 PAYLOAD_SIZE_MAX = 2 36 EVENT_TIMEOUT = 3 37 38 # message strings 39 query_msg = "How are you doing? 你好嗎?" 40 response_msg = "Doing ok - thanks! 做的不錯 - 謝謝!" 41 42 # message re-transmit counter (increases reliability in open-environment) 43 # Note: reliability of message transmission is tested elsewhere 44 msg_retx_count = 5 # hard-coded max value, internal API 45 46 def create_base_config(self, caps, is_publish, ptype, stype, payload_size, 47 ttl, term_ind_on, null_match): 48 """Create a base configuration based on input parameters. 49 50 Args: 51 caps: device capability dictionary 52 is_publish: True if a publish config, else False 53 ptype: unsolicited or solicited (used if is_publish is True) 54 stype: passive or active (used if is_publish is False) 55 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 56 ttl: time-to-live configuration (0 - forever) 57 term_ind_on: is termination indication enabled 58 null_match: null-out the middle match filter 59 Returns: 60 publish discovery configuration object. 61 """ 62 config = {} 63 if is_publish: 64 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = ptype 65 else: 66 config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = stype 67 config[aconsts.DISCOVERY_KEY_TTL] = ttl 68 config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_ind_on 69 if payload_size == self.PAYLOAD_SIZE_MIN: 70 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "a" 71 config[aconsts.DISCOVERY_KEY_SSI] = None 72 config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = [] 73 elif payload_size == self.PAYLOAD_SIZE_TYPICAL: 74 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" 75 if is_publish: 76 config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters 77 else: 78 config[aconsts. 79 DISCOVERY_KEY_SSI] = string.ascii_letters[:: 80 -1] # reverse 81 config[ 82 aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 83 [(10).to_bytes(1, byteorder="big"), "hello there string" 84 if not null_match else None, 85 bytes(range(40))]) 86 else: # PAYLOAD_SIZE_MAX 87 config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "VeryLong" + "X" * ( 88 caps[aconsts.CAP_MAX_SERVICE_NAME_LEN] - 8) 89 config[aconsts.DISCOVERY_KEY_SSI] = ( 90 "P" if is_publish else 91 "S") * caps[aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] 92 mf = autils.construct_max_match_filter( 93 caps[aconsts.CAP_MAX_MATCH_FILTER_LEN]) 94 if null_match: 95 mf[2] = None 96 config[aconsts. 97 DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list(mf) 98 99 return config 100 101 def create_publish_config(self, caps, ptype, payload_size, ttl, 102 term_ind_on, null_match): 103 """Create a publish configuration based on input parameters. 104 105 Args: 106 caps: device capability dictionary 107 ptype: unsolicited or solicited 108 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 109 ttl: time-to-live configuration (0 - forever) 110 term_ind_on: is termination indication enabled 111 null_match: null-out the middle match filter 112 Returns: 113 publish discovery configuration object. 114 """ 115 return self.create_base_config(caps, True, ptype, None, payload_size, 116 ttl, term_ind_on, null_match) 117 118 def create_subscribe_config(self, caps, stype, payload_size, ttl, 119 term_ind_on, null_match): 120 """Create a subscribe configuration based on input parameters. 121 122 Args: 123 caps: device capability dictionary 124 stype: passive or active 125 payload_size: min, typical, max (PAYLOAD_SIZE_xx) 126 ttl: time-to-live configuration (0 - forever) 127 term_ind_on: is termination indication enabled 128 null_match: null-out the middle match filter 129 Returns: 130 subscribe discovery configuration object. 131 """ 132 return self.create_base_config(caps, False, None, stype, payload_size, 133 ttl, term_ind_on, null_match) 134 135 def positive_discovery_test_utility(self, ptype, stype, payload_size): 136 """Utility which runs a positive discovery test: 137 - Discovery (publish/subscribe) with TTL=0 (non-self-terminating) 138 - Exchange messages 139 - Update publish/subscribe 140 - Terminate 141 142 Args: 143 ptype: Publish discovery type 144 stype: Subscribe discovery type 145 payload_size: One of PAYLOAD_SIZE_* constants - MIN, TYPICAL, MAX 146 """ 147 p_dut = self.android_devices[0] 148 p_dut.pretty_name = "Publisher" 149 s_dut = self.android_devices[1] 150 s_dut.pretty_name = "Subscriber" 151 152 # Publisher+Subscriber: attach and wait for confirmation 153 p_id = p_dut.droid.wifiAwareAttach(False) 154 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) 155 time.sleep(self.device_startup_offset) 156 s_id = s_dut.droid.wifiAwareAttach(False) 157 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) 158 159 # Publisher: start publish and wait for confirmation 160 p_config = self.create_publish_config( 161 p_dut.aware_capabilities, 162 ptype, 163 payload_size, 164 ttl=0, 165 term_ind_on=False, 166 null_match=False) 167 p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) 168 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 169 170 # Subscriber: start subscribe and wait for confirmation 171 s_config = self.create_subscribe_config( 172 s_dut.aware_capabilities, 173 stype, 174 payload_size, 175 ttl=0, 176 term_ind_on=False, 177 null_match=True) 178 s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) 179 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 180 181 # Subscriber: wait for service discovery 182 discovery_event = autils.wait_for_event( 183 s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 184 peer_id_on_sub = discovery_event["data"][ 185 aconsts.SESSION_CB_KEY_PEER_ID] 186 187 # Subscriber: validate contents of discovery: 188 # - SSI: publisher's 189 # - Match filter: UNSOLICITED - publisher, SOLICITED - subscriber 190 autils.assert_equal_strings( 191 bytes(discovery_event["data"][ 192 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), 193 p_config[aconsts.DISCOVERY_KEY_SSI], 194 "Discovery mismatch: service specific info (SSI)") 195 asserts.assert_equal( 196 autils.decode_list(discovery_event["data"][ 197 aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), 198 autils.decode_list( 199 p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] 200 if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ 201 aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), 202 "Discovery mismatch: match filter") 203 204 # Subscriber: send message to peer (Publisher) 205 s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, 206 self.get_next_msg_id(), 207 self.query_msg, self.msg_retx_count) 208 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) 209 210 # Publisher: wait for received message 211 pub_rx_msg_event = autils.wait_for_event( 212 p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 213 peer_id_on_pub = pub_rx_msg_event["data"][ 214 aconsts.SESSION_CB_KEY_PEER_ID] 215 216 # Publisher: validate contents of message 217 asserts.assert_equal( 218 pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], 219 self.query_msg, "Subscriber -> Publisher message corrupted") 220 221 # Publisher: send message to peer (Subscriber) 222 p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, 223 self.get_next_msg_id(), 224 self.response_msg, 225 self.msg_retx_count) 226 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) 227 228 # Subscriber: wait for received message 229 sub_rx_msg_event = autils.wait_for_event( 230 s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 231 232 # Subscriber: validate contents of message 233 asserts.assert_equal( 234 sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], 235 peer_id_on_sub, 236 "Subscriber received message from different peer ID then discovery!?" 237 ) 238 autils.assert_equal_strings( 239 sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], 240 self.response_msg, "Publisher -> Subscriber message corrupted") 241 242 # Subscriber: validate that we're not getting another Service Discovery 243 autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 244 245 # Publisher: update publish and wait for confirmation 246 p_config[aconsts.DISCOVERY_KEY_SSI] = "something else" 247 p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) 248 autils.wait_for_event(p_dut, 249 aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) 250 251 # Subscriber: expect a new service discovery 252 discovery_event = autils.wait_for_event( 253 s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 254 255 # Subscriber: validate contents of discovery 256 autils.assert_equal_strings( 257 bytes(discovery_event["data"][ 258 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), 259 p_config[aconsts.DISCOVERY_KEY_SSI], 260 "Discovery mismatch (after pub update): service specific info (SSI)" 261 ) 262 asserts.assert_equal( 263 autils.decode_list(discovery_event["data"][ 264 aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), 265 autils.decode_list( 266 p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] 267 if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ 268 aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), 269 "Discovery mismatch: match filter") 270 asserts.assert_equal( 271 peer_id_on_sub, 272 discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], 273 "Peer ID changed when publish was updated!?") 274 275 # Subscribe: update subscribe and wait for confirmation 276 s_config = self.create_subscribe_config( 277 s_dut.aware_capabilities, 278 stype, 279 payload_size, 280 ttl=0, 281 term_ind_on=False, 282 null_match=False) 283 s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) 284 autils.wait_for_event(s_dut, 285 aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) 286 287 # Publisher+Subscriber: Terminate sessions 288 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) 289 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) 290 291 autils.wait_for_event(p_dut, 292 aconsts.SESSION_CB_ON_SESSION_TERMINATED) 293 autils.wait_for_event(s_dut, 294 aconsts.SESSION_CB_ON_SESSION_TERMINATED) 295 296 297 # verify that there were no other events 298 autils.verify_no_more_events(p_dut, timeout=0) 299 autils.verify_no_more_events(s_dut, timeout=0) 300 301 # verify that forbidden callbacks aren't called 302 autils.validate_forbidden_callbacks(p_dut, {aconsts.CB_EV_MATCH: 0}) 303 304 def verify_discovery_session_term(self, dut, disc_id, config, is_publish, 305 term_ind_on): 306 """Utility to verify that the specified discovery session has terminated (by 307 waiting for the TTL and then attempting to reconfigure). 308 309 Args: 310 dut: device under test 311 disc_id: discovery id for the existing session 312 config: configuration of the existing session 313 is_publish: True if the configuration was publish, False if subscribe 314 term_ind_on: True if a termination indication is expected, False otherwise 315 """ 316 # Wait for session termination 317 if term_ind_on: 318 autils.wait_for_event( 319 dut, 320 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, 321 disc_id)) 322 else: 323 # can't defer wait to end since in any case have to wait for session to 324 # expire 325 autils.fail_on_event( 326 dut, 327 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, 328 disc_id)) 329 330 # Validate that session expired by trying to configure it (expect failure) 331 config[aconsts.DISCOVERY_KEY_SSI] = "something else" 332 if is_publish: 333 dut.droid.wifiAwareUpdatePublish(disc_id, config) 334 else: 335 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 336 337 # The response to update discovery session is: 338 # term_ind_on=True: session was cleaned-up so won't get an explicit failure, but won't get a 339 # success either. Can check for no SESSION_CB_ON_SESSION_CONFIG_UPDATED but 340 # will defer to the end of the test (no events on queue). 341 # term_ind_on=False: session was not cleaned-up (yet). So expect 342 # SESSION_CB_ON_SESSION_CONFIG_FAILED. 343 if not term_ind_on: 344 autils.wait_for_event( 345 dut, 346 autils.decorate_event( 347 aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED, disc_id)) 348 349 def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): 350 """Utility which runs a positive discovery session TTL configuration test 351 352 Iteration 1: Verify session started with TTL 353 Iteration 2: Verify session started without TTL and reconfigured with TTL 354 Iteration 3: Verify session started with (long) TTL and reconfigured with 355 (short) TTL 356 357 Args: 358 is_publish: True if testing publish, False if testing subscribe 359 ptype: Publish discovery type (used if is_publish is True) 360 stype: Subscribe discovery type (used if is_publish is False) 361 term_ind_on: Configuration of termination indication 362 """ 363 SHORT_TTL = 5 # 5 seconds 364 LONG_TTL = 100 # 100 seconds 365 dut = self.android_devices[0] 366 367 # Attach and wait for confirmation 368 id = dut.droid.wifiAwareAttach(False) 369 autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) 370 371 # Iteration 1: Start discovery session with TTL 372 config = self.create_base_config( 373 dut.aware_capabilities, is_publish, ptype, stype, 374 self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) 375 if is_publish: 376 disc_id = dut.droid.wifiAwarePublish(id, config, True) 377 autils.wait_for_event( 378 dut, 379 autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, 380 disc_id)) 381 else: 382 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 383 autils.wait_for_event( 384 dut, 385 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 386 disc_id)) 387 388 # Wait for session termination & verify 389 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 390 term_ind_on) 391 392 # Iteration 2: Start a discovery session without TTL 393 config = self.create_base_config( 394 dut.aware_capabilities, is_publish, ptype, stype, 395 self.PAYLOAD_SIZE_TYPICAL, 0, term_ind_on, False) 396 if is_publish: 397 disc_id = dut.droid.wifiAwarePublish(id, config, True) 398 autils.wait_for_event( 399 dut, 400 autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, 401 disc_id)) 402 else: 403 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 404 autils.wait_for_event( 405 dut, 406 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 407 disc_id)) 408 409 # Update with a TTL 410 config = self.create_base_config( 411 dut.aware_capabilities, is_publish, ptype, stype, 412 self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) 413 if is_publish: 414 dut.droid.wifiAwareUpdatePublish(disc_id, config) 415 else: 416 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 417 autils.wait_for_event( 418 dut, 419 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, 420 disc_id)) 421 422 # Wait for session termination & verify 423 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 424 term_ind_on) 425 426 # Iteration 3: Start a discovery session with (long) TTL 427 config = self.create_base_config( 428 dut.aware_capabilities, is_publish, ptype, stype, 429 self.PAYLOAD_SIZE_TYPICAL, LONG_TTL, term_ind_on, False) 430 if is_publish: 431 disc_id = dut.droid.wifiAwarePublish(id, config, True) 432 autils.wait_for_event( 433 dut, 434 autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, 435 disc_id)) 436 else: 437 disc_id = dut.droid.wifiAwareSubscribe(id, config, True) 438 autils.wait_for_event( 439 dut, 440 autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, 441 disc_id)) 442 443 # Update with a TTL 444 config = self.create_base_config( 445 dut.aware_capabilities, is_publish, ptype, stype, 446 self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) 447 if is_publish: 448 dut.droid.wifiAwareUpdatePublish(disc_id, config) 449 else: 450 dut.droid.wifiAwareUpdateSubscribe(disc_id, config) 451 autils.wait_for_event( 452 dut, 453 autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, 454 disc_id)) 455 456 # Wait for session termination & verify 457 self.verify_discovery_session_term(dut, disc_id, config, is_publish, 458 term_ind_on) 459 460 # verify that there were no other events 461 autils.verify_no_more_events(dut) 462 463 # verify that forbidden callbacks aren't called 464 if not term_ind_on: 465 autils.validate_forbidden_callbacks( 466 dut, { 467 aconsts.CB_EV_PUBLISH_TERMINATED: 0, 468 aconsts.CB_EV_SUBSCRIBE_TERMINATED: 0 469 }) 470 471 def discovery_mismatch_test_utility(self, 472 is_expected_to_pass, 473 p_type, 474 s_type, 475 p_service_name=None, 476 s_service_name=None, 477 p_mf_1=None, 478 s_mf_1=None): 479 """Utility which runs the negative discovery test for mismatched service 480 configs. 481 482 Args: 483 is_expected_to_pass: True if positive test, False if negative 484 p_type: Publish discovery type 485 s_type: Subscribe discovery type 486 p_service_name: Publish service name (or None to leave unchanged) 487 s_service_name: Subscribe service name (or None to leave unchanged) 488 p_mf_1: Publish match filter element [1] (or None to leave unchanged) 489 s_mf_1: Subscribe match filter element [1] (or None to leave unchanged) 490 """ 491 p_dut = self.android_devices[0] 492 p_dut.pretty_name = "Publisher" 493 s_dut = self.android_devices[1] 494 s_dut.pretty_name = "Subscriber" 495 496 # create configurations 497 p_config = self.create_publish_config( 498 p_dut.aware_capabilities, 499 p_type, 500 self.PAYLOAD_SIZE_TYPICAL, 501 ttl=0, 502 term_ind_on=False, 503 null_match=False) 504 if p_service_name is not None: 505 p_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = p_service_name 506 if p_mf_1 is not None: 507 p_config[ 508 aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 509 [(10).to_bytes(1, byteorder="big"), p_mf_1, 510 bytes(range(40))]) 511 s_config = self.create_publish_config( 512 s_dut.aware_capabilities, 513 s_type, 514 self.PAYLOAD_SIZE_TYPICAL, 515 ttl=0, 516 term_ind_on=False, 517 null_match=False) 518 if s_service_name is not None: 519 s_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = s_service_name 520 if s_mf_1 is not None: 521 s_config[ 522 aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( 523 [(10).to_bytes(1, byteorder="big"), s_mf_1, 524 bytes(range(40))]) 525 526 p_id = p_dut.droid.wifiAwareAttach(False) 527 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) 528 time.sleep(self.device_startup_offset) 529 s_id = s_dut.droid.wifiAwareAttach(False) 530 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) 531 532 # Publisher: start publish and wait for confirmation 533 p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) 534 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 535 536 # Subscriber: start subscribe and wait for confirmation 537 s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) 538 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 539 540 # Subscriber: fail on service discovery 541 if is_expected_to_pass: 542 autils.wait_for_event(s_dut, 543 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 544 else: 545 autils.fail_on_event(s_dut, 546 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 547 548 # Publisher+Subscriber: Terminate sessions 549 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) 550 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) 551 autils.wait_for_event(p_dut, 552 aconsts.SESSION_CB_ON_SESSION_TERMINATED) 553 autils.wait_for_event(s_dut, 554 aconsts.SESSION_CB_ON_SESSION_TERMINATED) 555 556 # verify that there were no other events (including terminations) 557 autils.verify_no_more_events(p_dut, timeout=0) 558 autils.verify_no_more_events(s_dut, timeout=0) 559 560 ####################################### 561 # Positive tests key: 562 # 563 # names is: test_<pub_type>_<sub_type>_<size> 564 # where: 565 # 566 # pub_type: Type of publish discovery session: unsolicited or solicited. 567 # sub_type: Type of subscribe discovery session: passive or active. 568 # size: Size of payload fields (service name, service specific info, and match 569 # filter: typical, max, or min. 570 ####################################### 571 572 @test_tracker_info(uuid="954ebbde-ed2b-4f04-9e68-88239187d69d") 573 @WifiBaseTest.wifi_test_wrap 574 def test_positive_unsolicited_passive_typical(self): 575 """Functional test case / Discovery test cases / positive test case: 576 - Solicited publish + passive subscribe 577 - Typical payload fields size 578 579 Verifies that discovery and message exchange succeeds. 580 """ 581 self.positive_discovery_test_utility( 582 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 583 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 584 payload_size=self.PAYLOAD_SIZE_TYPICAL) 585 586 @test_tracker_info(uuid="67fb22bb-6985-4345-95a4-90b76681a58b") 587 def test_positive_unsolicited_passive_min(self): 588 """Functional test case / Discovery test cases / positive test case: 589 - Solicited publish + passive subscribe 590 - Minimal payload fields size 591 592 Verifies that discovery and message exchange succeeds. 593 """ 594 self.positive_discovery_test_utility( 595 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 596 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 597 payload_size=self.PAYLOAD_SIZE_MIN) 598 599 @test_tracker_info(uuid="a02a47b9-41bb-47bb-883b-921024a2c30d") 600 def test_positive_unsolicited_passive_max(self): 601 """Functional test case / Discovery test cases / positive test case: 602 - Solicited publish + passive subscribe 603 - Maximal payload fields size 604 605 Verifies that discovery and message exchange succeeds. 606 """ 607 self.positive_discovery_test_utility( 608 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 609 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 610 payload_size=self.PAYLOAD_SIZE_MAX) 611 612 @test_tracker_info(uuid="586c657f-2388-4e7a-baee-9bce2f3d1a16") 613 def test_positive_solicited_active_typical(self): 614 """Functional test case / Discovery test cases / positive test case: 615 - Unsolicited publish + active subscribe 616 - Typical payload fields size 617 618 Verifies that discovery and message exchange succeeds. 619 """ 620 self.positive_discovery_test_utility( 621 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 622 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 623 payload_size=self.PAYLOAD_SIZE_TYPICAL) 624 625 @test_tracker_info(uuid="5369e4ff-f406-48c5-b41a-df38ec340146") 626 def test_positive_solicited_active_min(self): 627 """Functional test case / Discovery test cases / positive test case: 628 - Unsolicited publish + active subscribe 629 - Minimal payload fields size 630 631 Verifies that discovery and message exchange succeeds. 632 """ 633 self.positive_discovery_test_utility( 634 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 635 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 636 payload_size=self.PAYLOAD_SIZE_MIN) 637 638 @test_tracker_info(uuid="634c6eb8-2c4f-42bd-9bbb-d874d0ec22f3") 639 def test_positive_solicited_active_max(self): 640 """Functional test case / Discovery test cases / positive test case: 641 - Unsolicited publish + active subscribe 642 - Maximal payload fields size 643 644 Verifies that discovery and message exchange succeeds. 645 """ 646 self.positive_discovery_test_utility( 647 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 648 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 649 payload_size=self.PAYLOAD_SIZE_MAX) 650 651 ####################################### 652 # TTL tests key: 653 # 654 # names is: test_ttl_<pub_type|sub_type>_<term_ind> 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 # term_ind: ind_on or ind_off 660 ####################################### 661 662 @test_tracker_info(uuid="9d7e758e-e0e2-4550-bcee-bfb6a2bff63e") 663 def test_ttl_unsolicited_ind_on(self): 664 """Functional test case / Discovery test cases / TTL test case: 665 - Unsolicited publish 666 - Termination indication enabled 667 """ 668 self.positive_ttl_test_utility( 669 is_publish=True, 670 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 671 stype=None, 672 term_ind_on=True) 673 674 @test_tracker_info(uuid="48fd69bc-cc2a-4f65-a0a1-63d7c1720702") 675 def test_ttl_unsolicited_ind_off(self): 676 """Functional test case / Discovery test cases / TTL test case: 677 - Unsolicited publish 678 - Termination indication disabled 679 """ 680 self.positive_ttl_test_utility( 681 is_publish=True, 682 ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, 683 stype=None, 684 term_ind_on=False) 685 686 @test_tracker_info(uuid="afb75fc1-9ba7-446a-b5ed-7cd37ab51b1c") 687 def test_ttl_solicited_ind_on(self): 688 """Functional test case / Discovery test cases / TTL test case: 689 - Solicited publish 690 - Termination indication enabled 691 """ 692 self.positive_ttl_test_utility( 693 is_publish=True, 694 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 695 stype=None, 696 term_ind_on=True) 697 698 @test_tracker_info(uuid="703311a6-e444-4055-94ee-ea9b9b71799e") 699 def test_ttl_solicited_ind_off(self): 700 """Functional test case / Discovery test cases / TTL test case: 701 - Solicited publish 702 - Termination indication disabled 703 """ 704 self.positive_ttl_test_utility( 705 is_publish=True, 706 ptype=aconsts.PUBLISH_TYPE_SOLICITED, 707 stype=None, 708 term_ind_on=False) 709 710 @test_tracker_info(uuid="38a541c4-ff55-4387-87b7-4d940489da9d") 711 def test_ttl_passive_ind_on(self): 712 """Functional test case / Discovery test cases / TTL test case: 713 - Passive subscribe 714 - Termination indication enabled 715 """ 716 self.positive_ttl_test_utility( 717 is_publish=False, 718 ptype=None, 719 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 720 term_ind_on=True) 721 722 @test_tracker_info(uuid="ba971e12-b0ca-417c-a1b5-9451598de47d") 723 def test_ttl_passive_ind_off(self): 724 """Functional test case / Discovery test cases / TTL test case: 725 - Passive subscribe 726 - Termination indication disabled 727 """ 728 self.positive_ttl_test_utility( 729 is_publish=False, 730 ptype=None, 731 stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, 732 term_ind_on=False) 733 734 @test_tracker_info(uuid="7b5d96f2-2415-4b98-9a51-32957f0679a0") 735 def test_ttl_active_ind_on(self): 736 """Functional test case / Discovery test cases / TTL test case: 737 - Active subscribe 738 - Termination indication enabled 739 """ 740 self.positive_ttl_test_utility( 741 is_publish=False, 742 ptype=None, 743 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 744 term_ind_on=True) 745 746 @test_tracker_info(uuid="c9268eca-0a30-42dd-8e6c-b8b0b84697fb") 747 def test_ttl_active_ind_off(self): 748 """Functional test case / Discovery test cases / TTL test case: 749 - Active subscribe 750 - Termination indication disabled 751 """ 752 self.positive_ttl_test_utility( 753 is_publish=False, 754 ptype=None, 755 stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, 756 term_ind_on=False) 757 758 ####################################### 759 # Mismatched service name tests key: 760 # 761 # names is: test_mismatch_service_name_<pub_type>_<sub_type> 762 # where: 763 # 764 # pub_type: Type of publish discovery session: unsolicited or solicited. 765 # sub_type: Type of subscribe discovery session: passive or active. 766 ####################################### 767 768 @test_tracker_info(uuid="175415e9-7d07-40d0-95f0-3a5f91ea4711") 769 def test_mismatch_service_name_unsolicited_passive(self): 770 """Functional test case / Discovery test cases / Mismatch service name 771 - Unsolicited publish 772 - Passive subscribe 773 """ 774 self.discovery_mismatch_test_utility( 775 is_expected_to_pass=False, 776 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 777 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, 778 p_service_name="GoogleTestServiceXXX", 779 s_service_name="GoogleTestServiceYYY") 780 781 @test_tracker_info(uuid="c22a54ce-9e46-47a5-ac44-831faf93d317") 782 def test_mismatch_service_name_solicited_active(self): 783 """Functional test case / Discovery test cases / Mismatch service name 784 - Solicited publish 785 - Active subscribe 786 """ 787 self.discovery_mismatch_test_utility( 788 is_expected_to_pass=False, 789 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 790 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, 791 p_service_name="GoogleTestServiceXXX", 792 s_service_name="GoogleTestServiceYYY") 793 794 ####################################### 795 # Mismatched discovery session type tests key: 796 # 797 # names is: test_mismatch_service_type_<pub_type>_<sub_type> 798 # where: 799 # 800 # pub_type: Type of publish discovery session: unsolicited or solicited. 801 # sub_type: Type of subscribe discovery session: passive or active. 802 ####################################### 803 804 @test_tracker_info(uuid="4806f631-d9eb-45fd-9e75-24674962770f") 805 def test_mismatch_service_type_unsolicited_active(self): 806 """Functional test case / Discovery test cases / Mismatch service name 807 - Unsolicited publish 808 - Active subscribe 809 """ 810 self.discovery_mismatch_test_utility( 811 is_expected_to_pass=True, 812 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 813 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE) 814 815 @test_tracker_info(uuid="12d648fd-b8fa-4c0f-9467-95e2366047de") 816 def test_mismatch_service_type_solicited_passive(self): 817 """Functional test case / Discovery test cases / Mismatch service name 818 - Unsolicited publish 819 - Active subscribe 820 """ 821 self.discovery_mismatch_test_utility( 822 is_expected_to_pass=False, 823 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 824 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE) 825 826 ####################################### 827 # Mismatched discovery match filter tests key: 828 # 829 # names is: test_mismatch_match_filter_<pub_type>_<sub_type> 830 # where: 831 # 832 # pub_type: Type of publish discovery session: unsolicited or solicited. 833 # sub_type: Type of subscribe discovery session: passive or active. 834 ####################################### 835 836 @test_tracker_info(uuid="d98454cb-64af-4266-8fed-f0b545a2d7c4") 837 def test_mismatch_match_filter_unsolicited_passive(self): 838 """Functional test case / Discovery test cases / Mismatch match filter 839 - Unsolicited publish 840 - Passive subscribe 841 """ 842 self.discovery_mismatch_test_utility( 843 is_expected_to_pass=False, 844 p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, 845 s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, 846 p_mf_1="hello there string", 847 s_mf_1="goodbye there string") 848 849 @test_tracker_info(uuid="663c1008-ae11-4e1a-87c7-c311d83f481c") 850 def test_mismatch_match_filter_solicited_active(self): 851 """Functional test case / Discovery test cases / Mismatch match filter 852 - Solicited publish 853 - Active subscribe 854 """ 855 self.discovery_mismatch_test_utility( 856 is_expected_to_pass=False, 857 p_type=aconsts.PUBLISH_TYPE_SOLICITED, 858 s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, 859 p_mf_1="hello there string", 860 s_mf_1="goodbye there string") 861 862 ####################################### 863 # Multiple concurrent services 864 ####################################### 865 866 def run_multiple_concurrent_services(self, type_x, type_y): 867 """Validate multiple identical discovery services running on both devices: 868 - DUT1 & DUT2 running Publish for X 869 - DUT1 & DUT2 running Publish for Y 870 - DUT1 Subscribes for X 871 - DUT2 Subscribes for Y 872 Message exchanges. 873 874 Note: test requires that devices support 2 publish sessions concurrently. 875 The test will be skipped if the devices are not capable. 876 877 Args: 878 type_x, type_y: A list of [ptype, stype] of the publish and subscribe 879 types for services X and Y respectively. 880 """ 881 dut1 = self.android_devices[0] 882 dut2 = self.android_devices[1] 883 884 X_SERVICE_NAME = "ServiceXXX" 885 Y_SERVICE_NAME = "ServiceYYY" 886 887 asserts.skip_if( 888 dut1.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 889 or dut2.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2, 890 "Devices do not support 2 publish sessions") 891 892 # attach and wait for confirmation 893 id1 = dut1.droid.wifiAwareAttach(False) 894 autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) 895 time.sleep(self.device_startup_offset) 896 id2 = dut2.droid.wifiAwareAttach(False) 897 autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) 898 899 # DUT1 & DUT2: start publishing both X & Y services and wait for 900 # confirmations 901 dut1_x_pid = dut1.droid.wifiAwarePublish( 902 id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) 903 event = autils.wait_for_event(dut1, 904 aconsts.SESSION_CB_ON_PUBLISH_STARTED) 905 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 906 dut1_x_pid, 907 "Unexpected DUT1 X publish session discovery ID") 908 909 dut1_y_pid = dut1.droid.wifiAwarePublish( 910 id1, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) 911 event = autils.wait_for_event(dut1, 912 aconsts.SESSION_CB_ON_PUBLISH_STARTED) 913 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 914 dut1_y_pid, 915 "Unexpected DUT1 Y publish session discovery ID") 916 917 dut2_x_pid = dut2.droid.wifiAwarePublish( 918 id2, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) 919 event = autils.wait_for_event(dut2, 920 aconsts.SESSION_CB_ON_PUBLISH_STARTED) 921 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 922 dut2_x_pid, 923 "Unexpected DUT2 X publish session discovery ID") 924 925 dut2_y_pid = dut2.droid.wifiAwarePublish( 926 id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) 927 event = autils.wait_for_event(dut2, 928 aconsts.SESSION_CB_ON_PUBLISH_STARTED) 929 asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], 930 dut2_y_pid, 931 "Unexpected DUT2 Y publish session discovery ID") 932 933 # DUT1: start subscribing for X 934 dut1_x_sid = dut1.droid.wifiAwareSubscribe( 935 id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[1])) 936 autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 937 938 # DUT2: start subscribing for Y 939 dut2_y_sid = dut2.droid.wifiAwareSubscribe( 940 id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[1])) 941 autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 942 943 # DUT1 & DUT2: wait for service discovery 944 event = autils.wait_for_event(dut1, 945 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 946 asserts.assert_equal( 947 event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_x_sid, 948 "Unexpected DUT1 X subscribe session discovery ID") 949 dut1_peer_id_for_dut2_x = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 950 951 event = autils.wait_for_event(dut2, 952 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 953 asserts.assert_equal( 954 event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_y_sid, 955 "Unexpected DUT2 Y subscribe session discovery ID") 956 dut2_peer_id_for_dut1_y = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 957 958 # DUT1.X send message to DUT2 959 x_msg = "Hello X on DUT2!" 960 dut1.droid.wifiAwareSendMessage(dut1_x_sid, dut1_peer_id_for_dut2_x, 961 self.get_next_msg_id(), x_msg, 962 self.msg_retx_count) 963 autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_SENT) 964 event = autils.wait_for_event(dut2, 965 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 966 asserts.assert_equal( 967 event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_x_pid, 968 "Unexpected publish session ID on DUT2 for meesage " 969 "received on service X") 970 asserts.assert_equal( 971 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], x_msg, 972 "Message on service X from DUT1 to DUT2 not received correctly") 973 974 # DUT2.Y send message to DUT1 975 y_msg = "Hello Y on DUT1!" 976 dut2.droid.wifiAwareSendMessage(dut2_y_sid, dut2_peer_id_for_dut1_y, 977 self.get_next_msg_id(), y_msg, 978 self.msg_retx_count) 979 autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_SENT) 980 event = autils.wait_for_event(dut1, 981 aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) 982 asserts.assert_equal( 983 event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_y_pid, 984 "Unexpected publish session ID on DUT1 for meesage " 985 "received on service Y") 986 asserts.assert_equal( 987 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], y_msg, 988 "Message on service Y from DUT2 to DUT1 not received correctly") 989 990 @test_tracker_info(uuid="eef80cf3-1fd2-4526-969b-6af2dce785d7") 991 def test_multiple_concurrent_services_both_unsolicited_passive(self): 992 """Validate multiple concurrent discovery sessions running on both devices. 993 - DUT1 & DUT2 running Publish for X 994 - DUT1 & DUT2 running Publish for Y 995 - DUT1 Subscribes for X 996 - DUT2 Subscribes for Y 997 Message exchanges. 998 999 Both sessions are Unsolicited/Passive. 1000 1001 Note: test requires that devices support 2 publish sessions concurrently. 1002 The test will be skipped if the devices are not capable. 1003 """ 1004 self.run_multiple_concurrent_services( 1005 type_x=[ 1006 aconsts.PUBLISH_TYPE_UNSOLICITED, 1007 aconsts.SUBSCRIBE_TYPE_PASSIVE 1008 ], 1009 type_y=[ 1010 aconsts.PUBLISH_TYPE_UNSOLICITED, 1011 aconsts.SUBSCRIBE_TYPE_PASSIVE 1012 ]) 1013 1014 @test_tracker_info(uuid="46739f04-ab2b-4556-b1a4-9aa2774869b5") 1015 def test_multiple_concurrent_services_both_solicited_active(self): 1016 """Validate multiple concurrent discovery sessions running on both devices. 1017 - DUT1 & DUT2 running Publish for X 1018 - DUT1 & DUT2 running Publish for Y 1019 - DUT1 Subscribes for X 1020 - DUT2 Subscribes for Y 1021 Message exchanges. 1022 1023 Both sessions are Solicited/Active. 1024 1025 Note: test requires that devices support 2 publish sessions concurrently. 1026 The test will be skipped if the devices are not capable. 1027 """ 1028 self.run_multiple_concurrent_services( 1029 type_x=[ 1030 aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE 1031 ], 1032 type_y=[ 1033 aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE 1034 ]) 1035 1036 @test_tracker_info(uuid="5f8f7fd2-4a0e-4cca-8cbb-6d54353f2baa") 1037 def test_multiple_concurrent_services_mix_unsolicited_solicited(self): 1038 """Validate multiple concurrent discovery sessions running on both devices. 1039 - DUT1 & DUT2 running Publish for X 1040 - DUT1 & DUT2 running Publish for Y 1041 - DUT1 Subscribes for X 1042 - DUT2 Subscribes for Y 1043 Message exchanges. 1044 1045 Session A is Unsolicited/Passive. 1046 Session B is Solicited/Active. 1047 1048 Note: test requires that devices support 2 publish sessions concurrently. 1049 The test will be skipped if the devices are not capable. 1050 """ 1051 self.run_multiple_concurrent_services( 1052 type_x=[ 1053 aconsts.PUBLISH_TYPE_UNSOLICITED, 1054 aconsts.SUBSCRIBE_TYPE_PASSIVE 1055 ], 1056 type_y=[ 1057 aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE 1058 ]) 1059 1060 ######################################################### 1061 1062 @test_tracker_info(uuid="908ec896-fc7a-4ee4-b633-a2f042b74448") 1063 def test_upper_lower_service_name_equivalence(self): 1064 """Validate that Service Name is case-insensitive. Publish a service name 1065 with mixed case, subscribe to the same service name with alternative case 1066 and verify that discovery happens.""" 1067 p_dut = self.android_devices[0] 1068 s_dut = self.android_devices[1] 1069 1070 pub_service_name = "GoogleAbCdEf" 1071 sub_service_name = "GoogleaBcDeF" 1072 1073 autils.create_discovery_pair( 1074 p_dut, 1075 s_dut, 1076 p_config=autils.create_discovery_config( 1077 pub_service_name, aconsts.PUBLISH_TYPE_UNSOLICITED), 1078 s_config=autils.create_discovery_config( 1079 sub_service_name, aconsts.SUBSCRIBE_TYPE_PASSIVE), 1080 device_startup_offset=self.device_startup_offset) 1081 1082 ########################################################## 1083 1084 def exchange_messages(self, p_dut, p_disc_id, s_dut, s_disc_id, peer_id_on_sub, session_name): 1085 """ 1086 Exchange message between Publisher and Subscriber on target discovery session 1087 1088 Args: 1089 p_dut: Publisher device 1090 p_disc_id: Publish discovery session id 1091 s_dut: Subscriber device 1092 s_disc_id: Subscribe discovery session id 1093 peer_id_on_sub: Peer ID of the Publisher as seen on the Subscriber 1094 session_name: dictionary of discovery session name base on role("pub" or "sub") 1095 {role: {disc_id: name}} 1096 """ 1097 msg_template = "Hello {} from {} !" 1098 1099 # Message send from Subscriber to Publisher 1100 s_to_p_msg = msg_template.format(session_name["pub"][p_disc_id], 1101 session_name["sub"][s_disc_id]) 1102 s_dut.droid.wifiAwareSendMessage(s_disc_id, 1103 peer_id_on_sub, 1104 self.get_next_msg_id(), 1105 s_to_p_msg, 1106 self.msg_retx_count) 1107 autils.wait_for_event(s_dut, 1108 autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, s_disc_id)) 1109 event = autils.wait_for_event(p_dut, 1110 autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 1111 p_disc_id)) 1112 asserts.assert_equal( 1113 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], s_to_p_msg, 1114 "Message on service %s from Subscriber to Publisher " 1115 "not received correctly" % session_name["pub"][p_disc_id]) 1116 try: 1117 event = p_dut.ed.pop_event(autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 1118 p_disc_id), self.EVENT_TIMEOUT) 1119 p_dut.log.info("re-transmit message received: " 1120 + event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]) 1121 asserts.assert_equal( 1122 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], s_to_p_msg, 1123 "Message on service %s from Subscriber to Publisher " 1124 "not received correctly" % session_name["pub"][p_disc_id]) 1125 except queue.Empty: 1126 p_dut.log.info("no re-transmit message") 1127 1128 peer_id_on_pub = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] 1129 1130 # Message send from Publisher to Subscriber 1131 p_to_s_msg = msg_template.format(session_name["sub"][s_disc_id], 1132 session_name["pub"][p_disc_id]) 1133 p_dut.droid.wifiAwareSendMessage(p_disc_id, 1134 peer_id_on_pub, 1135 self.get_next_msg_id(), p_to_s_msg, 1136 self.msg_retx_count) 1137 autils.wait_for_event( 1138 p_dut, autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, p_disc_id)) 1139 event = autils.wait_for_event(s_dut, 1140 autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 1141 s_disc_id)) 1142 asserts.assert_equal( 1143 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], p_to_s_msg, 1144 "Message on service %s from Publisher to Subscriber" 1145 "not received correctly" % session_name["sub"][s_disc_id]) 1146 try: 1147 event = s_dut.ed.pop_event(autils.decorate_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 1148 s_disc_id), self.EVENT_TIMEOUT) 1149 s_dut.log.info("re-transmit message received: " 1150 + event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING]) 1151 asserts.assert_equal( 1152 event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], p_to_s_msg, 1153 "Message on service %s from Publisher to Subscriber" 1154 "not received correctly" % session_name["sub"][s_disc_id]) 1155 except queue.Empty: 1156 s_dut.log.info("no re-transmit message") 1157 1158 def run_multiple_concurrent_services_same_name_diff_ssi(self, type_x, type_y): 1159 """Validate same service name with multiple service specific info on publisher 1160 and subscriber can see all service 1161 1162 - p_dut running Publish X and Y 1163 - s_dut running subscribe A and B 1164 - subscribe A find X and Y 1165 - subscribe B find X and Y 1166 1167 Message exchanges: 1168 - A to X and X to A 1169 - B to X and X to B 1170 - A to Y and Y to A 1171 - B to Y and Y to B 1172 1173 Note: test requires that publisher device support 2 publish sessions concurrently, 1174 and subscriber device support 2 subscribe sessions concurrently. 1175 The test will be skipped if the devices are not capable. 1176 1177 Args: 1178 type_x, type_y: A list of [ptype, stype] of the publish and subscribe 1179 types for services X and Y respectively. 1180 """ 1181 p_dut = self.android_devices[0] 1182 s_dut = self.android_devices[1] 1183 1184 asserts.skip_if( 1185 p_dut.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 1186 or s_dut.aware_capabilities[aconsts.CAP_MAX_SUBSCRIBES] < 2, 1187 "Devices do not support 2 publish sessions or 2 subscribe sessions") 1188 1189 SERVICE_NAME = "ServiceName" 1190 X_SERVICE_SSI = "ServiceSpecificInfoXXX" 1191 Y_SERVICE_SSI = "ServiceSpecificInfoYYY" 1192 use_id = True 1193 1194 # attach and wait for confirmation 1195 p_id = p_dut.droid.wifiAwareAttach(False, None, use_id) 1196 autils.wait_for_event(p_dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, p_id)) 1197 time.sleep(self.device_startup_offset) 1198 s_id = s_dut.droid.wifiAwareAttach(False, None, use_id) 1199 autils.wait_for_event(s_dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, s_id)) 1200 1201 # Publisher: start publishing both X & Y services and wait for confirmations 1202 p_disc_id_x = p_dut.droid.wifiAwarePublish( 1203 p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], X_SERVICE_SSI), use_id) 1204 event = autils.wait_for_event(p_dut, 1205 autils.decorate_event( 1206 aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id_x)) 1207 1208 p_disc_id_y = p_dut.droid.wifiAwarePublish( 1209 p_id, autils.create_discovery_config(SERVICE_NAME, type_x[0], Y_SERVICE_SSI), use_id) 1210 event = autils.wait_for_event(p_dut, 1211 autils.decorate_event( 1212 aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id_y)) 1213 1214 # Subscriber: start subscribe session A 1215 s_disc_id_a = s_dut.droid.wifiAwareSubscribe( 1216 s_id, autils.create_discovery_config(SERVICE_NAME, type_x[1]), use_id) 1217 autils.wait_for_event(s_dut, autils.decorate_event( 1218 aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, s_disc_id_a)) 1219 1220 # Subscriber: start subscribe session B 1221 s_disc_id_b = s_dut.droid.wifiAwareSubscribe( 1222 p_id, autils.create_discovery_config(SERVICE_NAME, type_y[1]), use_id) 1223 autils.wait_for_event(s_dut, autils.decorate_event( 1224 aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, s_disc_id_b)) 1225 1226 session_name = {"pub": {p_disc_id_x: "X", p_disc_id_y: "Y"}, 1227 "sub": {s_disc_id_a: "A", s_disc_id_b: "B"}} 1228 1229 # Subscriber: subscribe session A & B wait for service discovery 1230 # Number of results on each session should be exactly 2 1231 results_a = {} 1232 for i in range(2): 1233 event = autils.wait_for_event(s_dut, autils.decorate_event( 1234 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_a)) 1235 results_a[ 1236 bytes(event["data"][ 1237 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode('utf-8')] = event 1238 autils.fail_on_event(s_dut, autils.decorate_event( 1239 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_a)) 1240 1241 results_b = {} 1242 for i in range(2): 1243 event = autils.wait_for_event(s_dut, autils.decorate_event( 1244 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_b)) 1245 results_b[ 1246 bytes(event["data"][ 1247 aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode('utf-8')] = event 1248 autils.fail_on_event(s_dut, autils.decorate_event( 1249 aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id_b)) 1250 1251 s_a_peer_id_for_p_x = results_a[X_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] 1252 s_a_peer_id_for_p_y = results_a[Y_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] 1253 s_b_peer_id_for_p_x = results_b[X_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] 1254 s_b_peer_id_for_p_y = results_b[Y_SERVICE_SSI]["data"][aconsts.SESSION_CB_KEY_PEER_ID] 1255 1256 # Message exchange between Publisher and Subscribe 1257 self.exchange_messages(p_dut, p_disc_id_x, 1258 s_dut, s_disc_id_a, s_a_peer_id_for_p_x, session_name) 1259 1260 self.exchange_messages(p_dut, p_disc_id_x, 1261 s_dut, s_disc_id_b, s_b_peer_id_for_p_x, session_name) 1262 1263 self.exchange_messages(p_dut, p_disc_id_y, 1264 s_dut, s_disc_id_a, s_a_peer_id_for_p_y, session_name) 1265 1266 self.exchange_messages(p_dut, p_disc_id_y, 1267 s_dut, s_disc_id_b, s_b_peer_id_for_p_y, session_name) 1268 1269 # Check no more messages 1270 time.sleep(autils.EVENT_TIMEOUT) 1271 autils.verify_no_more_events(p_dut, timeout=0) 1272 autils.verify_no_more_events(s_dut, timeout=0) 1273 1274 ########################################################## 1275 1276 @test_tracker_info(uuid="78d89d63-1cbc-47f6-a8fc-74057fea655e") 1277 def test_multiple_concurrent_services_diff_ssi_unsolicited_passive(self): 1278 """Multi service test on same service name but different Service Specific Info 1279 - Unsolicited publish 1280 - Passive subscribe 1281 """ 1282 self.run_multiple_concurrent_services_same_name_diff_ssi( 1283 type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], 1284 type_y=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE]) 1285 1286 @test_tracker_info(uuid="5d349491-48e4-4ca1-a8af-7afb44e7bcbc") 1287 def test_multiple_concurrent_services_diff_ssi_solicited_active(self): 1288 """Multi service test on same service name but different Service Specific Info 1289 - Solicited publish 1290 - Active subscribe 1291 """ 1292 self.run_multiple_concurrent_services_same_name_diff_ssi( 1293 type_x=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE], 1294 type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) 1295 1296 def run_service_discovery_on_service_lost(self, p_type, s_type): 1297 """ 1298 Validate service lost callback will be receive on subscriber, when publisher stopped publish 1299 - p_dut running Publish 1300 - s_dut running subscribe 1301 - s_dut discover p_dut 1302 - p_dut stop publish 1303 - s_dut receive service lost callback 1304 1305 Args: 1306 p_type: Publish discovery type 1307 s_type: Subscribe discovery type 1308 """ 1309 p_dut = self.android_devices[0] 1310 p_dut.pretty_name = "Publisher" 1311 s_dut = self.android_devices[1] 1312 s_dut.pretty_name = "Subscriber" 1313 1314 asserts.skip_if(not s_dut.droid.isSdkAtLeastS(), 1315 "R build and below do not have onServiceLost API.") 1316 1317 # Publisher+Subscriber: attach and wait for confirmation 1318 p_id = p_dut.droid.wifiAwareAttach(False) 1319 autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) 1320 time.sleep(self.device_startup_offset) 1321 s_id = s_dut.droid.wifiAwareAttach(False) 1322 autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) 1323 1324 # Publisher: start publish and wait for confirmation 1325 p_config = self.create_publish_config( 1326 p_dut.aware_capabilities, 1327 p_type, 1328 self.PAYLOAD_SIZE_TYPICAL, 1329 ttl=0, 1330 term_ind_on=False, 1331 null_match=False) 1332 p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) 1333 autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) 1334 1335 # Subscriber: start subscribe and wait for confirmation 1336 s_config = self.create_subscribe_config( 1337 s_dut.aware_capabilities, 1338 s_type, 1339 self.PAYLOAD_SIZE_TYPICAL, 1340 ttl=0, 1341 term_ind_on=False, 1342 null_match=True) 1343 s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) 1344 autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) 1345 1346 # Subscriber: wait for service discovery 1347 discovery_event = autils.wait_for_event( 1348 s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) 1349 peer_id_on_sub = discovery_event["data"][ 1350 aconsts.SESSION_CB_KEY_PEER_ID] 1351 1352 # Publisher+Subscriber: Terminate sessions 1353 p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) 1354 time.sleep(10) 1355 service_lost_event = autils.wait_for_event( 1356 s_dut, aconsts.SESSION_CB_ON_SERVICE_LOST) 1357 asserts.assert_equal(peer_id_on_sub, 1358 service_lost_event["data"][aconsts.SESSION_CB_KEY_PEER_ID]) 1359 asserts.assert_equal(aconsts.REASON_PEER_NOT_VISIBLE, 1360 service_lost_event["data"][aconsts.SESSION_CB_KEY_LOST_REASON]) 1361 1362 s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) 1363 1364 @test_tracker_info(uuid="b1894ce3-8692-478b-a96f-db2797e22caa") 1365 def test_service_discovery_on_service_lost_unsolicited_passive(self): 1366 """ 1367 Test service discovery lost with unsolicited publish and passive subscribe 1368 """ 1369 self.run_service_discovery_on_service_lost(aconsts.PUBLISH_TYPE_UNSOLICITED, 1370 aconsts.SUBSCRIBE_TYPE_PASSIVE) 1371 1372 @test_tracker_info(uuid="4470d897-223a-4f9f-b21f-4061943137dd") 1373 def test_service_discovery_on_service_lost_solicited_active(self): 1374 """ 1375 Test service discovery lost with solicited publish and active subscribe 1376 """ 1377 self.run_service_discovery_on_service_lost(aconsts.PUBLISH_TYPE_SOLICITED, 1378 aconsts.SUBSCRIBE_TYPE_ACTIVE) 1379