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