1# -*- coding: utf-8 -*- 2# Copyright 2019 Oticon A/S 3# SPDX-License-Identifier: Apache-2.0 4 5# from enum import IntFlag; 6from components.utils import *; 7from components.basic_commands import *; 8from components.address import *; 9from components.events import *; 10 11# class LE_Events(IntFlag): 12# LE_Connection_Complete_Event = 1<<0 13# LE_Advertising_Report_Event = 1<<1 14# LE_Connection_Update_Complete_Event = 1<<2 15# LE_Read_Remote_Features_Complete_Event = 1<<3 16# LE_Long_Term_Key_Request_Event = 1<<4 17# LE_Remote_Connection_Parameter_Request_Event = 1<<5 18# LE_Data_Length_Change_Event = 1<<6 19# LE_Read_Local_P_256_Public_Key_Complete_Event = 1<<7 20# LE_Generate_DHKey_Complete_Event = 1<<8 21# LE_Enhanced_Connection_Complete_Event = 1<<9 22# LE_Directed_Advertising_Report_Event = 1<<10 23# LE_PHY_Update_Complete_Event = 1<<11 24# LE_Extended_Advertising_Report_Event = 1<<12 25# LE_Periodic_Advertising_Sync_Established_Event = 1<<13 26# LE_Periodic_Advertising_Report_Event = 1<<14 27# LE_Periodic_Advertising_Sync_Lost_Event = 1<<15 28# LE_Extended_Scan_Timeout_Event = 1<<16 29# LE_Extended_Advertising_Set_Terminated_Event = 1<<17 30# LE_Scan_Request_Received_Event = 1<<18 31# LE_Channel_Selection_Algorithm_Event = 1<<19 32# LE_Events_All = (1<<20)-1 33 34def __verifyAndShowEvent(transport, idx, expectedEvent, trace): 35 36 event = get_event(transport, idx, 100); 37 trace.trace(7, str(event)); 38 return event.event == expectedEvent; 39 40def __verifyAndShowMetaEvent(transport, idx, expectedEvent, trace): 41 42 event = get_event(transport, idx, 100); 43 trace.trace(7, str(event)); 44 return event.subEvent == expectedEvent; 45 46def __verifyAndFetchEvent(transport, idx, expectedEvent, trace): 47 48 event = get_event(transport, idx, 100)[1:]; 49 trace.trace(7, str(event)); 50 return event.event == expectedEvent, event.data; 51 52def __verifyAndFetchMetaEvent(transport, idx, expectedEvent, trace): 53 54 event = get_event(transport, idx, 100)[1:]; 55 trace.trace(7, str(event)); 56 return event.subEvent == expectedEvent, event.data; 57 58def __getCommandCompleteEvent(transport, idx, trace): 59 60 return __verifyAndShowEvent(transport, idx, Events.BT_HCI_EVT_CMD_COMPLETE, trace); 61 62def __random(transport, idx, trace): 63 status, rand = le_rand(transport, idx, 100); 64 trace.trace(6, "LE Rand Command returns status: 0x%02X; rand: 0x%016X" % (status, toNumber(rand))); 65 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 66 return success, rand; 67 68def __encrypt(transport, idx, key, plaintext, trace): 69 status, encrypted = le_encrypt(transport, idx, key, plaintext, 2000); 70 trace.trace(6, "LE Encrypt Command returns status: 0x%02X" % status); 71 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 72 return success, encrypted; 73 74""" 75 Prepare for testing, by 76 - Resetting the DUT 77 - Read Local Supported Features and insure that 'LE Supported (Controller)' and 'BR/EDR Not Supported' are both set 78 - Read LE Local Supported Features 79 - Set Event Masks: 'Event Mask', 'LE Event Mask' and 'Event Mask Page 2' 80 81 Returns a boolean indicating whether all went well. 82""" 83def preamble_standby(transport, idx, trace): 84 trace.trace(3, "Standby preamble steps..."); 85 86 try: 87 flush_events(transport, idx, 100); 88 le_data_flush(transport, idx, 100); 89 90 status = reset(transport, idx, 100); 91 trace.trace(6, "Reset Command returns status: 0x%02X" % status); 92 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 93 if not success: 94 trace.trace(6, "RESET command not confirmed!"); 95 96 status, features = read_local_supported_features(transport, idx, 100); 97 trace.trace(6, "Read Local Supported Features Command returns status: 0x%02X" % status); 98 """ 99 Check that features 'BR/EDR Not Supported' and 'LE Supported (Controller)' are both enabled 100 """ 101 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and ((features[4] & 0x60) == 0x60) and success; 102 103 status, features = le_read_local_supported_features(transport, idx, 100); 104 trace.trace(6, "LE Read Local Supported Features Command returns status: 0x%02X" % status); 105 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 106 """ 107 Bit Parameter Description 108 0 Inquiry Complete Event 109 1 Inquiry Result Event 110 2 Connection Complete Event 111 3 Connection Request Event 112 4 Disconnection Complete Event 113 5 Authentication Complete Event 114 6 Remote Name Request Complete Event 115 7 Encryption Change Event 116 8 Change Connection Link Key Complete Event 117 9 Master Link Key Complete Event 118 10 Read Remote Supported Features Complete Event 119 11 Read Remote Version Information Complete Event 120 12 QoS Setup Complete Event 121 13 Reserved for future use 122 14 Reserved for future use 123 15 Hardware Error Event 124 16 Flush Occurred Event 125 17 Role Change Event 126 18 Reserved for future use 127 19 Mode Change Event 128 20 Return Link Keys Event 129 21 PIN Code Request Event 130 22 Link Key Request Event 131 23 Link Key Notification Event 132 24 Loopback Command Event 133 25 Data Buffer Overflow Event 134 26 Max Slots Change Event 135 27 Read Clock Offset Complete Event 136 28 Connection Packet Type Changed Event 137 29 QoS Violation Event 138 30 Page Scan Mode Change Event [deprecated] 139 31 Page Scan Repetition Mode Change Event 140 32 Flow Specification Complete Event 141 33 Inquiry Result with RSSI Event 142 34 Read Remote Extended Features Complete Event 143 35 Reserved for future use 144 36 Reserved for future use 145 37 Reserved for future use 146 38 Reserved for future use 147 39 Reserved for future use 148 40 Reserved for future use 149 41 Reserved for future use 150 42 Reserved for future use 151 43 Synchronous Connection Complete Event 152 44 Synchronous Connection Changed Event 153 45 Sniff Subrating Event 154 46 Extended Inquiry Result Event 155 47 Encryption Key Refresh Complete Event 156 48 IO Capability Request Event 157 49 IO Capability Response Event 158 50 User Confirmation Request Event 159 51 User Passkey Request Event 160 52 Remote OOB Data Request Event 161 53 Simple Pairing Complete Event 162 54 Reserved for future use 163 55 Link Supervision Timeout Changed Event 164 56 Enhanced Flush Complete Event 165 57 Reserved for Future Use 166 58 User Passkey Notification Event 167 59 Keypress Notification Event 168 60 Remote Host Supported Features Notification Event 169 61 LE Meta Event 170 62 Reserved for future use 171 63 Reserved for future use 172 173 Bit: 5 4 4 3 2 1 0 0 174 6 8 0 2 4 6 8 0 175 0x00 00 1F FF FF FF FF FF ~ Default. 176 0x20 00 1F FF FF FF FF FF ~ Default + Bit 61 ~ LE Meta Event 177 """ 178 events = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x20]; 179 180 status = set_event_mask(transport, idx, events, 100); 181 trace.trace(6, "Set Event Mask Command returns status: 0x%02X" % status); 182 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 183 """ 184 Bit LE Subevent Types 185 0 LE Connection Complete Event 186 1 LE Advertising Report Event 187 2 LE Connection Update Complete Event 188 3 LE Read Remote Features Complete Event 189 4 LE Long Term Key Request Event 190 5 LE Remote Connection Parameter Request Event 191 6 LE Data Length Change Event 192 7 LE Read Local P-256 Public Key Complete Event 193 8 LE Generate DHKey Complete Event 194 9 LE Enhanced Connection Complete Event 195 10 LE Directed Advertising Report Event 196 11 LE PHY Update Complete Event 197 12 LE Extended Advertising Report Event 198 13 LE Periodic Advertising Sync Established Event 199 14 LE Periodic Advertising Report Event 200 15 LE Periodic Advertising Sync Lost Event 201 16 LE Extended Scan Timeout Event 202 17 LE Extended Advertising Set Terminated Event 203 18 LE Scan Request Received Event 204 19 LE Channel Selection Algorithm Event 205 206 Bit: 5 4 4 3 2 1 0 0 207 6 8 0 2 4 6 8 0 208 0x00 00 00 00 00 00 00 1F ~ Default. 209 0x00 00 00 00 00 07 FF FF ~ All except 'LE Channel Selection Algorithm Event' 210 """ 211 events = [0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00]; 212 213 status = le_set_event_mask(transport, idx, events, 100); 214 trace.trace(6, "LE Set Event Mask Command returns status: 0x%02X" % status); 215 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 216 """ 217 0x00 00 00 00 00 00 00 00 ~ Default. 218 """ 219 events = [0 for _ in range(8)]; 220 221 status = set_event_mask_page_2(transport, idx, events, 100); 222 trace.trace(6, "Set Event Mask Page2 Command returns status: 0x%02X" % status); 223 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 224 except Exception as e: 225 import traceback 226 traceback.print_exc() 227 trace.trace(3, "Standby preamble steps failed: %s" % str(e)); 228 success = False; 229 230 return success; 231 232""" 233 Calculate IRK from IR 234""" 235def __calculateIRK(transport, idx, key, trace): 236 plaintext = [1 if i == 0 else 0 for i in range(16)]; 237 success, irk = __encrypt(transport, idx, key, plaintext, trace); 238 return success, irk; 239 240""" 241 Generate a random static address from IRK 242""" 243def preamble_random_static_address(transport, idx, key, trace): 244 success, rand = __random(transport, idx, trace); 245 246 nrand = (toNumber(rand) & 0xFFFFFF) | 0xC00000; 247 _success, localHash = __encrypt(transport, idx, key, toArray(nrand, 16), trace); 248 success = success and _success; 249 250 nlocalHash = toNumber(localHash) & 0xFFFFFF; 251 address = nlocalHash | (nrand << 24); 252 return success, toArray(address, 6); 253 254""" 255 Generate a private non-resolvable random address from IRK 256""" 257def preamble_random_non_resolvable_address(transport, idx, key, trace): 258 success, rand = __random(transport, idx, trace); 259 260 nrand = toNumber(rand) & 0x3FFFFF; 261 _success, localHash = __encrypt(transport, idx, key, toArray(nrand, 16), trace); 262 success = success and _success; 263 264 nlocalHash = toNumber(localHash) & 0xFFFFFF; 265 address = nlocalHash | (nrand << 24); 266 return success, toArray(address, 6); 267 268""" 269 Calculates a Random Private Address based on the IR (passed to the function) 270 271 The random address generation behavior is an extract from GAP [1] Section 2.1.2 and represents here the typical HCI sequences required from a Controller. 272 The identity resolving key ‘irk’ is used in the test procedures in group ‘SEC’. 273 274 key is the IR - Identity Root 275""" 276def preamble_random_address_calculated(transport, idx, key, trace): 277 trace.trace(4, "Random Address Calculated preamble steps..."); 278 279 try: 280 """ 281 Generate IRK from IR 282 """ 283 success, irk = __calculateIRK(transport, idx, key, trace); 284 trace.trace(7, "IRK: 0x%032X" % toNumber(irk)); 285 286 _success, address = preamble_random_static_address(transport, idx, irk, trace); 287 success = success and _success; 288 trace.trace(7, "Random address: 0x%012X" % toNumber(address)); 289 290 except Exception as e: 291 trace.trace(3, "Random Address Calculated preamble failed: %s" % str(e)); 292 success = False; 293 address = [0 for _ in range(6)]; 294 295 return (success, irk, address); 296 297""" 298 Calculates Encryption Keys based on the IR (identity root) and the ER (encryption root) 299 300 Encryption keys are input to a Controller from [1](part H, section 2.4.2). 301 The identity root, IR is referred to as 'ir' and has the default value 0x112233445566778899AABBCCDDEEFF00. 302 The encryption root, ER is referred to as 'er' and has the default value 0x112233445566778899AABBCCDDEEFF00. 303""" 304def preamble_excryption_keys_calculated(transport, idx, trace): 305 trace.trace(4, "Encryption Keys Calculated preamble steps..."); 306 307 try: 308 success, div = __random(transport, idx, trace); 309 310 _success, rand = __random(transport, idx, trace); 311 success = success and _success; 312 313 ir = er = 0x112233445566778899AABBCCDDEEFF00; 314 315 _success, dhk = _-encrypt(transport, idx, toArray(ir, 16), toArray(0x02, 16), trace); 316 success = success and _success; 317 318 _success, y = __encrypt(transport, idx, dhk, rand, trace); 319 success = success and _success; 320 321 _success, ltk = __encrypt(transport, idx, toArray(er, 16), div, trace); 322 success = success and _success; 323 324 ediv = toArray(toNumber(y) ^ toNumber(div), 16); 325 326 except Exception as e: 327 trace.trace(3, "Encryption Keys Calculated preamble failed: %s" % str(e)); 328 success = False; 329 rand = [0 for _ in range(8)]; 330 ediv = [0 for _ in range(16)]; 331 ltk = [0 for _ in range(16)]; 332 333 return (success, rand, ediv, ltk); 334 335def preamble_set_public_address(transport, idx, address, trace): 336 trace.trace(4, "Set Public Address preamble steps..."); 337 338 try: 339 status = write_bd_addr(transport, idx, toArray(address, 6), 100); 340 trace.trace(6, "Write BD_ADDR Command returns status: 0x%02X" % status); 341 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 342 except Exception as e: 343 trace.trace(3, "Set Public Address preamble failed: %s" % str(e)); 344 success = False; 345 346 return success; 347 348""" 349 The preamble_set_random_address function can be used to set three different kinds of random addresses. 350 351 See [Vol 6] Part B, Section 1.3 - 352 353 - A Static address (two MSBs are 11) 354 - A static address is a 48-bit randomly generated address and shall meet the following requirements: 355 • The two most significant bits of the address shall be equal to 1 356 • At least one bit of the random part of the address shall be 0 357 • At least one bit of the random part of the address shall be 1 358 - A Private address 359 - A non-resolvable Private adress (two MSBs are 00) 360 - To generate a non-resolvable address, the device shall generate a 48-bit address with the following requirements: 361 • The two most significant bits of the address shall be equal to 0 362 • At least one bit of the random part of the address shall be 1 363 • At least one bit of the random part of the address shall be 0 364 • The address shall not be equal to the public address 365 - A resolvable Private address (two MSBs are 01) 366 - To generate a resolvable private address, the device must have either the Local Identity Resolving Key (IRK) or the Peer Identity Resolving Key (IRK). 367 The resolvable private address shall be generated with the IRK and a randomly generated 24-bit number. The random number is known as prand and shall 368 meet the following requirements: 369 • The two most significant bits of prand shall be equal to 0 and 1. 370 • At least one bit of the random part of prand shall be 0 371 • At least one bit of the random part of prand shall be 1 372""" 373def preamble_set_random_address(transport, idx, address, trace): 374 trace.trace(4, "Set Random Address preamble steps..."); 375 376 try: 377 status = le_set_random_address(transport, idx, toArray(address, 6), 100); 378 trace.trace(6, "LE Set Random Address Command returns status: 0x%02X" % status); 379 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 380 except Exception as e: 381 trace.trace(3, "Set Random Address preamble failed: %s" % str(e)); 382 success = False; 383 384 return success; 385 386 387""" 388 When the IUT is in advertising state or slave role, a default value for the scanning, initiating or master address used is 0x123456789ABC. 389 When the IUT is in scanning state, initiating state or master role, a default value for the address used for the state of advertising 390 or the role of slave is 0x456789ABCDEF. 391 392 When it is required to modify the Lower Tester address either in the company_assigned field, the company_id field, 393 it has to be done by exchanging bytes 1 and 3 of company_assigned field or company_id field. 394 If it is required to modify the Lower Tester address in the company_assigned and company_id fields, 395 it has to be done by exchanging bytes 1 of company_assigned and company_id fields. 396""" 397def preamble_device_address_set(transport, idx, trace): 398 trace.trace(4, "Device Address Set preamble steps..."); 399 400 try: 401 """ 402 The Identity Root IR has the default value 0x112233445566778899AABBCCDDEEFF00 403 """ 404 ir = 0x00112233445566778899AABBCCDDEEFF if idx == 0 else 0x112233445566778899AABBCCDDEEFF00; 405 trace.trace(6, "Using default identity root value ir: 0x%032X" % ir); 406 407 success, irk, randAddress = preamble_random_address_calculated(transport, idx, toArray(ir, 16), trace); 408 trace.trace(6, "Generated IRK: 0x%032X" % toNumber(irk)); 409 trace.trace(6, "Generated random address %s" % formatAddress(randAddress)); 410 success = True; 411 412 address = 0x123456789ABC if idx == 0 else 0x456789ABCDEF; 413 success = success and preamble_set_public_address(transport, idx, address, trace); 414 success = success and preamble_set_random_address(transport, idx, toNumber(randAddress), trace); 415 416 except Exception as e: 417 trace.trace(3, "Device address set preamble failed: %s" % str(e)); 418 success = False; 419 irk = [0 for _ in range(16)]; 420 421 return (success, irk, randAddress); 422 423""" 424 The Bluetooth address (BD_ADDR) is 48 bit unique number. BD_ADDR ~ (NAP | UAP | LAP) - OUI ~ (NAP | UAP). 425 The most significant 16 bits - the NAP - is a company specific id. 426 The next significant 8 bits - the UAP - is a company specific id. 427 The least significant 24 bits - the LAP - is a company assigned number. 428 429 The upper half of a Bluetooth Address (most-significant 24 bits) is so called Organizationally Unique Identifier (OUI). 430 It can be used to determine the manufacturer of a device (Bluetooth MAC Address Lookup form). 431 OUI prefixes are assigned by the Institute of Electrical and Electronics Engineers (IEEE). 432 433 NAP 434 Non-significant Address Part (2 bytes). Contains first 16 bits of the OUI. 435 The NAP value is used in Frequency Hopping Synchronization frames. 436 UAP 437 Upper Address Part (1 byte). Contains remaining 8 bits of the OUI. 438 The UAP value is used for seeding in various Bluetooth specification algorithms. 439 LAP 440 Lower Address Part (3 bytes). This portion of Bluetooth Address is allocated by the vendor of device. 441 The LAP value uniquely identifies a Bluetooth device as part of the Access Code in every transmitted frame. 442 The LAP and the UAP make the significant address part (SAP) of the Bluetooth Address. 443""" 444 445""" 446 Scramble the company_id part of the Bluetooth address. 447""" 448def address_scramble_OUI(address): 449 return (address ^ 0xff00ff000000); 450 451""" 452 Scramble the company_assigned part of the Bluetooth address. 453""" 454def address_scramble_LAP(address): 455 return (address ^ 0x000000ff00ff); 456 457""" 458 Scramble both the company_id part and the company_assigned part of the Bluetooth address. 459""" 460def address_exchange_OUI_LAP(address): 461 return (address ^ 0xff00000000ff); 462 463def preamble_specific_white_listed(transport, idx, addresses, trace): 464 trace.trace(5, "Specific White Listed preamble steps..."); 465 466 try: 467 status = le_clear_white_list(transport, idx, 100); 468 trace.trace(6, "LE Clear White List Command returns status: 0x%02X" % status); 469 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 470 471 for i in range(len(addresses)): 472 address = toArray(addresses[i][1], 6); 473 trace.trace(7, "Addding Device to White List %s" % formatAddress(address, addresses[i][0])); 474 status = le_add_device_to_white_list(transport, idx, addresses[i][0], address, 100); 475 trace.trace(6, "LE Add Device to White List Command returns status: 0x%02X" % status); 476 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 477 except Exception as e: 478 trace.trace(3, "Specific White Listed preamble failed: %s" % str(e)); 479 success = False; 480 481 return success; 482 483def preamble_buffer_size_read(transport, idx, trace): 484 trace.trace(5, "Buffer Size Read preamble steps..."); 485 486 try: 487 status, LeMaxLen, LeMaxNum = le_read_buffer_size(transport, idx, 100); 488 trace.trace(6, "LE Read Buffer Size Command returns status: 0x%02X" % status); 489 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 490 491 if LeMaxLen == 0 and LeMaxNum == 0: 492 status, AclMaxLen, ScoMaxLen, AclMaxNum, ScoMaxNum = read_buffer_size(transport, idx, 100); 493 trace.trace(6, "Read Buffer Size Command returns status: 0x%02X" % status); 494 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 495 """ 496 0x90 88 01 00 00 80 00 20 ~ 0x2000800000018890 497 """ 498 events = [0x90, 0x88, 0x01, 0x00, 0x00, 0x80, 0x00, 0x20]; 499 500 status = set_event_mask(transport, idx, events, 100); 501 trace.trace(6, "Set Event Mask Command returns status: 0x%02X" % status); 502 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0) and success; 503 except Exception as e: 504 trace.trace(3, "Buffer Size Read preamble failed: %s" % str(e)); 505 success = False; 506 507 return success; 508 509def preamble_ext_advertising_parameters_set(transport, idx, Handle, Properties, PrimMinInterval, PrimMaxInterval, PrimChannelMap, OwnAddrType, PeerAddrType, PeerAddress, FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, SecAdvPhy, Sid, ScanReqNotifyEnable, trace): 510 trace.trace(5, "Extended Advertising Parameters Set preamble steps..."); 511 512 try: 513 status = le_set_extended_advertising_parameters(transport, idx, Handle, Properties, PrimMinInterval, PrimMaxInterval, PrimChannelMap, OwnAddrType, PeerAddrType, \ 514 PeerAddress, FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, SecAdvPhy, Sid, ScanReqNotifyEnable, 100); 515 trace.trace(6, "LE Set Extended Advertising Parameters Command returns status: 0x%02X" % status); 516 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 517 except Exception as e: 518 trace.trace(3, "Extended Advertising Parameters Set preamble failed: %s" % str(e)); 519 success = False; 520 521 return success; 522 523def preamble_ext_advertising_data_set(transport, idx, Handle, Operation, FragPreference, advData, trace): 524 trace.trace(5, "Extended Advertising Data Set preamble steps..."); 525 526 try: 527 dataSize = len(advData) if len(advData) <= 251 else 251; 528 advertiseData = advData[ : ]; 529 if len(advData) > 251: 530 advertiseData = advertiseData[:251]; 531 532 status = le_set_extended_advertising_data(transport, idx, Handle, Operation, FragPreference, dataSize, advertiseData, 100); 533 trace.trace(6, "LE Set Extended Advertising Data Command returns status: 0x%02X" % status); 534 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 535 except Exception as e: 536 trace.trace(3, "Extended Advertising Data Set preamble failed: %s" % str(e)); 537 success = False; 538 539 return success; 540 541def preamble_ext_advertise_enable(transport, idx, enable, SHandle, SDuration, SMaxExtAdvEvts, trace): 542 trace.trace(5, "Extended Advertising " + ("Enable" if enable else "Disable") + " preamble steps..."); 543 544 try: 545 NumberOfSets = max(len(sHandle), len(SDuration), len(SMaxExtAdvEvts)); 546 if len(SHandle) < NumberOfSets: 547 SHandle += [ 0 for _ in range(len(SHandle), NumberOfSets) ]; 548 if len(SDuration) < NumberOfSets: 549 SDuration += [ 0 for _ in range(len(SDuration), NumberOfSets) ]; 550 if len(SMaxExtAdvEvts) < NumberOfSets: 551 SMaxExtAdvEvts += [ 0 for _ in range(len(SMaxExtAdvEvts), NumberOfSets) ]; 552 553 status = le_set_extended_advertising_enable(transport, idx, enable, NumberOfSets, SHandle, SDuration, SMaxExtAdvEvts, 100); 554 trace.trace(6, "LE Set Extended Advertising Enable Command returns status: 0x%02X" % status); 555 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 556 except Exception as e: 557 trace.trace(3, "Extended Advertising " + "Enable" if enable else "Disable" + " preamble failed: %s" % str(e)); 558 success = False; 559 560 return success; 561 562def preamble_scan_parameters_set(transport, idx, scanType, scanInterval, scanWindow, addrType, filterPolicy, trace): 563 trace.trace(5, "Scan Parameters Set preamble steps..."); 564 565 try: 566 status = le_set_scan_parameters(transport, idx, scanType, scanInterval, scanWindow, addrType, filterPolicy, 100); 567 trace.trace(6, "LE Set Scan Parameters Command returns status: 0x%02X" % status); 568 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 569 except Exception as e: 570 trace.trace(3, "Scan Parameters Set preamble failed: %s" % str(e)); 571 success = False; 572 573 return success; 574 575def preamble_scan_enable(transport, idx, enable, filterDuplicate, trace): 576 trace.trace(5, "Scanning " + ("Enable" if enable else "Disable") + " preamble steps..."); 577 578 try: 579 status = le_set_scan_enable(transport, idx, enable, filterDuplicate, 100); 580 trace.trace(6, "LE Set Scan Enable Command returns status: 0x%02X" % status); 581 success = (status == 0); 582 while not __getCommandCompleteEvent(transport, idx, trace): 583 pass; 584 except Exception as e: 585 trace.trace(3, "Scanning " + ("Enable" if enable else "Disable") + " preamble failed: %s" % str(e)); 586 success = False; 587 588 return success; 589 590def preamble_passive_scanning(transport, idx, scanInterval, scanWindow, addrType, filterPolicy, trace): 591 trace.trace(5, "Passive Scanning preamble steps..."); 592 593 success = preamble_scan_parameters_set(transport, idx, ScanType.PASSIVE, scanInterval, scanWindow, addrType, filterPolicy, trace); 594 success = success and preamble_scan_enable(transport, idx, Scan.ENABLE, ScanFilterDuplicate.DISABLE, trace); 595 return success; 596 597def preamble_default_physical_channel(transport, idx, AllPhys, TxPhys, RxPhys, trace): 598 trace.trace(5, "Default physical channels preamble steps..."); 599 600 try: 601 status = le_set_default_phy(transport, idx, AllPhys, TxPhys, RxPhys, 100); 602 success = __getCommandCompleteEvent(transport, idx, trace) and (status == 0); 603 except Exception as e: 604 trace.trace(3, "Default physical channels preamble failed: %s" % str(e)); 605 success = False; 606 607 return success; 608 609def public_address( address ): 610 return ExtendedAddressType.PUBLIC, toArray(address, 6); 611 612def random_address( address ): 613 return ExtendedAddressType.RANDOM, toArray(address, 6); 614 615def public_identity_address( address ): 616 return ExtendedAddressType.RESOLVABLE_OR_PUBLIC, toArray(address, 6); 617 618def random_identity_address( address ): 619 return ExtendedAddressType.RESOLVABLE_OR_RANDOM, toArray(address, 6); 620