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