1# -*- coding: utf-8 -*-
2# Copyright 2019 Oticon A/S
3# SPDX-License-Identifier: Apache-2.0
4
5import struct;
6from enum import IntEnum;
7from itertools import chain;
8from components.address import *;
9from components.events import *;
10
11class Commands(IntEnum):
12    CMD_ECHO_REQ                                                  = 1
13    CMD_ECHO_RSP                                                  = 2
14    CMD_INQUIRE_REQ                                               = 3
15    CMD_INQUIRE_RSP                                               = 4
16    CMD_DISCONNECT_REQ                                            = 5
17    CMD_DISCONNECT_RSP                                            = 6
18    CMD_READ_REMOTE_VERSION_INFORMATION_REQ                       = 7
19    CMD_READ_REMOTE_VERSION_INFORMATION_RSP                       = 8
20    CMD_SET_EVENT_MASK_REQ                                        = 9
21    CMD_SET_EVENT_MASK_RSP                                        = 10
22    CMD_RESET_REQ                                                 = 11
23    CMD_RESET_RSP                                                 = 12
24    CMD_READ_TRANSMIT_POWER_LEVEL_REQ                             = 13
25    CMD_READ_TRANSMIT_POWER_LEVEL_RSP                             = 14
26    CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_REQ                   = 15
27    CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_RSP                   = 16
28    CMD_HOST_BUFFER_SIZE_REQ                                      = 17
29    CMD_HOST_BUFFER_SIZE_RSP                                      = 18
30    CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_REQ                      = 19
31    CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_RSP                      = 20
32    CMD_SET_EVENT_MASK_PAGE_2_REQ                                 = 21
33    CMD_SET_EVENT_MASK_PAGE_2_RSP                                 = 22
34    CMD_WRITE_LE_HOST_SUPPORT_REQ                                 = 23
35    CMD_WRITE_LE_HOST_SUPPORT_RSP                                 = 24
36    CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ                    = 25
37    CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP                    = 26
38    CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ                   = 27
39    CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP                   = 28
40    CMD_READ_LOCAL_VERSION_INFORMATION_REQ                        = 29
41    CMD_READ_LOCAL_VERSION_INFORMATION_RSP                        = 30
42    CMD_READ_LOCAL_SUPPORTED_COMMANDS_REQ                         = 31
43    CMD_READ_LOCAL_SUPPORTED_COMMANDS_RSP                         = 32
44    CMD_READ_LOCAL_SUPPORTED_FEATURES_REQ                         = 33
45    CMD_READ_LOCAL_SUPPORTED_FEATURES_RSP                         = 34
46    CMD_READ_BUFFER_SIZE_REQ                                      = 35
47    CMD_READ_BUFFER_SIZE_RSP                                      = 36
48    CMD_READ_BD_ADDR_REQ                                          = 37
49    CMD_READ_BD_ADDR_RSP                                          = 38
50    CMD_READ_RSSI_REQ                                             = 39
51    CMD_READ_RSSI_RSP                                             = 40
52    CMD_LE_SET_EVENT_MASK_REQ                                     = 41
53    CMD_LE_SET_EVENT_MASK_RSP                                     = 42
54    CMD_LE_READ_BUFFER_SIZE_REQ                                   = 43
55    CMD_LE_READ_BUFFER_SIZE_RSP                                   = 44
56    CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_REQ                      = 45
57    CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_RSP                      = 46
58    CMD_LE_SET_RANDOM_ADDRESS_REQ                                 = 47
59    CMD_LE_SET_RANDOM_ADDRESS_RSP                                 = 48
60    CMD_LE_SET_ADVERTISING_PARAMETERS_REQ                         = 49
61    CMD_LE_SET_ADVERTISING_PARAMETERS_RSP                         = 50
62    CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_REQ                  = 51
63    CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_RSP                  = 52
64    CMD_LE_SET_ADVERTISING_DATA_REQ                               = 53
65    CMD_LE_SET_ADVERTISING_DATA_RSP                               = 54
66    CMD_LE_SET_SCAN_RESPONSE_DATA_REQ                             = 55
67    CMD_LE_SET_SCAN_RESPONSE_DATA_RSP                             = 56
68    CMD_LE_SET_ADVERTISING_ENABLE_REQ                             = 57
69    CMD_LE_SET_ADVERTISING_ENABLE_RSP                             = 58
70    CMD_LE_SET_SCAN_PARAMETERS_REQ                                = 59
71    CMD_LE_SET_SCAN_PARAMETERS_RSP                                = 60
72    CMD_LE_SET_SCAN_ENABLE_REQ                                    = 61
73    CMD_LE_SET_SCAN_ENABLE_RSP                                    = 62
74    CMD_LE_CREATE_CONNECTION_REQ                                  = 63
75    CMD_LE_CREATE_CONNECTION_RSP                                  = 64
76    CMD_LE_CREATE_CONNECTION_CANCEL_REQ                           = 65
77    CMD_LE_CREATE_CONNECTION_CANCEL_RSP                           = 66
78    CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_REQ                               = 67
79    CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_RSP                               = 68
80    CMD_LE_CLEAR_FILTER_ACCEPT_LIST_REQ                                   = 69
81    CMD_LE_CLEAR_FILTER_ACCEPT_LIST_RSP                                   = 70
82    CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_REQ                           = 71
83    CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_RSP                           = 72
84    CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_REQ                      = 73
85    CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_RSP                      = 74
86    CMD_LE_CONNECTION_UPDATE_REQ                                  = 75
87    CMD_LE_CONNECTION_UPDATE_RSP                                  = 76
88    CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_REQ                    = 77
89    CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_RSP                    = 78
90    CMD_LE_READ_CHANNEL_MAP_REQ                                   = 79
91    CMD_LE_READ_CHANNEL_MAP_RSP                                   = 80
92    CMD_LE_READ_REMOTE_FEATURES_REQ                               = 81
93    CMD_LE_READ_REMOTE_FEATURES_RSP                               = 82
94    CMD_LE_ENCRYPT_REQ                                            = 83
95    CMD_LE_ENCRYPT_RSP                                            = 84
96    CMD_LE_RAND_REQ                                               = 85
97    CMD_LE_RAND_RSP                                               = 86
98    CMD_LE_START_ENCRYPTION_REQ                                   = 87
99    CMD_LE_START_ENCRYPTION_RSP                                   = 88
100    CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_REQ                        = 89
101    CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_RSP                        = 90
102    CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_REQ               = 91
103    CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_RSP               = 92
104    CMD_LE_READ_SUPPORTED_STATES_REQ                              = 93
105    CMD_LE_READ_SUPPORTED_STATES_RSP                              = 94
106    CMD_LE_RECEIVER_TEST_REQ                                      = 95
107    CMD_LE_RECEIVER_TEST_RSP                                      = 96
108    CMD_LE_TRANSMITTER_TEST_REQ                                   = 97
109    CMD_LE_TRANSMITTER_TEST_RSP                                   = 98
110    CMD_LE_TEST_END_REQ                                           = 99
111    CMD_LE_TEST_END_RSP                                           = 100
112    CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_REQ          = 101
113    CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_RSP          = 102
114    CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_REQ = 103
115    CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_RSP = 104
116    CMD_LE_SET_DATA_LENGTH_REQ                                    = 105
117    CMD_LE_SET_DATA_LENGTH_RSP                                    = 106
118    CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_REQ                 = 107
119    CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_RSP                 = 108
120    CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_REQ                = 109
121    CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_RSP                = 110
122    CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_REQ                = 111
123    CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_RSP                = 112
124    CMD_LE_GENERATE_DHKEY_COMMAND_REQ                             = 113
125    CMD_LE_GENERATE_DHKEY_COMMAND_RSP                             = 114
126    CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_REQ                       = 115
127    CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_RSP                       = 116
128    CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_REQ                  = 117
129    CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_RSP                  = 118
130    CMD_LE_CLEAR_RESOLVING_LIST_REQ                               = 119
131    CMD_LE_CLEAR_RESOLVING_LIST_RSP                               = 120
132    CMD_LE_READ_RESOLVING_LIST_SIZE_REQ                           = 121
133    CMD_LE_READ_RESOLVING_LIST_SIZE_RSP                           = 122
134    CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_REQ                       = 123
135    CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_RSP                       = 124
136    CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_REQ                      = 125
137    CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_RSP                      = 126
138    CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_REQ                      = 127
139    CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_RSP                      = 128
140    CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_REQ             = 129
141    CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_RSP             = 130
142    CMD_LE_READ_MAXIMUM_DATA_LENGTH_REQ                           = 131
143    CMD_LE_READ_MAXIMUM_DATA_LENGTH_RSP                           = 132
144    CMD_LE_READ_PHY_REQ                                           = 133
145    CMD_LE_READ_PHY_RSP                                           = 134
146    CMD_LE_SET_DEFAULT_PHY_REQ                                    = 135
147    CMD_LE_SET_DEFAULT_PHY_RSP                                    = 136
148    CMD_LE_SET_PHY_REQ                                            = 137
149    CMD_LE_SET_PHY_RSP                                            = 138
150    CMD_LE_ENHANCED_RECEIVER_TEST_REQ                             = 139
151    CMD_LE_ENHANCED_RECEIVER_TEST_RSP                             = 140
152    CMD_LE_ENHANCED_TRANSMITTER_TEST_REQ                          = 141
153    CMD_LE_ENHANCED_TRANSMITTER_TEST_RSP                          = 142
154    CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_REQ                = 143
155    CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_RSP                = 144
156    CMD_LE_SET_EXTENDED_ADVERTISING_DATA_REQ                      = 145
157    CMD_LE_SET_EXTENDED_ADVERTISING_DATA_RSP                      = 146
158    CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_REQ                    = 147
159    CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_RSP                    = 148
160    CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_REQ                    = 149
161    CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_RSP                    = 150
162    CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_REQ               = 151
163    CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_RSP               = 152
164    CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_REQ          = 153
165    CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_RSP          = 154
166    CMD_LE_REMOVE_ADVERTISING_SET_REQ                             = 155
167    CMD_LE_REMOVE_ADVERTISING_SET_RSP                             = 156
168    CMD_LE_CLEAR_ADVERTISING_SETS_REQ                             = 157
169    CMD_LE_CLEAR_ADVERTISING_SETS_RSP                             = 158
170    CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_REQ                = 159
171    CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_RSP                = 160
172    CMD_LE_SET_PERIODIC_ADVERTISING_DATA_REQ                      = 161
173    CMD_LE_SET_PERIODIC_ADVERTISING_DATA_RSP                      = 162
174    CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_REQ                    = 163
175    CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_RSP                    = 164
176    CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_REQ                       = 165
177    CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_RSP                       = 166
178    CMD_LE_SET_EXTENDED_SCAN_ENABLE_REQ                           = 167
179    CMD_LE_SET_EXTENDED_SCAN_ENABLE_RSP                           = 168
180    CMD_LE_EXTENDED_CREATE_CONNECTION_REQ                         = 169
181    CMD_LE_EXTENDED_CREATE_CONNECTION_RSP                         = 170
182    CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_REQ                   = 171
183    CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_RSP                   = 172
184    CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_REQ            = 173
185    CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_RSP            = 174
186    CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_REQ                = 175
187    CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_RSP                = 176
188    CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_REQ             = 177
189    CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_RSP             = 178
190    CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_REQ        = 179
191    CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_RSP        = 180
192    CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_REQ                     = 181
193    CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_RSP                     = 182
194    CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_REQ                 = 183
195    CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_RSP                 = 184
196    CMD_LE_READ_TRANSMIT_POWER_REQ                                = 185
197    CMD_LE_READ_TRANSMIT_POWER_RSP                                = 186
198    CMD_LE_READ_RF_PATH_COMPENSATION_REQ                          = 187
199    CMD_LE_READ_RF_PATH_COMPENSATION_RSP                          = 188
200    CMD_LE_WRITE_RF_PATH_COMPENSATION_REQ                         = 189
201    CMD_LE_WRITE_RF_PATH_COMPENSATION_RSP                         = 190
202    CMD_LE_SET_PRIVACY_MODE_REQ                                   = 191
203    CMD_LE_SET_PRIVACY_MODE_RSP                                   = 192
204    CMD_WRITE_BD_ADDR_REQ                                         = 193
205    CMD_WRITE_BD_ADDR_RSP                                         = 194
206    CMD_FLUSH_EVENTS_REQ                                          = 195
207    CMD_FLUSH_EVENTS_RSP                                          = 196
208    CMD_HAS_EVENT_REQ                                             = 197
209    CMD_HAS_EVENT_RSP                                             = 198
210    CMD_GET_EVENT_REQ                                             = 199
211    CMD_GET_EVENT_RSP                                             = 200
212    CMD_LE_DATA_FLUSH_REQ                                         = 201
213    CMD_LE_DATA_FLUSH_RSP                                         = 202
214    CMD_LE_DATA_READY_REQ                                         = 203
215    CMD_LE_DATA_READY_RSP                                         = 204
216    CMD_LE_DATA_WRITE_REQ                                         = 205
217    CMD_LE_DATA_WRITE_RSP                                         = 206
218    CMD_LE_DATA_READ_REQ                                          = 207
219    CMD_LE_DATA_READ_RSP                                          = 208
220    CMD_GATT_SERVICE_SET_REQ                                      = 209
221    CMD_GATT_SERVICE_SET_RSP                                      = 210
222    CMD_GATT_SERVICE_NOTIFY_REQ                                   = 211
223    CMD_GATT_SERVICE_NOTIFY_RSP                                   = 212
224    CMD_GATT_SERVICE_INDICATE_REQ                                 = 213
225    CMD_GATT_SERVICE_INDICATE_RSP                                 = 214
226    CMD_GAP_ADVERTISING_MODE_REQ                                  = 215
227    CMD_GAP_ADVERTISING_MODE_RSP                                  = 216
228    CMD_GAP_ADVERTISING_DATA_REQ                                  = 217
229    CMD_GAP_ADVERTISING_DATA_RSP                                  = 218
230    CMD_GAP_SCANNING_MODE_REQ                                     = 219
231    CMD_GAP_SCANNING_MODE_RSP                                     = 220
232    CMD_READ_STATIC_ADDRESSES_REQ                                 = 221
233    CMD_READ_STATIC_ADDRESSES_RSP                                 = 222
234    CMD_READ_KEY_HIERARCHY_ROOTS_REQ                              = 223
235    CMD_READ_KEY_HIERARCHY_ROOTS_RSP                              = 224
236    CMD_GAP_READ_IRK_REQ                                          = 225
237    CMD_GAP_READ_IRK_RSP                                          = 226
238    CMD_GAP_ROLE_REQ                                              = 227
239    CMD_GAP_ROLE_RSP                                              = 228
240    CMD_LE_ISO_DATA_FLUSH_REQ                                     = 229
241    CMD_LE_ISO_DATA_FLUSH_RSP                                     = 230
242    CMD_LE_ISO_DATA_READY_REQ                                     = 231
243    CMD_LE_ISO_DATA_READY_RSP                                     = 232
244    CMD_LE_ISO_DATA_WRITE_REQ                                     = 233
245    CMD_LE_ISO_DATA_WRITE_RSP                                     = 234
246    CMD_LE_ISO_DATA_READ_REQ                                      = 235
247    CMD_LE_ISO_DATA_READ_RSP                                      = 236
248    CMD_LE_SET_CIG_PARAMETERS_REQ                                 = 237
249    CMD_LE_SET_CIG_PARAMETERS_RSP                                 = 238
250    CMD_LE_SET_CIG_PARAMETERS_TEST_REQ                            = 239
251    CMD_LE_SET_CIG_PARAMETERS_TEST_RSP                            = 240
252    CMD_LE_CREATE_CIS_REQ                                         = 241
253    CMD_LE_CREATE_CIS_RSP                                         = 242
254    CMD_LE_REMOVE_CIG_REQ                                         = 243
255    CMD_LE_REMOVE_CIG_RSP                                         = 244
256    CMD_LE_ACCEPT_CIS_REQUEST_REQ                                 = 245
257    CMD_LE_ACCEPT_CIS_REQUEST_RSP                                 = 246
258    CMD_LE_REJECT_CIS_REQUEST_REQ                                 = 247
259    CMD_LE_REJECT_CIS_REQUEST_RSP                                 = 248
260    CMD_LE_SETUP_ISO_DATA_PATH_REQ                                = 249
261    CMD_LE_SETUP_ISO_DATA_PATH_RSP                                = 250
262    CMD_LE_REMOVE_ISO_DATA_PATH_REQ                               = 251
263    CMD_LE_REMOVE_ISO_DATA_PATH_RSP                               = 252
264    CMD_LE_SET_HOST_FEATURE_REQ                                   = 253
265    CMD_LE_SET_HOST_FEATURE_RSP                                   = 254
266    CMD_GET_IXIT_VALUE_REQ                                        = 255
267    CMD_GET_IXIT_VALUE_RSP                                        = 256
268    CMD_HCI_LE_ISO_TRANSMIT_TEST_REQ                              = 257
269    CMD_HCI_LE_ISO_TRANSMIT_TEST_RSP                              = 258
270    CMD_HCI_LE_ISO_RECEIVE_TEST_REQ                               = 259
271    CMD_HCI_LE_ISO_RECEIVE_TEST_RSP                               = 260
272    CMD_HCI_LE_ISO_READ_TEST_COUNTERS_REQ                         = 261
273    CMD_HCI_LE_ISO_READ_TEST_COUNTERS_RSP                         = 262
274    CMD_HCI_LE_ISO_TEST_END_REQ                                   = 263
275    CMD_HCI_LE_ISO_TEST_END_RSP                                   = 264
276    CMD_HCI_LE_REQUEST_PEER_SCA_REQ                               = 265
277    CMD_HCI_LE_REQUEST_PEER_SCA_RSP                               = 266
278    CMD_LE_READ_BUFFER_SIZE_V2_REQ                                = 267
279    CMD_LE_READ_BUFFER_SIZE_V2_RSP                                = 268
280
281
282class HCICommands(IntEnum):
283    BT_HCI_OP_INQUIRY                       = 0x401
284    BT_HCI_OP_DISCONNECT                    = 0x406
285    BT_HCI_OP_READ_REMOTE_VERSION_INFO      = 0x41D
286    BT_HCI_OP_SET_EVENT_MASK                = 0xC01
287    BT_HCI_OP_RESET                         = 0xC03
288    BT_HCI_OP_READ_TX_POWER_LEVEL           = 0xC2D
289    BT_HCI_OP_SET_CTL_TO_HOST_FLOW          = 0xC31
290    BT_HCI_OP_HOST_BUFFER_SIZE              = 0xC33
291    BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS    = 0xC35
292    BT_HCI_OP_SET_EVENT_MASK_PAGE_2         = 0xC63
293    BT_HCI_OP_LE_WRITE_LE_HOST_SUPP         = 0xC6D
294    BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT     = 0xC7B
295    BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT    = 0xC7C
296    BT_HCI_OP_READ_LOCAL_VERSION_INFO       = 0x1001
297    BT_HCI_OP_READ_SUPPORTED_COMMANDS       = 0x1002
298    BT_HCI_OP_READ_LOCAL_FEATURES           = 0x1003
299    BT_HCI_OP_READ_BUFFER_SIZE              = 0x1005
300    BT_HCI_OP_READ_BD_ADDR                  = 0x1009
301    BT_HCI_OP_READ_RSSI                     = 0x1405
302    BT_HCI_OP_LE_SET_EVENT_MASK             = 0x2001
303    BT_HCI_OP_LE_READ_BUFFER_SIZE           = 0x2002
304    BT_HCI_OP_LE_READ_LOCAL_FEATURES        = 0x2003
305    BT_HCI_OP_LE_SET_RANDOM_ADDRESS         = 0x2005
306    BT_HCI_OP_LE_SET_ADV_PARAM              = 0x2006
307    BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER     = 0x2007
308    BT_HCI_OP_LE_SET_ADV_DATA               = 0x2008
309    BT_HCI_OP_LE_SET_SCAN_RSP_DATA          = 0x2009
310    BT_HCI_OP_LE_SET_ADV_ENABLE             = 0x200A
311    BT_HCI_OP_LE_SET_SCAN_PARAM             = 0x200B
312    BT_HCI_OP_LE_SET_SCAN_ENABLE            = 0x200C
313    BT_HCI_OP_LE_CREATE_CONN                = 0x200D
314    BT_HCI_OP_LE_CREATE_CONN_CANCEL         = 0x200E
315    BT_HCI_OP_LE_READ_FAL_SIZE               = 0x200F
316    BT_HCI_OP_LE_CLEAR_FAL                   = 0x2010
317    BT_HCI_OP_LE_ADD_DEV_TO_FAL              = 0x2011
318    BT_HCI_OP_LE_REM_DEV_FROM_FAL            = 0x2012
319    BT_HCI_OP_LE_CONN_UPDATE                = 0x2013
320    BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF      = 0x2014
321    BT_HCI_OP_LE_READ_CHAN_MAP              = 0x2015
322    BT_HCI_OP_LE_READ_REMOTE_FEATURES       = 0x2016
323    BT_HCI_OP_LE_ENCRYPT                    = 0x2017
324    BT_HCI_OP_LE_RAND                       = 0x2018
325    BT_HCI_OP_LE_START_ENCRYPTION           = 0x2019
326    BT_HCI_OP_LE_LTK_REQ_REPLY              = 0x201A
327    BT_HCI_OP_LE_LTK_REQ_NEG_REPLY          = 0x201B
328    BT_HCI_OP_LE_READ_SUPP_STATES           = 0x201C
329    BT_HCI_OP_LE_RX_TEST                    = 0x201D
330    BT_HCI_OP_LE_TX_TEST                    = 0x201E
331    BT_HCI_OP_LE_TEST_END                   = 0x201F
332    BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY       = 0x2020
333    BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY   = 0x2021
334    BT_HCI_OP_LE_SET_DATA_LEN               = 0x2022
335    BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN      = 0x2023
336    BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN     = 0x2024
337    BT_HCI_OP_LE_P256_PUBLIC_KEY            = 0x2025
338    BT_HCI_OP_LE_GENERATE_DHKEY             = 0x2026
339    BT_HCI_OP_LE_ADD_DEV_TO_RL              = 0x2027
340    BT_HCI_OP_LE_REM_DEV_FROM_RL            = 0x2028
341    BT_HCI_OP_LE_CLEAR_RL                   = 0x2029
342    BT_HCI_OP_LE_READ_RL_SIZE               = 0x202A
343    BT_HCI_OP_LE_READ_PEER_RPA              = 0x202B
344    BT_HCI_OP_LE_READ_LOCAL_RPA             = 0x202C
345    BT_HCI_OP_LE_SET_ADDR_RES_ENABLE        = 0x202D
346    BT_HCI_OP_LE_SET_RPA_TIMEOUT            = 0x202E
347    BT_HCI_OP_LE_READ_MAX_DATA_LEN          = 0x202F
348    BT_HCI_OP_LE_READ_PHY                   = 0x2030
349    BT_HCI_OP_LE_SET_DEFAULT_PHY            = 0x2031
350    BT_HCI_OP_LE_SET_PHY                    = 0x2032
351    BT_HCI_OP_LE_ENH_RX_TEST                = 0x2033
352    BT_HCI_OP_LE_ENH_TX_TEST                = 0x2034
353    BT_HCI_OP_LE_SET_EXT_ADV_PARAM          = 0x2036
354    BT_HCI_OP_LE_SET_EXT_ADV_DATA           = 0x2037
355    BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA      = 0x2038
356    BT_HCI_OP_LE_SET_EXT_ADV_ENABLE         = 0x2039
357    BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN      = 0x203A
358    BT_HCI_OP_LE_READ_NUM_ADV_SETS          = 0x203B
359    BT_HCI_OP_LE_REMOVE_ADV_SET             = 0x203C
360    BT_HCI_OP_CLEAR_ADV_SETS                = 0x203D
361    BT_HCI_OP_LE_SET_PER_ADV_PARAM          = 0x203E
362    BT_HCI_OP_LE_SET_PER_ADV_DATA           = 0x203F
363    BT_HCI_OP_LE_SET_PER_ADV_ENABLE         = 0x2040
364    BT_HCI_OP_LE_SET_EXT_SCAN_PARAM         = 0x2041
365    BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE        = 0x2042
366    BT_HCI_OP_LE_EXT_CREATE_CONN            = 0x2043
367    BT_HCI_OP_LE_PER_ADV_CREATE_SYNC        = 0x2044
368    BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL = 0x2045
369    BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC     = 0x2046
370    BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST    = 0x2047
371    BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST  = 0x2048
372    BT_HCI_OP_LE_CLEAR_PER_ADV_LIST         = 0x2049
373    BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE     = 0x204A
374    BT_HCI_OP_LE_READ_TX_POWER              = 0x204B
375    BT_HCI_OP_LE_READ_RF_PATH_COMP          = 0x204C
376    BT_HCI_OP_LE_WRITE_RF_PATH_COMP         = 0x204D
377    BT_HCI_OP_LE_SET_PRIVACY_MODE           = 0x204E
378    BT_HCI_OP_LE_READ_BUFFER_SIZE_V2        = 0x2060
379    BT_HCI_OP_LE_SET_CIG_PARAMETERS         = 0x2062
380    BT_HCI_OP_LE_SET_CIG_PARAMETERS_TEST    = 0x2063
381    BT_HCI_OP_LE_CREATE_CIS                 = 0x2064
382    BT_HCI_OP_LE_REMOVE_CIG                 = 0x2065
383    BT_HCI_OP_LE_ACCEPT_CIS_REQUEST         = 0x2066
384    BT_HCI_OP_LE_REJECT_CIS_REQUEST         = 0x2067
385    BT_HCI_OP_LE_REQUEST_PEER_SCA           = 0x206D
386    BT_HCI_OP_LE_SETUP_ISO_DATA_PATH        = 0x206E
387    BT_HCI_OP_LE_REMOVE_ISO_DATA_PATH       = 0x206F
388    BT_HCI_OP_LE_ISO_TRANSMIT_TEST          = 0x2070
389    BT_HCI_OP_LE_ISO_RECEIVE_TEST           = 0x2071
390    BT_HCI_OP_LE_ISO_READ_TEST_COUNTERS     = 0x2072
391    BT_HCI_OP_LE_ISO_TEST_END               = 0x2073
392    BT_HCI_OP_LE_SET_HOST_FEATURE           = 0x2074
393    BT_HCI_OP_VS_WRITE_BD_ADDR              = 0xFC06
394
395class Events(IntEnum):
396    BT_HCI_EVT_NONE                         = 0
397    BT_HCI_EVT_DISCONN_COMPLETE             = 5
398    BT_HCI_EVT_ENCRYPT_CHANGE_V1            = 8
399    BT_HCI_EVT_REMOTE_VERSION_INFO          = 12
400    BT_HCI_EVT_CMD_COMPLETE                 = 14
401    BT_HCI_EVT_CMD_STATUS                   = 15
402    BT_HCI_EVT_NUM_COMPLETED_PACKETS        = 19
403    BT_HCI_EVT_DATA_BUF_OVERFLOW            = 26
404    BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE = 48
405    BT_HCI_EVT_LE_META_EVENT                = 62
406    BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP     = 87
407    BT_HCI_EVT_ENCRYPT_CHANGE_V2            = 89
408
409
410class MetaEvents(IntEnum):
411    BT_HCI_EVT_LE_CONN_COMPLETE             = 1
412    BT_HCI_EVT_LE_ADVERTISING_REPORT        = 2
413    BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE      = 3
414    BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE       = 4
415    BT_HCI_EVT_LE_LTK_REQUEST               = 5
416    BT_HCI_EVT_LE_CONN_PARAM_REQ            = 6
417    BT_HCI_EVT_LE_DATA_LEN_CHANGE           = 7
418    BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE  = 8
419    BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE   = 9
420    BT_HCI_EVT_LE_ENH_CONN_COMPLETE         = 10
421    BT_HCI_EVT_LE_DIRECT_ADV_REPORT         = 11
422    BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE       = 12
423    BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT    = 13
424    BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED  = 14
425    BT_HCI_EVT_LE_PER_ADVERTISING_REPORT    = 15
426    BT_HCI_EVT_LE_PER_ADV_SYNC_LOST         = 16
427    BT_HCI_EVT_LE_SCAN_TIMEOUT              = 17
428    BT_HCI_EVT_LE_ADV_SET_TERMINATED        = 18
429    BT_HCI_EVT_LE_SCAN_REQ_RECEIVED         = 19
430    BT_HCI_EVT_LE_CHAN_SEL_ALGO             = 20
431    BT_HCI_EVT_LE_CIS_ESTABLISHED           = 25
432    BT_HCI_EVT_LE_CIS_REQUEST               = 26
433    BT_HCI_EVT_LE_REQUEST_PEER_SCA_COMPLETE = 31
434
435
436class ProfileId(IntEnum):
437    PROFILE_ID_GAP                          = 0
438    PROFILE_ID_GATT                         = 1
439    PROFILE_ID_HCI                          = 2
440    PROFILE_ID_L2CAP                        = 3
441    PROFILE_ID_LL                           = 4
442    PROFILE_ID_SM                           = 5
443
444class PhysicalChannel(IntEnum):
445    LE_1M    = 1
446    LE_2M    = 2
447    LE_CODED = 3
448
449class FragmentOperation(IntEnum):
450    INTERMEDIATE_FRAGMENT = 0      # Intermediate fragment of fragmented extended advertising data
451    FIRST_FRAGMENT        = 1      # First fragment of fragmented extended advertising data
452    LAST_FRAGMENT         = 2      # Last fragment of fragmented extended advertising data
453    COMPLETE_FRAGMENT     = 3      # Complete extended advertising data
454    UNCHANGED_FRAGMENT    = 4      # Unchanged data (just update the Advertising DID)
455
456class Ixit:
457    """
458    Definition of Implementation eXtra Information for Test (IXIT)
459    """
460    def __init__(self, profile_id, ref_major, ref_minor, value_fmt):
461        self.profile_id = profile_id
462        self.ref_major = ref_major
463        self.ref_minor = ref_minor
464        self.value_fmt = value_fmt
465
466"""
467The IXIT (Proforma for Bluetooth Conformance Test Suites) comes from Core.IXIT document
468https://www.bluetooth.com/specifications/qualification-test-requirements/
469"""
470IXITS = {
471    "TSPX_max_sdu_length": Ixit(ProfileId.PROFILE_ID_LL, 7, 1, 'H'),
472    "TSPX_max_cis_nse":  Ixit(ProfileId.PROFILE_ID_LL, 7, 14, 'B'),
473    "TSPX_max_cis_bn": Ixit(ProfileId.PROFILE_ID_LL, 7, 15, 'B'),
474}
475
476"""
477BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 6, Part B, 4.6 FEATURE SUPPORT
478"""
479class FeatureSupport(IntEnum):
480    ISOCHRONOUS_BROADCASTER = 30
481    ISOCHRONOUS_CHANNELS = 32
482
483
484def edtt_send_cmd(transport, idx, opcode, payload_fmt, payload_tuple):
485    """Send EDTT command
486    EDTT command PDU format
487    0--------16--------------32--------+
488    | Opcode | PayloadLength | Payload |
489    +--------+---------------+---------+
490    :param transport: bearer to be used
491    :param idx: device index
492    :param opcode: command opcode
493    :param payload_fmt: command payload format used to serialize the data
494    :param payload_tuple: payload as tuple
495    :return:
496    """
497    req = struct.pack('<HH' + payload_fmt, opcode, struct.calcsize('<' + payload_fmt), *payload_tuple)
498    transport.send(idx, req)
499
500
501def edtt_wait_cmd_cmpl(transport, idx, opcode, payload_fmt, to):
502    """Wait for command complete reception
503    EDTT command complete PDU format
504    0--------16--------------32--------+
505    | Opcode | PayloadLength | Payload |
506    +--------+---------------+---------+
507    :param transport: bearer to be used
508    :param idx: device index
509    :param opcode: command complete opcode
510    :param payload_fmt: command complete payload format used to deserialize the data
511    :param to: timeout
512    :return:
513    """
514    payload_fmt = '<' + payload_fmt  # specify endianess, avoid alignment
515    exp_payload_len = struct.calcsize(payload_fmt)
516    rsp_size = 4 + exp_payload_len
517    rsp = transport.recv(idx, rsp_size, to)
518    if rsp_size != len(rsp):
519        raise Exception("Response too short (Expected %i bytes got %i bytes)" % (rsp_size, len(rsp)))
520
521    # unpack and validate EDTT header first
522    op, payload_len = struct.unpack_from('<HH', rsp)
523    if op != opcode:
524        raise Exception("Inappropriate command response received (%i)" % op)
525
526    if payload_len != exp_payload_len:
527        raise Exception("Payload length field corrupted (Expected %i got %i)" % (exp_payload_len, payload_len))
528
529    # finally, unpack the payload
530    return struct.unpack_from(payload_fmt, rsp, 4)
531
532
533def echo(transport, idx, message, to):
534
535    cmd = struct.pack('<HH', Commands.CMD_ECHO_REQ, len(message)) + message;
536    transport.send(idx, cmd);
537
538    packet = transport.recv(idx, len(cmd), to);
539
540    if ( len(cmd) != len(packet) ):
541        raise Exception("echo test failed: Response too short (Expected %i bytes got %i bytes)" % (len(cmd), len(packet)));
542
543    RespCmd, RespLen = struct.unpack('<HH', packet[:4]);
544
545    if ( RespCmd != Commands.CMD_ECHO_RSP ):
546        raise Exception("echo test failed: Inappropriate command response received");
547
548    if ( RespLen != len(message) ):
549        raise Exception("echo test failed: Response length corrupted (%i)" % RespLen);
550
551    if ( packet[4:] != message ):
552        raise Exception("echo test failed: Message content corrupted (%s)" % packet[4:]);
553
554    return packet[4:];
555
556"""
557    This command causes the BR/EDR Controller to enter Inquiry Mode. Inquiry Mode is used to discover other nearby BR/EDR
558    Controllers. The LAP input parameter contains the LAP from which the inquiry access code shall be derived when the inquiry
559    procedure is made. The Inquiry_Length parameter specifies the total duration of the Inquiry Mode and, when this time
560    expires, Inquiry will be halted. When Extended_Inquiry_Length is greater than zero, the duration of the Inquiry Mode may
561    be changed to (Inquiry_Length + Extended_Inquiry_Length). The Num_Responses parameter specifies the number of responses
562    that can be received before the Inquiry is halted. Inquiry Result, Inquiry Result with RSSI, or Extended Inquiry Result
563    events will be sent to report the details of nearby BR/EDR Controllers that have responded to this inquiry. The Inquiry
564    Complete event is sent to report that Inquiry Mode has ended.
565"""
566def inquire(transport, idx, lap, length, NumRsp, to):
567
568    cmd = struct.pack('<HHH3B', Commands.CMD_INQUIRE_REQ, 7, HCICommands.BT_HCI_OP_INQUIRY, *lap);
569    cmd += struct.pack('<BB', length, NumRsp);
570    transport.send(idx, cmd);
571
572    packet = transport.recv(idx, 5, to);
573
574    if ( 5 != len(packet) ):
575        raise Exception("Inquire command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
576
577    RespCmd, RespLen, status, = struct.unpack('<HHB', packet);
578
579    if ( RespCmd != Commands.CMD_INQUIRE_RSP ):
580        raise Exception("Inquire command failed: Inappropriate command response received");
581
582    if ( RespLen != 1 ):
583        raise Exception("Inquire command failed: Response length field corrupted (%i)" % RespLen);
584
585    return status;
586
587"""
588    The Disconnect command is used to terminate an existing connection.
589"""
590def disconnect(transport, idx, handle, reason, to):
591
592    cmd = struct.pack('<HHHHB', Commands.CMD_DISCONNECT_REQ, 5, HCICommands.BT_HCI_OP_DISCONNECT, handle, reason);
593    transport.send(idx, cmd);
594
595    packet = transport.recv(idx, 5, to);
596
597    if ( 5 != len(packet) ):
598        raise Exception("Disconnect command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
599
600    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
601
602    if ( RespCmd != Commands.CMD_DISCONNECT_RSP ):
603        raise Exception("Disconnect command failed: Inappropriate command response received");
604
605    if ( RespLen != 1 ):
606        raise Exception("Disconnect command failed: Response length field corrupted (%i)" % RespLen);
607
608    return status;
609
610"""
611    This command will obtain the values for the version information for the remote device identified by the Connection_Handle
612    parameter.
613"""
614def read_remote_version_information(transport, idx, handle, to):
615
616    cmd = struct.pack('<HHHH', Commands.CMD_READ_REMOTE_VERSION_INFORMATION_REQ, 4, HCICommands.BT_HCI_OP_READ_REMOTE_VERSION_INFO, handle);
617    transport.send(idx, cmd);
618
619    packet = transport.recv(idx, 5, to);
620
621    if ( 5 != len(packet) ):
622        raise Exception("Read Remote Version Information command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
623
624    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
625
626    if ( RespCmd != Commands.CMD_READ_REMOTE_VERSION_INFORMATION_RSP ):
627        raise Exception("Read Remote Version Information command failed: Inappropriate command response received");
628
629    if ( RespLen != 1 ):
630        raise Exception("Read Remote Version Information command failed: Response length field corrupted (%i)" % RespLen);
631
632    return status;
633
634"""
635    The Set_Event_Mask command is used to control which events are generated by the HCI for the Host. If the bit in the
636    Event_Mask is set to a one, then the event associated with that bit will be enabled. For an LE Controller, the \93LE Meta
637    Event\94 bit in the Event_Mask shall enable or disable all LE events in the LE Meta Event (see Section 7.7.65).
638"""
639def set_event_mask(transport, idx, events, to):
640
641    cmd = struct.pack('<HHH8B', Commands.CMD_SET_EVENT_MASK_REQ, 10, HCICommands.BT_HCI_OP_SET_EVENT_MASK, *events);
642    transport.send(idx, cmd);
643
644    packet = transport.recv(idx, 5, to);
645
646    if ( 5 != len(packet) ):
647        raise Exception("Set Event Mask command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
648
649    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
650
651    if ( RespCmd != Commands.CMD_SET_EVENT_MASK_RSP ):
652        raise Exception("Set Event Mask command failed: Inappropriate command response received");
653
654    if ( RespLen != 1 ):
655        raise Exception("Set Event Mask command failed: Response length field corrupted (%i)" % RespLen);
656
657    return status;
658
659"""
660    The Reset command will reset the Controller and the Link Manager on the BR/ EDR Controller, the PAL on an AMP Controller,
661    or the Link Layer on an LE Controller. If the Controller supports both BR/EDR and LE then the Reset command shall reset
662    the Link Manager, Baseband and Link Layer. The Reset command shall not affect the used HCI transport layer since the HCI
663    transport layers may have reset mechanisms of their own. After the reset is completed, the current operational state will
664    be lost, the Controller will enter standby mode and the Controller will automatically revert to the default values for the
665    parameters for which default values are defined in the specification.
666"""
667def reset(transport, idx, to):
668
669    cmd = struct.pack('<HHH', Commands.CMD_RESET_REQ, 2, HCICommands.BT_HCI_OP_RESET);
670    transport.send(idx, cmd);
671
672    packet = transport.recv(idx, 5, to);
673
674    if ( 5 != len(packet) ):
675        raise Exception("Reset command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
676
677    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
678
679    if ( RespCmd != Commands.CMD_RESET_RSP ):
680        raise Exception("Reset command failed: Inappropriate command response received");
681
682    if ( RespLen != 1 ):
683        raise Exception("Reset command failed: Response length field corrupted (%i)" % RespLen);
684
685    return status;
686
687"""
688    This command reads the values for the Transmit_Power_Level parameter for the specified Connection_Handle. The
689    Connection_Handle shall be a Connection_Handle for an ACL connection.
690"""
691def read_transmit_power_level(transport, idx, handle, levelType, to):
692
693    cmd = struct.pack('<HHHHB', Commands.CMD_READ_TRANSMIT_POWER_LEVEL_REQ, 5, HCICommands.BT_HCI_OP_READ_TX_POWER_LEVEL, handle, levelType);
694    transport.send(idx, cmd);
695
696    packet = transport.recv(idx, 8, to);
697
698    if ( 8 != len(packet) ):
699        raise Exception("Read Transmit Power Level command failed: Response too short (Expected %i bytes got %i bytes)" % (8, len(packet)));
700
701    RespCmd, RespLen, status, handle, TxPowerLevel = struct.unpack('<HHBHb', packet);
702
703    if ( RespCmd != Commands.CMD_READ_TRANSMIT_POWER_LEVEL_RSP ):
704        raise Exception("Read Transmit Power Level command failed: Inappropriate command response received");
705
706    if ( RespLen != 4 ):
707        raise Exception("Read Transmit Power Level command failed: Response length field corrupted (%i)" % RespLen);
708
709    return status, handle, TxPowerLevel;
710
711"""
712    This command is used by the Host to turn flow control on or off for data and/or voice sent in the direction from the
713    Controller to the Host.
714"""
715def set_controller_to_host_flow_control(transport, idx, FlowEnable, to):
716
717    cmd = struct.pack('<HHHB', Commands.CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_REQ, 3, HCICommands.BT_HCI_OP_SET_CTL_TO_HOST_FLOW, FlowEnable);
718    transport.send(idx, cmd);
719
720    packet = transport.recv(idx, 5, to);
721
722    if ( 5 != len(packet) ):
723        raise Exception("Set Controller To Host Flow Control command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
724
725    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
726
727    if ( RespCmd != Commands.CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_RSP ):
728        raise Exception("Set Controller To Host Flow Control command failed: Inappropriate command response received");
729
730    if ( RespLen != 1 ):
731        raise Exception("Set Controller To Host Flow Control command failed: Response length field corrupted (%i)" % RespLen);
732
733    return status;
734
735"""
736    The Host_Buffer_Size command is used by the Host to notify the Controller about the maximum size of the data portion of
737    HCI ACL and synchronous Data Packets sent from the Controller to the Host.
738"""
739def host_buffer_size(transport, idx, AclMtu, ScoMtu, AclPkts, ScoPkts, to):
740
741    cmd = struct.pack('<HHHHBHH', Commands.CMD_HOST_BUFFER_SIZE_REQ, 9, HCICommands.BT_HCI_OP_HOST_BUFFER_SIZE, AclMtu, ScoMtu, AclPkts, ScoPkts);
742    transport.send(idx, cmd);
743
744    packet = transport.recv(idx, 5, to);
745
746    if ( 5 != len(packet) ):
747        raise Exception("Host Buffer Size command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
748
749    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
750
751    if ( RespCmd != Commands.CMD_HOST_BUFFER_SIZE_RSP ):
752        raise Exception("Host Buffer Size command failed: Inappropriate command response received");
753
754    if ( RespLen != 1 ):
755        raise Exception("Host Buffer Size command failed: Response length field corrupted (%i)" % RespLen);
756
757    return status;
758
759"""
760    The Host_Number_Of_Completed_Packets command is used by the Host to indicate to the Controller the number of HCI Data
761    Packets that have been completed for each Connection_Handle since the previous Host_Number_Of_Completed_Packets command
762    was sent to the Controller.
763"""
764def host_number_of_completed_packets(transport, idx, NumHandles, HHandle, HCount, to):
765    cmd = struct.pack('<HHHB' + 'HH' * NumHandles, Commands.CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_REQ, 7 + 4 * NumHandles,
766                      HCICommands.BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, NumHandles, *list(chain(*list(zip(HHandle, HCount)))));
767
768    transport.send(idx, cmd);
769
770    packet = transport.recv(idx, 5, to);
771
772    if ( 5 != len(packet) ):
773        raise Exception("Host Number Of Completed Packets command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
774
775    RespCmd, RespLen, status = struct.unpack('<HH', packet);
776
777    if ( RespCmd != Commands.CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_RSP ):
778        raise Exception("Host Number Of Completed Packets command failed: Inappropriate command response received");
779
780    if ( RespLen != 1 ):
781        raise Exception("Host Number Of Completed Packets command failed: Response length field corrupted (%i)" % RespLen);
782
783
784"""
785    The Set_Event_Mask_Page_2 command is used to control which events are generated by the HCI for the Host. The
786    Event_Mask_Page_2 is a logical extension to the Event_Mask parameter of the Set_Event_Mask command.
787"""
788def set_event_mask_page_2(transport, idx, EventsPage2, to):
789
790    cmd = struct.pack('<HHH8B', Commands.CMD_SET_EVENT_MASK_PAGE_2_REQ, 10, HCICommands.BT_HCI_OP_SET_EVENT_MASK_PAGE_2, *EventsPage2);
791    transport.send(idx, cmd);
792
793    packet = transport.recv(idx, 5, to);
794
795    if ( 5 != len(packet) ):
796        raise Exception("Set Event Mask Page 2 command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
797
798    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
799
800    if ( RespCmd != Commands.CMD_SET_EVENT_MASK_PAGE_2_RSP ):
801        raise Exception("Set Event Mask Page 2 command failed: Inappropriate command response received");
802
803    if ( RespLen != 1 ):
804        raise Exception("Set Event Mask Page 2 command failed: Response length field corrupted (%i)" % RespLen);
805
806    return status;
807
808"""
809    The Write_LE_Host_Support command is used to set the LE Supported (Host) and Simultaneous LE and BR/EDR to Same Device
810    Capable (Host) Link Manager Protocol feature bits. These Link Manager Protocol feature bits are used by a remote Host. See
811    [Vol 2] Part C, Section 3.2.
812"""
813def write_le_host_support(transport, idx, suppLe, simul, to):
814
815    cmd = struct.pack('<HHHBB', Commands.CMD_WRITE_LE_HOST_SUPPORT_REQ, 4, HCICommands.BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, suppLe, simul);
816    transport.send(idx, cmd);
817
818    packet = transport.recv(idx, 5, to);
819
820    if ( 5 != len(packet) ):
821        raise Exception("Write LE Host Support command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
822
823    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
824
825    if ( RespCmd != Commands.CMD_WRITE_LE_HOST_SUPPORT_RSP ):
826        raise Exception("Write LE Host Support command failed: Inappropriate command response received");
827
828    if ( RespLen != 1 ):
829        raise Exception("Write LE Host Support command failed: Response length field corrupted (%i)" % RespLen);
830
831    return status;
832
833"""
834    This command reads the Authenticated_Payload_Timeout (authenticatedPayloadTO, see [Vol 2] Part B, Section Appendix B for
835    BR/EDR connections and [Vol 6] Part B, Section 5.4 for LE connections) parameter in the Primary Controller on the
836    specified Connection_Handle.
837"""
838def read_authenticated_payload_timeout(transport, idx, handle, to):
839
840    cmd = struct.pack('<HHHH', Commands.CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ, 4, HCICommands.BT_HCI_OP_READ_AUTH_PAYLOAD_TIMEOUT, handle);
841    transport.send(idx, cmd);
842
843    packet = transport.recv(idx, 9, to);
844
845    if ( 9 != len(packet) ):
846        raise Exception("Read Authenticated Payload Timeout command failed: Response too short (Expected %i bytes got %i bytes)" % (9, len(packet)));
847
848    RespCmd, RespLen, status, handle, AuthPayloadTimeout = struct.unpack('<HHBHH', packet);
849
850    if ( RespCmd != Commands.CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP ):
851        raise Exception("Read Authenticated Payload Timeout command failed: Inappropriate command response received");
852
853    if ( RespLen != 5 ):
854        raise Exception("Read Authenticated Payload Timeout command failed: Response length field corrupted (%i)" % RespLen);
855
856    return status, handle, AuthPayloadTimeout;
857
858"""
859    This command writes the Authenticated_Payload_Timeout (authenticatedPayloadTO, see [Vol 2] Part B, Section Appendix B and
860    [Vol 6] Part B, Section 5.4 for the LE connection) parameter in the Primary Controller for the specified
861    Connection_Handle.
862"""
863def write_authenticated_payload_timeout(transport, idx, handle, AuthPayloadTimeout, to):
864
865    cmd = struct.pack('<HHHHH', Commands.CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ, 6, HCICommands.BT_HCI_OP_WRITE_AUTH_PAYLOAD_TIMEOUT, handle, AuthPayloadTimeout);
866    transport.send(idx, cmd);
867
868    packet = transport.recv(idx, 7, to);
869
870    if ( 7 != len(packet) ):
871        raise Exception("Write Authenticated Payload Timeout command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
872
873    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
874
875    if ( RespCmd != Commands.CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP ):
876        raise Exception("Write Authenticated Payload Timeout command failed: Inappropriate command response received");
877
878    if ( RespLen != 3 ):
879        raise Exception("Write Authenticated Payload Timeout command failed: Response length field corrupted (%i)" % RespLen);
880
881    return status, handle;
882
883"""
884    This command reads the values for the version information for the local Controller. The HCI Version information defines
885    the version information of the HCI layer. The LMP/PAL Version information defines the version of the LMP or PAL. The
886    Manufacturer_Name information indicates the manufacturer of the local device. The HCI Revision and LMP/PAL Subversion are
887    implementation dependent.
888"""
889def read_local_version_information(transport, idx, to):
890
891    cmd = struct.pack('<HHH', Commands.CMD_READ_LOCAL_VERSION_INFORMATION_REQ, 2, HCICommands.BT_HCI_OP_READ_LOCAL_VERSION_INFO);
892    transport.send(idx, cmd);
893
894    packet = transport.recv(idx, 13, to);
895
896    if ( 13 != len(packet) ):
897        raise Exception("Read Local Version Information command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
898
899    RespCmd, RespLen, status, HCIVersion, HCIRevision, LMPVersion, manufacturer, LMPSubversion = struct.unpack('<HHBBHBHH', packet);
900
901    if ( RespCmd != Commands.CMD_READ_LOCAL_VERSION_INFORMATION_RSP ):
902        raise Exception("Read Local Version Information command failed: Inappropriate command response received");
903
904    if ( RespLen != 9 ):
905        raise Exception("Read Local Version Information command failed: Response length field corrupted (%i)" % RespLen);
906
907    return status, HCIVersion, HCIRevision, LMPVersion, manufacturer, LMPSubversion;
908
909"""
910    This command reads the list of HCI commands supported for the local Controller. This command shall return the
911    Supported_Commands configuration parameter. It is implied that if a command is listed as supported, the feature underlying
912    that command is also supported.
913"""
914def read_local_supported_commands(transport, idx, to):
915
916    cmd = struct.pack('<HHH', Commands.CMD_READ_LOCAL_SUPPORTED_COMMANDS_REQ, 2, HCICommands.BT_HCI_OP_READ_SUPPORTED_COMMANDS);
917    transport.send(idx, cmd);
918
919    packet = transport.recv(idx, 69, to);
920
921    if ( 69 != len(packet) ):
922        raise Exception("Read Local Supported Commands command failed: Response too short (Expected %i bytes got %i bytes)" % (69, len(packet)));
923
924    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
925    commands = struct.unpack('<64B', packet[5:]);
926
927    if ( RespCmd != Commands.CMD_READ_LOCAL_SUPPORTED_COMMANDS_RSP ):
928        raise Exception("Read Local Supported Commands command failed: Inappropriate command response received");
929
930    if ( RespLen != 65 ):
931        raise Exception("Read Local Supported Commands command failed: Response length field corrupted (%i)" % RespLen);
932
933    return status, commands;
934
935"""
936    This command requests a list of the supported features for the local BR/EDR Controller. This command will return a list of
937    the LMP features. For details see [Vol 2] Part C, Link Manager Protocol Specification.
938"""
939def read_local_supported_features(transport, idx, to):
940
941    cmd = struct.pack('<HHH', Commands.CMD_READ_LOCAL_SUPPORTED_FEATURES_REQ, 2, HCICommands.BT_HCI_OP_READ_LOCAL_FEATURES);
942    transport.send(idx, cmd);
943
944    packet = transport.recv(idx, 13, to);
945
946    if ( 13 != len(packet) ):
947        raise Exception("Read Local Supported Features command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
948
949    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
950    features = struct.unpack('<8B', packet[5:]);
951
952    if ( RespCmd != Commands.CMD_READ_LOCAL_SUPPORTED_FEATURES_RSP ):
953        raise Exception("Read Local Supported Features command failed: Inappropriate command response received");
954
955    if ( RespLen != 9 ):
956        raise Exception("Read Local Supported Features command failed: Response length field corrupted (%i)" % RespLen);
957
958    return status, features;
959
960"""
961    The Read_Buffer_Size command is used to read the maximum size of the data portion of HCI ACL and synchronous Data Packets
962    sent from the Host to the Controller. The Host will segment the data to be transmitted from the Host to the Controller
963    according to these sizes, so that the HCI Data Packets will contain data with up to these sizes. The Read_Buffer_Size
964    command also returns the total number of HCI ACL and synchronous Data Packets that can be stored in the data buffers of
965    the Controller. The Read_Buffer_Size command must be issued by the Host before it sends any data to the Controller.
966"""
967def read_buffer_size(transport, idx, to):
968
969    cmd = struct.pack('<HHH', Commands.CMD_READ_BUFFER_SIZE_REQ, 2, HCICommands.BT_HCI_OP_READ_BUFFER_SIZE);
970    transport.send(idx, cmd);
971
972    packet = transport.recv(idx, 5, to);
973    assert 5 == len(packet), f"Received invalid length packet {len(packet)}"
974
975    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
976
977    if ( RespCmd != Commands.CMD_READ_BUFFER_SIZE_RSP ):
978        raise Exception("Read Buffer Size command failed: Inappropriate command response received");
979
980    if RespLen == 1:
981        # Unsupported command
982        return status
983
984    assert RespLen != 8, f"Response length field corrupted ({RespLen})"
985
986    packet = transport.recv(idx, 7, to)
987    assert 7 == len(packet), f"Received invalid length packet {len(packet)}"
988
989    AclMaxLen, ScoMaxLen, AclMaxNum, ScoMaxNum = struct.unpack('<HBHH', packet);
990
991    return status, AclMaxLen, ScoMaxLen, AclMaxNum, ScoMaxNum
992
993"""
994    On an LE Controller, this command shall read the Public Device Address as defined in [Vol 6] Part B, Section 1.3. If this
995    Controller does not have a Public Device Address, the value 0x000000000000 shall be returned. On a BR/EDR/LE Controller,
996    the public address shall be the same as the BD_ADDR.
997"""
998def read_bd_addr(transport, idx, to):
999
1000    cmd = struct.pack('<HHH', Commands.CMD_READ_BD_ADDR_REQ, 2, HCICommands.BT_HCI_OP_READ_BD_ADDR);
1001    transport.send(idx, cmd);
1002
1003    packet = transport.recv(idx, 11, to);
1004
1005    if ( 11 != len(packet) ):
1006        raise Exception("Read BD_ADDR command failed: Response too short (Expected %i bytes got %i bytes)" % (11, len(packet)));
1007
1008    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
1009    BdaddrVal = struct.unpack('<6B', packet[5:]);
1010
1011    if ( RespCmd != Commands.CMD_READ_BD_ADDR_RSP ):
1012        raise Exception("Read BD_ADDR command failed: Inappropriate command response received");
1013
1014    if ( RespLen != 7 ):
1015        raise Exception("Read BD_ADDR command failed: Response length field corrupted (%i)" % RespLen);
1016
1017    return status, BdaddrVal;
1018
1019"""
1020    This command reads the Received Signal Strength Indication (RSSI) value from a Controller.
1021"""
1022def read_rssi(transport, idx, handle, to):
1023
1024    cmd = struct.pack('<HHHH', Commands.CMD_READ_RSSI_REQ, 4, HCICommands.BT_HCI_OP_READ_RSSI, handle);
1025    transport.send(idx, cmd);
1026
1027    packet = transport.recv(idx, 8, to);
1028
1029    if ( 8 != len(packet) ):
1030        raise Exception("Read RSSI command failed: Response too short (Expected %i bytes got %i bytes)" % (8, len(packet)));
1031
1032    RespCmd, RespLen, status, handle, rssi = struct.unpack('<HHBHb', packet);
1033
1034    if ( RespCmd != Commands.CMD_READ_RSSI_RSP ):
1035        raise Exception("Read RSSI command failed: Inappropriate command response received");
1036
1037    if ( RespLen != 4 ):
1038        raise Exception("Read RSSI command failed: Response length field corrupted (%i)" % RespLen);
1039
1040    return status, handle, rssi;
1041
1042"""
1043    The LE_Set_Event_Mask command is used to control which LE events are generated by the HCI for the Host.
1044"""
1045def le_set_event_mask(transport, idx, events, to):
1046
1047    cmd = struct.pack('<HHH8B', Commands.CMD_LE_SET_EVENT_MASK_REQ, 10, HCICommands.BT_HCI_OP_LE_SET_EVENT_MASK, *events);
1048    transport.send(idx, cmd);
1049
1050    packet = transport.recv(idx, 5, to);
1051
1052    if ( 5 != len(packet) ):
1053        raise Exception("LE Set Event Mask command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1054
1055    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1056
1057    if ( RespCmd != Commands.CMD_LE_SET_EVENT_MASK_RSP ):
1058        raise Exception("LE Set Event Mask command failed: Inappropriate command response received");
1059
1060    if ( RespLen != 1 ):
1061        raise Exception("LE Set Event Mask command failed: Response length field corrupted (%i)" % RespLen);
1062
1063    return status;
1064
1065"""
1066    The LE_Read_Buffer_Size command is used to read the maximum size of the data portion of HCI LE ACL Data Packets sent from
1067    the Host to the Controller. The Host will segment the data transmitted to the Controller according to these values, so
1068    that the HCI Data Packets will contain data with up to this size. The LE_Read_Buffer_Size command also returns the total
1069    number of HCI LE ACL Data Packets that can be stored in the data buffers of the Controller. The LE_Read_Buffer_Size
1070    command must be issued by the Host before it sends any data to an LE Controller (see Section 4.1.1).
1071"""
1072def le_read_buffer_size(transport, idx, to):
1073
1074    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_BUFFER_SIZE_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_BUFFER_SIZE);
1075    transport.send(idx, cmd);
1076
1077    packet = transport.recv(idx, 8, to);
1078
1079    if ( 8 != len(packet) ):
1080        raise Exception("LE Read Buffer Size command failed: Response too short (Expected %i bytes got %i bytes)" % (8, len(packet)));
1081
1082    RespCmd, RespLen, status, LeMaxLen, LeMaxNum = struct.unpack('<HHBHB', packet);
1083
1084    if ( RespCmd != Commands.CMD_LE_READ_BUFFER_SIZE_RSP ):
1085        raise Exception("LE Read Buffer Size command failed: Inappropriate command response received");
1086
1087    if ( RespLen != 4 ):
1088        raise Exception("LE Read Buffer Size command failed: Response length field corrupted (%i)" % RespLen);
1089
1090    return status, LeMaxLen, LeMaxNum;
1091
1092"""
1093    The LE_Read_Buffer_Size command is used to read the maximum size of the data portion of HCI LE ACL Data Packets sent from
1094    the Host to the Controller. The Host will segment the data transmitted to the Controller according to these values, so
1095    that the HCI Data Packets will contain data with up to this size. The LE_Read_Buffer_Size command also returns the total
1096    number of HCI LE ACL Data Packets that can be stored in the data buffers of the Controller. The LE_Read_Buffer_Size
1097    command must be issued by the Host before it sends any data to an LE Controller (see Section 4.1.1).
1098"""
1099def le_read_buffer_size_v2(transport, idx, to):
1100
1101    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_BUFFER_SIZE_V2_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_BUFFER_SIZE_V2);
1102    transport.send(idx, cmd);
1103
1104    packet = transport.recv(idx, 11, to);
1105
1106    if ( 11 != len(packet) ):
1107        raise Exception("LE Read Buffer Size V2 command failed: Response too short (Expected %i bytes got %i bytes)" % (11, len(packet)));
1108
1109    RespCmd, RespLen, status, LeMaxLen, LeMaxNum, IsoMaxLen, IsoMaxNum = struct.unpack('<HHBHBHB', packet);
1110
1111    if ( RespCmd != Commands.CMD_LE_READ_BUFFER_SIZE_V2_RSP ):
1112        raise Exception("LE Read Buffer Size V2 command failed: Inappropriate command response received");
1113
1114    if ( RespLen != 7 ):
1115        raise Exception("LE Read Buffer Size V2 command failed: Response length field corrupted (%i)" % RespLen);
1116
1117    return status, LeMaxLen, LeMaxNum, IsoMaxLen, IsoMaxNum;
1118
1119"""
1120    This command requests the list of the supported LE features for the Controller.
1121"""
1122def le_read_local_supported_features(transport, idx, to):
1123
1124    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_LOCAL_FEATURES);
1125    transport.send(idx, cmd);
1126
1127    packet = transport.recv(idx, 13, to);
1128
1129    if ( 13 != len(packet) ):
1130        raise Exception("LE Read Local Supported Features command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
1131
1132    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
1133    features = struct.unpack('<8B', packet[5:]);
1134
1135    if ( RespCmd != Commands.CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_RSP ):
1136        raise Exception("LE Read Local Supported Features command failed: Inappropriate command response received");
1137
1138    if ( RespLen != 9 ):
1139        raise Exception("LE Read Local Supported Features command failed: Response length field corrupted (%i)" % RespLen);
1140
1141    return status, features;
1142
1143"""
1144    The LE_Set_Random_Address command is used by the Host to set the LE Random Device Address in the Controller (see [Vol 6]
1145    Part B, Section 1.3).
1146"""
1147def le_set_random_address(transport, idx, BdaddrVal, to):
1148
1149    cmd = struct.pack('<HHH6B', Commands.CMD_LE_SET_RANDOM_ADDRESS_REQ, 8, HCICommands.BT_HCI_OP_LE_SET_RANDOM_ADDRESS, *BdaddrVal);
1150    transport.send(idx, cmd);
1151
1152    packet = transport.recv(idx, 5, to);
1153
1154    if ( 5 != len(packet) ):
1155        raise Exception("LE Set Random Address command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1156
1157    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1158
1159    if ( RespCmd != Commands.CMD_LE_SET_RANDOM_ADDRESS_RSP ):
1160        raise Exception("LE Set Random Address command failed: Inappropriate command response received");
1161
1162    if ( RespLen != 1 ):
1163        raise Exception("LE Set Random Address command failed: Response length field corrupted (%i)" % RespLen);
1164
1165    return status;
1166
1167"""
1168    The LE_Set_Advertising_Parameters command is used by the Host to set the advertising parameters.
1169"""
1170def le_set_advertising_parameters(transport, idx, MinInterval, MaxInterval, paramType, OwnAddrType, DirectAddrType, AVal, ChannelMap, FilterPolicy, to):
1171
1172    cmd = struct.pack('<HHHHHBBB6B', Commands.CMD_LE_SET_ADVERTISING_PARAMETERS_REQ, 17, HCICommands.BT_HCI_OP_LE_SET_ADV_PARAM, MinInterval, MaxInterval, paramType, OwnAddrType, DirectAddrType, *AVal);
1173    cmd += struct.pack('<BB', ChannelMap, FilterPolicy);
1174    transport.send(idx, cmd);
1175
1176    packet = transport.recv(idx, 5, to);
1177
1178    if ( 5 != len(packet) ):
1179        raise Exception("LE Set Advertising Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1180
1181    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1182
1183    if ( RespCmd != Commands.CMD_LE_SET_ADVERTISING_PARAMETERS_RSP ):
1184        raise Exception("LE Set Advertising Parameters command failed: Inappropriate command response received");
1185
1186    if ( RespLen != 1 ):
1187        raise Exception("LE Set Advertising Parameters command failed: Response length field corrupted (%i)" % RespLen);
1188
1189    return status;
1190
1191"""
1192    The LE_Read_Advertising_Channel_TX_Power command is used by the Host to read the transmit power level used for LE
1193    advertising channel packets.
1194"""
1195def le_read_advertising_channel_tx_power(transport, idx, to):
1196
1197    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_ADV_CHAN_TX_POWER);
1198    transport.send(idx, cmd);
1199
1200    packet = transport.recv(idx, 6, to);
1201
1202    if ( 6 != len(packet) ):
1203        raise Exception("LE Read Advertising Channel TX Power command failed: Response too short (Expected %i bytes got %i bytes)" % (6, len(packet)));
1204
1205    RespCmd, RespLen, status, TxPowerLevel = struct.unpack('<HHBb', packet);
1206
1207    if ( RespCmd != Commands.CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_RSP ):
1208        raise Exception("LE Read Advertising Channel TX Power command failed: Inappropriate command response received");
1209
1210    if ( RespLen != 2 ):
1211        raise Exception("LE Read Advertising Channel TX Power command failed: Response length field corrupted (%i)" % RespLen);
1212
1213    return status, TxPowerLevel;
1214
1215"""
1216    The LE_Set_Advertising_Data command is used to set the data used in advertising packets that have a data field.
1217"""
1218def le_set_advertising_data(transport, idx, dataLen, data, to):
1219
1220    cmd = struct.pack('<HHHB31B', Commands.CMD_LE_SET_ADVERTISING_DATA_REQ, 34, HCICommands.BT_HCI_OP_LE_SET_ADV_DATA, dataLen, *data);
1221    transport.send(idx, cmd);
1222
1223    packet = transport.recv(idx, 5, to);
1224
1225    if ( 5 != len(packet) ):
1226        raise Exception("LE Set Advertising Data command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1227
1228    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1229
1230    if ( RespCmd != Commands.CMD_LE_SET_ADVERTISING_DATA_RSP ):
1231        raise Exception("LE Set Advertising Data command failed: Inappropriate command response received");
1232
1233    if ( RespLen != 1 ):
1234        raise Exception("LE Set Advertising Data command failed: Response length field corrupted (%i)" % RespLen);
1235
1236    return status;
1237
1238"""
1239    This command is used to provide data used in Scanning Packets that have a data field.
1240"""
1241def le_set_scan_response_data(transport, idx, dataLen, data, to):
1242
1243    cmd = struct.pack('<HHHB31B', Commands.CMD_LE_SET_SCAN_RESPONSE_DATA_REQ, 34, HCICommands.BT_HCI_OP_LE_SET_SCAN_RSP_DATA, dataLen, *data);
1244    transport.send(idx, cmd);
1245
1246    packet = transport.recv(idx, 5, to);
1247
1248    if ( 5 != len(packet) ):
1249        raise Exception("LE Set Scan Response Data command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1250
1251    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1252
1253    if ( RespCmd != Commands.CMD_LE_SET_SCAN_RESPONSE_DATA_RSP ):
1254        raise Exception("LE Set Scan Response Data command failed: Inappropriate command response received");
1255
1256    if ( RespLen != 1 ):
1257        raise Exception("LE Set Scan Response Data command failed: Response length field corrupted (%i)" % RespLen);
1258
1259    return status;
1260
1261"""
1262    The LE_Set_Advertising_Enable command is used to request the Controller to start or stop advertising. The Controller
1263    manages the timing of advertisements as per the advertising parameters given in the LE_Set_Advertising_Parameters command.
1264"""
1265def le_set_advertising_enable(transport, idx, enable, to):
1266
1267    cmd = struct.pack('<HHHB', Commands.CMD_LE_SET_ADVERTISING_ENABLE_REQ, 3, HCICommands.BT_HCI_OP_LE_SET_ADV_ENABLE, enable);
1268    transport.send(idx, cmd);
1269
1270    packet = transport.recv(idx, 5, to);
1271
1272    if ( 5 != len(packet) ):
1273        raise Exception("LE Set Advertising Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1274
1275    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1276
1277    if ( RespCmd != Commands.CMD_LE_SET_ADVERTISING_ENABLE_RSP ):
1278        raise Exception("LE Set Advertising Enable command failed: Inappropriate command response received");
1279
1280    if ( RespLen != 1 ):
1281        raise Exception("LE Set Advertising Enable command failed: Response length field corrupted (%i)" % RespLen);
1282
1283    return status;
1284
1285"""
1286    The LE_Set_Scan_Parameters command is used to set the scan parameters. The LE_Scan_Type parameter controls the type of
1287    scan to perform.
1288"""
1289def le_set_scan_parameters(transport, idx, ScanType, interval, window, AddrType, FilterPolicy, to):
1290
1291    cmd = struct.pack('<HHHBHHBB', Commands.CMD_LE_SET_SCAN_PARAMETERS_REQ, 9, HCICommands.BT_HCI_OP_LE_SET_SCAN_PARAM, ScanType, interval, window, AddrType, FilterPolicy);
1292    transport.send(idx, cmd);
1293
1294    packet = transport.recv(idx, 5, to);
1295
1296    if ( 5 != len(packet) ):
1297        raise Exception("LE Set Scan Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1298
1299    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1300
1301    if ( RespCmd != Commands.CMD_LE_SET_SCAN_PARAMETERS_RSP ):
1302        raise Exception("LE Set Scan Parameters command failed: Inappropriate command response received");
1303
1304    if ( RespLen != 1 ):
1305        raise Exception("LE Set Scan Parameters command failed: Response length field corrupted (%i)" % RespLen);
1306
1307    return status;
1308
1309"""
1310    The LE_Set_Scan_Enable command is used to start scanning. Scanning is used to discover advertising devices nearby.
1311"""
1312def le_set_scan_enable(transport, idx, enable, FilterDup, to):
1313
1314    cmd = struct.pack('<HHHBB', Commands.CMD_LE_SET_SCAN_ENABLE_REQ, 4, HCICommands.BT_HCI_OP_LE_SET_SCAN_ENABLE, enable, FilterDup);
1315    transport.send(idx, cmd);
1316
1317    packet = transport.recv(idx, 5, to);
1318
1319    if ( 5 != len(packet) ):
1320        raise Exception("LE Set Scan Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1321
1322    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1323
1324    if ( RespCmd != Commands.CMD_LE_SET_SCAN_ENABLE_RSP ):
1325        raise Exception("LE Set Scan Enable command failed: Inappropriate command response received");
1326
1327    if ( RespLen != 1 ):
1328        raise Exception("LE Set Scan Enable command failed: Response length field corrupted (%i)" % RespLen);
1329
1330    return status;
1331
1332"""
1333    The LE_Create_Connection command is used to create a Link Layer connection to a connectable advertiser.
1334"""
1335def le_create_connection(transport, idx, ScanInterval, ScanWindow, FilterPolicy, PeerAddrType, AVal, OwnAddrType, ConnIntervalMin, ConnIntervalMax, ConnLatency, SupervisionTimeout, MinCeLen, MaxCeLen, to):
1336
1337    cmd = struct.pack('<HHHHHBB6B', Commands.CMD_LE_CREATE_CONNECTION_REQ, 27, HCICommands.BT_HCI_OP_LE_CREATE_CONN, ScanInterval, ScanWindow, FilterPolicy, PeerAddrType, *AVal);
1338    cmd += struct.pack('<BHHHHHH', OwnAddrType, ConnIntervalMin, ConnIntervalMax, ConnLatency, SupervisionTimeout, MinCeLen, MaxCeLen);
1339    transport.send(idx, cmd);
1340
1341    packet = transport.recv(idx, 5, to);
1342
1343    if ( 5 != len(packet) ):
1344        raise Exception("LE Create Connection command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1345
1346    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1347
1348    if ( RespCmd != Commands.CMD_LE_CREATE_CONNECTION_RSP ):
1349        raise Exception("LE Create Connection command failed: Inappropriate command response received");
1350
1351    if ( RespLen != 1 ):
1352        raise Exception("LE Create Connection command failed: Response length field corrupted (%i)" % RespLen);
1353
1354    return status;
1355
1356"""
1357    The LE_Create_Connection_Cancel command is used to cancel the LE_Create_Connection or LE_Extended_Create_Connection
1358    commands. This command shall only be issued after the LE_Create_Connection or LE_Extended_Create_Connection commands have
1359    been issued, a Command Status event has been received for the LE Create Connection or LE_Extended_Create_Connection
1360    commands, and before the LE Connection Complete or LE Enhanced Connection Complete events.
1361"""
1362def le_create_connection_cancel(transport, idx, to):
1363
1364    cmd = struct.pack('<HHH', Commands.CMD_LE_CREATE_CONNECTION_CANCEL_REQ, 2, HCICommands.BT_HCI_OP_LE_CREATE_CONN_CANCEL);
1365    transport.send(idx, cmd);
1366
1367    packet = transport.recv(idx, 5, to);
1368
1369    if ( 5 != len(packet) ):
1370        raise Exception("LE Create Connection Cancel command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1371
1372    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1373
1374    if ( RespCmd != Commands.CMD_LE_CREATE_CONNECTION_CANCEL_RSP ):
1375        raise Exception("LE Create Connection Cancel command failed: Inappropriate command response received");
1376
1377    if ( RespLen != 1 ):
1378        raise Exception("LE Create Connection Cancel command failed: Response length field corrupted (%i)" % RespLen);
1379
1380    return status;
1381
1382"""
1383    The LE_Read_Filter_Accept_List_Size command is used to read the total number of Filter Accept List entries that can be stored in the
1384    Controller.
1385"""
1386def le_read_filter_accept_list_size(transport, idx, to):
1387
1388    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_FAL_SIZE);
1389    transport.send(idx, cmd);
1390
1391    packet = transport.recv(idx, 6, to);
1392
1393    if ( 6 != len(packet) ):
1394        raise Exception("LE Read Filter Accept List Size command failed: Response too short (Expected %i bytes got %i bytes)" % (6, len(packet)));
1395
1396    RespCmd, RespLen, status, FalSize = struct.unpack('<HHBB', packet);
1397
1398    if ( RespCmd != Commands.CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_RSP ):
1399        raise Exception("LE Read Filter Accept List Size command failed: Inappropriate command response received");
1400
1401    if ( RespLen != 2 ):
1402        raise Exception("LE Read Filter Accept List Size command failed: Response length field corrupted (%i)" % RespLen);
1403
1404    return status, FalSize;
1405
1406"""
1407    The LE_Clear_Filter_Accept_List command is used to clear the Filter Accept List stored in the Controller.
1408"""
1409def le_clear_filter_accept_list(transport, idx, to):
1410
1411    cmd = struct.pack('<HHH', Commands.CMD_LE_CLEAR_FILTER_ACCEPT_LIST_REQ, 2, HCICommands.BT_HCI_OP_LE_CLEAR_FAL);
1412    transport.send(idx, cmd);
1413
1414    packet = transport.recv(idx, 5, to);
1415
1416    if ( 5 != len(packet) ):
1417        raise Exception("LE Clear Filter Accept List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1418
1419    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1420
1421    if ( RespCmd != Commands.CMD_LE_CLEAR_FILTER_ACCEPT_LIST_RSP ):
1422        raise Exception("LE Clear Filter Accept List command failed: Inappropriate command response received");
1423
1424    if ( RespLen != 1 ):
1425        raise Exception("LE Clear Filter Accept List command failed: Response length field corrupted (%i)" % RespLen);
1426
1427    return status;
1428
1429"""
1430    The LE_Add_Device_To_Filter_Accept_List command is used to add a single device to the Filter Accept List stored in the Controller.
1431"""
1432def le_add_device_to_filter_accept_list(transport, idx, AddrType, AVal, to):
1433
1434    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_REQ, 9, HCICommands.BT_HCI_OP_LE_ADD_DEV_TO_FAL, AddrType, *AVal);
1435    transport.send(idx, cmd);
1436
1437    packet = transport.recv(idx, 5, to);
1438
1439    if ( 5 != len(packet) ):
1440        raise Exception("LE Add Device To Filter Accept List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1441
1442    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1443
1444    if ( RespCmd != Commands.CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_RSP ):
1445        raise Exception("LE Add Device To Filter Accept List command failed: Inappropriate command response received");
1446
1447    if ( RespLen != 1 ):
1448        raise Exception("LE Add Device To Filter Accept List command failed: Response length field corrupted (%i)" % RespLen);
1449
1450    return status;
1451
1452"""
1453    The LE_Remove_Device_From_Filter_Accept_List command is used to remove a single device from the Filter Accept List stored in the
1454    Controller.
1455"""
1456def le_remove_device_from_filter_accept_list(transport, idx, AddrType, AVal, to):
1457
1458    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_REQ, 9, HCICommands.BT_HCI_OP_LE_REM_DEV_FROM_FAL, AddrType, *AVal);
1459    transport.send(idx, cmd);
1460
1461    packet = transport.recv(idx, 5, to);
1462
1463    if ( 5 != len(packet) ):
1464        raise Exception("LE Remove Device From Filter Accept List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1465
1466    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1467
1468    if ( RespCmd != Commands.CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_RSP ):
1469        raise Exception("LE Remove Device From Filter Accept List command failed: Inappropriate command response received");
1470
1471    if ( RespLen != 1 ):
1472        raise Exception("LE Remove Device From Filter Accept List command failed: Response length field corrupted (%i)" % RespLen);
1473
1474    return status;
1475
1476"""
1477    The LE_Connection_Update command is used to change the Link Layer connection parameters of a connection. This command may
1478    be issued on both the central and peripheral.
1479"""
1480def le_connection_update(transport, idx, handle, ConnIntervalMin, ConnIntervalMax, ConnLatency, SupervisionTimeout, MinCeLen, MaxCeLen, to):
1481
1482    cmd = struct.pack('<HHHHHHHHHH', Commands.CMD_LE_CONNECTION_UPDATE_REQ, 16, HCICommands.BT_HCI_OP_LE_CONN_UPDATE, handle, ConnIntervalMin, ConnIntervalMax, ConnLatency, SupervisionTimeout, MinCeLen, MaxCeLen);
1483    transport.send(idx, cmd);
1484
1485    packet = transport.recv(idx, 5, to);
1486
1487    if ( 5 != len(packet) ):
1488        raise Exception("LE Connection Update command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1489
1490    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1491
1492    if ( RespCmd != Commands.CMD_LE_CONNECTION_UPDATE_RSP ):
1493        raise Exception("LE Connection Update command failed: Inappropriate command response received");
1494
1495    if ( RespLen != 1 ):
1496        raise Exception("LE Connection Update command failed: Response length field corrupted (%i)" % RespLen);
1497
1498    return status;
1499
1500"""
1501    The LE_Set_Host_Channel_Classification command allows the Host to specify a channel classification for data channels based
1502    on its \93local information\94. This classification persists until overwritten with a subsequent
1503    LE_Set_Host_Channel_Classification command or until the Controller is reset using the Reset command (see [Vol 6] Part B,
1504    Section 4.5.8.1).
1505"""
1506def le_set_host_channel_classification(transport, idx, ChMap, to):
1507
1508    cmd = struct.pack('<HHH5B', Commands.CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_REQ, 7, HCICommands.BT_HCI_OP_LE_SET_HOST_CHAN_CLASSIF, *ChMap);
1509    transport.send(idx, cmd);
1510
1511    packet = transport.recv(idx, 5, to);
1512
1513    if ( 5 != len(packet) ):
1514        raise Exception("LE Set Host Channel Classification command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1515
1516    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1517
1518    if ( RespCmd != Commands.CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_RSP ):
1519        raise Exception("LE Set Host Channel Classification command failed: Inappropriate command response received");
1520
1521    if ( RespLen != 1 ):
1522        raise Exception("LE Set Host Channel Classification command failed: Response length field corrupted (%i)" % RespLen);
1523
1524    return status;
1525
1526"""
1527    The LE_Read_Channel_Map command returns the current Channel_Map for the specified Connection_Handle.
1528"""
1529def le_read_channel_map(transport, idx, handle, to):
1530
1531    cmd = struct.pack('<HHHH', Commands.CMD_LE_READ_CHANNEL_MAP_REQ, 4, HCICommands.BT_HCI_OP_LE_READ_CHAN_MAP, handle);
1532    transport.send(idx, cmd);
1533
1534    packet = transport.recv(idx, 12, to);
1535
1536    if ( 12 != len(packet) ):
1537        raise Exception("LE Read Channel Map command failed: Response too short (Expected %i bytes got %i bytes)" % (12, len(packet)));
1538
1539    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet[:7]);
1540    ChMap = struct.unpack('<5B', packet[7:]);
1541
1542    if ( RespCmd != Commands.CMD_LE_READ_CHANNEL_MAP_RSP ):
1543        raise Exception("LE Read Channel Map command failed: Inappropriate command response received");
1544
1545    if ( RespLen != 8 ):
1546        raise Exception("LE Read Channel Map command failed: Response length field corrupted (%i)" % RespLen);
1547
1548    return status, handle, int.from_bytes(ChMap, 'little', signed=False)
1549
1550"""
1551    This command requests, from the remote device identified by the connection handle, the features used on the connection and
1552    the features supported by the remote device. For details see [Vol 6] Part B, Section 4.6.
1553"""
1554def le_read_remote_features(transport, idx, handle, to):
1555
1556    cmd = struct.pack('<HHHH', Commands.CMD_LE_READ_REMOTE_FEATURES_REQ, 4, HCICommands.BT_HCI_OP_LE_READ_REMOTE_FEATURES, handle);
1557    transport.send(idx, cmd);
1558
1559    packet = transport.recv(idx, 5, to);
1560
1561    if ( 5 != len(packet) ):
1562        raise Exception("LE Read Remote Features command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1563
1564    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1565
1566    if ( RespCmd != Commands.CMD_LE_READ_REMOTE_FEATURES_RSP ):
1567        raise Exception("LE Read Remote Features command failed: Inappropriate command response received");
1568
1569    if ( RespLen != 1 ):
1570        raise Exception("LE Read Remote Features command failed: Response length field corrupted (%i)" % RespLen);
1571
1572    return status;
1573
1574"""
1575    The LE_Encrypt command is used to request the Controller to encrypt the Plaintext_Data in the command using the Key given
1576    in the command and returns the Encrypted_Data to the Host.
1577"""
1578def le_encrypt(transport, idx, key, plaintext, to):
1579    def pad_or_slice(L, n):
1580        L = list(L)
1581        if len(L) < n:
1582            return L + ([0] * (n - len(L)))
1583        else:
1584            return L[:n]
1585
1586    key = pad_or_slice(key, 16)
1587    plaintext = pad_or_slice(plaintext, 16)
1588
1589    cmd = struct.pack('<HHH16B', Commands.CMD_LE_ENCRYPT_REQ, 34, HCICommands.BT_HCI_OP_LE_ENCRYPT, *key);
1590    cmd += struct.pack('<16B', *plaintext);
1591    transport.send(idx, cmd);
1592
1593    packet = transport.recv(idx, 21, to);
1594
1595    if ( 21 != len(packet) ):
1596        raise Exception("LE Encrypt command failed: Response too short (Expected %i bytes got %i bytes)" % (21, len(packet)));
1597
1598    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
1599    EncData = struct.unpack('<16B', packet[5:]);
1600
1601    if ( RespCmd != Commands.CMD_LE_ENCRYPT_RSP ):
1602        raise Exception("LE Encrypt command failed: Inappropriate command response received");
1603
1604    if ( RespLen != 17 ):
1605        raise Exception("LE Encrypt command failed: Response length field corrupted (%i)" % RespLen);
1606
1607    return status, EncData;
1608
1609"""
1610    The LE_Rand command is used to request the Controller to generate 8 octets of random data to be sent to the Host. The
1611    Random_Number shall be generated according to [Vol 2] Part H, Section 2 if the LE Feature (LE Encryption) is supported.
1612"""
1613def le_rand(transport, idx, to):
1614
1615    cmd = struct.pack('<HHH', Commands.CMD_LE_RAND_REQ, 2, HCICommands.BT_HCI_OP_LE_RAND);
1616    transport.send(idx, cmd);
1617
1618    packet = transport.recv(idx, 13, to);
1619
1620    if ( 13 != len(packet) ):
1621        raise Exception("LE Rand command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
1622
1623    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
1624    rand = struct.unpack('<8B', packet[5:]);
1625
1626    if ( RespCmd != Commands.CMD_LE_RAND_RSP ):
1627        raise Exception("LE Rand command failed: Inappropriate command response received");
1628
1629    if ( RespLen != 9 ):
1630        raise Exception("LE Rand command failed: Response length field corrupted (%i)" % RespLen);
1631
1632    return status, rand;
1633
1634
1635def le_start_encryption(transport, idx, handle, rand, ediv, ltk, to):
1636    """The LE_Start_Encryption command is used to authenticate the given encryption key associated with the remote
1637    device specified by the Connection_Handle, and once authenticated will encrypt the connection.
1638    :param transport: bearer to be used
1639    :param idx: device index
1640    :param handle: connection handle
1641    :param rand: random number
1642    :param ediv: encrypted diversifier
1643    :param ltk: 16 byte long term key array
1644    :param to: Receiver timeout
1645    :return: status
1646    """
1647    edtt_send_cmd(transport, idx, Commands.CMD_LE_START_ENCRYPTION_REQ, 'HHQH16B',
1648                  (HCICommands.BT_HCI_OP_LE_START_ENCRYPTION, handle, rand, ediv, *ltk))
1649    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_LE_START_ENCRYPTION_RSP, 'B', to)[0]
1650
1651
1652"""
1653    The LE_Long_Term_Key_Request_Reply command is used to reply to an LE Long Term Key Request event from the Controller, and
1654    specifies the Long_Term_Key parameter that shall be used for this Connection_Handle. The Long_Term_Key is used as defined
1655    in [Vol 6] Part B, Section 5.1.3.
1656"""
1657def le_long_term_key_request_reply(transport, idx, handle, ltk, to):
1658
1659    cmd = struct.pack('<HHHH16B', Commands.CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_REQ, 20, HCICommands.BT_HCI_OP_LE_LTK_REQ_REPLY, handle, *ltk);
1660    transport.send(idx, cmd);
1661
1662    packet = transport.recv(idx, 7, to);
1663
1664    if ( 7 != len(packet) ):
1665        raise Exception("LE Long Term Key Request Reply command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1666
1667    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
1668
1669    if ( RespCmd != Commands.CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_RSP ):
1670        raise Exception("LE Long Term Key Request Reply command failed: Inappropriate command response received");
1671
1672    if ( RespLen != 3 ):
1673        raise Exception("LE Long Term Key Request Reply command failed: Response length field corrupted (%i)" % RespLen);
1674
1675    return status, handle;
1676
1677"""
1678    The LE_Long_Term_Key_Request_Negative_Reply command is used to reply to an LE Long Term Key Request event from the
1679    Controller if the Host cannot provide a Long Term Key for this Connection_Handle.
1680"""
1681def le_long_term_key_request_negative_reply(transport, idx, handle, to):
1682
1683    cmd = struct.pack('<HHHH', Commands.CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_REQ, 4, HCICommands.BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, handle);
1684    transport.send(idx, cmd);
1685
1686    packet = transport.recv(idx, 7, to);
1687
1688    if ( 7 != len(packet) ):
1689        raise Exception("LE Long Term Key Request Negative Reply command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1690
1691    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
1692
1693    if ( RespCmd != Commands.CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_RSP ):
1694        raise Exception("LE Long Term Key Request Negative Reply command failed: Inappropriate command response received");
1695
1696    if ( RespLen != 3 ):
1697        raise Exception("LE Long Term Key Request Negative Reply command failed: Response length field corrupted (%i)" % RespLen);
1698
1699    return status, handle;
1700
1701"""
1702    The LE_Read_Supported_States command reads the states and state combinations that the link layer supports. See [Vol 6]
1703    Part B, Section 1.1.1. LE_States is an 8-octet bit field. If a bit is set to 1 then this state or state combination is
1704    supported by the Controller. Multiple bits in LE_States may be set to 1 to indicate support for multiple state and state
1705    combinations.
1706"""
1707def le_read_supported_states(transport, idx, to):
1708
1709    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_SUPPORTED_STATES_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_SUPP_STATES);
1710    transport.send(idx, cmd);
1711
1712    packet = transport.recv(idx, 13, to);
1713
1714    if ( 13 != len(packet) ):
1715        raise Exception("LE Read Supported States command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
1716
1717    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
1718    LeStates = struct.unpack('<8B', packet[5:]);
1719
1720    if ( RespCmd != Commands.CMD_LE_READ_SUPPORTED_STATES_RSP ):
1721        raise Exception("LE Read Supported States command failed: Inappropriate command response received");
1722
1723    if ( RespLen != 9 ):
1724        raise Exception("LE Read Supported States command failed: Response length field corrupted (%i)" % RespLen);
1725
1726    return status, LeStates;
1727
1728"""
1729    This command is used to start a test where the DUT receives test reference packets at a fixed interval. The tester
1730    generates the test reference packets.
1731"""
1732def le_receiver_test(transport, idx, RxCh, to):
1733
1734    cmd = struct.pack('<HHHB', Commands.CMD_LE_RECEIVER_TEST_REQ, 3, HCICommands.BT_HCI_OP_LE_RX_TEST, RxCh);
1735    transport.send(idx, cmd);
1736
1737    packet = transport.recv(idx, 5, to);
1738
1739    if ( 5 != len(packet) ):
1740        raise Exception("LE Receiver Test command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1741
1742    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1743
1744    if ( RespCmd != Commands.CMD_LE_RECEIVER_TEST_RSP ):
1745        raise Exception("LE Receiver Test command failed: Inappropriate command response received");
1746
1747    if ( RespLen != 1 ):
1748        raise Exception("LE Receiver Test command failed: Response length field corrupted (%i)" % RespLen);
1749
1750    return status;
1751
1752"""
1753    This command is used to start a test where the DUT generates test reference packets at a fixed interval. The Controller
1754    shall transmit at maximum power.
1755"""
1756def le_transmitter_test(transport, idx, TxCh, TestDataLen, PktPayload, to):
1757
1758    cmd = struct.pack('<HHHBBB', Commands.CMD_LE_TRANSMITTER_TEST_REQ, 5, HCICommands.BT_HCI_OP_LE_TX_TEST, TxCh, TestDataLen, PktPayload);
1759    transport.send(idx, cmd);
1760
1761    packet = transport.recv(idx, 5, to);
1762
1763    if ( 5 != len(packet) ):
1764        raise Exception("LE Transmitter Test command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1765
1766    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1767
1768    if ( RespCmd != Commands.CMD_LE_TRANSMITTER_TEST_RSP ):
1769        raise Exception("LE Transmitter Test command failed: Inappropriate command response received");
1770
1771    if ( RespLen != 1 ):
1772        raise Exception("LE Transmitter Test command failed: Response length field corrupted (%i)" % RespLen);
1773
1774    return status;
1775
1776"""
1777    This command is used to stop any test which is in progress. The Number_Of_Packets for a transmitter test shall be reported
1778    as 0x0000. The Number_Of_Packets is an unsigned number and contains the number of received packets.
1779"""
1780def le_test_end(transport, idx, to):
1781
1782    cmd = struct.pack('<HHH', Commands.CMD_LE_TEST_END_REQ, 2, HCICommands.BT_HCI_OP_LE_TEST_END);
1783    transport.send(idx, cmd);
1784
1785    packet = transport.recv(idx, 7, to);
1786
1787    if ( 7 != len(packet) ):
1788        raise Exception("LE Test End command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1789
1790    RespCmd, RespLen, status, RxPktCount = struct.unpack('<HHBH', packet);
1791
1792    if ( RespCmd != Commands.CMD_LE_TEST_END_RSP ):
1793        raise Exception("LE Test End command failed: Inappropriate command response received");
1794
1795    if ( RespLen != 3 ):
1796        raise Exception("LE Test End command failed: Response length field corrupted (%i)" % RespLen);
1797
1798    return status, RxPktCount;
1799
1800"""
1801    Both the central Host and the peripheral Host use this command to reply to the HCI LE Remote Connection Parameter Request event.
1802    This indicates that the Host has accepted the remote device\92s request to change connection parameters.
1803"""
1804def le_remote_connection_parameter_request_reply(transport, idx, handle, IntervalMin, IntervalMax, latency, timeout, MinCeLen, MaxCeLen, to):
1805
1806    cmd = struct.pack('<HHHHHHHHHH', Commands.CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_REQ, 16, HCICommands.BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, handle, IntervalMin, IntervalMax, latency, timeout, MinCeLen, MaxCeLen);
1807    transport.send(idx, cmd);
1808
1809    packet = transport.recv(idx, 7, to);
1810
1811    if ( 7 != len(packet) ):
1812        raise Exception("LE Remote Connection Parameter Request Reply command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1813
1814    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
1815
1816    if ( RespCmd != Commands.CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_RSP ):
1817        raise Exception("LE Remote Connection Parameter Request Reply command failed: Inappropriate command response received");
1818
1819    if ( RespLen != 3 ):
1820        raise Exception("LE Remote Connection Parameter Request Reply command failed: Response length field corrupted (%i)" % RespLen);
1821
1822    return status, handle;
1823
1824"""
1825    Both the central Host and the peripheral Host use this command to reply to the HCI LE Remote Connection Parameter Request event.
1826    This indicates that the Host has rejected the remote device\92s request to change connection parameters. The reason for the
1827    rejection is given in the Reason parameter.
1828"""
1829def le_remote_connection_parameter_request_negative_reply(transport, idx, handle, reason, to):
1830
1831    cmd = struct.pack('<HHHHB', Commands.CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_REQ, 5, HCICommands.BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, handle, reason);
1832    transport.send(idx, cmd);
1833
1834    packet = transport.recv(idx, 7, to);
1835
1836    if ( 7 != len(packet) ):
1837        raise Exception("LE Remote Connection Parameter Request Negative Reply command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1838
1839    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
1840
1841    if ( RespCmd != Commands.CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_RSP ):
1842        raise Exception("LE Remote Connection Parameter Request Negative Reply command failed: Inappropriate command response received");
1843
1844    if ( RespLen != 3 ):
1845        raise Exception("LE Remote Connection Parameter Request Negative Reply command failed: Response length field corrupted (%i)" % RespLen);
1846
1847    return status, handle;
1848
1849"""
1850    The LE_Set_Data_Length command allows the Host to suggest maximum transmission packet size and maximum packet transmission
1851    time (connMaxTxOctets and connMaxTxTime - see [Vol 6] Part B, Section 4.5.10) to be used for a given connection. The
1852    Controller may use smaller or larger values based on local information.
1853"""
1854def le_set_data_length(transport, idx, handle, TxOctets, TxTime, to):
1855
1856    cmd = struct.pack('<HHHHHH', Commands.CMD_LE_SET_DATA_LENGTH_REQ, 8, HCICommands.BT_HCI_OP_LE_SET_DATA_LEN, handle, TxOctets, TxTime);
1857    transport.send(idx, cmd);
1858
1859    packet = transport.recv(idx, 7, to);
1860
1861    if ( 7 != len(packet) ):
1862        raise Exception("LE Set Data Length command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
1863
1864    RespCmd, RespLen, status, handle = struct.unpack('<HHBH', packet);
1865
1866    if ( RespCmd != Commands.CMD_LE_SET_DATA_LENGTH_RSP ):
1867        raise Exception("LE Set Data Length command failed: Inappropriate command response received");
1868
1869    if ( RespLen != 3 ):
1870        raise Exception("LE Set Data Length command failed: Response length field corrupted (%i)" % RespLen);
1871
1872    return status, handle;
1873
1874"""
1875    The LE_Read_Suggested_Default_Data_Length command allows the Host to read the Host's suggested values
1876    (SuggestedMaxTxOctets and SuggestedMaxTxTime) for the Controller's maximum transmitted number of payload octets and
1877    maximum packet transmission time to be used for new connections (see [Vol 6] Part B, Section 4.5.10).
1878"""
1879def le_read_suggested_default_data_length(transport, idx, to):
1880
1881    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN);
1882    transport.send(idx, cmd);
1883
1884    packet = transport.recv(idx, 9, to);
1885
1886    if ( 9 != len(packet) ):
1887        raise Exception("LE Read Suggested Default Data Length command failed: Response too short (Expected %i bytes got %i bytes)" % (9, len(packet)));
1888
1889    RespCmd, RespLen, status, MaxTxOctets, MaxTxTime = struct.unpack('<HHBHH', packet);
1890
1891    if ( RespCmd != Commands.CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_RSP ):
1892        raise Exception("LE Read Suggested Default Data Length command failed: Inappropriate command response received");
1893
1894    if ( RespLen != 5 ):
1895        raise Exception("LE Read Suggested Default Data Length command failed: Response length field corrupted (%i)" % RespLen);
1896
1897    return status, MaxTxOctets, MaxTxTime;
1898
1899"""
1900    The LE_Write_Suggested_Default_Data_Length command allows the Host to specify its suggested values for the Controller's
1901    maximum transmission number of payload octets and maximum packet transmission time to be used for new connections. The
1902    Controller may use smaller or larger values for connInitialMaxTxOctets and connInitialMaxTxTime based on local information
1903    (see [Vol 6] Part B, Section 4.5.10).
1904"""
1905def le_write_suggested_default_data_length(transport, idx, MaxTxOctets, MaxTxTime, to):
1906
1907    cmd = struct.pack('<HHHHH', Commands.CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_REQ, 6, HCICommands.BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, MaxTxOctets, MaxTxTime);
1908    transport.send(idx, cmd);
1909
1910    packet = transport.recv(idx, 5, to);
1911
1912    if ( 5 != len(packet) ):
1913        raise Exception("LE Write Suggested Default Data Length command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1914
1915    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1916
1917    if ( RespCmd != Commands.CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_RSP ):
1918        raise Exception("LE Write Suggested Default Data Length command failed: Inappropriate command response received");
1919
1920    if ( RespLen != 1 ):
1921        raise Exception("LE Write Suggested Default Data Length command failed: Response length field corrupted (%i)" % RespLen);
1922
1923    return status;
1924
1925"""
1926    The LE_Read_Local_P-256_Public_Key command is used to return the local P-256 public key from the Controller. The
1927    Controller shall generate a new P-256 public/private key pair upon receipt of this command. The keys returned via this
1928    command shall not be used when Secure Connections is used over the BR/EDR transport.
1929"""
1930def le_read_local_p_256_public_key_command(transport, idx, to):
1931
1932    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_REQ, 2, HCICommands.BT_HCI_OP_LE_P256_PUBLIC_KEY);
1933    transport.send(idx, cmd);
1934
1935    packet = transport.recv(idx, 5, to);
1936
1937    if ( 5 != len(packet) ):
1938        raise Exception("LE Read Local P-256 Public Key Command command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1939
1940    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1941
1942    if ( RespCmd != Commands.CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_RSP ):
1943        raise Exception("LE Read Local P-256 Public Key Command command failed: Inappropriate command response received");
1944
1945    if ( RespLen != 1 ):
1946        raise Exception("LE Read Local P-256 Public Key Command command failed: Response length field corrupted (%i)" % RespLen);
1947
1948    return status;
1949
1950"""
1951    The LE_Generate_DHKey command is used to initiate generation of a Diffie-Hellman key in the Controller for use over the LE
1952    transport. This command takes the remote P-256 public key as input. The Diffie-Hellman key generation uses the private key
1953    generated by LE_Read_Local_P256_Public_Key command. The Diffie-Hellman key returned via this command shall not be
1954    generated using any keys used for Secure Connections over the BR/EDR transport.
1955"""
1956def le_generate_dhkey_command(transport, idx, key, to):
1957
1958    cmd = struct.pack('<HHH64B', Commands.CMD_LE_GENERATE_DHKEY_COMMAND_REQ, 66, HCICommands.BT_HCI_OP_LE_GENERATE_DHKEY, *key);
1959    transport.send(idx, cmd);
1960
1961    packet = transport.recv(idx, 5, to);
1962
1963    if ( 5 != len(packet) ):
1964        raise Exception("LE Generate DHKey Command command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1965
1966    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1967
1968    if ( RespCmd != Commands.CMD_LE_GENERATE_DHKEY_COMMAND_RSP ):
1969        raise Exception("LE Generate DHKey Command command failed: Inappropriate command response received");
1970
1971    if ( RespLen != 1 ):
1972        raise Exception("LE Generate DHKey Command command failed: Response length field corrupted (%i)" % RespLen);
1973
1974    return status;
1975
1976"""
1977    The LE_Add_Device_To_Resolving_List command is used to add one device to the list of address translations used to resolve
1978    Resolvable Private Addresses in the Controller.
1979"""
1980def le_add_device_to_resolving_list(transport, idx, PeerIdAddrType, AVal, PeerIrk, LocalIrk, to):
1981
1982    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_REQ, 41, HCICommands.BT_HCI_OP_LE_ADD_DEV_TO_RL, PeerIdAddrType, *AVal);
1983    cmd += struct.pack('<16B', *PeerIrk);
1984    cmd += struct.pack('<16B', *LocalIrk);
1985    transport.send(idx, cmd);
1986
1987    packet = transport.recv(idx, 5, to);
1988
1989    if ( 5 != len(packet) ):
1990        raise Exception("LE Add Device To Resolving List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
1991
1992    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
1993
1994    if ( RespCmd != Commands.CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_RSP ):
1995        raise Exception("LE Add Device To Resolving List command failed: Inappropriate command response received");
1996
1997    if ( RespLen != 1 ):
1998        raise Exception("LE Add Device To Resolving List command failed: Response length field corrupted (%i)" % RespLen);
1999
2000    return status;
2001
2002"""
2003    The LE_Remove_Device_From_Resolving_List command is used to remove one device from the list of address translations used
2004    to resolve Resolvable Private Addresses in the Controller.
2005"""
2006def le_remove_device_from_resolving_list(transport, idx, PeerIdAddrType, AVal, to):
2007
2008    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_REQ, 9, HCICommands.BT_HCI_OP_LE_REM_DEV_FROM_RL, PeerIdAddrType, *AVal);
2009    transport.send(idx, cmd);
2010
2011    packet = transport.recv(idx, 5, to);
2012
2013    if ( 5 != len(packet) ):
2014        raise Exception("LE Remove Device From Resolving List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2015
2016    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2017
2018    if ( RespCmd != Commands.CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_RSP ):
2019        raise Exception("LE Remove Device From Resolving List command failed: Inappropriate command response received");
2020
2021    if ( RespLen != 1 ):
2022        raise Exception("LE Remove Device From Resolving List command failed: Response length field corrupted (%i)" % RespLen);
2023
2024    return status;
2025
2026"""
2027    The LE_Clear_Resolving_List command is used to remove all devices from the list of address translations used to resolve
2028    Resolvable Private Addresses in the Controller.
2029"""
2030def le_clear_resolving_list(transport, idx, to):
2031
2032    cmd = struct.pack('<HHH', Commands.CMD_LE_CLEAR_RESOLVING_LIST_REQ, 2, HCICommands.BT_HCI_OP_LE_CLEAR_RL);
2033    transport.send(idx, cmd);
2034
2035    packet = transport.recv(idx, 5, to);
2036
2037    if ( 5 != len(packet) ):
2038        raise Exception("LE Clear Resolving List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2039
2040    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2041
2042    if ( RespCmd != Commands.CMD_LE_CLEAR_RESOLVING_LIST_RSP ):
2043        raise Exception("LE Clear Resolving List command failed: Inappropriate command response received");
2044
2045    if ( RespLen != 1 ):
2046        raise Exception("LE Clear Resolving List command failed: Response length field corrupted (%i)" % RespLen);
2047
2048    return status;
2049
2050"""
2051    The LE_Read_Resolving_List_Size command is used to read the total number of address translation entries in the resolving
2052    list that can be stored in the Controller. Note: The number of entries that can be stored is not fixed and the Controller
2053    can change it at any time (e.g. because the memory used to store the list can also be used for other purposes).
2054"""
2055def le_read_resolving_list_size(transport, idx, to):
2056
2057    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_RESOLVING_LIST_SIZE_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_RL_SIZE);
2058    transport.send(idx, cmd);
2059
2060    packet = transport.recv(idx, 6, to);
2061
2062    if ( 6 != len(packet) ):
2063        raise Exception("LE Read Resolving List Size command failed: Response too short (Expected %i bytes got %i bytes)" % (6, len(packet)));
2064
2065    RespCmd, RespLen, status, RlSize = struct.unpack('<HHBB', packet);
2066
2067    if ( RespCmd != Commands.CMD_LE_READ_RESOLVING_LIST_SIZE_RSP ):
2068        raise Exception("LE Read Resolving List Size command failed: Inappropriate command response received");
2069
2070    if ( RespLen != 2 ):
2071        raise Exception("LE Read Resolving List Size command failed: Response length field corrupted (%i)" % RespLen);
2072
2073    return status, RlSize;
2074
2075"""
2076    The LE_Read_Peer_Resolvable_Address command is used to get the current peer Resolvable Private Address being used for the
2077    corresponding peer Public and Random (static) Identity Address. The peer\92s resolvable address being used may change after
2078    the command is called.
2079"""
2080def le_read_peer_resolvable_address(transport, idx, PeerIdAddrType, AVal, to):
2081
2082    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_REQ, 9, HCICommands.BT_HCI_OP_LE_READ_PEER_RPA, PeerIdAddrType, *AVal);
2083    transport.send(idx, cmd);
2084
2085    packet = transport.recv(idx, 11, to);
2086
2087    if ( 11 != len(packet) ):
2088        raise Exception("LE Read Peer Resolvable Address command failed: Response too short (Expected %i bytes got %i bytes)" % (11, len(packet)));
2089
2090    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
2091    PeerRpaVal = struct.unpack('<6B', packet[5:]);
2092
2093    if ( RespCmd != Commands.CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_RSP ):
2094        raise Exception("LE Read Peer Resolvable Address command failed: Inappropriate command response received");
2095
2096    if ( RespLen != 7 ):
2097        raise Exception("LE Read Peer Resolvable Address command failed: Response length field corrupted (%i)" % RespLen);
2098
2099    return status, list(PeerRpaVal);
2100
2101"""
2102    The LE_Read_Local_Resolvable_Address command is used to get the current local Resolvable Private Address being used for
2103    the corresponding peer Identity Address. The local\92s resolvable address being used may change after the command is called.
2104"""
2105def le_read_local_resolvable_address(transport, idx, PeerIdAddrType, AVal, to):
2106
2107    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_REQ, 9, HCICommands.BT_HCI_OP_LE_READ_LOCAL_RPA, PeerIdAddrType, *AVal);
2108    transport.send(idx, cmd);
2109
2110    packet = transport.recv(idx, 11, to);
2111
2112    if ( 11 != len(packet) ):
2113        raise Exception("LE Read Local Resolvable Address command failed: Response too short (Expected %i bytes got %i bytes)" % (11, len(packet)));
2114
2115    RespCmd, RespLen, status = struct.unpack('<HHB', packet[:5]);
2116    LocalRpaVal = struct.unpack('<6B', packet[5:]);
2117
2118    if ( RespCmd != Commands.CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_RSP ):
2119        raise Exception("LE Read Local Resolvable Address command failed: Inappropriate command response received");
2120
2121    if ( RespLen != 7 ):
2122        raise Exception("LE Read Local Resolvable Address command failed: Response length field corrupted (%i)" % RespLen);
2123
2124    return status, list(LocalRpaVal);
2125
2126"""
2127    The LE_Set_Address_Resolution_Enable command is used to enable resolution of Resolvable Private Addresses in the
2128    Controller. This causes the Controller to use the resolving list whenever the Controller receives a local or peer
2129    Resolvable Private Address.
2130"""
2131def le_set_address_resolution_enable(transport, idx, enable, to):
2132
2133    cmd = struct.pack('<HHHB', Commands.CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_REQ, 3, HCICommands.BT_HCI_OP_LE_SET_ADDR_RES_ENABLE, enable);
2134    transport.send(idx, cmd);
2135
2136    packet = transport.recv(idx, 5, to);
2137
2138    if ( 5 != len(packet) ):
2139        raise Exception("LE Set Address Resolution Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2140
2141    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2142
2143    if ( RespCmd != Commands.CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_RSP ):
2144        raise Exception("LE Set Address Resolution Enable command failed: Inappropriate command response received");
2145
2146    if ( RespLen != 1 ):
2147        raise Exception("LE Set Address Resolution Enable command failed: Response length field corrupted (%i)" % RespLen);
2148
2149    return status;
2150
2151"""
2152    The LE_Set_Resolvable_Private_Address_Timeout command set the length of time the Controller uses a Resolvable Private
2153    Address before a new resolvable private address is generated and starts being used.
2154"""
2155def le_set_resolvable_private_address_timeout(transport, idx, RpaTimeout, to):
2156
2157    cmd = struct.pack('<HHHH', Commands.CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_REQ, 4, HCICommands.BT_HCI_OP_LE_SET_RPA_TIMEOUT, RpaTimeout);
2158    transport.send(idx, cmd);
2159
2160    packet = transport.recv(idx, 5, to);
2161
2162    if ( 5 != len(packet) ):
2163        raise Exception("LE Set Resolvable Private Address Timeout command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2164
2165    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2166
2167    if ( RespCmd != Commands.CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_RSP ):
2168        raise Exception("LE Set Resolvable Private Address Timeout command failed: Inappropriate command response received");
2169
2170    if ( RespLen != 1 ):
2171        raise Exception("LE Set Resolvable Private Address Timeout command failed: Response length field corrupted (%i)" % RespLen);
2172
2173    return status;
2174
2175"""
2176    The LE_Read_Maximum_Data_Length command allows the Host to read the Controller\92s maximum supported payload octets and
2177    packet duration times for transmission and reception (supportedMaxTxOctets and supportedMaxTxTime, supportedMaxRxOctets,
2178    and supportedMaxRxTime, see [Vol 6] Part B, Section 4.5.10).
2179"""
2180def le_read_maximum_data_length(transport, idx, to):
2181
2182    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_MAXIMUM_DATA_LENGTH_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_MAX_DATA_LEN);
2183    transport.send(idx, cmd);
2184
2185    packet = transport.recv(idx, 13, to);
2186
2187    if ( 13 != len(packet) ):
2188        raise Exception("LE Read Maximum Data Length command failed: Response too short (Expected %i bytes got %i bytes)" % (13, len(packet)));
2189
2190    RespCmd, RespLen, status, MaxTxOctets, MaxTxTime, MaxRxOctets, MaxRxTime = struct.unpack('<HHBHHHH', packet);
2191
2192    if ( RespCmd != Commands.CMD_LE_READ_MAXIMUM_DATA_LENGTH_RSP ):
2193        raise Exception("LE Read Maximum Data Length command failed: Inappropriate command response received");
2194
2195    if ( RespLen != 9 ):
2196        raise Exception("LE Read Maximum Data Length command failed: Response length field corrupted (%i)" % RespLen);
2197
2198    return status, MaxTxOctets, MaxTxTime, MaxRxOctets, MaxRxTime;
2199
2200"""
2201    The LE_Read_PHY command is used to read the current transmitter PHY and receiver PHY on the connection identified by the
2202    Connection_Handle.
2203"""
2204def le_read_phy(transport, idx, handle, to):
2205
2206    cmd = struct.pack('<HHHH', Commands.CMD_LE_READ_PHY_REQ, 4, HCICommands.BT_HCI_OP_LE_READ_PHY, handle);
2207    transport.send(idx, cmd);
2208
2209    packet = transport.recv(idx, 9, to);
2210
2211    if ( 9 != len(packet) ):
2212        raise Exception("LE Read PHY command failed: Response too short (Expected %i bytes got %i bytes)" % (9, len(packet)));
2213
2214    RespCmd, RespLen, status, handle, TxPhy, RxPhy = struct.unpack('<HHBHBB', packet);
2215
2216    if ( RespCmd != Commands.CMD_LE_READ_PHY_RSP ):
2217        raise Exception("LE Read PHY command failed: Inappropriate command response received");
2218
2219    if ( RespLen != 5 ):
2220        raise Exception("LE Read PHY command failed: Response length field corrupted (%i)" % RespLen);
2221
2222    return status, handle, TxPhy, RxPhy;
2223
2224"""
2225    The LE_Set_Default_PHY command allows the Host to specify its preferred values for the transmitter PHY and receiver PHY to
2226    be used for all subsequent connections over the LE transport.
2227"""
2228def le_set_default_phy(transport, idx, AllPhys, TxPhys, RxPhys, to):
2229
2230    cmd = struct.pack('<HHHBBB', Commands.CMD_LE_SET_DEFAULT_PHY_REQ, 5, HCICommands.BT_HCI_OP_LE_SET_DEFAULT_PHY, AllPhys, TxPhys, RxPhys);
2231    transport.send(idx, cmd);
2232
2233    packet = transport.recv(idx, 5, to);
2234
2235    if ( 5 != len(packet) ):
2236        raise Exception("LE Set Default PHY command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2237
2238    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2239
2240    if ( RespCmd != Commands.CMD_LE_SET_DEFAULT_PHY_RSP ):
2241        raise Exception("LE Set Default PHY command failed: Inappropriate command response received");
2242
2243    if ( RespLen != 1 ):
2244        raise Exception("LE Set Default PHY command failed: Response length field corrupted (%i)" % RespLen);
2245
2246    return status;
2247
2248"""
2249    The LE_Set_PHY command is used to set the PHY preferences for the connection identified by the Connection_Handle. The
2250    Controller might not be able to make the change (e.g. because the peer does not support the requested PHY) or may decide
2251    that the current PHY is preferable.
2252"""
2253def le_set_phy(transport, idx, handle, AllPhys, TxPhys, RxPhys, PhyOpts, to):
2254
2255    cmd = struct.pack('<HHHHBBBH', Commands.CMD_LE_SET_PHY_REQ, 9, HCICommands.BT_HCI_OP_LE_SET_PHY, handle, AllPhys, TxPhys, RxPhys, PhyOpts);
2256    transport.send(idx, cmd);
2257
2258    packet = transport.recv(idx, 5, to);
2259
2260    if ( 5 != len(packet) ):
2261        raise Exception("LE Set PHY command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2262
2263    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2264
2265    if ( RespCmd != Commands.CMD_LE_SET_PHY_RSP ):
2266        raise Exception("LE Set PHY command failed: Inappropriate command response received");
2267
2268    if ( RespLen != 1 ):
2269        raise Exception("LE Set PHY command failed: Response length field corrupted (%i)" % RespLen);
2270
2271    return status;
2272
2273"""
2274    This command is used to start a test where the DUT receives test reference packets at a fixed interval. The tester
2275    generates the test reference packets.
2276"""
2277def le_enhanced_receiver_test(transport, idx, RxCh, phy, ModIndex, to):
2278
2279    cmd = struct.pack('<HHHBBB', Commands.CMD_LE_ENHANCED_RECEIVER_TEST_REQ, 5, HCICommands.BT_HCI_OP_LE_ENH_RX_TEST, RxCh, phy, ModIndex);
2280    transport.send(idx, cmd);
2281
2282    packet = transport.recv(idx, 5, to);
2283
2284    if ( 5 != len(packet) ):
2285        raise Exception("LE Enhanced Receiver Test command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2286
2287    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2288
2289    if ( RespCmd != Commands.CMD_LE_ENHANCED_RECEIVER_TEST_RSP ):
2290        raise Exception("LE Enhanced Receiver Test command failed: Inappropriate command response received");
2291
2292    if ( RespLen != 1 ):
2293        raise Exception("LE Enhanced Receiver Test command failed: Response length field corrupted (%i)" % RespLen);
2294
2295    return status;
2296
2297"""
2298    This command is used to start a test where the DUT generates test reference packets at a fixed interval. The Controller
2299    shall transmit at maximum power.
2300"""
2301def le_enhanced_transmitter_test(transport, idx, TxCh, TestDataLen, PktPayload, phy, to):
2302
2303    cmd = struct.pack('<HHHBBBB', Commands.CMD_LE_ENHANCED_TRANSMITTER_TEST_REQ, 6, HCICommands.BT_HCI_OP_LE_ENH_TX_TEST, TxCh, TestDataLen, PktPayload, phy);
2304    transport.send(idx, cmd);
2305
2306    packet = transport.recv(idx, 5, to);
2307
2308    if ( 5 != len(packet) ):
2309        raise Exception("LE Enhanced Transmitter Test command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2310
2311    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2312
2313    if ( RespCmd != Commands.CMD_LE_ENHANCED_TRANSMITTER_TEST_RSP ):
2314        raise Exception("LE Enhanced Transmitter Test command failed: Inappropriate command response received");
2315
2316    if ( RespLen != 1 ):
2317        raise Exception("LE Enhanced Transmitter Test command failed: Response length field corrupted (%i)" % RespLen);
2318
2319    return status;
2320
2321"""
2322    The LE_Set_Extended_Advertising_Parameters command is used by the Host to set the advertising parameters.
2323"""
2324def le_set_extended_advertising_parameters(transport, idx, handle, props, PrimMinInterval, PrimMaxInterval, PrimChannelMap, OwnAddrType, PeerAddrType, AVal, FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, SecAdvPhy, sid, ScanReqNotifyEnable, to):
2325
2326    cmd = struct.pack('<HHHBH3B', Commands.CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_REQ, 27, HCICommands.BT_HCI_OP_LE_SET_EXT_ADV_PARAM, handle, props, *PrimMinInterval);
2327    cmd += struct.pack('<3B', *PrimMaxInterval);
2328    cmd += struct.pack('<BBB6B', PrimChannelMap, OwnAddrType, PeerAddrType, *AVal);
2329    cmd += struct.pack('<BbBBBBB', FilterPolicy, TxPower, PrimAdvPhy, SecAdvMaxSkip, SecAdvPhy, sid, ScanReqNotifyEnable);
2330    transport.send(idx, cmd);
2331
2332    packet = transport.recv(idx, 5, to);
2333
2334    if ( 5 != len(packet) ):
2335        raise Exception("LE Set Extended Advertising Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2336
2337    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2338
2339    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_RSP ):
2340        raise Exception("LE Set Extended Advertising Parameters command failed: Inappropriate command response received");
2341
2342    if ( status == 0x01 ):
2343        # Unsupported command, no Selected_TX_Power in response
2344        if ( RespLen != 1 ):
2345            raise Exception("LE Set Extended Advertising Parameters command failed: Response length field corrupted (%i)" % RespLen);
2346        return status
2347
2348    if ( RespLen != 2 ):
2349        raise Exception("LE Set Extended Advertising Parameters command failed: Response length field corrupted (%i)" % RespLen);
2350
2351    # Read out the last byte of the message
2352    packet = transport.recv(idx, 1, to);
2353    if ( 1 != len(packet) ):
2354        raise Exception("LE Set Extended Advertising Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (6, 5));
2355
2356    return status;
2357
2358"""
2359    The LE_Set_Extended_Advertising_Data command is used to set the data used in advertising PDUs that have a data field. This
2360    command may be issued at any time after an advertising set identified by the Advertising_Handle parameter has been created
2361    using the LE Set Extended Advertising Parameters Command (see Section 7.8.53), regardless of whether advertising in that
2362    set is enabled or disabled.
2363"""
2364def le_set_extended_advertising_data(transport, idx, handle, op, FragPref, data, to):
2365
2366    cmd = struct.pack('<HHHBBBB' + str(len(data)) + 'B', Commands.CMD_LE_SET_EXTENDED_ADVERTISING_DATA_REQ, len(data) + 6, HCICommands.BT_HCI_OP_LE_SET_EXT_ADV_DATA, handle, op, FragPref, len(data), *data);
2367    transport.send(idx, cmd);
2368
2369    packet = transport.recv(idx, 5, to);
2370
2371    if ( 5 != len(packet) ):
2372        raise Exception("LE Set Extended Advertising Data command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2373
2374    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2375
2376    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_ADVERTISING_DATA_RSP ):
2377        raise Exception("LE Set Extended Advertising Data command failed: Inappropriate command response received");
2378
2379    if ( RespLen != 1 ):
2380        raise Exception("LE Set Extended Advertising Data command failed: Response length field corrupted (%i)" % RespLen);
2381
2382    return status;
2383
2384"""
2385
2386"""
2387def le_set_extended_scan_response_data(transport, idx, handle, op, FragPref, data, to):
2388
2389    cmd = struct.pack('<HHHBBBB' + str(len(data)) + 'B', Commands.CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_REQ, len(data) + 6, HCICommands.BT_HCI_OP_LE_SET_EXT_SCAN_RSP_DATA, handle, op, FragPref, len(data), *data);
2390    transport.send(idx, cmd);
2391
2392    packet = transport.recv(idx, 5, to);
2393
2394    if ( 5 != len(packet) ):
2395        raise Exception("LE Set Extended Scan Response Data command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2396
2397    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2398
2399    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_RSP ):
2400        raise Exception("LE Set Extended Scan Response Data command failed: Inappropriate command response received");
2401
2402    if ( RespLen != 1 ):
2403        raise Exception("LE Set Extended Scan Response Data command failed: Response length field corrupted (%i)" % RespLen);
2404
2405    return status;
2406
2407"""
2408    The LE_Set_Extended_Advertising_Enable command is used to request the Controller to enable or disable one or more
2409    advertising sets using the advertising sets identified by the Advertising_Handle[i] parameter. The Controller manages the
2410    timing of advertisements in accordance with the advertising parameters given in the LE_Set_Extended_Advertising_Parameters
2411    command. The Number_of_Sets parameter is the number of advertising sets contained in the parameter arrays. If Enable and
2412    Number_of_Sets are both set to 0x00, then all advertising sets are disabled.
2413"""
2414def le_set_extended_advertising_enable(transport, idx, enable, SetNum, SHandle, SDuration, SMaxExtAdvEvts, to):
2415    cmd = struct.pack('<HHHBB' + 'BHB' * SetNum,
2416                      Commands.CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_REQ, 4 + 4 * SetNum,
2417                      HCICommands.BT_HCI_OP_LE_SET_EXT_ADV_ENABLE, enable, SetNum, *list(chain(*list(zip(SHandle, SDuration, SMaxExtAdvEvts)))))
2418
2419    transport.send(idx, cmd);
2420
2421    packet = transport.recv(idx, 5, to);
2422
2423    if ( 5 != len(packet) ):
2424        raise Exception("LE Set Extended Advertising Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2425
2426    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2427
2428    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_RSP ):
2429        raise Exception("LE Set Extended Advertising Enable command failed: Inappropriate command response received");
2430
2431    if ( RespLen != 1 ):
2432        raise Exception("LE Set Extended Advertising Enable command failed: Response length field corrupted (%i)" % RespLen);
2433
2434    return status;
2435
2436"""
2437    The LE_Read_Maximum_Advertising_Data_Length command is used to read the maximum length of data supported by the Controller
2438    for use as advertisement data or scan response data in an advertising event or as periodic advertisement data.
2439"""
2440def le_read_maximum_advertising_data_length(transport, idx, to):
2441
2442    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_MAX_ADV_DATA_LEN);
2443    transport.send(idx, cmd);
2444
2445    packet = transport.recv(idx, 5, to);
2446    assert 5 == len(packet), f"Received invalid length packet {len(packet)}"
2447
2448    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
2449
2450    if ( RespCmd != Commands.CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_RSP ):
2451        raise Exception("LE Read Maximum Advertising Data Length command failed: Inappropriate command response received");
2452
2453    if RespLen == 1:
2454        # Unsupported command.
2455        return status
2456
2457    assert RespLen == 3, f"Response length field corrupted ({RespLen})"
2458
2459    packet = transport.recv(idx, 2, to)
2460    assert 2 == len(packet), f"Received invalid length packet {len(packet)}"
2461
2462    MaxAdvDataLen, = struct.unpack('<H', packet)
2463    return status, MaxAdvDataLen
2464
2465"""
2466    The LE_Read_Number_of_Supported_Advertising_Sets command is used to read the maximum number of advertising sets supported
2467    by the advertising Controller at the same time. Note: The number of advertising sets that can be supported is not fixed
2468    and the Controller can change it at any time because the memory used to store advertising sets can also be used for other
2469    purposes.
2470"""
2471def le_read_number_of_supported_advertising_sets(transport, idx, to):
2472
2473    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_NUM_ADV_SETS);
2474    transport.send(idx, cmd);
2475
2476    packet = transport.recv(idx, 5, to);
2477    assert 5 == len(packet), f"Received invalid length packet {len(packet)}"
2478
2479    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
2480
2481    if ( RespCmd != Commands.CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_RSP ):
2482        raise Exception("LE Read Number of Supported Advertising Sets command failed: Inappropriate command response received");
2483
2484    if RespLen == 1:
2485        # Unsupported command.
2486        return status
2487
2488    assert RespLen != 2, f"Response length field corrupted ({RespLen})"
2489
2490    packet = transport.recv(idx, 1, to)
2491    assert 1 == len(packet), f"Received invalid length packet {len(packet)}"
2492
2493    NumSets = struct.unpack('<B', packet)
2494    return status, NumSets
2495
2496"""
2497    The LE_Remove_Advertising_Set command is used to remove an advertising set from the Controller.
2498"""
2499def le_remove_advertising_set(transport, idx, handle, to):
2500
2501    cmd = struct.pack('<HHHB', Commands.CMD_LE_REMOVE_ADVERTISING_SET_REQ, 3, HCICommands.BT_HCI_OP_LE_REMOVE_ADV_SET, handle);
2502    transport.send(idx, cmd);
2503
2504    packet = transport.recv(idx, 5, to);
2505
2506    if ( 5 != len(packet) ):
2507        raise Exception("LE Remove Advertising Set command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2508
2509    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2510
2511    if ( RespCmd != Commands.CMD_LE_REMOVE_ADVERTISING_SET_RSP ):
2512        raise Exception("LE Remove Advertising Set command failed: Inappropriate command response received");
2513
2514    if ( RespLen != 1 ):
2515        raise Exception("LE Remove Advertising Set command failed: Response length field corrupted (%i)" % RespLen);
2516
2517    return status;
2518
2519"""
2520    The LE_Clear_Advertising_Sets command is used to remove all existing advertising sets from the Controller.
2521"""
2522def le_clear_advertising_sets(transport, idx, to):
2523
2524    cmd = struct.pack('<HHH', Commands.CMD_LE_CLEAR_ADVERTISING_SETS_REQ, 2, HCICommands.BT_HCI_OP_CLEAR_ADV_SETS);
2525    transport.send(idx, cmd);
2526
2527    packet = transport.recv(idx, 5, to);
2528
2529    if ( 5 != len(packet) ):
2530        raise Exception("LE Clear Advertising Sets command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2531
2532    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2533
2534    if ( RespCmd != Commands.CMD_LE_CLEAR_ADVERTISING_SETS_RSP ):
2535        raise Exception("LE Clear Advertising Sets command failed: Inappropriate command response received");
2536
2537    if ( RespLen != 1 ):
2538        raise Exception("LE Clear Advertising Sets command failed: Response length field corrupted (%i)" % RespLen);
2539
2540    return status;
2541
2542"""
2543    The LE_Set_Periodic_Advertising_Parameters command is used by the Host to set the parameters for periodic advertising.
2544"""
2545def le_set_periodic_advertising_parameters(transport, idx, handle, MinInterval, MaxInterval, props, to):
2546
2547    cmd = struct.pack('<HHHBHHH', Commands.CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_REQ, 9, HCICommands.BT_HCI_OP_LE_SET_PER_ADV_PARAM, handle, MinInterval, MaxInterval, props);
2548    transport.send(idx, cmd);
2549
2550    packet = transport.recv(idx, 5, to);
2551
2552    if ( 5 != len(packet) ):
2553        raise Exception("LE Set Periodic Advertising Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2554
2555    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2556
2557    if ( RespCmd != Commands.CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_RSP ):
2558        raise Exception("LE Set Periodic Advertising Parameters command failed: Inappropriate command response received");
2559
2560    if ( RespLen != 1 ):
2561        raise Exception("LE Set Periodic Advertising Parameters command failed: Response length field corrupted (%i)" % RespLen);
2562
2563    return status;
2564
2565"""
2566    The LE_Set_Periodic_Advertising_Data command is used to set the data used in periodic advertising PDUs. This command may
2567    be issued at any time after the advertising set identified by the Advertising_Handle parameter has been configured for
2568    periodic advertising using the LE_Set_Periodic_Advertising_Parameters Command (see Section 7.8.61), regardless of whether
2569    advertising in that set is enabled or disabled. If the advertising set has not been configured for periodic advertising,
2570    then the Controller shall return the error code Command Disallowed (0x0C).
2571"""
2572def le_set_periodic_advertising_data(transport, idx, handle, op, dataLen, data, to):
2573
2574    cmd = struct.pack('<HHHBBB251B', Commands.CMD_LE_SET_PERIODIC_ADVERTISING_DATA_REQ, 256, HCICommands.BT_HCI_OP_LE_SET_PER_ADV_DATA, handle, op, dataLen, *data);
2575    transport.send(idx, cmd);
2576
2577    packet = transport.recv(idx, 5, to);
2578
2579    if ( 5 != len(packet) ):
2580        raise Exception("LE Set Periodic Advertising Data command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2581
2582    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2583
2584    if ( RespCmd != Commands.CMD_LE_SET_PERIODIC_ADVERTISING_DATA_RSP ):
2585        raise Exception("LE Set Periodic Advertising Data command failed: Inappropriate command response received");
2586
2587    if ( RespLen != 1 ):
2588        raise Exception("LE Set Periodic Advertising Data command failed: Response length field corrupted (%i)" % RespLen);
2589
2590    return status;
2591
2592"""
2593    The LE_Set_Periodic_Advertising_Enable command is used to request the Controller to enable or disable the periodic
2594    advertising for the advertising set specified by the Advertising_Handle parameter (ordinary advertising is not affected).
2595"""
2596def le_set_periodic_advertising_enable(transport, idx, enable, handle, to):
2597
2598    cmd = struct.pack('<HHHBB', Commands.CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_REQ, 4, HCICommands.BT_HCI_OP_LE_SET_PER_ADV_ENABLE, enable, handle);
2599    transport.send(idx, cmd);
2600
2601    packet = transport.recv(idx, 5, to);
2602
2603    if ( 5 != len(packet) ):
2604        raise Exception("LE Set Periodic Advertising Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2605
2606    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2607
2608    if ( RespCmd != Commands.CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_RSP ):
2609        raise Exception("LE Set Periodic Advertising Enable command failed: Inappropriate command response received");
2610
2611    if ( RespLen != 1 ):
2612        raise Exception("LE Set Periodic Advertising Enable command failed: Response length field corrupted (%i)" % RespLen);
2613
2614    return status;
2615
2616"""
2617    The LE_Set_Extended_Scan_Parameters command is used to set the extended scan parameters to be used on the advertising
2618    channels.
2619"""
2620def le_set_extended_scan_parameters(transport, idx, OwnAddrType, FilterPolicy, phys, PType, PInterval, PWindow, to):
2621
2622    cmd = struct.pack('<HHHBBB' + 'BHH' * phys, Commands.CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_REQ, 5 + 5 * phys,
2623                      HCICommands.BT_HCI_OP_LE_SET_EXT_SCAN_PARAM, OwnAddrType, FilterPolicy, phys,
2624                      *list(chain(*list(zip(PType, PInterval, PWindow)))))
2625
2626    transport.send(idx, cmd);
2627
2628    packet = transport.recv(idx, 5, to);
2629
2630    if ( 5 != len(packet) ):
2631        raise Exception("LE Set Extended Scan Parameters command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2632
2633    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2634
2635    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_RSP ):
2636        raise Exception("LE Set Extended Scan Parameters command failed: Inappropriate command response received");
2637
2638    if ( RespLen != 1 ):
2639        raise Exception("LE Set Extended Scan Parameters command failed: Response length field corrupted (%i)" % RespLen);
2640
2641    return status;
2642
2643"""
2644    The LE_Set_Extended_Scan_Enable command is used to enable or disable scanning.
2645"""
2646def le_set_extended_scan_enable(transport, idx, enable, FilterDup, duration, period, to):
2647
2648    cmd = struct.pack('<HHHBBHH', Commands.CMD_LE_SET_EXTENDED_SCAN_ENABLE_REQ, 8, HCICommands.BT_HCI_OP_LE_SET_EXT_SCAN_ENABLE, enable, FilterDup, duration, period);
2649    transport.send(idx, cmd);
2650
2651    packet = transport.recv(idx, 5, to);
2652
2653    if ( 5 != len(packet) ):
2654        raise Exception("LE Set Extended Scan Enable command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2655
2656    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2657
2658    if ( RespCmd != Commands.CMD_LE_SET_EXTENDED_SCAN_ENABLE_RSP ):
2659        raise Exception("LE Set Extended Scan Enable command failed: Inappropriate command response received");
2660
2661    if ( RespLen != 1 ):
2662        raise Exception("LE Set Extended Scan Enable command failed: Response length field corrupted (%i)" % RespLen);
2663
2664    return status;
2665
2666"""
2667    The LE_Extended_Create_Connection command is used to create a Link Layer connection to a connectable advertiser.
2668    LE_Extended_Create_Connection command can be used in place of LE_Create_Connection command.
2669"""
2670def le_extended_create_connection(transport, idx, FilterPolicy, OwnAddrType, PeerAddrType, AVal, phys, PInterval, PWindow, PConnIntervalMin, PConnIntervalMax, PConnLatency, PSupervisionTimeout, PMinCeLen, PMaxCeLen, to):
2671
2672    PHYCount = bin(phys).count("1")
2673
2674    cmd = struct.pack('<HHHBBB6BB' + 'HHHHHHHH' * PHYCount, Commands.CMD_LE_EXTENDED_CREATE_CONNECTION_REQ, 12 + 16 * PHYCount,
2675                      HCICommands.BT_HCI_OP_LE_EXT_CREATE_CONN, FilterPolicy, OwnAddrType, PeerAddrType, *AVal, phys,
2676                      *list(chain(*list(zip(PInterval, PWindow, PConnIntervalMin, PConnIntervalMax, PConnLatency, PSupervisionTimeout, PMinCeLen, PMaxCeLen)))))
2677
2678    transport.send(idx, cmd);
2679
2680    packet = transport.recv(idx, 5, to);
2681
2682    if ( 5 != len(packet) ):
2683        raise Exception("LE Extended Create Connection command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2684
2685    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2686
2687    if ( RespCmd != Commands.CMD_LE_EXTENDED_CREATE_CONNECTION_RSP ):
2688        raise Exception("LE Extended Create Connection command failed: Inappropriate command response received");
2689
2690    if ( RespLen != 1 ):
2691        raise Exception("LE Extended Create Connection command failed: Response length field corrupted (%i)" % RespLen);
2692
2693    return status;
2694
2695"""
2696    The LE_Periodic_Advertising_Create_Sync command is used to synchronize with periodic advertising from an advertiser and
2697    begin receiving periodic advertising packets.
2698"""
2699def le_periodic_advertising_create_sync(transport, idx, FilterPolicy, sid, AddrType, AVal, skip, SyncTimeout, unused, to):
2700
2701    cmd = struct.pack('<HHHBBB6B', Commands.CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_REQ, 16, HCICommands.BT_HCI_OP_LE_PER_ADV_CREATE_SYNC, FilterPolicy, sid, AddrType, *AVal);
2702    cmd += struct.pack('<HHB', skip, SyncTimeout, unused);
2703    transport.send(idx, cmd);
2704
2705    packet = transport.recv(idx, 5, to);
2706
2707    if ( 5 != len(packet) ):
2708        raise Exception("LE Periodic Advertising Create Sync command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2709
2710    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2711
2712    if ( RespCmd != Commands.CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_RSP ):
2713        raise Exception("LE Periodic Advertising Create Sync command failed: Inappropriate command response received");
2714
2715    if ( RespLen != 1 ):
2716        raise Exception("LE Periodic Advertising Create Sync command failed: Response length field corrupted (%i)" % RespLen);
2717
2718    return status;
2719
2720"""
2721    The LE_Periodic_Advertising_Create_Sync_Cancel command is used to cancel the LE_Periodic_Advertising_Create_Sync command
2722    while it is pending.
2723"""
2724def le_periodic_advertising_create_sync_cancel(transport, idx, to):
2725
2726    cmd = struct.pack('<HHH', Commands.CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_REQ, 2, HCICommands.BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL);
2727    transport.send(idx, cmd);
2728
2729    packet = transport.recv(idx, 5, to);
2730
2731    if ( 5 != len(packet) ):
2732        raise Exception("LE Periodic Advertising Create Sync Cancel command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2733
2734    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2735
2736    if ( RespCmd != Commands.CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_RSP ):
2737        raise Exception("LE Periodic Advertising Create Sync Cancel command failed: Inappropriate command response received");
2738
2739    if ( RespLen != 1 ):
2740        raise Exception("LE Periodic Advertising Create Sync Cancel command failed: Response length field corrupted (%i)" % RespLen);
2741
2742    return status;
2743
2744"""
2745    The LE_Periodic_Advertising_Terminate_Sync command is used to stop reception of the periodic advertising identified by the
2746    Sync_Handle parameter.
2747"""
2748def le_periodic_advertising_terminate_sync(transport, idx, handle, to):
2749
2750    cmd = struct.pack('<HHHH', Commands.CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_REQ, 4, HCICommands.BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC, handle);
2751    transport.send(idx, cmd);
2752
2753    packet = transport.recv(idx, 5, to);
2754
2755    if ( 5 != len(packet) ):
2756        raise Exception("LE Periodic Advertising Terminate Sync command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2757
2758    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2759
2760    if ( RespCmd != Commands.CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_RSP ):
2761        raise Exception("LE Periodic Advertising Terminate Sync command failed: Inappropriate command response received");
2762
2763    if ( RespLen != 1 ):
2764        raise Exception("LE Periodic Advertising Terminate Sync command failed: Response length field corrupted (%i)" % RespLen);
2765
2766    return status;
2767
2768"""
2769    The LE_Add_Device_To_Periodic_Advertiser_List command is used to add a single device to the Periodic Advertiser list
2770    stored in the Controller. Any additions to the Periodic Advertiser list take effect immediately. If the device is already
2771    on the list, the Controller shall return the error code Invalid HCI Command Parameters (0x12).
2772"""
2773def le_add_device_to_periodic_advertiser_list(transport, idx, AddrType, AVal, sid, to):
2774
2775    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_REQ, 10, HCICommands.BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST, AddrType, *AVal);
2776    cmd += struct.pack('<B', sid);
2777    transport.send(idx, cmd);
2778
2779    packet = transport.recv(idx, 5, to);
2780
2781    if ( 5 != len(packet) ):
2782        raise Exception("LE Add Device To Periodic Advertiser List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2783
2784    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2785
2786    if ( RespCmd != Commands.CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_RSP ):
2787        raise Exception("LE Add Device To Periodic Advertiser List command failed: Inappropriate command response received");
2788
2789    if ( RespLen != 1 ):
2790        raise Exception("LE Add Device To Periodic Advertiser List command failed: Response length field corrupted (%i)" % RespLen);
2791
2792    return status;
2793
2794"""
2795    The LE_Remove_Device_From_Periodic_Advertiser_List command is used to remove one device from the list of Periodic
2796    Advertisers stored in the Controller. Removals from the Periodic Advertisers List take effect immediately.
2797"""
2798def le_remove_device_from_periodic_advertiser_list(transport, idx, AddrType, AVal, sid, to):
2799
2800    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_REQ, 10, HCICommands.BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST, AddrType, *AVal);
2801    cmd += struct.pack('<B', sid);
2802    transport.send(idx, cmd);
2803
2804    packet = transport.recv(idx, 5, to);
2805
2806    if ( 5 != len(packet) ):
2807        raise Exception("LE Remove Device From Periodic Advertiser List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2808
2809    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2810
2811    if ( RespCmd != Commands.CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_RSP ):
2812        raise Exception("LE Remove Device From Periodic Advertiser List command failed: Inappropriate command response received");
2813
2814    if ( RespLen != 1 ):
2815        raise Exception("LE Remove Device From Periodic Advertiser List command failed: Response length field corrupted (%i)" % RespLen);
2816
2817    return status;
2818
2819"""
2820    The LE_Clear_Periodic_Advertiser_List command is used to remove all devices from the list of Periodic Advertisers in the
2821    Controller.
2822"""
2823def le_clear_periodic_advertiser_list(transport, idx, to):
2824
2825    cmd = struct.pack('<HHH', Commands.CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_REQ, 2, HCICommands.BT_HCI_OP_LE_CLEAR_PER_ADV_LIST);
2826    transport.send(idx, cmd);
2827
2828    packet = transport.recv(idx, 5, to);
2829
2830    if ( 5 != len(packet) ):
2831        raise Exception("LE Clear Periodic Advertiser List command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2832
2833    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2834
2835    if ( RespCmd != Commands.CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_RSP ):
2836        raise Exception("LE Clear Periodic Advertiser List command failed: Inappropriate command response received");
2837
2838    if ( RespLen != 1 ):
2839        raise Exception("LE Clear Periodic Advertiser List command failed: Response length field corrupted (%i)" % RespLen);
2840
2841    return status;
2842
2843"""
2844    The LE_Read_Periodic_Advertiser_List_Size command is used to read the total number of Periodic Advertiser list entries
2845    that can be stored in the Controller. Note: The number of entries that can be stored is not fixed and the Controller can
2846    change it at any time (e.g., because the memory used to store the list can also be used for other purposes).
2847"""
2848def le_read_periodic_advertiser_list_size(transport, idx, to):
2849
2850    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_PER_ADV_LIST_SIZE);
2851    transport.send(idx, cmd);
2852
2853    packet = transport.recv(idx, 5, to);
2854    assert 5 == len(packet), f"Received invalid length packet {len(packet)}"
2855
2856    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
2857
2858    if ( RespCmd != Commands.CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_RSP ):
2859        raise Exception("LE Read Periodic Advertiser List Size command failed: Inappropriate command response received");
2860
2861    if RespLen == 1:
2862        # Unsupported command.
2863        return status
2864
2865    assert RespLen != 2, f"Response length field corrupted ({RespLen})"
2866
2867    packet = transport.recv(idx, 1, to)
2868    assert 1 == len(packet), f"Received invalid length packet {len(packet)}"
2869
2870    ListSize = struct.unpack('<B', packet)
2871    return status, ListSize;
2872
2873"""
2874    The LE_Read_Transmit_Power command is used to read the minimum and maximum transmit powers supported by the Controller.
2875"""
2876def le_read_transmit_power(transport, idx, to):
2877
2878    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_TRANSMIT_POWER_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_TX_POWER);
2879    transport.send(idx, cmd);
2880
2881    packet = transport.recv(idx, 7, to);
2882
2883    if ( 7 != len(packet) ):
2884        raise Exception("LE Read Transmit Power command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)));
2885
2886    RespCmd, RespLen, status, MinTxPower, MaxTxPower = struct.unpack('<HHBbb', packet);
2887
2888    if ( RespCmd != Commands.CMD_LE_READ_TRANSMIT_POWER_RSP ):
2889        raise Exception("LE Read Transmit Power command failed: Inappropriate command response received");
2890
2891    if ( RespLen != 3 ):
2892        raise Exception("LE Read Transmit Power command failed: Response length field corrupted (%i)" % RespLen);
2893
2894    return status, MinTxPower, MaxTxPower;
2895
2896"""
2897    The LE_Read_RF_Path_Compensation command is used to read the RF Path Compensation Values parameter used in the Tx Power
2898    Level and RSSI calculation.
2899"""
2900def le_read_rf_path_compensation(transport, idx, to):
2901
2902    cmd = struct.pack('<HHH', Commands.CMD_LE_READ_RF_PATH_COMPENSATION_REQ, 2, HCICommands.BT_HCI_OP_LE_READ_RF_PATH_COMP);
2903    transport.send(idx, cmd);
2904
2905    packet = transport.recv(idx, 5, to);
2906    assert 5 == len(packet), f"Received invalid length packet {len(packet)}"
2907
2908    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
2909
2910    if ( RespCmd != Commands.CMD_LE_READ_RF_PATH_COMPENSATION_RSP ):
2911        raise Exception("LE Read RF Path Compensation command failed: Inappropriate command response received");
2912
2913    if RespLen == 1:
2914        # Unsupported command.
2915        return status
2916
2917    assert RespLen != 5, f"Response length field corrupted ({RespLen})"
2918
2919    packet = transport.recv(idx, 4, to)
2920    assert 4 == len(packet), f"Received invalid length packet {len(packet)}"
2921
2922    TxPathComp, RxPathComp  = struct.unpack('<HH', packet)
2923    return status, TxPathComp, RxPathComp
2924
2925"""
2926    The LE_Write_RF_Path_Compensation command is used to indicate the RF path gain or loss between the RF transceiver and the
2927    antenna contributed by intermediate components. A positive value means a net RF path gain and a negative value means a net
2928    RF path loss. The RF Tx Path Compensation Value parameter shall be used by the Controller to calculate radiative Tx Power
2929    Level used in the TxPower field in the Extended Header using the following equation: Radiative Tx Power Level = Tx Power
2930    Level at RF transceiver output + RF Tx Path Compensation Value For example, if the Tx Power Level is +4 (dBm) at RF
2931    transceiver output and the RF Path Compensation Value is -1.5 (dB), the radiative Tx Power Level is +4+(-1.5) = 2.5 (dBm).
2932"""
2933def le_write_rf_path_compensation(transport, idx, TxPathComp, RxPathComp, to):
2934
2935    cmd = struct.pack('<HHHhh', Commands.CMD_LE_WRITE_RF_PATH_COMPENSATION_REQ, 6, HCICommands.BT_HCI_OP_LE_WRITE_RF_PATH_COMP, TxPathComp, RxPathComp);
2936    transport.send(idx, cmd);
2937
2938    packet = transport.recv(idx, 5, to);
2939
2940    if ( 5 != len(packet) ):
2941        raise Exception("LE Write RF Path Compensation command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2942
2943    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2944
2945    if ( RespCmd != Commands.CMD_LE_WRITE_RF_PATH_COMPENSATION_RSP ):
2946        raise Exception("LE Write RF Path Compensation command failed: Inappropriate command response received");
2947
2948    if ( RespLen != 1 ):
2949        raise Exception("LE Write RF Path Compensation command failed: Response length field corrupted (%i)" % RespLen);
2950
2951    return status;
2952
2953"""
2954    The LE_Set_Privacy_Mode command is used to allow the Host to specify the privacy mode to be used for a given entry on the
2955    resolving list. The effect of this setting is specified in [Vol 6] Part B, Section 4.7.
2956"""
2957def le_set_privacy_mode(transport, idx, IdAddrType, AVal, mode, to):
2958
2959    cmd = struct.pack('<HHHB6B', Commands.CMD_LE_SET_PRIVACY_MODE_REQ, 10, HCICommands.BT_HCI_OP_LE_SET_PRIVACY_MODE, IdAddrType, *AVal);
2960    cmd += struct.pack('<B', mode);
2961    transport.send(idx, cmd);
2962
2963    packet = transport.recv(idx, 5, to);
2964
2965    if ( 5 != len(packet) ):
2966        raise Exception("LE Set Privacy Mode command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2967
2968    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2969
2970    if ( RespCmd != Commands.CMD_LE_SET_PRIVACY_MODE_RSP ):
2971        raise Exception("LE Set Privacy Mode command failed: Inappropriate command response received");
2972
2973    if ( RespLen != 1 ):
2974        raise Exception("LE Set Privacy Mode command failed: Response length field corrupted (%i)" % RespLen);
2975
2976    return status;
2977
2978"""
2979    The Write_BD_ADDR command is used to set the Public address of the Device.
2980"""
2981def write_bd_addr(transport, idx, BdaddrVal, to):
2982
2983    cmd = struct.pack('<HHH6B', Commands.CMD_WRITE_BD_ADDR_REQ, 8, HCICommands.BT_HCI_OP_VS_WRITE_BD_ADDR, *BdaddrVal);
2984    transport.send(idx, cmd);
2985
2986    packet = transport.recv(idx, 5, to);
2987
2988    if ( 5 != len(packet) ):
2989        raise Exception("Write BD_ADDR command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
2990
2991    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
2992
2993    if ( RespCmd != Commands.CMD_WRITE_BD_ADDR_RSP ):
2994        raise Exception("Write BD_ADDR command failed: Inappropriate command response received");
2995
2996    if ( RespLen != 1 ):
2997        raise Exception("Write BD_ADDR command failed: Response length field corrupted (%i)" % RespLen);
2998
2999    return status;
3000
3001"""
3002    Flush the events queue
3003"""
3004def flush_events(transport, idx, to):
3005
3006    cmd = struct.pack('<HH', Commands.CMD_FLUSH_EVENTS_REQ, 0);
3007    transport.send(idx, cmd);
3008
3009    packet = transport.recv(idx, 4, to);
3010
3011    if ( 4 != len(packet) ):
3012        raise Exception("Flush Events command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
3013
3014    RespCmd, RespLen = struct.unpack('<HH', packet);
3015
3016    if ( RespCmd != Commands.CMD_FLUSH_EVENTS_RSP ):
3017        raise Exception("Flush Events command failed: Inappropriate command response received");
3018
3019    if ( RespLen != 0 ):
3020        raise Exception("Flush Events command failed: Response length field corrupted (%i)" % RespLen);
3021
3022
3023"""
3024    Check whether an event is available in the events queue
3025"""
3026def has_event(transport, idx, to):
3027
3028    while to >= 0:
3029        start_t = transport.last_t
3030
3031        cmd = struct.pack('<HH', Commands.CMD_HAS_EVENT_REQ, 0);
3032        transport.send(idx, cmd);
3033
3034        packet = transport.recv(idx, 5, 100);
3035
3036        if ( 5 != len(packet) ):
3037            raise Exception("Has Event command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
3038
3039        RespCmd, RespLen, count = struct.unpack('<HHB', packet);
3040
3041        if ( RespCmd != Commands.CMD_HAS_EVENT_RSP ):
3042            raise Exception("Has Event command failed: Inappropriate command response received");
3043
3044        if ( RespLen != 1 ):
3045            raise Exception("Has Event command failed: Response length field corrupted (%i)" % RespLen);
3046
3047        if count > 0:
3048            break;
3049
3050        to_tmp = 100 - int((transport.last_t - start_t) / 1000);
3051        to -= 100;
3052        if to >= 0 and to_tmp > 0:
3053            transport.wait(to_tmp);
3054
3055    return count > 0, count;
3056
3057"""
3058    Get event(s) from the events queue
3059"""
3060def get_event(transport, idx, to, multiple=False):
3061
3062    cmd = struct.pack('<HHB', Commands.CMD_GET_EVENT_REQ, 1, 1 if multiple else 0);
3063    transport.send(idx, cmd);
3064
3065    nBytes = 3 if multiple else 10;
3066    packet = transport.recv(idx, nBytes, to);
3067
3068    if nBytes != len(packet):
3069        raise Exception("Get Event command failed: Response too short (Expected %i bytes got %i bytes)" % (nBytes, len(packet)));
3070
3071    if multiple:
3072        RespCmd, count = struct.unpack('<HB', packet);
3073        if RespCmd != Commands.CMD_GET_EVENT_RSP:
3074            raise Exception("Get Event command failed: Inappropriate command response received");
3075
3076        events = [];
3077        while count > 0:
3078            packet = transport.recv(idx, 8, to);
3079            RespLen, time, event, eventLen = struct.unpack('<HIBB', packet);
3080            data = "" if eventLen == 0 else transport.recv(idx, eventLen, to);
3081
3082            if RespLen != (6 + eventLen):
3083                raise Exception("Get Event command failed: Response length field corrupted (%i)" % RespLen);
3084
3085            events += [Event(event, data, time)];
3086            count -= 1;
3087
3088        return events;
3089    else:
3090        RespCmd, RespLen, time, event, eventLen = struct.unpack('<HHIBB', packet[:10]);
3091        data = "" if RespLen <= 6 else transport.recv(idx, RespLen - 6, to);
3092
3093        if RespCmd != Commands.CMD_GET_EVENT_RSP:
3094            raise Exception("Get Event command failed: Inappropriate command response received (%i)" % RespCmd);
3095
3096        if RespLen != 6 + eventLen:
3097            raise Exception("Get Event command failed: Response length field corrupted (%i)" % RespLen);
3098
3099        transport.Trace.btsnoop.send_event(idx, packet, data)
3100
3101        return Event(event, data, time);
3102
3103"""
3104    Flush the Data queue
3105"""
3106def le_data_flush(transport, idx, to):
3107
3108    cmd = struct.pack('<HH', Commands.CMD_LE_DATA_FLUSH_REQ, 0);
3109    transport.send(idx, cmd);
3110
3111    packet = transport.recv(idx, 4, to);
3112
3113    if ( 4 != len(packet) ):
3114        raise Exception("LE Data Flush command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
3115
3116    RespCmd, RespLen = struct.unpack('<HH', packet);
3117
3118    if ( RespCmd != Commands.CMD_LE_DATA_FLUSH_RSP ):
3119        raise Exception("LE Data Flush command failed: Inappropriate command response received");
3120
3121    if ( RespLen != 0 ):
3122        raise Exception("LE Data Flush command failed: Response length field corrupted (%i)" % RespLen);
3123
3124
3125"""
3126    Check whether data is available in the data queue
3127"""
3128def le_data_ready(transport, idx, to):
3129
3130    while to >= 0:
3131        cmd = struct.pack('<HH', Commands.CMD_LE_DATA_READY_REQ, 0);
3132        transport.send(idx, cmd);
3133
3134        packet = transport.recv(idx, 5, 100);
3135
3136        if ( 5 != len(packet) ):
3137            raise Exception("LE Data Ready command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
3138
3139        RespCmd, RespLen, empty = struct.unpack('<HHB', packet);
3140
3141        if ( RespCmd != Commands.CMD_LE_DATA_READY_RSP ):
3142            raise Exception("LE Data Ready command failed: Inappropriate command response received");
3143
3144        if ( RespLen != 1 ):
3145            raise Exception("LE Data Ready command failed: Response length field corrupted (%i)" % RespLen);
3146
3147        if empty != 1:
3148            break;
3149
3150        to -= 100;
3151        if to >= 0:
3152            transport.wait(100);
3153
3154    return empty != 1;
3155
3156"""
3157    Write Data packet
3158"""
3159def le_data_write(transport, idx, handle, PbFlags, BcFlags, data, to):
3160
3161    handle &= 0x0fff;
3162    handle |= (PbFlags | (BcFlags << 2)) << 12;
3163    cmd = struct.pack('<HHHH' + str(len(data)) + 'B', Commands.CMD_LE_DATA_WRITE_REQ, 4 + len(data), handle, len(data), *data);
3164    transport.send(idx, cmd);
3165
3166    packet = transport.recv(idx, 5, to);
3167
3168    if ( 5 != len(packet) ):
3169        raise Exception("LE Data Write command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)));
3170
3171    RespCmd, RespLen, status = struct.unpack('<HHB', packet);
3172
3173    if ( RespCmd != Commands.CMD_LE_DATA_WRITE_RSP ):
3174        raise Exception("LE Data Write command failed: Inappropriate command response received");
3175
3176    if ( RespLen != 1 ):
3177        raise Exception("LE Data Write command failed: Response length field corrupted (%i)" % RespLen);
3178
3179    return status;
3180
3181"""
3182    Read Data packet
3183"""
3184def le_data_read(transport, idx, to):
3185
3186    cmd = struct.pack('<HH', Commands.CMD_LE_DATA_READ_REQ, 0);
3187    transport.send(idx, cmd);
3188
3189    packet = transport.recv(idx, 12, to);
3190
3191    if ( 12 != len(packet) ):
3192        raise Exception("LE Data Read command failed: Response too short (Expected %i bytes got %i bytes)" % (12, len(packet)));
3193
3194    RespCmd, RespLen, time, handle, dataLen = struct.unpack('<HHIHH', packet[:12]);
3195    if RespLen > 8:
3196        packet = transport.recv(idx, RespLen - 8, to);
3197    if dataLen > 0:
3198        data = struct.unpack('<' + str(dataLen) + 'B', packet);
3199    else:
3200        data = [];
3201
3202    if ( RespCmd != Commands.CMD_LE_DATA_READ_RSP ):
3203        raise Exception("LE Data Read command failed: Inappropriate command response received");
3204
3205    if ( RespLen != 8 + dataLen ):
3206        raise Exception("LE Data Read command failed: Response length field corrupted (%i)" % RespLen);
3207
3208    PbFlags = (handle >> 12) & 0x03;
3209    BcFlags = (handle >> 14) & 0x03;
3210    handle &= 0x0fff;
3211
3212    transport.Trace.btsnoop.send_monitor_acl_rx(idx, handle, dataLen, packet)
3213
3214    return time, handle, PbFlags, BcFlags, data;
3215
3216"""
3217    Switch GATT Service Set
3218"""
3219def switch_gatt_service_set(transport, idx, serviceSet, to):
3220
3221    cmd = struct.pack('<HHB', Commands.CMD_GATT_SERVICE_SET_REQ, 1, serviceSet);
3222    transport.send(idx, cmd);
3223
3224    packet = transport.recv(idx, 4, to);
3225
3226    if ( 4 != len(packet) ):
3227        raise Exception("Switch GATT Service Set command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
3228
3229    RespCmd, RespLen = struct.unpack('<HH', packet);
3230
3231    if ( RespCmd != Commands.CMD_GATT_SERVICE_SET_RSP ):
3232        raise Exception("Switch GATT Service Set command failed: Inappropriate command response received");
3233
3234    if ( RespLen != 0 ):
3235        raise Exception("Switch GATT Service Set command failed: Response length field corrupted (%i)" % RespLen);
3236
3237"""
3238    Invoke GATT Service Set Notifications
3239"""
3240def gatt_service_notify(transport, idx, to):
3241
3242    cmd = struct.pack('<HH', Commands.CMD_GATT_SERVICE_NOTIFY_REQ, 0);
3243    transport.send(idx, cmd);
3244
3245    packet = transport.recv(idx, 4, to);
3246
3247    if ( 4 != len(packet) ):
3248        raise Exception("Invoke GATT Service Set Notifications command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
3249
3250    RespCmd, RespLen = struct.unpack('<HH', packet);
3251
3252    if ( RespCmd != Commands.CMD_GATT_SERVICE_NOTIFY_RSP ):
3253        raise Exception("Invoke GATT Service Set Notifications command failed: Inappropriate command response received");
3254
3255    if ( RespLen != 0 ):
3256        raise Exception("Invoke GATT Service Set Notifications command failed: Response length field corrupted (%i)" % RespLen);
3257
3258"""
3259    Invoke GATT Service Set Indications
3260"""
3261def gatt_service_indicate(transport, idx, to):
3262
3263    cmd = struct.pack('<HH', Commands.CMD_GATT_SERVICE_INDICATE_REQ, 0);
3264    transport.send(idx, cmd);
3265
3266    packet = transport.recv(idx, 4, to);
3267
3268    if ( 4 != len(packet) ):
3269        raise Exception("Invoke GATT Service Set Indications command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)));
3270
3271    RespCmd, RespLen = struct.unpack('<HH', packet);
3272
3273    if ( RespCmd != Commands.CMD_GATT_SERVICE_INDICATE_RSP ):
3274        raise Exception("Invoke GATT Service Set Indications command failed: Inappropriate command response received");
3275
3276    if ( RespLen != 0 ):
3277        raise Exception("Invoke GATT Service Set Indications command failed: Response length field corrupted (%i)" % RespLen);
3278
3279"""
3280    Flush the ISO Data queue
3281"""
3282def le_iso_data_flush(transport, idx, to):
3283
3284    cmd = struct.pack('<HH', Commands.CMD_LE_ISO_DATA_FLUSH_REQ, 0)
3285    transport.send(idx, cmd)
3286
3287    packet = transport.recv(idx, 4, to)
3288
3289    if ( 4 != len(packet) ):
3290        raise Exception("LE ISO Data Flush command failed: Response too short (Expected %i bytes got %i bytes)" % (4, len(packet)))
3291
3292    RespCmd, RespLen = struct.unpack('<HH', packet)
3293
3294    if ( RespCmd != Commands.CMD_LE_ISO_DATA_FLUSH_RSP ):
3295        raise Exception("LE ISO Data Flush command failed: Inappropriate command response received")
3296
3297    if ( RespLen != 0 ):
3298        raise Exception("LE ISO Data Flush command failed: Response length field corrupted (%i)" % RespLen)
3299
3300"""
3301    Check whether ISO data is available in the data queue
3302"""
3303def le_iso_data_ready(transport, idx, to):
3304
3305    while to >= 0:
3306        cmd = struct.pack('<HH', Commands.CMD_LE_ISO_DATA_READY_REQ, 0)
3307        transport.send(idx, cmd)
3308
3309        packet = transport.recv(idx, 5, 100);
3310
3311        if ( 5 != len(packet) ):
3312            raise Exception("LE ISO Data Ready command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)))
3313
3314        RespCmd, RespLen, empty = struct.unpack('<HHB', packet)
3315
3316        if ( RespCmd != Commands.CMD_LE_ISO_DATA_READY_RSP ):
3317            raise Exception("LE ISO Data Ready command failed: Inappropriate command response received")
3318
3319        if ( RespLen != 1 ):
3320            raise Exception("LE ISO Data Ready command failed: Response length field corrupted (%i)" % RespLen)
3321
3322        if empty != 1:
3323            break
3324
3325        to -= 100;
3326        if to >= 0:
3327            transport.wait(100)
3328
3329    return empty != 1
3330
3331
3332
3333def le_iso_data_write_rsp(transport, idx, to):
3334    packet = transport.recv(idx, 5, to)
3335
3336    if ( 5 != len(packet) ):
3337        raise Exception("LE ISO Data Write command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)))
3338
3339    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
3340
3341    if ( RespCmd != Commands.CMD_LE_ISO_DATA_WRITE_RSP ):
3342        raise Exception("LE ISO Data Write command failed: Inappropriate command response received")
3343
3344    if ( RespLen != 1 ):
3345        raise Exception("LE ISO Data Write command failed: Response length field corrupted (%i)" % RespLen)
3346
3347    return status
3348
3349"""
3350    Write ISO Data packet
3351"""
3352def le_iso_data_write(transport, idx, handle, PbFlags, TsFlag, data, to):
3353
3354    handle &= 0x0fff
3355    handle |= ((PbFlags | (TsFlag << 2)) << 12) & 0x7fff
3356
3357    cmd = struct.pack('<HHHH' + str(len(data)) + 'B', Commands.CMD_LE_ISO_DATA_WRITE_REQ, 4 + len(data), handle, len(data), *data)
3358    transport.send(idx, cmd)
3359
3360    if ( to == 0 ):
3361        return 0
3362
3363    return le_iso_data_write_rsp(transport, idx, to)
3364
3365"""
3366    Read ISO Data packet
3367"""
3368def le_iso_data_read(transport, idx, to):
3369
3370    cmd = struct.pack('<HH', Commands.CMD_LE_ISO_DATA_READ_REQ, 0)
3371    transport.send(idx, cmd)
3372
3373    packet = transport.recv(idx, 12, to)
3374
3375    if ( 12 != len(packet) ):
3376        raise Exception("LE ISO Data Read command failed: Response too short (Expected %i bytes got %i bytes)" % (12, len(packet)))
3377
3378    RespCmd, RespLen, time, handle, dataLen = struct.unpack('<HHIHH', packet[:12])
3379    if RespLen > 8:
3380        packet = transport.recv(idx, RespLen - 8, to)
3381    if dataLen > 0:
3382        data = struct.unpack('<' + str(dataLen) + 'B', packet)
3383    else:
3384        data = []
3385
3386    if ( RespCmd != Commands.CMD_LE_ISO_DATA_READ_RSP ):
3387        raise Exception("LE ISO Data Read command failed: Inappropriate command response received")
3388
3389    if ( RespLen != 8 + dataLen ):
3390        raise Exception("LE ISO Data Read command failed: Response length field corrupted (%i)" % RespLen)
3391
3392    transport.Trace.btsnoop.send_monitor_iso_rx(idx, handle, dataLen, packet)
3393
3394    PbFlags = (handle >> 12) & 0x03
3395    TsFlag  = (handle >> 14) & 0x01
3396    handle &= 0x0fff
3397
3398    return time, handle, PbFlags, TsFlag, data
3399
3400"""
3401    The HCI_LE_Set_CIG_Parameters command is used by a central's Host to
3402    set the parameters of one or more CISes that are associated with a CIG in the
3403    Controller.
3404"""
3405def le_set_cig_parameters(transport, idx, CigId, SduIntervalMToS, SduIntervalSToM, PeripheralsClockAccuracy, Packing,
3406                          Framing, MaxTransportLatencyMToS, MaxTransportLatencySToM, CisCount, CisId, MaxSduMToS, MaxSduSToM,
3407                          PhyMToS, PhySToM, RtnMToS, RtnSToM, to):
3408    cmd_parameters = [HCICommands.BT_HCI_OP_LE_SET_CIG_PARAMETERS, CigId, *toArray(SduIntervalMToS, 3),
3409                      *toArray(SduIntervalSToM, 3), PeripheralsClockAccuracy, Packing, Framing, MaxTransportLatencyMToS,
3410                      MaxTransportLatencySToM, CisCount]
3411    for i in range(CisCount):
3412        cmd_parameters += [CisId[i], MaxSduMToS[i], MaxSduSToM[i], PhyMToS[i], PhySToM[i], RtnMToS[i], RtnSToM[i]]
3413
3414    edtt_send_cmd(transport, idx, Commands.CMD_LE_SET_CIG_PARAMETERS_REQ, 'HB3B3BBBBHHB' + CisCount * 'BHHBBBB',
3415                  cmd_parameters)
3416
3417    status, cigId, cisCount, *cisConnectionHandle = \
3418        edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_LE_SET_CIG_PARAMETERS_RSP, f'BBB{CisCount}H', to)
3419
3420    return status, cigId, cisCount, cisConnectionHandle
3421
3422"""
3423    The command is used by a central's Host to set the parameters of one or more
3424    CISes that are associated with a CIG in the Controller. Should only be used for
3425    testing purposes.
3426"""
3427def le_set_cig_parameters_test(transport, idx, CigId, SduIntervalMToS, SduIntervalSToM, FtMToS, FtSToM, IsoInterval, PeripheralsClockAccuracy,
3428                               Packing, Framing, CisCount, CisId, Nse, MaxSduMToS, MaxSduSToM, MaxPduMToS, MaxPduSToM,
3429                               PhyMToS, PhySToM, BnMToS, BnSToM, to):
3430    cmd_parameters = [HCICommands.BT_HCI_OP_LE_SET_CIG_PARAMETERS_TEST, CigId, *toArray(SduIntervalMToS, 3),
3431                      *toArray(SduIntervalSToM, 3), FtMToS, FtSToM, IsoInterval, PeripheralsClockAccuracy, Packing, Framing,
3432                      CisCount]
3433    for i in range(CisCount):
3434        cmd_parameters += [CisId[i], Nse[i], MaxSduMToS[i], MaxSduSToM[i], MaxPduMToS[i], MaxPduSToM[i], PhyMToS[i],
3435                           PhySToM[i], BnMToS[i], BnSToM[i]]
3436
3437    edtt_send_cmd(transport, idx, Commands.CMD_LE_SET_CIG_PARAMETERS_TEST_REQ,
3438                  'HB3B3BBBHBBBB' + CisCount * 'BBHHHHBBBB', cmd_parameters)
3439
3440    status, cigId, cisCount, *cisConnectionHandle = \
3441        edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_LE_SET_CIG_PARAMETERS_TEST_RSP, f'BBB{CisCount}H', to)
3442
3443    return status, cigId, cisCount, cisConnectionHandle
3444
3445"""
3446    The HCI_LE_Create_CIS command is used by the central's Host to create one
3447    or more CISes using the connections identified by the ACL_Connection_Handle[i]
3448    parameter array.
3449"""
3450def le_create_cis(transport, idx, CisCount, CisConnectionHandle, AclConnectionHandle, to):
3451    cmd_parameters = [HCICommands.BT_HCI_OP_LE_CREATE_CIS, CisCount]
3452    for i in range(CisCount):
3453        cmd_parameters += [CisConnectionHandle[i], AclConnectionHandle[i]]
3454
3455    edtt_send_cmd(transport, idx, Commands.CMD_LE_CREATE_CIS_REQ, 'HB' + CisCount * 'HH', cmd_parameters)
3456
3457    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_LE_CREATE_CIS_RSP, 'B', to)[0]
3458
3459"""
3460    The HCI_LE_Remove_CIG command is used by the central's Host to remove
3461    all the CISes associated with the CIG identified by CIG_ID.
3462"""
3463def le_remove_cig(transport, idx, CigId, to):
3464
3465    cmd = struct.pack('<HHHB', Commands.CMD_LE_REMOVE_CIG_REQ, 3, HCICommands.BT_HCI_OP_LE_REMOVE_CIG, CigId)
3466    transport.send(idx, cmd)
3467
3468    packet = transport.recv(idx, 6, to)
3469
3470    if ( 6 != len(packet) ):
3471        raise Exception("LE Remove CIG command failed: Response too short (Expected %i bytes got %i bytes)" % (6, len(packet)))
3472
3473    RespCmd, RespLen, status, cigId = struct.unpack('<HHBB', packet)
3474
3475    if ( RespCmd != Commands.CMD_LE_REMOVE_CIG_RSP ):
3476        raise Exception("LE Remove CIG command failed: Inappropriate command response received")
3477
3478    if ( RespLen != 2 ):
3479        raise Exception("LE Remove CIG command failed: Response length field corrupted (%i)" % RespLen)
3480
3481    return status, cigId
3482
3483"""
3484    The HCI_LE_Accept_CIS_Request command is used by the peripheral's Host to
3485    inform the Controller to accept the request for the CIS that is identified by the
3486    Connection_Handle.
3487"""
3488def le_accept_cis_request(transport, idx, ConnectionHandle, to):
3489
3490    ConnectionHandle &= 0x0fff
3491
3492    cmd = struct.pack('<HHHH', Commands.CMD_LE_ACCEPT_CIS_REQUEST_REQ, 4, HCICommands.BT_HCI_OP_LE_ACCEPT_CIS_REQUEST,
3493                      ConnectionHandle)
3494    transport.send(idx, cmd)
3495
3496    packet = transport.recv(idx, 5, to)
3497
3498    if ( 5 != len(packet) ):
3499        raise Exception("LE Accept CIS Request command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)))
3500
3501    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
3502
3503    if ( RespCmd != Commands.CMD_LE_ACCEPT_CIS_REQUEST_RSP ):
3504        raise Exception("LE Accept CIS Request command failed: Inappropriate command response received")
3505
3506    if ( RespLen != 1 ):
3507        raise Exception("LE Accept CIS Request command failed: Response length field corrupted (%i)" % RespLen)
3508
3509    return status
3510
3511"""
3512    The HCI_LE_Reject_CIS_Request command is used by the peripheral's Host to
3513    inform the Controller to reject the request for the CIS that is identified by the
3514    Connection_Handle.
3515"""
3516def le_reject_cis_request(transport, idx, ConnectionHandle, Reason, to):
3517
3518    ConnectionHandle &= 0x0fff
3519
3520    cmd = struct.pack('<HHHHB', Commands.CMD_LE_REJECT_CIS_REQUEST_REQ, 5, HCICommands.BT_HCI_OP_LE_REJECT_CIS_REQUEST,
3521                      ConnectionHandle, Reason)
3522    transport.send(idx, cmd)
3523
3524    packet = transport.recv(idx, 7, to)
3525
3526    if ( 7 != len(packet) ):
3527        raise Exception("LE Reject CIS Request command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)))
3528
3529    RespCmd, RespLen, status, connectionHandle = struct.unpack('<HHBH', packet)
3530
3531    if ( RespCmd != Commands.CMD_LE_REJECT_CIS_REQUEST_RSP ):
3532        raise Exception("LE Reject CIS Request command failed: Inappropriate command response received")
3533
3534    if ( RespLen != 3 ):
3535        raise Exception("LE Reject CIS Request command failed: Response length field corrupted (%i)" % RespLen)
3536
3537    return status, connectionHandle
3538
3539
3540def le_request_peer_sca(transport, idx, acl_conn_handle, to):
3541    """
3542    The command is used to read the Sleep Clock Accuracy (SCA) of the peer device.
3543    :param transport: bearer to be used
3544    :param idx: device index
3545    :param acl_conn_handle: Connection handle of the ACL
3546    :param to: Receiver timeout
3547    :return: command status
3548    """
3549    cmd_parameters = [HCICommands.BT_HCI_OP_LE_REQUEST_PEER_SCA, acl_conn_handle]
3550    edtt_send_cmd(transport, idx, Commands.CMD_HCI_LE_REQUEST_PEER_SCA_REQ, 'HH', cmd_parameters)
3551
3552    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_HCI_LE_REQUEST_PEER_SCA_RSP, 'B', to)[0]
3553
3554
3555"""
3556    The HCI_LE_Setup_ISO_Data_Path command is used to identify and create
3557    the isochronous data path between the Host and the Controller for an
3558    established CIS or BIS identified by the Connection_Handle parameter.
3559"""
3560def le_setup_iso_data_path(transport, idx, ConnectionHandle, DataPathDirection, DataPathId, CodecId, ControllerDelay,
3561                           CodecConfigurationLength, CodecConfiguration, to):
3562
3563    ConnectionHandle &= 0x0fff
3564
3565    cmd = struct.pack('<HHHHBB5B3BB' + str(CodecConfigurationLength) + 'B',
3566                      Commands.CMD_LE_SETUP_ISO_DATA_PATH_REQ, 15 + (CodecConfigurationLength * 1), HCICommands.BT_HCI_OP_LE_SETUP_ISO_DATA_PATH,
3567                      ConnectionHandle, DataPathDirection, DataPathId, *CodecId, *toArray(ControllerDelay, 3), CodecConfigurationLength, *CodecConfiguration)
3568    transport.send(idx, cmd)
3569
3570    packet = transport.recv(idx, 7, to)
3571
3572    if ( 7 != len(packet) ):
3573        raise Exception("LE Setup ISO Data Path command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)))
3574
3575    RespCmd, RespLen, status, connectionHandle = struct.unpack('<HHBH', packet)
3576
3577    if ( RespCmd != Commands.CMD_LE_SETUP_ISO_DATA_PATH_RSP ):
3578        raise Exception("LE Setup ISO Data Path command failed: Inappropriate command response received")
3579
3580    if ( RespLen != 3 ):
3581        raise Exception("LE Setup ISO Data Path command failed: Response length field corrupted (%i)" % RespLen)
3582
3583    return status, connectionHandle
3584
3585"""
3586    The HCI_LE_Remove_ISO_Data_Path command is used to remove the input
3587    and/or output data path(s) associated with a CIS or BIS identified by the
3588    Connection_Handle parameter.
3589"""
3590def le_remove_iso_data_path(transport, idx, ConnectionHandle, DataPathDirection, to):
3591
3592    ConnectionHandle &= 0x0fff
3593
3594    cmd = struct.pack('<HHHHB',
3595                      Commands.CMD_LE_REMOVE_ISO_DATA_PATH_REQ, 5, HCICommands.BT_HCI_OP_LE_REMOVE_ISO_DATA_PATH,
3596                      ConnectionHandle, DataPathDirection)
3597    transport.send(idx, cmd)
3598
3599    packet = transport.recv(idx, 7, to)
3600
3601    if ( 7 != len(packet) ):
3602        raise Exception("LE Remove ISO Data Path command failed: Response too short (Expected %i bytes got %i bytes)" % (7, len(packet)))
3603
3604    RespCmd, RespLen, status, connectionHandle = struct.unpack('<HHBH', packet)
3605
3606    if ( RespCmd != Commands.CMD_LE_REMOVE_ISO_DATA_PATH_RSP ):
3607        raise Exception("LE Remove ISO Data Path command failed: Inappropriate command response received")
3608
3609    if ( RespLen != 3 ):
3610        raise Exception("LE Remove ISO Data Path command failed: Response length field corrupted (%i)" % RespLen)
3611
3612    return status, connectionHandle
3613
3614"""
3615    The HCI_LE_Set_Host_Feature command is used by the Host to set or clear a bit
3616    controlled by the Host in the Link Layer FeatureSet stored in the Controller.
3617"""
3618def le_set_host_feature(transport, idx, BitNumber, BitValue, to):
3619
3620    cmd = struct.pack('<HHHBB', Commands.CMD_LE_SET_HOST_FEATURE_REQ, 4, HCICommands.BT_HCI_OP_LE_SET_HOST_FEATURE, BitNumber, BitValue)
3621    transport.send(idx, cmd)
3622
3623    packet = transport.recv(idx, 5, to)
3624
3625    if ( 5 != len(packet) ):
3626        raise Exception("LE Set Host Feature command failed: Response too short (Expected %i bytes got %i bytes)" % (5, len(packet)))
3627
3628    RespCmd, RespLen, status = struct.unpack('<HHB', packet)
3629
3630    if ( RespCmd != Commands.CMD_LE_SET_HOST_FEATURE_RSP ):
3631        raise Exception("LE Set Host Feature command failed: Inappropriate command response received")
3632
3633    if ( RespLen != 1 ):
3634        raise Exception("LE Set Host Feature command failed: Response length field corrupted (%i)" % RespLen)
3635
3636    return status
3637
3638
3639def get_ixit_value(transport, idx, ixit, to):
3640    """Request IXIT value from test device
3641    :param transport: bearer to be used
3642    :param idx: device index
3643    :param ixit: IXIT to read
3644    :param to: Receiver timeout
3645    :return: IXIT value
3646    """
3647    edtt_send_cmd(transport, idx, Commands.CMD_GET_IXIT_VALUE_REQ, 'BBB',
3648                  (ixit.profile_id, ixit.ref_major, ixit.ref_minor))
3649    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_GET_IXIT_VALUE_RSP, ixit.value_fmt, to)[0]
3650
3651
3652def hci_le_iso_transmit_test(transport, idx, connection_handle, payload_type, to):
3653    """
3654    The command is used to configure an established CIS or BIS specified by the Connection_Handle parameter, and
3655    transmit test payloads which are generated by the Controller.
3656    :param transport: bearer to be used
3657    :param idx: device index
3658    :param connection_handle: CIS or BIS connection handle
3659    :param payload_type: defines the configuration of SDUs in the payload.
3660    :param to: Receiver timeout
3661    :return: (status, connection_handle)
3662    """
3663    edtt_send_cmd(transport, idx, Commands.CMD_HCI_LE_ISO_TRANSMIT_TEST_REQ, 'HHB',
3664                  (HCICommands.BT_HCI_OP_LE_ISO_TRANSMIT_TEST, connection_handle, payload_type))
3665    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_HCI_LE_ISO_TRANSMIT_TEST_RSP, 'BH', to)
3666
3667
3668def hci_le_iso_receive_test(transport, idx, connection_handle, payload_type, to):
3669    """
3670    The command is used to configure an established CIS or a synchronized BIG specified by the Connection_Handle
3671    parameter to receive payloads.
3672    :param transport: bearer to be used
3673    :param idx: device index
3674    :param connection_handle: CIS or BIS connection handle
3675    :param payload_type: defines the configuration of SDUs in the payload.
3676    :param to: Receiver timeout
3677    :return: (status, connection_handle)
3678    """
3679    edtt_send_cmd(transport, idx, Commands.CMD_HCI_LE_ISO_RECEIVE_TEST_REQ, 'HHB',
3680                  (HCICommands.BT_HCI_OP_LE_ISO_RECEIVE_TEST, connection_handle, payload_type))
3681    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_HCI_LE_ISO_RECEIVE_TEST_RSP, 'BH', to)
3682
3683
3684def hci_le_iso_read_test_counters_test(transport, idx, connection_handle, to):
3685    """
3686    The command is used to read the test counters in the Controller which is configured in ISO Receive Test mode for a
3687    CIS or BIS specified by the Connection_Handle. Reading the test counters does not reset the test counters.
3688    :param transport: bearer to be used
3689    :param idx: device index
3690    :param connection_handle: CIS or BIS connection handle
3691    :param to: Receiver timeout
3692    :return: (status, connection_handle, received_sdu_count, missed_sdu_count, failed_sdu_count)
3693    """
3694    edtt_send_cmd(transport, idx, Commands.CMD_HCI_LE_ISO_READ_TEST_COUNTERS_REQ, 'HH',
3695                  (HCICommands.BT_HCI_OP_LE_ISO_READ_TEST_COUNTERS, connection_handle))
3696    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_HCI_LE_ISO_READ_TEST_COUNTERS_RSP, 'BHIII', to)
3697
3698
3699def hci_le_iso_test_end(transport, idx, connection_handle, to):
3700    """The command is used to terminate the ISO Transmit and/or Receive Test mode for a CIS or BIS specified by the
3701    Connection_Handle parameter but does not terminate the CIS or BIS.
3702    :param transport: bearer to be used
3703    :param idx: device index
3704    :param connection_handle: CIS or BIS connection handle
3705    :param to: Receiver timeout
3706    :return: (status, connection_handle, received_sdu_count, missed_sdu_count, failed_sdu_count)
3707    """
3708    edtt_send_cmd(transport, idx, Commands.CMD_HCI_LE_ISO_TEST_END_REQ, 'HH', (HCICommands.BT_HCI_OP_LE_ISO_TEST_END,
3709                                                                               connection_handle))
3710    return edtt_wait_cmd_cmpl(transport, idx, Commands.CMD_HCI_LE_ISO_TEST_END_RSP, 'BHIII', to)
3711