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