1# -*- coding: utf-8 -*-
2# Copyright 2019 Oticon A/S
3# SPDX-License-Identifier: Apache-2.0
4
5import statistics;
6import os;
7import numpy;
8from enum import IntEnum;
9from components.utils import *;
10from components.basic_commands import *;
11from components.address import *;
12from components.resolvable import *;
13from components.advertiser import *;
14from components.scanner import *;
15from components.initiator import *;
16from components.preambles import *;
17from components.addata import *;
18from components.pairing import *;
19from components.test_spec import TestSpec;
20
21global lowerIRK, upperIRK, lowerRandomAddress, upperRandomAddress;
22
23"""
24    GAP/DISC/NONM/BV-01-C [Non-discoverable Mode and Non-Connectable Mode]
25"""
26def gap_disc_nonm_bv_01_c(transport, upperTester, lowerTester, trace):
27
28    ownAddress = Address( ExtendedAddressType.PUBLIC );
29    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
30    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
31                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
32    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
33
34    adData = ADData();
35    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.BR_EDR_NOT_SUPPORTED );
36    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
37    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
38    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
39
40    success = advertiser.enable();
41    if success:
42        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
43        for address in devices:
44            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
45                                                                                      devices[address]["type"] ), devices[address]["name"]) );
46        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
47        success = not success;
48
49    success = success and advertiser.disable();
50
51    return success;
52
53"""
54    GAP/DISC/NONM/BV-02-C [Non-discoverable Mode and Undirected Connectable Mode]
55"""
56def gap_disc_nonm_bv_02_c(transport, upperTester, lowerTester, trace):
57
58    ownAddress = Address( ExtendedAddressType.PUBLIC );
59    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
60    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
61                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
62    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
63
64    adData = ADData();
65    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.BR_EDR_NOT_SUPPORTED );
66    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
67    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
68    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
69
70    success = advertiser.enable();
71    if success:
72        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
73        for address in devices:
74            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
75                                                                                      devices[address]["type"] ), devices[address]["name"]) );
76        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
77        success = not success;
78
79    success = success and advertiser.disable();
80
81    return success;
82
83"""
84    GAP/DISC/LIMM/BV-01-C [Limited Discoverable Mode and Non-Connectable Mode in BR/EDR/LE configuration]
85"""
86def gap_disc_limm_bv_01_c(transport, upperTester, lowerTester, trace):
87
88    ownAddress = Address( ExtendedAddressType.PUBLIC );
89    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
90    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
91                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
92    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
93
94    adData = ADData();
95    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE );
96    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
97    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
98    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
99
100    success = advertiser.enable();
101    if success:
102        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
103        for address in devices:
104            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
105                                                                                      devices[address]["type"] ), devices[address]["name"]) );
106        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
107
108    success = success and advertiser.disable();
109
110    return success;
111
112"""
113    GAP/DISC/LIMM/BV-02-C [Limited Discoverable Mode and Undirected Connectable Mode in BR/EDR/LE configuration]
114"""
115def gap_disc_limm_bv_02_c(transport, upperTester, lowerTester, trace):
116
117    ownAddress = Address( ExtendedAddressType.PUBLIC );
118    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
119    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
120                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
121    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
122
123    adData = ADData();
124    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE );
125    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
126    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
127    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
128
129    success = advertiser.enable();
130    if success:
131        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
132        for address in devices:
133            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
134                                                                                      devices[address]["type"] ), devices[address]["name"]) );
135        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
136
137    success = success and advertiser.disable();
138
139    return success;
140
141"""
142    GAP/DISC/LIMM/BV-03-C [Limited Discoverable Mode and Non-Connectable Mode in LE Only configuration]
143"""
144def gap_disc_limm_bv_03_c(transport, upperTester, lowerTester, trace):
145
146    ownAddress = Address( ExtendedAddressType.PUBLIC );
147    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
148    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
149                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
150    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
151
152    adData = ADData();
153    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
154    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
155    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
156    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
157
158    success = advertiser.enable();
159    if success:
160        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
161        for address in devices:
162            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
163                                                                                      devices[address]["type"] ), devices[address]["name"]) );
164        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
165
166    success = success and advertiser.disable();
167
168    return success;
169
170"""
171    GAP/DISC/LIMM/BV-04-C [Limited Discoverable Mode and Undirected Connectable Mode in LE Only configuration]
172"""
173def gap_disc_limm_bv_04_c(transport, upperTester, lowerTester, trace):
174
175    ownAddress = Address( ExtendedAddressType.PUBLIC );
176    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
177    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
178                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
179    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
180
181    adData = ADData();
182    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
183    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
184    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
185    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
186
187    success = advertiser.enable();
188    if success:
189        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
190        for address in devices:
191            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
192                                                                                      devices[address]["type"] ), devices[address]["name"]) );
193        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
194
195    success = success and advertiser.disable();
196
197    return success;
198
199"""
200    GAP/DISC/GENM/BV-01-C [General Discoverable Mode and Non-Connectable Mode in BR/EDR/LE configuration]
201"""
202def gap_disc_genm_bv_01_c(transport, upperTester, lowerTester, trace):
203
204    ownAddress = Address( ExtendedAddressType.PUBLIC );
205    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
206    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
207                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
208    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
209
210    adData = ADData();
211    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE );
212    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
213    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
214    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
215
216    success = advertiser.enable();
217    if success:
218        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE);
219        for address in devices:
220            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
221                                                                                      devices[address]["type"] ), devices[address]["name"]) );
222        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
223
224    success = success and advertiser.disable();
225
226    return success;
227
228"""
229    GAP/DISC/GENM/BV-02-C [General Discoverable Mode and Undirected Connectable Mode in BR/EDR/LE configuration]
230"""
231def gap_disc_genm_bv_02_c(transport, upperTester, lowerTester, trace):
232
233    ownAddress = Address( ExtendedAddressType.PUBLIC );
234    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
235    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
236                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
237    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
238
239    adData = ADData();
240    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE );
241    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
242    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
243    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
244
245    success = advertiser.enable();
246    if success:
247        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
248        for address in devices:
249            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
250                                                                                      devices[address]["type"] ), devices[address]["name"]) );
251        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
252
253    success = success and advertiser.disable();
254
255    return success;
256
257"""
258    GAP/DISC/GENM/BV-03-C [General Discoverable Mode and Non-Connectable Mode in LE Only configuration]
259"""
260def gap_disc_genm_bv_03_c(transport, upperTester, lowerTester, trace):
261
262    ownAddress = Address( ExtendedAddressType.PUBLIC );
263    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
264    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
265                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
266    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
267
268    adData = ADData();
269    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
270    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
271    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
272    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
273
274    success = advertiser.enable();
275    if success:
276        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
277        for address in devices:
278            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
279                                                                                      devices[address]["type"] ), devices[address]["name"]) );
280        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
281
282    success = success and advertiser.disable();
283
284    return success;
285
286"""
287    GAP/DISC/GENM/BV-04-C [General Discoverable Mode and Undirected Connectable Mode in LE Only configuration]
288"""
289def gap_disc_genm_bv_04_c(transport, upperTester, lowerTester, trace):
290
291    ownAddress = Address( ExtendedAddressType.PUBLIC );
292    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
293    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
294                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
295    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
296
297    adData = ADData();
298    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
299    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
300    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
301    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
302
303    success = advertiser.enable();
304    if success:
305        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
306        for address in devices:
307            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
308                                                                                      devices[address]["type"] ), devices[address]["name"]) );
309        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
310
311    success = success and advertiser.disable();
312
313    return success;
314
315"""
316    GAP/DISC/LIMP/BV-01-C [Limited Discovery finding Limited Discoverable Device]
317"""
318def gap_disc_limp_bv_01_c(transport, upperTester, lowerTester, trace):
319
320    ownAddress = Address( ExtendedAddressType.PUBLIC );
321    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
322    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
323                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
324
325    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
326
327    adData = ADData();
328    advertiser.advertiseData = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
329    advertiser.responseData  = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
330
331    success = advertiser.enable();
332    if success:
333        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
334        for address in devices:
335            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
336                                                                                      devices[address]["type"] ), devices[address]["name"]) );
337        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
338
339    success = success and advertiser.disable();
340
341    return success;
342
343"""
344    GAP/DISC/LIMP/BV-02-C [Limited Discovery not finding General Discoverable Device]
345"""
346def gap_disc_limp_bv_02_c(transport, upperTester, lowerTester, trace):
347
348    ownAddress = Address( ExtendedAddressType.PUBLIC );
349    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
350    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
351                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
352    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
353
354    adData = ADData();
355    advertiser.advertiseData = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
356    advertiser.responseData  = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
357
358    success = advertiser.enable();
359    if success:
360        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
361        for address in devices:
362            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
363                                                                                      devices[address]["type"] ), devices[address]["name"]) );
364        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
365        success = not success;
366
367    success = success and advertiser.disable();
368
369    return success;
370
371"""
372    GAP/DISC/LIMP/BV-04-C [Limited Discovery not finding Undirected Connectable device]
373"""
374def gap_disc_limp_bv_04_c(transport, upperTester, lowerTester, trace):
375
376    ownAddress = Address( ExtendedAddressType.PUBLIC );
377    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
378    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
379                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
380    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
381
382    adData = ADData();
383    advertiser.advertiseData  = adData.encode( ADType.TX_POWER_LEVEL, -4 );
384    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
385    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
386
387    success = advertiser.enable();
388    if success:
389        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
390        for address in devices:
391            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
392                                                                                      devices[address]["type"] ), devices[address]["name"]) );
393        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
394        success = not success;
395
396    success = success and advertiser.disable();
397
398    return success;
399
400"""
401    GAP/DISC/LIMP/BV-05-C [Limited Discovery not finding Directed Connectable device]
402"""
403def gap_disc_limp_bv_05_c(transport, upperTester, lowerTester, trace):
404
405    ownAddress = Address( ExtendedAddressType.PUBLIC );
406    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
407    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
408                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
409    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
410
411    adData = ADData();
412    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
413    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
414    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
415    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
416
417    success = advertiser.enable();
418    if success:
419        success, devices = scanner.discover( 2000, ADFlag.LE_LIMITED_DISCOVERABLE );
420        for address in devices:
421            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
422                                                                                      devices[address]["type"] ), devices[address]["name"]) );
423        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
424        success = not success;
425
426    success = success and advertiser.disable();
427
428    return success;
429
430"""
431    GAP/DISC/GENP/BV-01-C [General Discovery finding General Discoverable Device]
432"""
433def gap_disc_genp_bv_01_c(transport, upperTester, lowerTester, trace):
434
435    ownAddress = Address( ExtendedAddressType.PUBLIC );
436    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
437    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
438                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
439    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
440
441    adData = ADData();
442    advertiser.advertiseData = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
443    advertiser.responseData  = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
444
445    success = advertiser.enable();
446    if success:
447        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
448        for address in devices:
449            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
450                                                                                      devices[address]["type"] ), devices[address]["name"]) );
451        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
452
453    success = success and advertiser.disable();
454
455    return success;
456
457"""
458    GAP/DISC/GENP/BV-02-C [General Discovery finding Limited Discoverable Device]
459"""
460def gap_disc_genp_bv_02_c(transport, upperTester, lowerTester, trace):
461
462    ownAddress = Address( ExtendedAddressType.PUBLIC );
463    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
464    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
465                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
466    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
467
468    adData = ADData();
469    advertiser.advertiseData = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
470    advertiser.responseData  = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
471
472    success = advertiser.enable();
473    if success:
474        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
475        for address in devices:
476            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
477                                                                                      devices[address]["type"] ), devices[address]["name"]) );
478        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
479
480    success = success and advertiser.disable();
481
482    return success;
483
484"""
485    GAP/DISC/GENP/BV-04-C [General Discovery not finding Undirected Connectable device]
486"""
487def gap_disc_genp_bv_04_c(transport, upperTester, lowerTester, trace):
488
489    ownAddress = Address( ExtendedAddressType.PUBLIC );
490    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
491    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
492                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
493    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
494
495    adData = ADData();
496    advertiser.advertiseData  = adData.encode( ADType.TX_POWER_LEVEL, -4 );
497    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
498    advertiser.responseData  = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
499
500    success = advertiser.enable();
501    if success:
502        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
503        for address in devices:
504            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
505                                                                                      devices[address]["type"] ), devices[address]["name"]) );
506        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
507        success = not success;
508
509    success = success and advertiser.disable();
510
511    return success;
512
513"""
514    GAP/DISC/GENP/BV-05-C [General Discovery not finding Directed Connectable device]
515"""
516def gap_disc_genp_bv_05_c(transport, upperTester, lowerTester, trace):
517
518    ownAddress = Address( ExtendedAddressType.PUBLIC );
519    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
520    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
521                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
522    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
523
524    adData = ADData();
525    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
526    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
527    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
528    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
529
530    success = advertiser.enable();
531    if success:
532        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
533        for address in devices:
534            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
535                                                                                      devices[address]["type"] ), devices[address]["name"]) );
536        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
537        success = not success;
538
539    success = success and advertiser.disable();
540
541    return success;
542
543"""
544    GAP/DISC/RPA/BV-01-C [Find Discoverable Device using Resolvable Private Address]
545"""
546def gap_disc_rpa_bv_01_c(transport, upperTester, lowerTester, trace):
547
548    """
549        Add Public address of lowerTester to upperTesters Resolving List
550        Add Public address of upperTester to lowerTesters Resolving List (to allow the Controller to generate a Private Resolvable Address)
551    """
552    RPAs = [ ResolvableAddresses( transport, upperTester, trace ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ];
553    success = RPAs[upperTester].clear() and RPAs[lowerTester].clear();
554    success = success and RPAs[lowerTester].add( Address( SimpleAddressType.PUBLIC, 0x123456789ABC ) );
555    success = success and RPAs[upperTester].add( Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ), lowerIRK );
556    """
557        Set Resolvable Private Address timeout in seconds ( sixty seconds )
558    """
559    success = success and RPAs[upperTester].timeout( 60 ) and RPAs[lowerTester].timeout(60);
560    success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable();
561    """
562        Scan interval should be three times the average Advertise interval. Scan window should be the maximum possible.
563    """
564    ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC );
565    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
566    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
567                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
568    scanner = Scanner(transport, upperTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
569
570    adData = ADData();
571    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
572    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
573    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
574    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
575
576    success = advertiser.enable();
577    if success:
578        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
579        for address in devices:
580            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
581                                                                                      devices[address]["type"] ), devices[address]["name"]) );
582        trace.trace(6, "Received %d advertising reports; %d scan responses" % (scanner.reports, scanner.responses));
583
584    success = success and advertiser.disable();
585    success = success and RPAs[upperTester].disable() and RPAs[lowerTester].disable();
586
587    return success;
588
589"""
590    GAP/CONN/NCON/BV-01-C [Non-Connectable Mode]
591"""
592def gap_conn_ncon_bv_01_c(transport, upperTester, lowerTester, trace):
593
594    ownAddress = Address( ExtendedAddressType.PUBLIC );
595    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
596    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
597                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
598    initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x123456789ABC ));
599
600    adData = ADData();
601    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.BR_EDR_NOT_SUPPORTED );
602    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
603    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
604    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
605    """
606        Attempt to initiate connection with Advertiser
607    """
608    success = advertiser.enable();
609    connected = initiator.connect();
610    success = success and not connected;
611    success = success and advertiser.disable();
612
613    return success;
614
615"""
616    GAP/CONN/NCON/BV-02-C [Non-Connectable Mode and  General Discoverable Mode]
617"""
618def gap_conn_ncon_bv_02_c(transport, upperTester, lowerTester, trace):
619
620    ownAddress = Address( ExtendedAddressType.PUBLIC );
621    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
622    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
623                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
624    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
625
626    adData = ADData();
627    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
628    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
629    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
630    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
631
632    success = advertiser.enable();
633    if success:
634        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
635        for address in devices:
636            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
637                                                                                      devices[address]["type"] ), devices[address]["name"]) );
638
639        if success:
640            address = next(iter(devices));
641            """
642                Attempt to initiate connection with Advertiser
643            """
644            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
645            connected = initiator.connect();
646            success = success and not connected;
647
648    success = success and advertiser.disable();
649
650    return success;
651
652"""
653    GAP/CONN/NCON/BV-03-C [Non-Connectable Mode and  Limited Discoverable Mode]
654"""
655def gap_conn_ncon_bv_03_c(transport, upperTester, lowerTester, trace):
656
657    ownAddress = Address( ExtendedAddressType.PUBLIC );
658    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
659    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.NON_CONNECTABLE_UNDIRECTED, \
660                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
661    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
662
663    adData = ADData();
664    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
665    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
666    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
667    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
668
669    success = advertiser.enable();
670    if success:
671        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
672        for address in devices:
673            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
674                                                                                      devices[address]["type"] ), devices[address]["name"]) );
675
676        if success:
677            address = next(iter(devices));
678            """
679                Attempt to initiate connection with Advertiser
680            """
681            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
682            connected = initiator.connect();
683            success = success and not connected;
684
685    success = success and advertiser.disable();
686
687    return success;
688
689"""
690    GAP/CONN/DCON/BV-01-C [Directed Connectable Mode]
691"""
692def gap_conn_dcon_bv_01_c(transport, upperTester, lowerTester, trace):
693
694    ownAddress = Address( ExtendedAddressType.PUBLIC );
695    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
696    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
697                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
698    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_DIRECT_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
699
700    success = advertising = advertiser.enable();
701
702    if success:
703        success, devices = scanner.discover( 2000 );
704        for address in devices:
705            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
706                                                                                      devices[address]["type"] ), devices[address]["name"]) );
707
708        if success:
709            address = next(iter(devices));
710            """
711                Attempt to initiate connection with Advertiser
712            """
713            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
714            connected = initiator.connect();
715            success = success and connected;
716            advertising = not connected;
717
718            if connected:
719                connected = not initiator.disconnect(0x13);
720                success = success and not connected;
721
722    if advertising:
723        advertiser.disable();
724
725    return success;
726
727"""
728    GAP/CONN/UCON/BV-01-C [Undirected Connectable Mode and Non-Discoverable Mode]
729"""
730def gap_conn_ucon_bv_01_c(transport, upperTester, lowerTester, trace):
731
732    ownAddress = Address( ExtendedAddressType.PUBLIC );
733    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
734    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
735                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
736    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
737
738    adData = ADData();
739    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.BR_EDR_NOT_SUPPORTED );
740    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
741    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
742    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
743
744    success = advertising = advertiser.enable();
745
746    if success:
747        success, devices = scanner.discover( 2000 );
748        for address in devices:
749            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
750                                                                                      devices[address]["type"] ), devices[address]["name"]) );
751
752        if success:
753            address = next(iter(devices));
754            """
755                Attempt to initiate connection with Advertiser
756            """
757            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
758            connected = initiator.connect();
759            success = success and connected;
760            advertising = not connected;
761
762            connected = not initiator.disconnect(0x13);
763            success = success and not connected;
764
765    if advertising:
766        advertiser.disable();
767
768    return success;
769
770"""
771    GAP/CONN/UCON/BV-02-C [Undirected Connectable Mode and General Discoverable Mode]
772"""
773def gap_conn_ucon_bv_02_c(transport, upperTester, lowerTester, trace):
774
775    ownAddress = Address( ExtendedAddressType.PUBLIC );
776    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
777    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
778                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
779    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
780
781    adData = ADData();
782    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
783    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
784    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
785    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
786
787    success = advertising = advertiser.enable();
788
789    if success:
790        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
791        for address in devices:
792            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
793                                                                                      devices[address]["type"] ), devices[address]["name"]) );
794
795        if success:
796            address = next(iter(devices));
797            """
798                Attempt to initiate connection with Advertiser
799            """
800            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
801            connected = initiator.connect();
802            success = success and connected;
803            advertising = not connected;
804
805            connected = not initiator.disconnect(0x13);
806            success = success and not connected;
807
808    if advertising:
809        advertiser.disable();
810
811    return success;
812
813"""
814    GAP/CONN/UCON/BV-03-C [Undirected Connectable Mode and Limited Discoverable Mode]
815"""
816def gap_conn_ucon_bv_03_c(transport, upperTester, lowerTester, trace):
817
818    ownAddress = Address( ExtendedAddressType.PUBLIC );
819    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
820    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
821                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
822    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1 );
823
824    adData = ADData();
825    advertiser.advertiseData  = adData.encode( ADType.FLAGS, ADFlag.LE_LIMITED_DISCOVERABLE | ADFlag.BR_EDR_NOT_SUPPORTED );
826    advertiser.advertiseData += adData.encode( ADType.TX_POWER_LEVEL, -4 );
827    advertiser.advertiseData += adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
828    advertiser.responseData   = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Flødebolle' );
829
830    success = advertising = advertiser.enable();
831
832    if success:
833        success, devices = scanner.discover( 2000, ADFlag.LE_GENERAL_DISCOVERABLE | ADFlag.LE_LIMITED_DISCOVERABLE );
834        for address in devices:
835            trace.trace(6, "Found device with address: %s complete local name: %s" % (formatAddress( toArray( address, 6 ), \
836                                                                                      devices[address]["type"] ), devices[address]["name"]) );
837
838        if success:
839            address = next(iter(devices));
840            """
841                Attempt to initiate connection with Advertiser
842            """
843            initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( devices[address]["type"], address ));
844            connected = initiator.connect();
845            success = success and connected;
846            advertising = not connected;
847
848            connected = not initiator.disconnect(0x13);
849            success = success and not connected;
850
851    if advertising:
852        advertiser.disable();
853
854    return success;
855
856"""
857    GAP/CONN/ACEP/BV-01-C [Auto Connection Establishment with Directed Connectable Mode]
858"""
859def gap_conn_acep_bv_01_c(transport, upperTester, lowerTester, trace):
860
861    """
862        Place Public address of lowerTester in the White List for the Scanner
863    """
864    addresses = [[ SimpleAddressType.PUBLIC, 0x456789ABCDEF ]];
865    success = preamble_specific_white_listed(transport, upperTester, addresses, trace);
866
867    ownAddress = Address( ExtendedAddressType.PUBLIC );
868    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
869    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
870                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
871    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), \
872                          Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ), InitiatorFilterPolicy.FILTER_WHITE_LIST_ONLY);
873
874    advertising = advertiser.enable();
875    success = success and advertising;
876
877    if success:
878        connected = initiator.connect();
879        success = success and connected;
880        advertising = not connected;
881
882        connected = not initiator.disconnect(0x13);
883        success = success and not connected;
884
885    if advertising:
886        advertiser.disable();
887
888    return success;
889
890"""
891    GAP/CONN/ACEP/BV-03-C [Auto Connection Establishment with Directed Connectable Mode, Resolvable Private Address, Central Address Resolution]
892"""
893def gap_conn_acep_bv_03_c(transport, upperTester, lowerTester, trace):
894
895    """
896        Add Public address of lowerTester to upperTesters Resolving List
897        Add Public address of upperTester to lowerTesters Resolving List (to allow the Controller to generate a Private Resolvable Address)
898    """
899    RPAs = [ ResolvableAddresses( transport, upperTester, trace ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ];
900    success = RPAs[upperTester].clear() and RPAs[lowerTester].clear();
901    success = success and RPAs[lowerTester].add( Address( SimpleAddressType.PUBLIC, 0x123456789ABC ) );
902    success = success and RPAs[upperTester].add( Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ), lowerIRK );
903    """
904        Set Resolvable Private Address timeout in seconds ( sixty seconds )
905    """
906    success = success and RPAs[upperTester].timeout( 60 ) and RPAs[lowerTester].timeout(60);
907    success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable();
908    """
909        Place Public address of lowerTester in the White List for the Scanner
910    """
911    addresses = [[ SimpleAddressType.PUBLIC, 0x456789ABCDEF ]];
912    success = preamble_specific_white_listed(transport, upperTester, addresses, trace);
913
914    ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC );
915    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
916    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
917                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
918    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), \
919                          Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ), InitiatorFilterPolicy.FILTER_WHITE_LIST_ONLY);
920
921    advertising = advertiser.enable();
922    success = success and advertising;
923
924    if success:
925        connected = initiator.connect();
926        success = success and connected;
927        advertising = not connected;
928
929        connected = not initiator.disconnect(0x13);
930        success = success and not connected;
931
932    if advertising:
933        advertiser.disable();
934
935    success = success and RPAs[upperTester].disable() and RPAs[lowerTester].disable();
936
937    return success;
938
939"""
940    GAP/CONN/ACEP/BV-04-C [Auto Connection Establishment with Undirected Connectable Mode, Resolvable Private Address]
941"""
942def gap_conn_acep_bv_04_c(transport, upperTester, lowerTester, trace):
943
944    """
945        Add Public address of lowerTester to upperTesters Resolving List
946        Add Public address of upperTester to lowerTesters Resolving List (to allow the Controller to generate a Private Resolvable Address)
947    """
948    RPAs = [ ResolvableAddresses( transport, upperTester, trace ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ];
949    success = RPAs[upperTester].clear() and RPAs[lowerTester].clear();
950    success = success and RPAs[lowerTester].add( Address( SimpleAddressType.PUBLIC, 0x123456789ABC ) );
951    success = success and RPAs[upperTester].add( Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ), lowerIRK );
952    """
953        Set Resolvable Private Address timeout in seconds ( sixty seconds )
954    """
955    success = success and RPAs[upperTester].timeout( 60 ) and RPAs[lowerTester].timeout(60);
956    success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable();
957    """
958        Place Public address of lowerTester in the White List for the Scanner
959    """
960    addresses = [[ SimpleAddressType.PUBLIC, 0x456789ABCDEF ]];
961    success = preamble_specific_white_listed(transport, upperTester, addresses, trace);
962
963    ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC );
964    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
965    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
966                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
967    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), \
968                          Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ), InitiatorFilterPolicy.FILTER_WHITE_LIST_ONLY);
969
970    advertising = advertiser.enable();
971    success = success and advertising;
972
973    if success:
974        connected = initiator.connect();
975        success = success and connected;
976        advertising = not connected;
977
978        connected = not initiator.disconnect(0x13);
979        success = success and not connected;
980
981    if advertising:
982        advertiser.disable();
983
984    success = success and RPAs[upperTester].disable() and RPAs[lowerTester].disable();
985
986    return success;
987
988"""
989    GAP/CONN/GCEP/BV-01-C [General Connection Establishment with Directed Connectable Mode]
990"""
991def gap_conn_gcep_bv_01_c(transport, upperTester, lowerTester, trace):
992
993    ownAddress = Address( ExtendedAddressType.PUBLIC );
994    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
995    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
996                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
997    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ));
998
999    success = advertising = advertiser.enable();
1000    connected = initiator.connect()
1001    success = success and connected;
1002    advertising = not connected;
1003
1004    if connected:
1005        connected = not initiator.disconnect(0x13);
1006        success = success and not connected;
1007
1008    if advertising:
1009        advertiser.disable();
1010
1011    return success;
1012
1013"""
1014    GAP/CONN/GCEP/BV-02-C [General Connection Establishment with Undirected Connectable Mode]
1015"""
1016def gap_conn_gcep_bv_02_c(transport, upperTester, lowerTester, trace):
1017
1018    ownAddress = Address( ExtendedAddressType.PUBLIC );
1019    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
1020    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1021                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1022    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ));
1023
1024    success = advertising = advertiser.enable();
1025    connected = initiator.connect()
1026    success = success and connected;
1027    advertising = not connected;
1028
1029    if connected:
1030        connected = not initiator.disconnect(0x13);
1031        success = success and not connected;
1032
1033    if advertising:
1034        advertiser.disable();
1035
1036    return success;
1037
1038"""
1039    GAP/CONN/GCEP/BV-05-C [General Connection Establishment with Directed Connectable Mode, Resolvable Private Address, Central Address Resolution]
1040"""
1041def gap_conn_gcep_bv_05_c(transport, upperTester, lowerTester, trace):
1042
1043    """
1044        Add Public address of lowerTester to upperTesters Resolving List
1045        Add Public address of upperTester to lowerTesters Resolving List (to allow the Controller to generate a Private Resolvable Address)
1046    """
1047    RPAs = [ ResolvableAddresses( transport, upperTester, trace ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ];
1048    success = RPAs[upperTester].clear() and RPAs[lowerTester].clear();
1049    success = success and RPAs[lowerTester].add( Address( SimpleAddressType.PUBLIC, 0x123456789ABC ) );
1050    success = success and RPAs[upperTester].add( Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ), lowerIRK );
1051    """
1052        Set Resolvable Private Address timeout in seconds ( sixty seconds )
1053    """
1054    success = success and RPAs[upperTester].timeout( 60 ) and RPAs[lowerTester].timeout(60);
1055    success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable();
1056
1057    ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC );
1058    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
1059    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1060                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1061    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ));
1062
1063    success = advertising = advertiser.enable();
1064    connected = initiator.connect()
1065    success = success and connected;
1066    advertising = not connected;
1067
1068    if connected:
1069        connected = not initiator.disconnect(0x13);
1070        success = success and not connected;
1071
1072    if advertising:
1073        advertiser.disable();
1074
1075    success = success and RPAs[upperTester].disable() and RPAs[lowerTester].disable();
1076
1077    return success;
1078
1079"""
1080    GAP/CONN/GCEP/BV-06-C [General Connection Establishment with Undirected Connectable Mode, Resolvable Private Address]
1081"""
1082def gap_conn_gcep_bv_06_c(transport, upperTester, lowerTester, trace):
1083
1084    """
1085        Add Public address of lowerTester to upperTesters Resolving List
1086        Add Public address of upperTester to lowerTesters Resolving List (to allow the Controller to generate a Private Resolvable Address)
1087    """
1088    RPAs = [ ResolvableAddresses( transport, upperTester, trace ), ResolvableAddresses( transport, lowerTester, trace, lowerIRK ) ];
1089    success = RPAs[upperTester].clear() and RPAs[lowerTester].clear();
1090    success = success and RPAs[lowerTester].add( Address( SimpleAddressType.PUBLIC, 0x123456789ABC ) );
1091    success = success and RPAs[upperTester].add( Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF ), lowerIRK );
1092    """
1093        Set Resolvable Private Address timeout in seconds ( sixty seconds )
1094    """
1095    success = success and RPAs[upperTester].timeout( 60 ) and RPAs[lowerTester].timeout(60);
1096    success = success and RPAs[upperTester].enable() and RPAs[lowerTester].enable();
1097
1098    ownAddress = Address( ExtendedAddressType.RESOLVABLE_OR_PUBLIC );
1099    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
1100    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1101                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1102    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ));
1103
1104    success = advertising = advertiser.enable();
1105    connected = initiator.connect()
1106    success = success and connected;
1107    advertising = not connected;
1108
1109    if connected:
1110        connected = not initiator.disconnect(0x13);
1111        success = success and not connected;
1112
1113    if advertising:
1114        advertiser.disable();
1115
1116    success = success and RPAs[upperTester].disable() and RPAs[lowerTester].disable();
1117
1118    return success;
1119
1120"""
1121    GAP/CONN/CPUP/BV-01-C [Successful Peripheral initiated Connection Parameter Update]
1122"""
1123def gap_conn_cpup_bv_01_c(transport, upperTester, lowerTester, trace):
1124
1125    ownAddress = Address( ExtendedAddressType.PUBLIC )
1126    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF )
1127    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1128                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1129    initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x123456789ABC ))
1130
1131    success = advertising = advertiser.enable()
1132    connected = initiator.connect()
1133    success = success and connected
1134
1135    if connected:
1136        transport.wait(100)
1137        """
1138            Switch the roles, so that the upperTester initiates the Connection Parameter Update Procedure
1139        """
1140        initiator.switchRoles()
1141        """
1142            Setting new connection update parameters and send a LL_CONNECTION_PARAM_REQ
1143        """
1144        interval = 30
1145        timeout = 3000
1146        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1147        """
1148            Accept the LE Remote Connection Parameter Request Event by issuing a LL_CONNECTION_PARAM_RSP...
1149        """
1150        success = success and initiator.acceptUpdate()
1151        """
1152            Both lower and upper Tester should receive a LE Connection Update Complete Event...
1153        """
1154        success = success and initiator.updated()
1155
1156        transport.wait(100)
1157        initiator.resetRoles()
1158        disconnected = initiator.disconnect(0x13)
1159        success = success and disconnected
1160    else:
1161        advertiser.disable()
1162
1163    return success
1164
1165"""
1166    GAP/CONN/CPUP/BV-02-C [Timeout during Peripheral initiated Connection Parameter Update]
1167"""
1168def gap_conn_cpup_bv_02_c(transport, upperTester, lowerTester, trace):
1169
1170    ownAddress = Address( ExtendedAddressType.PUBLIC )
1171    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF )
1172    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1173                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1174    initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x123456789ABC ))
1175
1176    success = advertising = advertiser.enable()
1177    connected = initiator.connect()
1178    success = success and connected
1179
1180    if connected:
1181        transport.wait(100)
1182        """
1183            Switch the roles, so that the upperTester initiates the Connection Parameter Update Procedure
1184        """
1185        initiator.switchRoles()
1186        """
1187            Setting new connection update parameters and send a LL_CONNECTION_PARAM_REQ
1188        """
1189        interval = 30
1190        timeout = 3000
1191        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1192        """
1193            Verify if initiator received an LE Connection Update Complete Event
1194        """
1195        transport.wait(200)
1196        success = success and not initiator.updated()
1197        """
1198            IUT ignores error case and continues normal operation
1199        """
1200        initiator.resetRoles()
1201        disconnected = initiator.disconnect(0x13)
1202        success = success and disconnected
1203    else:
1204        advertiser.disable()
1205
1206    return success
1207
1208"""
1209    GAP/CONN/CPUP/BV-03-C [Invalid Parameters in Peripheral initiated Connection Parameter Update]
1210"""
1211def gap_conn_cpup_bv_03_c(transport, upperTester, lowerTester, trace):
1212
1213    ownAddress = Address( ExtendedAddressType.PUBLIC )
1214    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF )
1215    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1216                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1217    initiator = Initiator(transport, lowerTester, upperTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x123456789ABC ))
1218
1219    success = advertising = advertiser.enable()
1220    connected = initiator.connect()
1221    success = success and connected
1222
1223    if connected:
1224        transport.wait(100)
1225        initiator.switchRoles()
1226        """
1227            Setting invalid connection update parameters (timeout > max_timeout) and send a LL_CONNECTION_PARAM_REQ
1228        """
1229        interval = 30
1230        timeout = 3300
1231        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1232        """
1233            Try to accept the LE Remote Connection Parameter Request Event by issuing a LL_CONNECTION_PARAM_RSP...
1234        """
1235        success = success and not initiator.acceptUpdate()
1236        """
1237            The tester should not receive any LE Connection Update Complete Event...
1238        """
1239        success = success and not initiator.updated()
1240        """
1241            Close connection
1242        """
1243        initiator.resetRoles()
1244        disconnected = initiator.disconnect(0x13)
1245        success = success and disconnected
1246    else:
1247        advertiser.disable()
1248
1249    return success
1250
1251"""
1252    GAP/CONN/CPUP/BV-04-C [Successful Peripheral accepts Connection Parameter Update]
1253"""
1254def gap_conn_cpup_bv_04_c(transport, upperTester, lowerTester, trace):
1255
1256    ownAddress = Address( ExtendedAddressType.PUBLIC )
1257    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC )
1258    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1259                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1260    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ))
1261
1262    success = advertising = advertiser.enable()
1263    connected = initiator.connect()
1264    success = success and connected
1265
1266    if connected:
1267        transport.wait(100)
1268        initiator.switchRoles()
1269        """
1270            Setting invalid connection update parameters (timeout > max_timeout) and send a LL_CONNECTION_PARAM_REQ
1271        """
1272        interval = 30
1273        timeout = 3000
1274        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1275        """
1276            Try to accept the LE Remote Connection Parameter Request Event by issuing a LL_CONNECTION_PARAM_RSP...
1277        """
1278        success = success and initiator.acceptUpdate()
1279        """
1280            The testers should receive a Connection Update Complete Event...
1281        """
1282        success = success and initiator.updated()
1283        """
1284            Close connection
1285        """
1286        initiator.resetRoles()
1287        disconnected = initiator.disconnect(0x13)
1288        success = success and disconnected
1289    else:
1290        advertiser.disable()
1291
1292    return success
1293
1294"""
1295    GAP/CONN/CPUP/BV-05-C [Invalid Parameters in Peripheral receives Connection Parameter Update]
1296"""
1297def gap_conn_cpup_bv_05_c(transport, upperTester, lowerTester, trace):
1298
1299    ownAddress = Address( ExtendedAddressType.PUBLIC )
1300    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC )
1301    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1302                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1303    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ))
1304
1305    success = advertising = advertiser.enable()
1306    connected = initiator.connect()
1307    success = success and connected
1308
1309    if connected:
1310        transport.wait(100)
1311        initiator.switchRoles()
1312        """
1313            Setting invalid connection update parameters (timeout > max_timeout) and send a LL_CONNECTION_PARAM_REQ
1314        """
1315        interval = 30
1316        timeout = 3300
1317        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1318        """
1319            Accept the LE Remote Connection Parameter Request Event by issuing a LL_CONNECTION_PARAM_RSP...
1320        """
1321        success = success and not initiator.acceptUpdate()
1322        """
1323            The tester should not receive any LE Connection Update Complete Event...
1324        """
1325        success = success and not initiator.updated()
1326        """
1327            Close connection
1328        """
1329        initiator.resetRoles()
1330        disconnected = initiator.disconnect(0x13)
1331        success = success and disconnected
1332    else:
1333        advertiser.disable()
1334
1335    return success
1336
1337"""
1338    GAP/CONN/CPUP/BV-06-C [Successful Central initiated Connection Parameter Update]
1339"""
1340def gap_conn_cpup_bv_06_c(transport, upperTester, lowerTester, trace):
1341
1342    ownAddress = Address( ExtendedAddressType.PUBLIC )
1343    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC )
1344    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_LDC_DIRECTED, \
1345                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE)
1346    initiator = Initiator(transport, upperTester, lowerTester, trace, Address( ExtendedAddressType.PUBLIC ), Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF ))
1347
1348    success = advertising = advertiser.enable()
1349    connected = initiator.connect()
1350    success = success and connected
1351
1352    if connected:
1353        transport.wait(100)
1354        """
1355            Setting invalid connection update parameters (timeout > max_timeout) and send a LL_CONNECTION_PARAM_REQ
1356        """
1357        interval = 30
1358        timeout = 3000
1359        success = success and initiator.update(interval, interval, initiator.latency, timeout)
1360        """
1361            Accept the LE Remote Connection Parameter Request Event by issuing a LL_CONNECTION_PARAM_RSP...
1362        """
1363        success = success and initiator.acceptUpdate()
1364        """
1365            The testers should receive LE Connection Update Complete Events...
1366        """
1367        success = success and initiator.updated()
1368        """
1369            Close connection
1370        """
1371        disconnected = initiator.disconnect(0x13)
1372        success = success and disconnected
1373    else:
1374        advertiser.disable()
1375
1376    return success
1377
1378"""
1379    GAP/ADV/BV-01-C [Advertising with AD Type – Service UUID]
1380"""
1381def gap_adv_bv_01_c(transport, upperTester, lowerTester, trace):
1382
1383    ownAddress = Address( ExtendedAddressType.PUBLIC );
1384    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1385    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1386                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1387    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1388
1389    adData = ADData();
1390    advertiser.advertiseData = adData.encode( ADType.ILIST_UUIDS_16, 0x1234, 0x5678, 0x9ABC );
1391    advertiser.responseData = adData.encode( ADType.ILIST_UUIDS_16, 0x9ABC, 0x5678, 0x1234 );
1392
1393    success = advertiser.enable();
1394
1395    success = success and scanner.enable();
1396    scanner.monitor();
1397    success = success and scanner.disable();
1398    success = success and scanner.qualifyReports( 1 );
1399    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1400
1401    success = success and advertiser.disable();
1402
1403    advertiser.advertiseData = adData.encode( ADType.ILIST_UUIDS_128, 0x1429304977D74244AE6AD3873E4A3184 );
1404    advertiser.responseData = adData.encode( ADType.ILIST_UUIDS_128, 0x1429304977D74244AE6AD3873E4A3184 );
1405
1406    success = advertiser.enable();
1407
1408    success = success and scanner.enable();
1409    scanner.monitor();
1410    success = success and scanner.disable();
1411    success = success and scanner.qualifyReports( 1 );
1412    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1413
1414    success = success and advertiser.disable();
1415
1416    return success;
1417
1418"""
1419    GAP/ADV/BV-02-C [Advertising with AD Type - Local Name]
1420"""
1421def gap_adv_bv_02_c(transport, upperTester, lowerTester, trace):
1422
1423    ownAddress = Address( ExtendedAddressType.PUBLIC );
1424    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1425    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1426                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1427    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1428
1429    adData = ADData();
1430    advertiser.advertiseData = adData.encode( ADType.SHORTENED_LOCAL_NAME, 'Blåbær' );
1431    advertiser.responseData = adData.encode( ADType.COMPLETE_LOCAL_NAME, 'Rødgrød med fløde' );
1432
1433    success = advertiser.enable();
1434
1435    success = success and scanner.enable();
1436    scanner.monitor();
1437    success = success and scanner.disable();
1438    success = success and scanner.qualifyReports( 1 );
1439    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1440
1441    success = success and advertiser.disable();
1442
1443    return success;
1444
1445"""
1446    GAP/ADV/BV-03-C [Advertising with AD Type – Flags]
1447"""
1448def gap_adv_bv_03_c(transport, upperTester, lowerTester, trace):
1449
1450    ownAddress = Address( ExtendedAddressType.PUBLIC );
1451    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1452    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1453                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1454    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1455
1456    adData = ADData();
1457    advertiser.advertiseData = adData.encode( ADType.FLAGS, 0x06 );
1458    advertiser.responseData = adData.encode( ADType.FLAGS, 0x1F );
1459
1460    success = advertiser.enable();
1461
1462    success = success and scanner.enable();
1463    scanner.monitor();
1464    success = success and scanner.disable();
1465    success = success and scanner.qualifyReports( 1 );
1466    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1467
1468    success = success and advertiser.disable();
1469
1470    return success;
1471
1472"""
1473    GAP/ADV/BV-04-C [Advertising with AD Type – Manufacturer Specific Packet Data]
1474"""
1475def gap_adv_bv_04_c(transport, upperTester, lowerTester, trace):
1476
1477    ownAddress = Address( ExtendedAddressType.PUBLIC );
1478    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1479    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1480                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1481    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1482
1483    adData = ADData();
1484    advertiser.advertiseData = adData.encode( ADType.MANUFACTURER_DATA, 0x0107, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 ); # Manufacturer Oticon
1485    advertiser.responseData = adData.encode( ADType.MANUFACTURER_DATA, 0x0107, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 ); # Manufacturer Oticon
1486
1487    success = advertiser.enable();
1488
1489    success = success and scanner.enable();
1490    scanner.monitor();
1491    success = success and scanner.disable();
1492    success = success and scanner.qualifyReports( 1 );
1493    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1494
1495    success = success and advertiser.disable();
1496
1497    return success;
1498
1499"""
1500    GAP/ADV/BV-05-C [Advertising with AD Type – TX Power Level]
1501"""
1502def gap_adv_bv_05_c(transport, upperTester, lowerTester, trace):
1503
1504    ownAddress = Address( ExtendedAddressType.PUBLIC );
1505    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1506    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1507                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1508    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1509
1510    adData = ADData();
1511    advertiser.advertiseData = adData.encode( ADType.TX_POWER_LEVEL, -20 );
1512    advertiser.responseData = adData.encode( ADType.TX_POWER_LEVEL, -40 );
1513
1514    success = advertiser.enable();
1515
1516    success = success and scanner.enable();
1517    scanner.monitor();
1518    success = success and scanner.disable();
1519    success = success and scanner.qualifyReports( 1 );
1520    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1521
1522    success = success and advertiser.disable();
1523
1524    return success;
1525
1526"""
1527    GAP/ADV/BV-08-C [Advertising with AD Type – Slave Connection Interval Range]
1528"""
1529def gap_adv_bv_08_c(transport, upperTester, lowerTester, trace):
1530
1531    ownAddress = Address( ExtendedAddressType.PUBLIC );
1532    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1533    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1534                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1535    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1536
1537    adData = ADData();
1538    advertiser.advertiseData = adData.encode( ADType.SLAVE_CONNECT_INT, 20, 40 );
1539    advertiser.responseData = adData.encode( ADType.SLAVE_CONNECT_INT, 10, 50 );
1540
1541    success = advertiser.enable();
1542
1543    success = success and scanner.enable();
1544    scanner.monitor();
1545    success = success and scanner.disable();
1546    success = success and scanner.qualifyReports( 1 );
1547    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1548
1549    success = success and advertiser.disable();
1550
1551    return success;
1552
1553"""
1554    GAP/ADV/BV-09-C [Advertising with AD Type - Service Solicitation]
1555"""
1556def gap_adv_bv_09_c(transport, upperTester, lowerTester, trace):
1557
1558    ownAddress = Address( ExtendedAddressType.PUBLIC );
1559    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1560    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1561                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1562    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1563
1564    adData = ADData();
1565    advertiser.advertiseData = adData.encode( ADType.SS_UUIDS_16, 0x1234, 0x5678, 0x9ABC );
1566    advertiser.responseData = adData.encode( ADType.SS_UUIDS_128, 0x1429304977D74244AE6AD3873E4A3184 );
1567
1568    success = advertiser.enable();
1569
1570    success = success and scanner.enable();
1571    scanner.monitor();
1572    success = success and scanner.disable();
1573    success = success and scanner.qualifyReports( 1 );
1574    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1575
1576    success = success and advertiser.disable();
1577
1578    return success;
1579
1580"""
1581    GAP/ADV/BV-10-C [Advertising with AD Type – Service Packet Data]
1582"""
1583def gap_adv_bv_10_c(transport, upperTester, lowerTester, trace):
1584
1585    ownAddress = Address( ExtendedAddressType.PUBLIC );
1586    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1587    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1588                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1589    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1590
1591    adData = ADData();
1592    advertiser.advertiseData = adData.encode( ADType.SERVICE_DATA_16, 0x1234, 0x01, 0x02, 0x03 );
1593    advertiser.responseData = adData.encode( ADType.SERVICE_DATA_128, 0x1429304977D74244AE6AD3873E4A3184, 0x04, 0x05, 0x06 );
1594
1595    success = advertiser.enable();
1596
1597    success = success and scanner.enable();
1598    scanner.monitor();
1599    success = success and scanner.disable();
1600    success = success and scanner.qualifyReports( 1 );
1601    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1602
1603    success = success and advertiser.disable();
1604
1605    return success;
1606
1607"""
1608    GAP/ADV/BV-11-C [Advertising with AD Type – Appearance]
1609"""
1610def gap_adv_bv_11_c(transport, upperTester, lowerTester, trace):
1611
1612    ownAddress = Address( ExtendedAddressType.PUBLIC );
1613    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1614    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1615                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1616    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1617
1618    adData = ADData();
1619    advertiser.advertiseData = adData.encode( ADType.APPEARANCE, 640 );  # Media Player
1620    advertiser.responseData = adData.encode( ADType.APPEARANCE, 832 );   # Heart rate Sensor
1621
1622    success = advertiser.enable();
1623
1624    success = success and scanner.enable();
1625    scanner.monitor();
1626    success = success and scanner.disable();
1627    success = success and scanner.qualifyReports( 1 );
1628    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1629
1630    success = success and advertiser.disable();
1631
1632    return success;
1633
1634"""
1635    GAP/ADV/BV-12-C [Advertising with AD Type – Public Target Address]
1636"""
1637def gap_adv_bv_12_c(transport, upperTester, lowerTester, trace):
1638
1639    ownAddress = Address( ExtendedAddressType.PUBLIC );
1640    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1641    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1642                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1643    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1644
1645    adData = ADData();
1646    advertiser.advertiseData = adData.encode( ADType.PUBLIC_ADDRESS, 0x456789ABCDEF, 0x123456789ABC );
1647    advertiser.responseData = adData.encode( ADType.PUBLIC_ADDRESS, 0x123456789ABC, 0x456789ABCDEF );
1648
1649    success = advertiser.enable();
1650
1651    success = success and scanner.enable();
1652    scanner.monitor();
1653    success = success and scanner.disable();
1654    success = success and scanner.qualifyReports( 1 );
1655    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1656
1657    success = success and advertiser.disable();
1658
1659    return success;
1660
1661"""
1662    GAP/ADV/BV-13-C [Advertising with AD Type – Random Target Address]
1663"""
1664def gap_adv_bv_13_c(transport, upperTester, lowerTester, trace):
1665
1666    ownAddress = Address( ExtendedAddressType.PUBLIC );
1667    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1668    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1669                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1670    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1671
1672    adData = ADData();
1673    advertiser.advertiseData = adData.encode( ADType.RANDOM_ADDRESS, 0x456789ABCDEF, 0x123456789ABC );
1674    advertiser.responseData = adData.encode( ADType.RANDOM_ADDRESS, 0x123456789ABC, 0x456789ABCDEF );
1675
1676    success = advertiser.enable();
1677
1678    success = success and scanner.enable();
1679    scanner.monitor();
1680    success = success and scanner.disable();
1681    success = success and scanner.qualifyReports( 1 );
1682    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1683
1684    success = success and advertiser.disable();
1685
1686    return success;
1687
1688"""
1689    GAP/ADV/BV-14-C [Advertising with AD Type – Advertising Interval]
1690"""
1691def gap_adv_bv_14_c(transport, upperTester, lowerTester, trace):
1692
1693    ownAddress = Address( ExtendedAddressType.PUBLIC );
1694    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1695    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1696                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1697    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1698
1699    adData = ADData();
1700    advertiser.advertiseData = adData.encode( ADType.ADVERTISE_INT, 20 );
1701    advertiser.responseData = adData.encode( ADType.ADVERTISE_INT, 10 );
1702
1703    success = advertiser.enable();
1704
1705    success = success and scanner.enable();
1706    scanner.monitor();
1707    success = success and scanner.disable();
1708    success = success and scanner.qualifyReports( 1 );
1709    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1710
1711    success = success and advertiser.disable();
1712
1713    return success;
1714
1715"""
1716    GAP/ADV/BV-15-C [Advertising with AD Type – LE Bluetooth Device Address]
1717"""
1718def gap_adv_bv_15_c(transport, upperTester, lowerTester, trace):
1719
1720    ownAddress = Address( ExtendedAddressType.PUBLIC );
1721    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1722    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1723                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1724    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1725
1726    adData = ADData();
1727    advertiser.advertiseData = adData.encode( ADType.DEVICE_ADDRESS, 0x123456789ABC, 0 ); # Public Device Address
1728    advertiser.responseData = adData.encode( ADType.DEVICE_ADDRESS, 0x123456789ABC, 1 );  # Random Device Address
1729
1730    success = advertiser.enable();
1731
1732    success = success and scanner.enable();
1733    scanner.monitor();
1734    success = success and scanner.disable();
1735    success = success and scanner.qualifyReports( 1 );
1736    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1737
1738    success = success and advertiser.disable();
1739
1740    return success;
1741
1742"""
1743    GAP/ADV/BV-16-C [Advertising with AD Type – LE Role]
1744"""
1745def gap_adv_bv_16_c(transport, upperTester, lowerTester, trace):
1746
1747    ownAddress = Address( ExtendedAddressType.PUBLIC );
1748    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1749    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1750                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1751    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1752
1753    adData = ADData();
1754    advertiser.advertiseData = adData.encode( ADType.DEVICE_ROLE, ADRole.CENTRAL_PREFERRED );
1755    advertiser.responseData = adData.encode( ADType.DEVICE_ROLE, ADRole.PERIPHERAL_PREFERRED );
1756
1757    success = advertiser.enable();
1758
1759    success = success and scanner.enable();
1760    scanner.monitor();
1761    success = success and scanner.disable();
1762    success = success and scanner.qualifyReports( 1 );
1763    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1764
1765    success = success and advertiser.disable();
1766
1767    return success;
1768
1769"""
1770    GAP/ADV/BV-17-C [Advertising with AD Type – URI]
1771"""
1772def gap_adv_bv_17_c(transport, upperTester, lowerTester, trace):
1773
1774    ownAddress = Address( ExtendedAddressType.PUBLIC );
1775    peerAddress = Address( SimpleAddressType.PUBLIC, 0x456789ABCDEF );
1776    advertiser = Advertiser(transport, upperTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1777                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1778    scanner = Scanner(transport, lowerTester, trace, ScanType.ACTIVE, AdvertisingReport.ADV_IND, ownAddress, ScanningFilterPolicy.FILTER_NONE, 1, 1);
1779
1780    adData = ADData();
1781    advertiser.advertiseData = adData.encode( ADType.URI, 'http://www.bluetooth.org' );
1782    advertiser.responseData = adData.encode( ADType.URI, 'example://z.com/Ålborg' );
1783
1784    success = advertiser.enable();
1785
1786    success = success and scanner.enable();
1787    scanner.monitor();
1788    success = success and scanner.disable();
1789    success = success and scanner.qualifyReports( 1 );
1790    success = success and scanner.qualifyResponses( 1, advertiser.responseData );
1791
1792    success = success and advertiser.disable();
1793
1794    return success;
1795
1796"""
1797    GAP/CONN/ENC [Testing encryption]
1798"""
1799def gap_conn_enc(transport, upperTester, lowerTester, trace):
1800
1801    ownAddress = Address( ExtendedAddressType.PUBLIC );
1802    peerAddress = Address( SimpleAddressType.PUBLIC, 0x123456789ABC );
1803    advertiser = Advertiser(transport, lowerTester, trace, AdvertiseChannel.ALL_CHANNELS, Advertising.CONNECTABLE_UNDIRECTED, \
1804                            ownAddress, peerAddress, AdvertisingFilterPolicy.FILTER_NONE);
1805    ownAddress = Address( ExtendedAddressType.PUBLIC, 0x123456789ABC );
1806    peerAddress = Address( IdentityAddressType.PUBLIC, 0x456789ABCDEF );
1807    initiator = Initiator(transport, upperTester, lowerTester, trace, ownAddress, peerAddress);
1808
1809    success = advertising = advertiser.enable();
1810    connected = initiator.connect()
1811    success = success and connected;
1812    advertising = not connected;
1813
1814    pairing = Pairing(transport, trace, initiator, toNumber(upperIRK), toNumber(lowerIRK));
1815    success = pairing.pair();
1816    if success:
1817        trace.trace(6, "Link encrypted using LE Legacy Pairing...");
1818        success = pairing.pause();
1819        if success:
1820            trace.trace(6, "Link re-encrytpted using LE Legacy Pairing...");
1821        else:
1822            trace.trace(6, "Failed to re-encrypt link using LE Legacy Pairing!");
1823    else:
1824        trace.trace(6, "Failed to encrypt link using LE Legacy Pairing!");
1825
1826    if connected:
1827        connected = not initiator.disconnect(0x13);
1828        success = success and not connected;
1829
1830    if advertising:
1831        advertiser.disable();
1832
1833    return success;
1834
1835__tests__ = {
1836    "GAP/ADV/BV-01-C":       [ gap_adv_bv_01_c,       "Advertising with AD Type – Service UUID" ],
1837    "GAP/ADV/BV-02-C":       [ gap_adv_bv_02_c,       "Advertising with AD Type - Local Name" ],
1838    "GAP/ADV/BV-03-C":       [ gap_adv_bv_03_c,       "Advertising with AD Type – Flags" ],
1839    "GAP/ADV/BV-04-C":       [ gap_adv_bv_04_c,       "Advertising with AD Type – Manufacturer Specific Packet Data" ],
1840    "GAP/ADV/BV-05-C":       [ gap_adv_bv_05_c,       "Advertising with AD Type – TX Power Level" ],
1841    "GAP/ADV/BV-08-C":       [ gap_adv_bv_08_c,       "Advertising with AD Type – Slave Connection Interval Range" ],
1842    "GAP/ADV/BV-09-C":       [ gap_adv_bv_09_c,       "Advertising with AD Type - Service Solicitation" ],
1843    "GAP/ADV/BV-10-C":       [ gap_adv_bv_10_c,       "Advertising with AD Type – Service Packet Data" ],
1844    "GAP/ADV/BV-11-C":       [ gap_adv_bv_11_c,       "Advertising with AD Type – Appearance" ],
1845    "GAP/ADV/BV-12-C":       [ gap_adv_bv_12_c,       "Advertising with AD Type – Public Target Address" ],
1846    "GAP/ADV/BV-13-C":       [ gap_adv_bv_13_c,       "Advertising with AD Type – Random Target Address" ],
1847    "GAP/ADV/BV-14-C":       [ gap_adv_bv_14_c,       "Advertising with AD Type – Advertising Interval" ],
1848    "GAP/ADV/BV-15-C":       [ gap_adv_bv_15_c,       "Advertising with AD Type – LE Bluetooth Device Address" ],
1849    "GAP/ADV/BV-16-C":       [ gap_adv_bv_16_c,       "Advertising with AD Type – LE Role" ],
1850    "GAP/ADV/BV-17-C":       [ gap_adv_bv_17_c,       "Advertising with AD Type – URI" ],
1851    "GAP/CONN/ACEP/BV-01-C": [ gap_conn_acep_bv_01_c, "Auto Connection Establishment with Directed Connectable Mode" ],
1852    "GAP/CONN/ACEP/BV-03-C": [ gap_conn_acep_bv_03_c, "Auto Connection Establishment with Directed Connectable Mode, Resolvable Private Address, Central Address Resolution" ],
1853    "GAP/CONN/ACEP/BV-04-C": [ gap_conn_acep_bv_04_c, "Auto Connection Establishment with Undirected Connectable Mode, Resolvable Private Address" ],
1854    "GAP/CONN/DCON/BV-01-C": [ gap_conn_dcon_bv_01_c, "Directed Connectable Mode" ],
1855#   "GAP/CONN/ENC":          [ gap_conn_enc,          "Testing encryption" ],
1856    "GAP/CONN/GCEP/BV-01-C": [ gap_conn_gcep_bv_01_c, "General Connection Establishment with Directed Connectable Mode" ],
1857    "GAP/CONN/GCEP/BV-02-C": [ gap_conn_gcep_bv_02_c, "General Connection Establishment with Undirected Connectable Mode" ],
1858    "GAP/CONN/GCEP/BV-05-C": [ gap_conn_gcep_bv_05_c, "General Connection Establishment with Directed Connectable Mode, Resolvable Private Address, Central Address Resolution" ],
1859    "GAP/CONN/GCEP/BV-06-C": [ gap_conn_gcep_bv_06_c, "General Connection Establishment with Undirected Connectable Mode, Resolvable Private Address" ],
1860    "GAP/CONN/CPUP/BV-01-C": [ gap_conn_cpup_bv_01_c, "Successful Peripheral initiated Connection Parameter Update" ],
1861    "GAP/CONN/CPUP/BV-02-C": [ gap_conn_cpup_bv_02_c, "Timeout during Peripheral initiated Connection Parameter Update" ],
1862    "GAP/CONN/CPUP/BV-03-C": [ gap_conn_cpup_bv_03_c, "Invalid Parameters in Peripheral initiated Connection Parameter Update" ],
1863    "GAP/CONN/CPUP/BV-04-C": [ gap_conn_cpup_bv_04_c, "Successful Peripheral accepts Connection Parameter Update" ],
1864    "GAP/CONN/CPUP/BV-05-C": [ gap_conn_cpup_bv_05_c, "Invalid Parameters in Peripheral receives Connection Parameter Update" ],
1865    "GAP/CONN/CPUP/BV-06-C": [ gap_conn_cpup_bv_06_c, "Successful Central initiated Connection Parameter Update" ],
1866    "GAP/CONN/NCON/BV-01-C": [ gap_conn_ncon_bv_01_c, "Non-Connectable Mode" ],
1867    "GAP/CONN/NCON/BV-02-C": [ gap_conn_ncon_bv_02_c, "Non-Connectable Mode and  General Discoverable Mode" ],
1868    "GAP/CONN/NCON/BV-03-C": [ gap_conn_ncon_bv_03_c, "Non-Connectable Mode and  Limited Discoverable Mode" ],
1869    "GAP/CONN/UCON/BV-01-C": [ gap_conn_ucon_bv_01_c, "Undirected Connectable Mode and Non-Discoverable Mode" ],
1870    "GAP/CONN/UCON/BV-02-C": [ gap_conn_ucon_bv_02_c, "Undirected Connectable Mode and General Discoverable Mode" ],
1871    "GAP/CONN/UCON/BV-03-C": [ gap_conn_ucon_bv_03_c, "Undirected Connectable Mode and Limited Discoverable Mode" ],
1872    "GAP/DISC/GENM/BV-01-C": [ gap_disc_genm_bv_01_c, "General Discoverable Mode and Non-Connectable Mode in BR/EDR/LE configuration" ],
1873    "GAP/DISC/GENM/BV-02-C": [ gap_disc_genm_bv_02_c, "General Discoverable Mode and Undirected Connectable Mode in BR/EDR/LE configuration" ],
1874    "GAP/DISC/GENM/BV-03-C": [ gap_disc_genm_bv_03_c, "General Discoverable Mode and Non-Connectable Mode in LE Only configuration" ],
1875    "GAP/DISC/GENM/BV-04-C": [ gap_disc_genm_bv_04_c, "General Discoverable Mode and Undirected Connectable Mode in LE Only configuration" ],
1876    "GAP/DISC/GENP/BV-01-C": [ gap_disc_genp_bv_01_c, "General Discovery finding General Discoverable Device" ],
1877    "GAP/DISC/GENP/BV-02-C": [ gap_disc_genp_bv_02_c, "General Discovery finding Limited Discoverable Device" ],
1878    "GAP/DISC/GENP/BV-04-C": [ gap_disc_genp_bv_04_c, "General Discovery not finding Undirected Connectable device" ],
1879    "GAP/DISC/GENP/BV-05-C": [ gap_disc_genp_bv_05_c, "General Discovery not finding Directed Connectable device" ],
1880    "GAP/DISC/LIMM/BV-01-C": [ gap_disc_limm_bv_01_c, "Limited Discoverable Mode and Non-Connectable Mode in BR/EDR/LE configuration" ],
1881    "GAP/DISC/LIMM/BV-02-C": [ gap_disc_limm_bv_02_c, "Limited Discoverable Mode and Undirected Connectable Mode in BR/EDR/LE configuration" ],
1882    "GAP/DISC/LIMM/BV-03-C": [ gap_disc_limm_bv_03_c, "Limited Discoverable Mode and Non-Connectable Mode in LE Only configuration" ],
1883    "GAP/DISC/LIMM/BV-04-C": [ gap_disc_limm_bv_04_c, "Limited Discoverable Mode and Undirected Connectable Mode in LE Only configuration" ],
1884    "GAP/DISC/LIMP/BV-01-C": [ gap_disc_limp_bv_01_c, "Limited Discovery finding Limited Discoverable Device" ],
1885    "GAP/DISC/LIMP/BV-02-C": [ gap_disc_limp_bv_02_c, "Limited Discovery not finding General Discoverable Device" ],
1886    "GAP/DISC/LIMP/BV-04-C": [ gap_disc_limp_bv_04_c, "Limited Discovery not finding Undirected Connectable device" ],
1887    "GAP/DISC/LIMP/BV-05-C": [ gap_disc_limp_bv_05_c, "Limited Discovery not finding Directed Connectable device" ],
1888    "GAP/DISC/NONM/BV-01-C": [ gap_disc_nonm_bv_01_c, "Non-discoverable Mode and Non-Connectable Mode" ],
1889    "GAP/DISC/NONM/BV-02-C": [ gap_disc_nonm_bv_02_c, "Non-discoverable Mode and Undirected Connectable Mode" ],
1890    "GAP/DISC/RPA/BV-01-C":  [ gap_disc_rpa_bv_01_c,  "Find Discoverable Device using Resolvable Private Address" ]
1891};
1892
1893_maxNameLength = max([ len(key) for key in __tests__ ]);
1894
1895_spec = { key: TestSpec(name = key, number_devices = 2, description = "#[" + __tests__[key][1] + "]", test_private = __tests__[key][0]) for key in __tests__ };
1896
1897
1898"""
1899    Return the test spec which contains info about all the tests
1900    this test module provides
1901"""
1902def get_tests_specs():
1903    return _spec;
1904
1905def preamble(transport, trace):
1906    global lowerIRK, upperIRK, lowerRandomAddress, upperRandomAddress;
1907
1908    ok = success = preamble_standby(transport, 0, trace);
1909    trace.trace(4, "preamble Standby " + ("PASS" if success else "FAIL"));
1910    success = preamble_standby(transport, 1, trace);
1911    ok = ok and success;
1912    trace.trace(4, "preamble Standby " + ("PASS" if success else "FAIL"));
1913    success, upperIRK, upperRandomAddress = preamble_device_address_set(transport, 0, trace);
1914    trace.trace(4, "preamble Device Address Set " + ("PASS" if success else "FAIL"));
1915    ok = ok and success;
1916    success, lowerIRK, lowerRandomAddress = preamble_device_address_set(transport, 1, trace);
1917    trace.trace(4, "preamble Device Address Set " + ("PASS" if success else "FAIL"));
1918    return ok and success;
1919
1920"""
1921    Run a test given its test_spec
1922"""
1923def run_a_test(args, transport, trace, test_spec):
1924    try:
1925        success = preamble(transport, trace);
1926    except Exception as e:
1927        trace.trace(3, "Preamble generated exception: %s" % str(e));
1928        success = False;
1929
1930    trace.trace(2, "%-*s %s test started..." % (_maxNameLength, test_spec.name, test_spec.description[1:]));
1931    test_f = test_spec.test_private;
1932    try:
1933        if test_f.__code__.co_argcount > 3:
1934            success = success and test_f(transport, 0, 1, trace);
1935        else:
1936            success = success and test_f(transport, 0, trace);
1937    except Exception as e:
1938        import traceback
1939        traceback.print_exc()
1940        trace.trace(3, "Test generated exception: %s" % str(e));
1941        success = False;
1942
1943    return not success
1944