1# -*- coding: utf-8 -*- 2# Copyright 2019 Oticon A/S 3# SPDX-License-Identifier: Apache-2.0 4 5from numpy import random; 6import os; 7from enum import IntEnum; 8from components.utils import *; 9from components.basic_commands import *; 10from components.address import *; 11from components.events import *; 12from components.resolvable import *; 13from components.advertiser import *; 14from components.scanner import *; 15from components.initiator import *; 16from components.preambles import *; 17from components.test_spec import TestSpec; 18 19global lowerIRK, upperIRK, lowerRandomAddress, upperRandomAddress; 20 21class Role(IntEnum): 22 MASTER = 0 23 SLAVE = 1 24 25def __check_command_complete_event(transport, idx, trace): 26 event = get_event(transport, idx, 100); 27 trace.trace(7, str(event)); 28 return event.isCommandComplete(); 29 30def __check_unknown_command_rsp_event(transport, idx, trace, status): 31 event = get_event(transport, idx, 100); 32 trace.trace(7, str(event)); 33 return status == 1 and (event.isCommandComplete() or event.isCommandStatus()) 34 35""" 36 HCI/GEV/BV-01-C [Status return for Unsupported Commands] 37""" 38def hci_gev_bv_01_c(transport, idx, trace): 39 40 NumRsp, length, lap = 0, 1, toArray(0x9E8B00, 3); 41 42 status = inquire(transport, idx, lap, length, NumRsp, 100); 43 success = __check_unknown_command_rsp_event(transport, idx, trace, status); 44 45 status = read_buffer_size(transport, idx, 100); 46 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 47 48 le, simul = 0, 0; 49 50 status = write_le_host_support(transport, idx, le, simul, 100); 51 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 52 53 handle, props, PrimChannelMap, OwnAddrType, PeerAddrType = 0, 0, 0, 0, 0; 54 PrimMinInterval = [0 for _ in range(3)]; 55 PrimMaxInterval = [0 for _ in range(3)]; 56 AVal = [0 for _ in range(6)]; 57 FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, SecAdvPhy, sid, ScanReqNotifyEnable = 0, 0, 0, 0, 0, 0, 0; 58 59 status = le_set_extended_advertising_parameters(transport, idx, handle, props, PrimMinInterval, PrimMaxInterval, PrimChannelMap, \ 60 OwnAddrType, PeerAddrType, AVal, FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, \ 61 SecAdvPhy, sid, ScanReqNotifyEnable, 100); 62 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 63 64 handle, op, FragPref, dataLength = 0, 0, 0, 0; 65 data = [0 for _ in range(251)]; 66 67 status = le_set_extended_advertising_data(transport, idx, handle, op, FragPref, dataLength, data, 100); 68 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 69 70 handle, op, FragPref, dataLength = 0, 0, 0, 0; 71 data = [0 for _ in range(251)]; 72 73 status = le_set_extended_scan_response_data(transport, idx, handle, op, FragPref, dataLength, data, 100); 74 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 75 76 enable, SetNum = 0, 0; 77 SHandle = [0 for i in range(SetNum)]; 78 SDuration = [0 for i in range(SetNum)]; 79 SMaxExtAdvEvts = [0 for i in range(SetNum)]; 80 81 status = le_set_extended_advertising_enable(transport, idx, enable, SetNum, SHandle, SDuration, SMaxExtAdvEvts, 100); 82 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 83 84 status = le_read_maximum_advertising_data_length(transport, idx, 100); 85 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 86 87 status = le_read_number_of_supported_advertising_sets(transport, idx, 100); 88 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 89 90 handle = 0; 91 92 status = le_remove_advertising_set(transport, idx, handle, 100); 93 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 94 95 status = le_clear_advertising_sets(transport, idx, 100); 96 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 97 98 handle, MinInterval, MaxInterval, props = 0, 0, 0, 0; 99 100 status = le_set_periodic_advertising_parameters(transport, idx, handle, MinInterval, MaxInterval, props, 100); 101 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 102 103 handle, op, dataLength = 0, 0, 251; 104 data = [0 for i in range(dataLength)]; 105 106 status = le_set_periodic_advertising_data(transport, idx, handle, op, dataLength, data, 100); 107 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 108 109 handle, enable = 0, 0; 110 111 status = le_set_periodic_advertising_enable(transport, idx, enable, handle, 100); 112 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 113 114 OwnAddrType, FilterPolicy, phys = 0, 0, 0; 115 PType = [0 for i in range(phys)]; 116 PInterval = [0 for i in range(phys)]; 117 PWindow = [0 for i in range(phys)]; 118 119 status = le_set_extended_scan_parameters(transport, idx, OwnAddrType, FilterPolicy, phys, PType, PInterval, PWindow, 100); 120 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 121 122 enable, FilterDup, duration, period = 0, 0, 0, 0; 123 124 status = le_set_extended_scan_enable(transport, idx, enable, FilterDup, duration, period, 100); 125 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 126 127 FilterPolicy, OwnAddrType, PeerAddrType, phys = 0, 0, 0, 0; 128 AVal = [0 for i in range(6)]; 129 PInterval = [0 for i in range(phys)]; 130 PWindow = [0 for i in range(phys)]; 131 PConnIntervalMin = [0 for i in range(phys)]; 132 PConnIntervalMax = [0 for i in range(phys)]; 133 PConnLatency = [0 for i in range(phys)]; 134 PSupervisionTimeout = [0 for i in range(phys)]; 135 PMinCeLen = [0 for i in range(phys)]; 136 PMaxCeLen = [0 for i in range(phys)]; 137 138 status = le_extended_create_connection(transport, idx, FilterPolicy, OwnAddrType, PeerAddrType, AVal, phys, PInterval, PWindow, \ 139 PConnIntervalMin, PConnIntervalMax, PConnLatency, PSupervisionTimeout, PMinCeLen, PMaxCeLen, 100); 140 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 141 142 FilterPolicy, sid, AddrType, skip, SyncTimeout, unused = 0, 0, 0, 0, 0, 0; 143 AVal = [0 for i in range(6)]; 144 145 status = le_periodic_advertising_create_sync(transport, idx, FilterPolicy, sid, AddrType, AVal, skip, SyncTimeout, unused, 100); 146 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 147 148 status = le_periodic_advertising_create_sync_cancel(transport, idx, 100); 149 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 150 151 handle = 0; 152 153 status = le_periodic_advertising_terminate_sync(transport, idx, handle, 100); 154 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 155 156 AddrType, sid = 0, 0; 157 AVal = [0 for i in range(6)]; 158 159 status = le_add_device_to_periodic_advertiser_list(transport, idx, AddrType, AVal, sid, 100); 160 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 161 162 AddrType, sid = 0, 0; 163 AVal = [0 for i in range(6)]; 164 165 status = le_remove_device_from_periodic_advertiser_list(transport, idx, AddrType, AVal, sid, 100); 166 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 167 168 status = le_clear_periodic_advertiser_list(transport, idx, 100); 169 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 170 171 status = le_read_periodic_advertiser_list_size(transport, idx, 100); 172 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 173 174 status = le_read_rf_path_compensation(transport, idx, 100); 175 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 176 177 TxPathComp, RxPathComp = 0, 0; 178 179 status = le_write_rf_path_compensation(transport, idx, TxPathComp, RxPathComp, 100); 180 success = __check_unknown_command_rsp_event(transport, idx, trace, status) and success; 181 182 return success; 183 184""" 185 HCI/CFC/BV-02-C [Reported Buffer Size] 186""" 187def hci_cfc_bv_02_c(transport, idx, trace): 188 189 status, LeMaxLen, LeMaxNum = le_read_buffer_size(transport, idx, 100); 190 trace.trace(6, "LE Read Buffer Size Command returns status: 0x%02X" % status); 191 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 192 193 if LeMaxLen == 0 and LeMaxNum == 0: 194 status, AclMaxLen, ScoMaxLen, AclMaxNum, ScoMaxNum = read_buffer_size(transport, idx, 100); 195 trace.trace(6, "Read Buffer Size Command returns status: 0x%02X" % status); 196 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 197 198 return success; 199 200""" 201 HCI/CIN/BV-01-C [Features returned by Read Local Supported Features Command] 202""" 203def hci_cin_bv_01_c(transport, idx, trace): 204 205 status, features = read_local_supported_features(transport, idx, 100); 206 trace.trace(6, "Read Local Supported Features Command returns status: 0x%02X" % status); 207 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 208 if success: 209 showFeatures(features, trace); 210 211 return success; 212 213""" 214 HCI/CIN/BV-03-C [Supported Commands returned by Read Local Supported Commands Command] 215""" 216def hci_cin_bv_03_c(transport, idx, trace): 217 218 status, commands = read_local_supported_commands(transport, idx, 100); 219 trace.trace(6, "Read Local Supported Commands Command returns status: 0x%02X" % status); 220 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 221 if success: 222 showCommands(commands, trace); 223 224 return success; 225 226""" 227 HCI/CIN/BV-04-C [Versions returned by Read Local Version Information Command] 228""" 229def hci_cin_bv_04_c(transport, idx, trace): 230 231 status, HCIVersion, HCIRevision, LMPVersion, manufacturer, LMPSubversion = read_local_version_information(transport, idx, 100); 232 trace.trace(6, "Read Local Version Information Command returns status: 0x%02X" % status); 233 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 234 if success: 235 trace.trace(6, "HCI Version: %i" % HCIVersion); 236 trace.trace(6, "HCI Revision: 0x%04X" % HCIRevision); 237 trace.trace(6, "LMP Version: %i" % LMPVersion); 238 trace.trace(6, "LMP Subversion: 0x%04X" % LMPSubversion); 239 trace.trace(6, "Manufacturer: 0x%04X" % manufacturer); 240 241 return success; 242 243""" 244 HCI/CIN/BV-06-C [Reported White List Size] 245""" 246def hci_cin_bv_06_c(transport, idx, trace): 247 248 status = le_clear_white_list(transport, idx, 100); 249 trace.trace(6, "LE Clear White List Command returns status: 0x%02X" % status); 250 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 251 252 status, WlSize = le_read_white_list_size(transport, idx, 100); 253 trace.trace(6, "LE Read White List Size Command returns status: 0x%02X list size: %i" % (status, WlSize)); 254 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 255 256 for n in range(WlSize+1): 257 AddrType = 0; 258 AVal = [random.randint(0,255) for _ in range(6)]; 259 if n < WlSize: 260 lastAVal = AVal 261 status = le_add_device_to_white_list(transport, idx, AddrType, AVal, 100); 262 trace.trace(6, "LE Add Device to White List Command returns status: 0x%02X" % status); 263 success = success and __check_command_complete_event(transport, idx, trace) and ((status == 0) if n < WlSize else (status == 7)); 264 265 status = le_remove_device_from_white_list(transport, idx, AddrType, lastAVal, 100); 266 trace.trace(6, "LE Remove Device from White List Command returns status: 0x%02X" % status); 267 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 268 269 status = le_add_device_to_white_list(transport, idx, AddrType, lastAVal, 100); 270 trace.trace(6, "LE Add Device to White List Command returns status: 0x%02X" % status); 271 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 272 273 return success; 274 275""" 276 HCI/CIN/BV-09-C [Feature Bits returned by Read LE Public Key Validation Feature Bit] 277""" 278def hci_cin_bv_09_c(transport, idx, trace): 279 280 status, features = le_read_local_supported_features(transport, idx, 100); 281 trace.trace(6, "LE Read Local Supported Features Command returns status: 0x%02X" % status); 282 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 283 if success: 284 showLEFeatures(features, trace); 285 286 return success; 287 288""" 289 HCI/CCO/BV-07-C [BR/EDR Commands Not Supported on LE Device] 290""" 291def hci_cco_bv_07_c(transport, idx, trace): 292 293 status = inquire(transport, idx, toArray(0x9E8B00, 3), 1, 1, 100); 294 trace.trace(6, "Inquire Command returns status: 0x%02X" % status); 295 success = status == 1; # Unknown HCI Command (0x01) 296 event = get_event(transport, idx, 100); 297 success = success and (event.isCommandStatus() or event.isCommandComplete()); 298 trace.trace(7, str(event)); 299 300 return success; 301 302""" 303 HCI/CCO/BV-09-C [Handling LE Set Data Length Command] 304 305 Note: Requires that CONFIG_BT_CTLR_DATA_LENGTH_MAX=60 is set in the prj.conf file for the ptt_app. 306""" 307def hci_cco_bv_09_c(transport, upperTester, lowerTester, trace): 308 309 ownAddress = Address( ExtendedAddressType.PUBLIC ); 310 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 311 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 312 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 313 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 314 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 315 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x456789ABCDEF )); 316 success = advertiser.enable(); 317 318 connected = initiator.connect(); 319 success = success and connected; 320 321 if connected: 322 TxOctets, TxTime = 60, 592; 323 status, handle = le_set_data_length(transport, upperTester, initiator.handles[0], TxOctets, TxTime, 100); 324 trace.trace(6, "LE Set Data Length Command returns status: 0x%02X handle: 0x%04X" % (status, handle)); 325 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 326 """ 327 If parameters have changed - both upper- and lower-Tester will receive a LE Data Length Change event 328 """ 329 if has_event(transport, upperTester, 200)[0]: 330 event = get_event(transport, upperTester, 100); 331 success = success and (event.subEvent == MetaEvents.BT_HCI_EVT_LE_DATA_LEN_CHANGE); 332 trace.trace(7, str(event)); 333 334 if has_event(transport, lowerTester, 200)[0]: 335 event = get_event(transport, lowerTester, 100); 336 success = success and (event.subEvent == MetaEvents.BT_HCI_EVT_LE_DATA_LEN_CHANGE); 337 trace.trace(7, str(event)); 338 """ 339 Note: Disconnect can generate another LE Data Length Change event... 340 """ 341 success = success and initiator.disconnect(0x13); 342 343 else: 344 advertiser.disable(); 345 346 return success; 347 348""" 349 HCI/CCO/BV-10-C [Handling LE Read Suggested Default Data Length Command] 350""" 351def hci_cco_bv_10_c(transport, idx, trace): 352 353 status, maxTxOctets, maxTxTime = le_read_suggested_default_data_length(transport, idx, 100); 354 trace.trace(6, "LE Read Suggested Default Data Length Command returns status: 0x%02X" % status); 355 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 356 357 trace.trace(6, "Maximum number of transmitted payload octets: 0x%04X (%d)" % (maxTxOctets, maxTxOctets)); 358 trace.trace(6, "Maximum packet transmission time: 0x%04X (%d) microseconds" % (maxTxTime, maxTxTime)); 359 360 return success; 361 362""" 363 HCI/CCO/BV-11-C [Handling LE Write Suggested Default Data Length Command] 364""" 365def hci_cco_bv_11_c(transport, idx, trace): 366 367 maxTxOctetsIn, maxTxTimeIn = (0x001B + 0x00FB)//2, (0x0148 + 0x4290)//2; 368 status = le_write_suggested_default_data_length(transport, idx, maxTxOctetsIn, maxTxTimeIn, 100); 369 trace.trace(6, "LE Write Suggested Default Data Length Command returns status: 0x%02X" % status); 370 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 371 372 trace.trace(6, "Maximum number of transmitted payload octets: 0x%04X (%d)" % (maxTxOctetsIn, maxTxOctetsIn)); 373 trace.trace(6, "Maximum packet transmission time: 0x%04X (%d) microseconds" % (maxTxTimeIn, maxTxTimeIn)); 374 375 status, maxTxOctetsOut, maxTxTimeOut = le_read_suggested_default_data_length(transport, idx, 100); 376 trace.trace(6, "LE Read Suggested Default Data Length Command returns status: 0x%02X" % status); 377 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 378 379 trace.trace(6, "Maximum number of transmitted payload octets: 0x%04X (%d)" % (maxTxOctetsOut, maxTxOctetsOut)); 380 trace.trace(6, "Maximum packet transmission time: 0x%04X (%d) microseconds" % (maxTxTimeOut, maxTxTimeOut)); 381 382 success = success and (maxTxOctetsOut == maxTxOctetsIn) and (maxTxTimeOut == maxTxTimeIn); 383 384 return success; 385 386""" 387 HCI/CCO/BV-12-C [Handling LE Remove Device From Resolving List Command] 388""" 389def hci_cco_bv_12_c(transport, idx, trace): 390 391 peerAddress = Address(SimpleAddressType.PUBLIC, 0x123456789ABC); 392 status = le_add_device_to_resolving_list(transport, idx, peerAddress.type, peerAddress.address, lowerIRK, upperIRK, 100); 393 trace.trace(6, "LE Add Device to Resolving List Command returns status: 0x%02X" % status); 394 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 395 396 status = le_remove_device_from_resolving_list(transport, idx, peerAddress.type, peerAddress.address, 100); 397 trace.trace(6, "LE Remove Device from Resolving List Command returns status: 0x%02X" % status); 398 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 399 400 return success; 401 402""" 403 HCI/CCO/BV-13-C [Handling LE Clear Resolving List Command] 404""" 405def hci_cco_bv_13_c(transport, idx, trace): 406 407 peerAddress = Address(SimpleAddressType.PUBLIC, 0x456789ABCDEF); 408 status = le_add_device_to_resolving_list(transport, idx, peerAddress.type, peerAddress.address, lowerIRK, upperIRK, 100); 409 trace.trace(6, "LE Add Device to Resolving List Command returns status: 0x%02X" % status); 410 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 411 412 status = le_clear_resolving_list(transport, idx, 100); 413 trace.trace(6, "LE Clear Resolving List Command returns status: 0x%02X" % status); 414 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 415 416 return success; 417 418""" 419 HCI/CCO/BV-14-C [Handling LE Read Resolving List Size Command] 420""" 421def hci_cco_bv_14_c(transport, idx, trace): 422 423 status, listSize = le_read_resolving_list_size(transport, idx, 100); 424 trace.trace(6, "LE Read Resolving List Size Command returns status: 0x%02X" % status); 425 success = __check_command_complete_event(transport, idx, trace) and (status == 0) and (listSize > 0); 426 trace.trace(6, "Resolving List Size returned: %d" % listSize); 427 428 return success; 429 430""" 431 HCI/CCO/BV-15-C [Handling LE Set Default PHY Command] 432""" 433def hci_cco_bv_15_c(transport, idx, trace): 434 435 status = le_set_default_phy(transport, idx, 3, 0, 0, 100); 436 trace.trace(6, "LE Set Default PHY Command returns status: 0x%02X" % status); 437 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 438 439 return success; 440 441""" 442 HCI/CCO/BV-16-C [Handling LE Read Periodic Advertiser List Size Command] 443""" 444def hci_cco_bv_16_c(transport, idx, trace): 445 446 status, listSize = le_read_periodic_advertiser_list_size(transport, idx, 100); 447 trace.trace(6, "LE Read Periodic Advertiser List Size Command returns status: 0x%02X" % status); 448 success = __check_command_complete_event(transport, idx, trace) and (status == 0) and (listSize > 0); 449 trace.trace(6, "Periodic Advertiser List Size returned: %d" % listSize); 450 451 return success; 452 453""" 454 HCI/CCO/BV-17-C [Handling Add, Remove and Clear Periodic Advertiser List Commands] 455""" 456def hci_cco_bv_17_c(transport, idx, trace): 457 458 status = le_clear_periodic_advertiser_list(transport, idx, 100); 459 trace.trace(6, "LE Clear Periodic Advertiser List Command returns status: 0x%02X" % status); 460 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 461 462 peerAddress = Address(SimpleAddressType.PUBLIC, 0x123456789ABC); 463 status = le_add_device_to_periodic_advertiser_list(transport, idx, peerAddress.type, peerAddress.address, 1, 100); 464 trace.trace(6, "LE Add Device to Periodic Advertiser List Command returns status: 0x%02X" % status); 465 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 466 467 status = le_remove_device_from_periodic_advertiser_list(transport, idx, peerAddress.type, peerAddress.address, 1, 100); 468 trace.trace(6, "LE Remove Device from Periodic Advertiser List Command returns status: 0x%02X" % status); 469 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 470 471 status = le_remove_device_from_periodic_advertiser_list(transport, idx, peerAddress.type, peerAddress.address, 1, 100); 472 trace.trace(6, "LE Remove Device from Periodic Advertiser List Command returns status: 0x%02X" % status); 473 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0x42); 474 475 status = le_add_device_to_periodic_advertiser_list(transport, idx, peerAddress.type, peerAddress.address, 1, 100); 476 trace.trace(6, "LE Add Device to Periodic Advertiser List Command returns status: 0x%02X" % status); 477 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 478 479 status = le_clear_periodic_advertiser_list(transport, idx, 100); 480 trace.trace(6, "LE Clear Periodic Advertiser List Command returns status: 0x%02X" % status); 481 success = success and __check_command_complete_event(transport, idx, trace) and (status == 0); 482 483 return success; 484 485""" 486 HCI/CCO/BV-18-C [Handling LE Read Transmit Power Command] 487""" 488def hci_cco_bv_18_c(transport, idx, trace): 489 490 status, minTxPower, maxTxPower = le_read_transmit_power(transport, idx, 100); 491 trace.trace(6, "LE Read Transmit Power Command returns status: 0x%02X" % status); 492 success = __check_command_complete_event(transport, idx, trace) and (status == 0); 493 success = success and (-127 <= minTxPower) and (minTxPower <= 126) and (-127 <= maxTxPower) and (maxTxPower <= 126) and (minTxPower <= maxTxPower); 494 trace.trace(6, "LE Read Transmit Power Command returned range: [%d, %d] dBm." % (minTxPower, maxTxPower)); 495 496 return success; 497 498""" 499 HCI/DDI/BV-03-C [Disable Advertising with Set Advertising Enable Command] 500""" 501def hci_ddi_bv_03_c(transport, upperTester, lowerTester, trace): 502 503 ownAddress = Address( SimpleAddressType.PUBLIC ); 504 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 505 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 506 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 507 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 508 ownAddress = Address( SimpleAddressType.PUBLIC ); 509 scanner = Scanner(transport, lowerTester, trace, ScanType.PASSIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 5); 510 511 success = advertiser.enable(); 512 513 success = success and scanner.enable(); 514 scanner.monitor(); 515 success = success and scanner.disable(); 516 success = success and scanner.qualifyReports( 5 ); 517 518 success = success and advertiser.disable(); 519 success = success and scanner.enable(); 520 scanner.monitor(); 521 success = success and scanner.disable(); 522 success = success and not scanner.qualifyReports( 1 ); 523 524 return success; 525 526""" 527 HCI/DDI/BV-04-C [Disable Scanning with Set Scan Enable Command] 528""" 529def hci_ddi_bv_04_c(transport, upperTester, lowerTester, trace): 530 531 ownAddress = Address( SimpleAddressType.PUBLIC ); 532 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 533 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 534 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 535 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 536 ownAddress = Address( SimpleAddressType.PUBLIC ); 537 scanner = Scanner(transport, upperTester, trace, ScanType.PASSIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 5); 538 539 success = advertiser.enable(); 540 541 success = success and scanner.enable(); 542 scanner.monitor(); 543 success = success and scanner.disable(); 544 success = success and scanner.qualifyReports( 5 ); 545 546 scanner.monitor(); 547 success = success and not scanner.qualifyReports( 1 ); 548 549 success = success and advertiser.disable(); 550 551 return success; 552 553""" 554 HCI/DDI/BI-02-C [Rejecting invalid Advertising Parameters] 555""" 556def hci_ddi_bi_02_c(transport, upperTester, trace): 557 558 ownAddress = Address( SimpleAddressType.PUBLIC ); 559 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 560 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \ 561 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 562 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 563 564 advertiser.minInterval, advertiser.maxInterval = 32-2, 32-1; 565 566 successA = not advertiser.enable(); 567 success = successA and (advertiser.status == 0x12); 568 569 if not successA: 570 advertiser.disable(); 571 572 return success; 573 574""" 575 HCI/HFC/BV-04-C [Events enabled by LE Set Event Mask Command] 576""" 577def hci_hfc_bv_04_c(transport, upperTester, lowerTester, trace): 578 579 """ Bit: 5 4 4 3 2 1 0 0 580 6 8 0 2 4 6 8 0 581 0x20 00 00 00 00 00 80 10 ~ Bits 4, 15, 61 (Disconnection Complete Event, Hardware Error Event, LE Meta Event) 582 """ 583 events = [0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20]; 584 585 status = set_event_mask(transport, upperTester, events, 100); 586 trace.trace(6, "Set Event Mask Command returns status: 0x%02X" % status); 587 success = __check_command_complete_event(transport, upperTester, trace) and (status == 0); 588 589 """ Bit: 5 4 4 3 2 1 0 0 590 6 8 0 2 4 6 8 0 591 0x00 00 00 00 00 07 FF FD ~ All except 'LE Channel Selection Algorithm Event and LE Advertising Report Event' 592 """ 593 events = [0xFD, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00]; 594 595 status = le_set_event_mask(transport, upperTester, events, 100); 596 trace.trace(6, "LE Set Event Mask Command returns status: 0x%02X" % status); 597 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 598 599 """ 600 status = le_set_event_mask(transport, lowerTester, events, 100); 601 trace.trace(6, "LE Set Event Mask Command returns status: 0x%02X" % status); 602 success = success and __check_command_complete_event(transport, lowerTester, trace) and (status == 0); 603 """ 604 605 ownAddress = Address( SimpleAddressType.PUBLIC ); 606 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 607 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 608 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 609 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 610 ownAddress = Address( SimpleAddressType.PUBLIC ); 611 scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 5, 5); 612 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 613 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x456789ABCDEF )); 614 615 success = advertiser.enable(); 616 617 success = success and scanner.enable(); 618 scanner.monitor(); 619 success = success and scanner.disable(); 620 success = success and not scanner.qualifyResponses( 5 ); 621 success = success and not scanner.qualifyReports( 5 ); 622 623 transport.wait(100); 624 625 connected = initiator.connect(); 626 success = success and connected; 627 628 transport.wait(500); 629 630 if connected: 631 success = success and initiator.disconnect(0x13); 632 633 return success; 634 635""" 636 HCI/CM/BV-01-C [Handling LE Read Peer Resolvable Address Command] 637""" 638def hci_cm_bv_01_c(transport, upperTester, lowerTester, trace): 639 640 """ 641 Add Public address of lowerTester and upperTester to the Resolving List 642 """ 643 RPAs = [ ResolvableAddresses( transport, upperTester, trace, upperIRK ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ]; 644 ownAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 645 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 646 success = RPAs[upperTester].clear() and RPAs[lowerTester].clear(); 647 success = success and RPAs[upperTester].add( peerAddress, lowerIRK ); 648 success = success and RPAs[lowerTester].add( ownAddress, upperIRK ); 649 650 """ 651 Set resolvable private address timeout in seconds ( sixty seconds ) 652 """ 653 success = success and RPAs[upperTester].timeout(60) and RPAs[lowerTester].timeout(60); 654 success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable(); 655 656 for iutRole in [ Role.MASTER, Role.SLAVE ]: 657 ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC, 0x456789ABCDEF if iutRole is Role.MASTER else 0x123456789ABC); 658 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC if iutRole is Role.MASTER else 0x456789ABCDEF); 659 if iutRole == Role.MASTER: 660 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, ownAddress, peerAddress); 661 else: 662 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, ownAddress, peerAddress); 663 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 664 665 initiatorAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC ); 666 if iutRole == Role.MASTER: 667 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( IdentityAddressType.PUBLIC_IDENTITY, toNumber(ownAddress.address) )); 668 else: 669 initiator = Initiator(transport, lowerTester, upperTester, trace, initiatorAddress, Address( IdentityAddressType.PUBLIC_IDENTITY, toNumber(ownAddress.address) )); 670 success = success and advertiser.enable(); 671 672 connected = initiator.connect(); 673 success = success and connected; 674 675 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 676 status, RPA = le_read_peer_resolvable_address(transport, upperTester, peerAddress.type, peerAddress.address, 100); 677 trace.trace(6, "LE Read Peer Resolvable Address Command returns status: 0x%02X RPA: %s" % (status, formatAddress(RPA))); 678 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 679 680 if iutRole == Role.MASTER: 681 success = success and (initiator.peerRPA() == RPA); 682 if initiator.peerRPA() != RPA: 683 print((initiator.peerRPA())); 684 print(RPA); 685 trace.trace(5, "Expected: %s Received: %s" % (Address(None, initiator.peerRPA()), Address(None, RPA))); 686 else: 687 success = success and (initiator.localRPA() == RPA); 688 if initiator.localRPA() != RPA: 689 trace.trace(5, "Expected: %s Received: %s" % (Address(None, initiator.localRPA()), Address(None, RPA))); 690 691 transport.wait(200); 692 693 if connected: 694 connected = not initiator.disconnect(0x13); 695 success = success and not connected; 696 697 return success; 698 699""" 700 HCI/CM/BV-02-C [Handling LE Read Local Resolvable Address Command] 701""" 702def hci_cm_bv_02_c(transport, upperTester, lowerTester, trace): 703 704 """ 705 Add Public address of lowerTester and upperTester to the Resolving List 706 """ 707 RPAs = [ ResolvableAddresses( transport, upperTester, trace, upperIRK ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ]; 708 ownAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 709 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 710 success = RPAs[upperTester].clear() and RPAs[lowerTester].clear(); 711 success = success and RPAs[upperTester].add( peerAddress, lowerIRK ); 712 success = success and RPAs[lowerTester].add( ownAddress, upperIRK ); 713 714 """ 715 Set resolvable private address timeout in seconds ( sixty seconds ) 716 """ 717 success = success and RPAs[upperTester].timeout(60) and RPAs[lowerTester].timeout(60); 718 success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable(); 719 720 for iutRole in [ Role.MASTER, Role.SLAVE ]: 721 ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC, 0x456789ABCDEF if iutRole is Role.MASTER else 0x123456789ABC); 722 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC if iutRole is Role.MASTER else 0x456789ABCDEF); 723 if iutRole == Role.MASTER: 724 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, ownAddress, peerAddress); 725 else: 726 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, ownAddress, peerAddress); 727 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 728 729 initiatorAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC ); 730 if iutRole == Role.MASTER: 731 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( IdentityAddressType.PUBLIC_IDENTITY, toNumber(ownAddress.address) )); 732 else: 733 initiator = Initiator(transport, lowerTester, upperTester, trace, initiatorAddress, Address( IdentityAddressType.PUBLIC_IDENTITY, toNumber(ownAddress.address) )); 734 success = success and advertiser.enable(); 735 736 connected = initiator.connect(); 737 success = success and connected; 738 739 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 740 status, RPA = le_read_local_resolvable_address(transport, upperTester, peerAddress.type, peerAddress.address, 100); 741 trace.trace(6, "LE Read Local Resolvable Address Command returns status: 0x%02X RPA: %s" % (status, formatAddress(RPA))); 742 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 743 744 if iutRole == Role.MASTER: 745 success = success and (initiator.localRPA() == RPA); 746 else: 747 success = success and (initiator.peerRPA() == RPA); 748 749 transport.wait(200); 750 751 if connected: 752 connected = not initiator.disconnect(0x13); 753 success = success and not connected; 754 755 return success; 756 757""" 758 HCI/CM/BV-03-C [Handling LE Read PHY Command] 759""" 760def hci_cm_bv_03_c(transport, upperTester, lowerTester, trace): 761 762 ownAddress = Address( ExtendedAddressType.PUBLIC ); 763 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 764 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 765 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 766 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 767 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 768 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x456789ABCDEF )); 769 success = advertiser.enable(); 770 771 connected = initiator.connect(); 772 success = success and connected; 773 774 if success: 775 status, handle, TxPhy, RxPhy = le_read_phy(transport, upperTester, initiator.handles[0], 100); 776 trace.trace(6, "LE Read PHY Command returns status: 0x%02X handle: 0x%04X TxPHY: %d RxPHY: %d" % (status, handle, TxPhy, RxPhy)); 777 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 778 779 if connected: 780 connected = not initiator.disconnect(0x13); 781 success = success and not connected; 782 783 return success; 784 785""" 786 HCI/DSU/BV-02-C [Reset Command received in Advertising State] 787""" 788def hci_dsu_bv_02_c(transport, upperTester, lowerTester, trace): 789 790 ownAddress = Address( SimpleAddressType.PUBLIC ); 791 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 792 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 793 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 794 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 795 ownAddress = Address( SimpleAddressType.PUBLIC ); 796 scanner = Scanner(transport, lowerTester, trace, ScanType.PASSIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 5); 797 798 success = advertiser.enable(); 799 800 success = success and scanner.enable(); 801 scanner.monitor(); 802 success = success and scanner.disable(); 803 success = success and scanner.qualifyReports( 5 ); 804 805 status = reset(transport, upperTester, 100); 806 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 807 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 808 809 """ 810 Verify that the IUT has stopped Advertising 811 """ 812 success = success and scanner.enable(); 813 scanner.monitor(); 814 success = success and scanner.disable(); 815 success = success and not scanner.qualifyReports( 5 ); 816 817 return success; 818 819""" 820 HCI/DSU/BV-03-C [Reset Command received in Slave Role] 821""" 822def hci_dsu_bv_03_c(transport, upperTester, lowerTester, trace): 823 824 ownAddress = Address( ExtendedAddressType.PUBLIC ); 825 peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ); 826 advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 827 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 828 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 829 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 830 initiator = Initiator(transport, lowerTester, upperTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x123456789ABC )); 831 success = advertiser.enable(); 832 833 success = success and initiator.connect(); 834 835 transport.wait(200); 836 837 status = reset(transport, upperTester, 100); 838 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 839 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 840 841 """ 842 There might be pending disconnect events lying around... 843 """ 844 while has_event(transport, lowerTester, 200)[0]: 845 event = get_event(transport, lowerTester, 100); 846 trace.trace(7, str(event)); 847 if event.event == Events.BT_HCI_EVT_DISCONN_COMPLETE: 848 status, handle, reason = event.decode(); 849 success = success and (reason == 0x08); # Connection Timeout 850 851 while has_event(transport, upperTester, 200)[0]: 852 event = get_event(transport, upperTester, 100); 853 trace.trace(7, str(event)); 854 if event.event == Events.BT_HCI_EVT_DISCONN_COMPLETE: 855 status, handle, reason = event.decode(); 856 success = success and (reason == 0x08); # Connection Timeout 857 858 return success; 859 860""" 861 HCI/DSU/BV-04-C [Reset Command received in Scanning State] 862""" 863def hci_dsu_bv_04_c(transport, upperTester, lowerTester, trace): 864 865 ownAddress = Address( SimpleAddressType.PUBLIC ); 866 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 867 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 868 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 869 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 870 ownAddress = Address( SimpleAddressType.PUBLIC ); 871 scanner = Scanner(transport, upperTester, trace, ScanType.PASSIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 5); 872 873 success = advertiser.enable(); 874 875 success = success and scanner.enable(); 876 scanner.monitor(); 877 success = success and scanner.disable(); 878 success = success and scanner.qualifyReports( 5 ); 879 880 status = reset(transport, upperTester, 100); 881 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 882 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 883 884 """ 885 Verify that the IUT has stopped Advertising 886 """ 887 success = success and scanner.enable(); 888 scanner.monitor(); 889 success = success and scanner.disable(); 890 success = success and not scanner.qualifyReports( 5 ); 891 892 return success; 893 894""" 895 HCI/DSU/BV-05-C [Reset Command received in Initiating State] 896""" 897def hci_dsu_bv_05_c(transport, upperTester, lowerTester, trace): 898 899 ownAddress = Address( ExtendedAddressType.PUBLIC ); 900 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 901 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 902 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 903 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 904 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 905 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x456789ABCDEF )); 906 907 success = initiator.preConnect(); 908 909 status = reset(transport, upperTester, 100); 910 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 911 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 912 913 success = success and advertiser.enable(); 914 success = success and not initiator.postConnect(); 915 success = success and advertiser.disable(); 916 917 return success; 918 919""" 920 HCI/DSU/BV-06-C [Reset Command received in Master Role] 921""" 922def hci_dsu_bv_06_c(transport, upperTester, lowerTester, trace): 923 924 ownAddress = Address( ExtendedAddressType.PUBLIC ); 925 peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC ); 926 advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \ 927 ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE); 928 advertiser.responseData = [ 0x04, 0x09 ] + [ ord(char) for char in "IUT" ]; 929 initiatorAddress = Address( ExtendedAddressType.PUBLIC ); 930 initiator = Initiator(transport, upperTester, lowerTester, trace, initiatorAddress, Address( ExtendedAddressType.PUBLIC, 0x456789ABCDEF )); 931 success = advertiser.enable(); 932 933 success = success and initiator.connect(); 934 935 transport.wait(200); 936 937 status = reset(transport, upperTester, 100); 938 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 939 success = success and __check_command_complete_event(transport, upperTester, trace) and (status == 0); 940 941 return success; 942 943__tests__ = { 944 "HCI/CCO/BV-07-C": [ hci_cco_bv_07_c, 'BR/EDR Commands Not Supported on LE Device' ], 945 "HCI/CCO/BV-09-C": [ hci_cco_bv_09_c, 'Handling LE Set Data Length Command' ], 946 "HCI/CCO/BV-10-C": [ hci_cco_bv_10_c, 'Handling LE Read Suggested Default Data Length Command' ], 947 "HCI/CCO/BV-11-C": [ hci_cco_bv_11_c, 'Handling LE Write Suggested Default Data Length Command' ], 948 "HCI/CCO/BV-12-C": [ hci_cco_bv_12_c, 'Handling LE Remove Device From Resolving List Command' ], 949 "HCI/CCO/BV-13-C": [ hci_cco_bv_13_c, 'Handling LE Clear Resolving List Command' ], 950 "HCI/CCO/BV-14-C": [ hci_cco_bv_14_c, 'Handling LE Read Resolving List Size Command' ], 951 "HCI/CCO/BV-15-C": [ hci_cco_bv_15_c, 'Handling LE Set Default PHY Command' ], 952# "HCI/CCO/BV-16-C": [ hci_cco_bv_17_c, 'Handling LE Read Periodic Advertiser List Size Command' ], 953# "HCI/CCO/BV-17-C": [ hci_cco_bv_17_c, 'Handling Add, Remove and Clear Periodic Advertiser List Commands' ], 954 "HCI/CCO/BV-18-C": [ hci_cco_bv_18_c, 'Handling LE Read Transmit Power Command' ], 955 "HCI/CFC/BV-02-C": [ hci_cfc_bv_02_c, 'Reported Buffer Size' ], 956 "HCI/CIN/BV-01-C": [ hci_cin_bv_01_c, 'Features returned by Read Local Supported Features Command' ], 957 "HCI/CIN/BV-03-C": [ hci_cin_bv_03_c, 'Supported Commands returned by Read Local Supported Commands Command' ], 958 "HCI/CIN/BV-04-C": [ hci_cin_bv_04_c, 'Versions returned by Read Local Version Information Command' ], 959 "HCI/CIN/BV-06-C": [ hci_cin_bv_06_c, 'Reported White List Size' ], 960 "HCI/CIN/BV-09-C": [ hci_cin_bv_09_c, 'Feature Bits returned by Read LE Public Key Validation Feature Bit' ], 961 "HCI/CM/BV-01-C": [ hci_cm_bv_01_c, 'Handling LE Read Peer Resolvable Address Command' ], 962 "HCI/CM/BV-02-C": [ hci_cm_bv_02_c, 'Handling LE Read Local Resolvable Address Command' ], 963 "HCI/CM/BV-03-C": [ hci_cm_bv_03_c, 'Handling LE Read PHY Command' ], 964 "HCI/DDI/BI-02-C": [ hci_ddi_bi_02_c, 'Rejecting invalid Advertising Parameters' ], 965 "HCI/DDI/BV-03-C": [ hci_ddi_bv_03_c, 'Disable Advertising with Set Advertising Enable Command' ], 966 "HCI/DDI/BV-04-C": [ hci_ddi_bv_04_c, 'Disable Scanning with Set Scan Enable Command' ], 967 "HCI/DSU/BV-02-C": [ hci_dsu_bv_02_c, 'Reset Command received in Advertising State' ], 968 "HCI/DSU/BV-03-C": [ hci_dsu_bv_03_c, 'Reset Command received in Slave Role' ], 969 "HCI/DSU/BV-04-C": [ hci_dsu_bv_04_c, 'Reset Command received in Scanning State' ], 970 "HCI/DSU/BV-05-C": [ hci_dsu_bv_05_c, 'Reset Command received in Initiating State' ], 971 "HCI/DSU/BV-06-C": [ hci_dsu_bv_06_c, 'Reset Command received in Master Role' ], 972 "HCI/GEV/BV-01-C": [ hci_gev_bv_01_c, 'Status return for Unsupported Commands' ], 973 "HCI/HFC/BV-04-C": [ hci_hfc_bv_04_c, 'Events enabled by LE Set Event Mask Command' ] 974}; 975 976_maxNameLength = max([ len(key) for key in __tests__ ]); 977 978_spec = { key: TestSpec(name = key, number_devices = 2, description = "#[" + __tests__[key][1] + "]", test_private = __tests__[key][0]) for key in __tests__ }; 979 980""" 981 Return the test spec which contains info about all the tests 982 this test module provides 983""" 984def get_tests_specs(): 985 return _spec; 986 987def preamble(transport, trace): 988 global lowerIRK, upperIRK, lowerRandomAddress, upperRandomAddress; 989 990 ok = success = preamble_standby(transport, 0, trace); 991 trace.trace(4, "preamble Standby " + ("PASS" if success else "FAIL")); 992 success = preamble_standby(transport, 1, trace); 993 ok = ok and success; 994 trace.trace(4, "preamble Standby " + ("PASS" if success else "FAIL")); 995 success, upperIRK, upperRandomAddress = preamble_device_address_set(transport, 0, trace); 996 trace.trace(4, "preamble Device Address Set " + ("PASS" if success else "FAIL")); 997 ok = ok and success; 998 success, lowerIRK, lowerRandomAddress = preamble_device_address_set(transport, 1, trace); 999 trace.trace(4, "preamble Device Address Set " + ("PASS" if success else "FAIL")); 1000 return ok and success; 1001 1002""" 1003 Run a test given its test_spec 1004""" 1005def run_a_test(args, transport, trace, test_spec): 1006 try: 1007 success = preamble(transport, trace); 1008 except Exception as e: 1009 trace.trace(3, "Preamble generated exception: %s" % str(e)); 1010 success = False; 1011 1012 trace.trace(2, "%-*s %s test started..." % (_maxNameLength, test_spec.name, test_spec.description[1:])); 1013 test_f = test_spec.test_private; 1014 try: 1015 if test_f.__code__.co_argcount > 3: 1016 success = success and test_f(transport, 0, 1, trace); 1017 else: 1018 success = success and test_f(transport, 0, trace); 1019 except Exception as e: 1020 import traceback 1021 traceback.print_exc() 1022 trace.trace(3, "Test generated exception: %s" % str(e)); 1023 success = False; 1024 1025 return not success 1026