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