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