1. HCI_Read_Local_Supported_Commands 命令介绍
1. 命令介绍(Description)
HCI_Read_Local_Supported_Commands 是 HCI 层中非常重要的查询命令。它允许 Host(如 Android 系统中的 Bluetooth stack)获取 Controller(蓝牙芯片)支持的 所有 HCI 命令 列表。
这些命令的支持情况由 Supported_Commands
这个 64 字节位图 表示,每一位(bit)对应一个 HCI 命令是否支持。
🔹 本质:能力查询的位图(Command Capabilities Bitmap)
2.命令参数
13 2025-04-24 15:55:53.354453 host controller HCI_CMD 4 Sent Read Local Supported Commands
Bluetooth HCI Command - Read Local Supported Commands
Command Opcode: Read Local Supported Commands (0x1002)
0001 00.. .... .... = Opcode Group Field: Informational Parameters (0x04)
.... ..00 0000 0010 = Opcode Command Field: Read Local Supported Commands (0x002)
Parameter Total Length: 0
[Response in frame: 14]
[Command-Response Delta: 0.775ms]
无参数
3. 返回参数
14 2025-04-24 15:55:53.355228 controller host HCI_EVT 71 Rcvd Command Complete (Read Local Supported Commands)
Bluetooth HCI Event - Command Complete
Event Code: Command Complete (0x0e)
Parameter Total Length: 68
Number of Allowed Command Packets: 1
Command Opcode: Read Local Supported Commands (0x1002)
0001 00.. .... .... = Opcode Group Field: Informational Parameters (0x04)
.... ..00 0000 0010 = Opcode Command Field: Read Local Supported Commands (0x002)
Status: Success (0x00)
Local Supported Commands: ffffff03ceffefffffffff1ff20fe8fe3ff783ff1c00040061ffffff7f3820f5fff0ffff…
[Command in frame: 13]
[Command-Response Delta: 0.775ms]
参数名 | 大小 | 描述 |
---|---|---|
Status | 1 byte | 0x00 表示成功 |
Supported_Commands | 64 bytes | 每个 bit 对应一个 HCI 命令是否支持(参考 Vol 4, Part E, Section 6.27) |
4.事件
- 成功后会通过
HCI_Command_Complete
事件返回上述字段
5. Supported_Commands 的位图说明
这个位图是 HCI 控制器支持能力的集中体现。例如:
- Byte 0 bit 0 →
HCI_Inquiry
- Byte 0 bit 1 →
HCI_Inquiry_Cancel
- Byte 1 bit 5 →
HCI_Read_Remote_Supported_Features
- Byte 5 bit 6 →
HCI_LE_Set_Advertise_Enable
- Byte 27 bit 2 →
HCI_LE_Set_Extended_Advertising_Parameters
等等,具体定义见 Bluetooth Core Spec Vol 4, Part E, Section 6.27(共 64 字节,512 bits,分别映射所有可能的 HCI 命令)
2. aosp 中的应用
1. host 发送该命令
// system/gd/hci/controller.cc
struct Controller::impl {
void Start(hci::HciLayer* hci) {
...
hci_->EnqueueCommand(ReadLocalSupportedCommandsBuilder::Create(),
handler->BindOnceOn(this, &Controller::impl::read_local_supported_commands_complete_handler));
...
}
当收到 controller 的回复时将调用 read_local_supported_commands_complete_handler
1. read_local_supported_commands_complete_handler
void read_local_supported_commands_complete_handler(CommandCompleteView view) {
auto complete_view = ReadLocalSupportedCommandsCompleteView::Create(view);
ASSERT(complete_view.IsValid());
ErrorCode status = complete_view.GetStatus();
ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str());
local_supported_commands_ = complete_view.GetSupportedCommands();
}
- 将 命令支持位图 保存在 local_supported_commands_ 中
我们来看一下如何使用 local_supported_commands_
// system/gd/hci/controller.cc
#define OP_CODE_MAPPING(name) \
case OpCode::name: { \
uint16_t index = (uint16_t)OpCodeIndex::name; \
uint16_t byte_index = index / 10; \
uint16_t bit_index = index % 10; \
bool supported = local_supported_commands_[byte_index] & (1 << bit_index); \
if (!supported) { \
LOG_DEBUG("unsupported command opcode: 0x%04x", (uint16_t)OpCode::name); \
} \
return supported; \
}
OpCodeIndex 命令索引如下:
- system/gd/hci/hci_packets.pdl
// For mapping Local Supported Commands command
// Value = Octet * 10 + bit
enum OpCodeIndex : 16 {
INQUIRY = 0,
INQUIRY_CANCEL = 1,
PERIODIC_INQUIRY_MODE = 2,
EXIT_PERIODIC_INQUIRY_MODE = 3,
CREATE_CONNECTION = 4,
DISCONNECT = 5,
ADD_SCO_CONNECTION = 6,
CREATE_CONNECTION_CANCEL = 7,
ACCEPT_CONNECTION_REQUEST = 10,
REJECT_CONNECTION_REQUEST = 11,
LINK_KEY_REQUEST_REPLY = 12,
LINK_KEY_REQUEST_NEGATIVE_REPLY = 13,
PIN_CODE_REQUEST_REPLY = 14,
PIN_CODE_REQUEST_NEGATIVE_REPLY = 15,
CHANGE_CONNECTION_PACKET_TYPE = 16,
AUTHENTICATION_REQUESTED = 17,
SET_CONNECTION_ENCRYPTION = 20,
CHANGE_CONNECTION_LINK_KEY = 21,
CENTRAL_LINK_KEY = 22,
REMOTE_NAME_REQUEST = 23,
REMOTE_NAME_REQUEST_CANCEL = 24,
READ_REMOTE_SUPPORTED_FEATURES = 25,
READ_REMOTE_EXTENDED_FEATURES = 26,
READ_REMOTE_VERSION_INFORMATION = 27,
READ_CLOCK_OFFSET = 30,
READ_LMP_HANDLE = 31,
HOLD_MODE = 41,
SNIFF_MODE = 42,
EXIT_SNIFF_MODE = 43,
QOS_SETUP = 46,
ROLE_DISCOVERY = 47,
SWITCH_ROLE = 50,
READ_LINK_POLICY_SETTINGS = 51,
WRITE_LINK_POLICY_SETTINGS = 52,
READ_DEFAULT_LINK_POLICY_SETTINGS = 53,
WRITE_DEFAULT_LINK_POLICY_SETTINGS = 54,
FLOW_SPECIFICATION = 55,
SET_EVENT_MASK = 56,
RESET = 57,
SET_EVENT_FILTER = 60,
FLUSH = 61,
READ_PIN_TYPE = 62,
WRITE_PIN_TYPE = 63,
READ_STORED_LINK_KEY = 65,
WRITE_STORED_LINK_KEY = 66,
DELETE_STORED_LINK_KEY = 67,
WRITE_LOCAL_NAME = 70,
READ_LOCAL_NAME = 71,
READ_CONNECTION_ACCEPT_TIMEOUT = 72,
WRITE_CONNECTION_ACCEPT_TIMEOUT = 73,
READ_PAGE_TIMEOUT = 74,
WRITE_PAGE_TIMEOUT = 75,
READ_SCAN_ENABLE = 76,
WRITE_SCAN_ENABLE = 77,
READ_PAGE_SCAN_ACTIVITY = 80,
WRITE_PAGE_SCAN_ACTIVITY = 81,
READ_INQUIRY_SCAN_ACTIVITY = 82,
WRITE_INQUIRY_SCAN_ACTIVITY = 83,
READ_AUTHENTICATION_ENABLE = 84,
WRITE_AUTHENTICATION_ENABLE = 85,
READ_CLASS_OF_DEVICE = 90,
WRITE_CLASS_OF_DEVICE = 91,
READ_VOICE_SETTING = 92,
WRITE_VOICE_SETTING = 93,
READ_AUTOMATIC_FLUSH_TIMEOUT = 94,
WRITE_AUTOMATIC_FLUSH_TIMEOUT = 95,
READ_NUM_BROADCAST_RETRANSMITS = 96,
WRITE_NUM_BROADCAST_RETRANSMITS = 97,
READ_HOLD_MODE_ACTIVITY = 100,
WRITE_HOLD_MODE_ACTIVITY = 101,
READ_TRANSMIT_POWER_LEVEL = 102,
READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 103,
WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 104,
SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 105,
HOST_BUFFER_SIZE = 106,
HOST_NUM_COMPLETED_PACKETS = 107,
READ_LINK_SUPERVISION_TIMEOUT = 110,
WRITE_LINK_SUPERVISION_TIMEOUT = 111,
READ_NUMBER_OF_SUPPORTED_IAC = 112,
READ_CURRENT_IAC_LAP = 113,
WRITE_CURRENT_IAC_LAP = 114,
SET_AFH_HOST_CHANNEL_CLASSIFICATION = 121,
READ_INQUIRY_SCAN_TYPE = 124,
WRITE_INQUIRY_SCAN_TYPE = 125,
READ_INQUIRY_MODE = 126,
WRITE_INQUIRY_MODE = 127,
READ_PAGE_SCAN_TYPE = 130,
WRITE_PAGE_SCAN_TYPE = 131,
READ_AFH_CHANNEL_ASSESSMENT_MODE = 132,
WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 133,
READ_LOCAL_VERSION_INFORMATION = 143,
READ_LOCAL_SUPPORTED_FEATURES = 145,
READ_LOCAL_EXTENDED_FEATURES = 146,
READ_BUFFER_SIZE = 147,
READ_BD_ADDR = 151,
READ_FAILED_CONTACT_COUNTER = 152,
RESET_FAILED_CONTACT_COUNTER = 153,
READ_LINK_QUALITY = 154,
READ_RSSI = 155,
READ_AFH_CHANNEL_MAP = 156,
READ_CLOCK = 157,
READ_LOOPBACK_MODE = 160,
WRITE_LOOPBACK_MODE = 161,
ENABLE_DEVICE_UNDER_TEST_MODE = 162,
SETUP_SYNCHRONOUS_CONNECTION = 163,
ACCEPT_SYNCHRONOUS_CONNECTION = 164,
REJECT_SYNCHRONOUS_CONNECTION = 165,
READ_EXTENDED_INQUIRY_RESPONSE = 170,
WRITE_EXTENDED_INQUIRY_RESPONSE = 171,
REFRESH_ENCRYPTION_KEY = 172,
SNIFF_SUBRATING = 174,
READ_SIMPLE_PAIRING_MODE = 175,
WRITE_SIMPLE_PAIRING_MODE = 176,
READ_LOCAL_OOB_DATA = 177,
READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 180,
WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 181,
IO_CAPABILITY_REQUEST_REPLY = 187,
USER_CONFIRMATION_REQUEST_REPLY = 190,
USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 191,
USER_PASSKEY_REQUEST_REPLY = 192,
USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 193,
REMOTE_OOB_DATA_REQUEST_REPLY = 194,
WRITE_SIMPLE_PAIRING_DEBUG_MODE = 195,
ENHANCED_FLUSH = 196,
REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 197,
SEND_KEYPRESS_NOTIFICATION = 202,
IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 203,
READ_ENCRYPTION_KEY_SIZE = 204,
SET_EVENT_MASK_PAGE_2 = 222,
READ_DATA_BLOCK_SIZE = 232,
READ_LE_HOST_SUPPORT = 245,
WRITE_LE_HOST_SUPPORT = 246,
LE_SET_EVENT_MASK = 250,
LE_READ_BUFFER_SIZE_V1 = 251,
LE_READ_LOCAL_SUPPORTED_FEATURES = 252,
LE_SET_RANDOM_ADDRESS = 254,
LE_SET_ADVERTISING_PARAMETERS = 255,
LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 256,
LE_SET_ADVERTISING_DATA = 257,
LE_SET_SCAN_RESPONSE_DATA = 260,
LE_SET_ADVERTISING_ENABLE = 261,
LE_SET_SCAN_PARAMETERS = 262,
LE_SET_SCAN_ENABLE = 263,
LE_CREATE_CONNECTION = 264,
LE_CREATE_CONNECTION_CANCEL = 265,
LE_READ_FILTER_ACCEPT_LIST_SIZE = 266,
LE_CLEAR_FILTER_ACCEPT_LIST = 267,
LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST = 270,
LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST = 271,
LE_CONNECTION_UPDATE = 272,
LE_SET_HOST_CHANNEL_CLASSIFICATION = 273,
LE_READ_CHANNEL_MAP = 274,
LE_READ_REMOTE_FEATURES = 275,
LE_ENCRYPT = 276,
LE_RAND = 277,
LE_START_ENCRYPTION = 280,
LE_LONG_TERM_KEY_REQUEST_REPLY = 281,
LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 282,
LE_READ_SUPPORTED_STATES = 283,
LE_RECEIVER_TEST = 284,
LE_TRANSMITTER_TEST = 285,
LE_TEST_END = 286,
ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 293,
ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = 294,
READ_LOCAL_SUPPORTED_CODECS_V1 = 295,
REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY = 321,
READ_SECURE_CONNECTIONS_HOST_SUPPORT = 322,
WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 323,
READ_LOCAL_OOB_EXTENDED_DATA = 326,
WRITE_SECURE_CONNECTIONS_TEST_MODE = 327,
LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = 334,
LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = 335,
LE_SET_DATA_LENGTH = 336,
LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 337,
LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 340,
LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = 341,
LE_GENERATE_DHKEY_COMMAND_V1 = 342,
LE_ADD_DEVICE_TO_RESOLVING_LIST = 343,
LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 344,
LE_CLEAR_RESOLVING_LIST = 345,
LE_READ_RESOLVING_LIST_SIZE = 346,
LE_READ_PEER_RESOLVABLE_ADDRESS = 347,
LE_READ_LOCAL_RESOLVABLE_ADDRESS = 350,
LE_SET_ADDRESS_RESOLUTION_ENABLE = 351,
LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 352,
LE_READ_MAXIMUM_DATA_LENGTH = 353,
LE_READ_PHY = 354,
LE_SET_DEFAULT_PHY = 355,
LE_SET_PHY = 356,
LE_ENHANCED_RECEIVER_TEST = 357,
LE_ENHANCED_TRANSMITTER_TEST = 360,
LE_SET_ADVERTISING_SET_RANDOM_ADDRESS = 361,
LE_SET_EXTENDED_ADVERTISING_PARAMETERS = 362,
LE_SET_EXTENDED_ADVERTISING_DATA = 363,
LE_SET_EXTENDED_SCAN_RESPONSE_DATA = 364,
LE_SET_EXTENDED_ADVERTISING_ENABLE = 365,
LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 366,
LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 367,
LE_REMOVE_ADVERTISING_SET = 370,
LE_CLEAR_ADVERTISING_SETS = 371,
LE_SET_PERIODIC_ADVERTISING_PARAM = 372,
LE_SET_PERIODIC_ADVERTISING_DATA = 373,
LE_SET_PERIODIC_ADVERTISING_ENABLE = 374,
LE_SET_EXTENDED_SCAN_PARAMETERS = 375,
LE_SET_EXTENDED_SCAN_ENABLE = 376,
LE_EXTENDED_CREATE_CONNECTION = 377,
LE_PERIODIC_ADVERTISING_CREATE_SYNC = 380,
LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 381,
LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 382,
LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = 383,
LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = 384,
LE_CLEAR_PERIODIC_ADVERTISING_LIST = 385,
LE_READ_PERIODIC_ADVERTISING_LIST_SIZE = 386,
LE_READ_TRANSMIT_POWER = 387,
LE_READ_RF_PATH_COMPENSATION_POWER = 390,
LE_WRITE_RF_PATH_COMPENSATION_POWER = 391,
LE_SET_PRIVACY_MODE = 392,
LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE = 405,
LE_PERIODIC_ADVERTISING_SYNC_TRANSFER = 406,
LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER = 407,
LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 410,
LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 411,
LE_GENERATE_DHKEY_COMMAND = 412,
LE_MODIFY_SLEEP_CLOCK_ACCURACY = 414,
LE_READ_BUFFER_SIZE_V2 = 415,
LE_READ_ISO_TX_SYNC = 416,
LE_SET_CIG_PARAMETERS = 417,
LE_SET_CIG_PARAMETERS_TEST = 418,
LE_CREATE_CIS = 421,
LE_REMOVE_CIG = 422,
LE_ACCEPT_CIS_REQUEST = 423,
LE_REJECT_CIS_REQUEST = 424,
LE_CREATE_BIG = 425,
LE_TERMINATE_BIG = 427,
LE_BIG_CREATE_SYNC = 430,
LE_BIG_TERMINATE_SYNC = 431,
LE_REQUEST_PEER_SCA = 432,
LE_SETUP_ISO_DATA_PATH = 433,
LE_REMOVE_ISO_DATA_PATH = 434,
LE_SET_HOST_FEATURE = 441,
LE_READ_ISO_LINK_QUALITY = 442,
LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL = 443,
LE_READ_REMOTE_TRANSMIT_POWER_LEVEL = 444,
LE_SET_PATH_LOSS_REPORTING_PARAMETERS = 445,
LE_SET_PATH_LOSS_REPORTING_ENABLE = 446,
LE_SET_TRANSMIT_POWER_REPORTING_ENABLE = 447,
SET_ECOSYSTEM_BASE_INTERVAL = 451,
READ_LOCAL_SUPPORTED_CODECS_V2 = 452,
READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES = 453,
READ_LOCAL_SUPPORTED_CONTROLLER_DELAY = 454,
CONFIGURE_DATA_PATH = 455,
LE_SET_DATA_RELATED_ADDRESS_CHANGES = 456,
SET_MIN_ENCRYPTION_KEY_SIZE = 457,
LE_SET_DEFAULT_SUBRATE = 460,
LE_SUBRATE_REQUEST = 461,
}
这里我拿 LE_SUBRATE_REQUEST 为例 说明 OP_CODE_MAPPING 如何使用:
#define OP_CODE_MAPPING(LE_SUBRATE_REQUEST)
// 等价于下面的:
case OpCode::LE_SUBRATE_REQUEST: {
uint16_t index = (uint16_t)OpCodeIndex::LE_SUBRATE_REQUEST;// 461
uint16_t byte_index = index / 10; // 46
uint16_t bit_index = index % 10; // 1
bool supported = local_supported_commands_[byte_index] & (1 << bit_index); // local_supported_commands_ 位图中第 46 字节第1bit
if (!supported) {
LOG_DEBUG("unsupported command opcode: 0x%04x", (uint16_t)OpCode::LE_SUBRATE_REQUEST);
}
return supported;
}
- 通过 OP_CODE_MAPPING 我们可以成功索引到 该 hcicmd 在 位图中对应的位。
// system/gd/hci/controller.cc
bool is_supported(OpCode op_code) {
switch (op_code) {
OP_CODE_MAPPING(INQUIRY)
OP_CODE_MAPPING(INQUIRY_CANCEL)
OP_CODE_MAPPING(PERIODIC_INQUIRY_MODE)
OP_CODE_MAPPING(EXIT_PERIODIC_INQUIRY_MODE)
OP_CODE_MAPPING(CREATE_CONNECTION)
OP_CODE_MAPPING(DISCONNECT)
OP_CODE_MAPPING(CREATE_CONNECTION_CANCEL)
OP_CODE_MAPPING(ACCEPT_CONNECTION_REQUEST)
OP_CODE_MAPPING(REJECT_CONNECTION_REQUEST)
OP_CODE_MAPPING(LINK_KEY_REQUEST_REPLY)
OP_CODE_MAPPING(LINK_KEY_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(PIN_CODE_REQUEST_REPLY)
OP_CODE_MAPPING(PIN_CODE_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(CHANGE_CONNECTION_PACKET_TYPE)
OP_CODE_MAPPING(AUTHENTICATION_REQUESTED)
OP_CODE_MAPPING(SET_CONNECTION_ENCRYPTION)
OP_CODE_MAPPING(CHANGE_CONNECTION_LINK_KEY)
OP_CODE_MAPPING(CENTRAL_LINK_KEY)
OP_CODE_MAPPING(REMOTE_NAME_REQUEST)
OP_CODE_MAPPING(REMOTE_NAME_REQUEST_CANCEL)
OP_CODE_MAPPING(READ_REMOTE_SUPPORTED_FEATURES)
OP_CODE_MAPPING(READ_REMOTE_EXTENDED_FEATURES)
OP_CODE_MAPPING(READ_REMOTE_VERSION_INFORMATION)
OP_CODE_MAPPING(READ_CLOCK_OFFSET)
OP_CODE_MAPPING(READ_LMP_HANDLE)
OP_CODE_MAPPING(HOLD_MODE)
OP_CODE_MAPPING(SNIFF_MODE)
OP_CODE_MAPPING(EXIT_SNIFF_MODE)
OP_CODE_MAPPING(QOS_SETUP)
OP_CODE_MAPPING(ROLE_DISCOVERY)
OP_CODE_MAPPING(SWITCH_ROLE)
OP_CODE_MAPPING(READ_LINK_POLICY_SETTINGS)
OP_CODE_MAPPING(WRITE_LINK_POLICY_SETTINGS)
OP_CODE_MAPPING(READ_DEFAULT_LINK_POLICY_SETTINGS)
OP_CODE_MAPPING(WRITE_DEFAULT_LINK_POLICY_SETTINGS)
OP_CODE_MAPPING(FLOW_SPECIFICATION)
OP_CODE_MAPPING(SET_EVENT_MASK)
OP_CODE_MAPPING(RESET)
OP_CODE_MAPPING(SET_EVENT_FILTER)
OP_CODE_MAPPING(FLUSH)
OP_CODE_MAPPING(READ_PIN_TYPE)
OP_CODE_MAPPING(WRITE_PIN_TYPE)
OP_CODE_MAPPING(READ_STORED_LINK_KEY)
OP_CODE_MAPPING(WRITE_STORED_LINK_KEY)
OP_CODE_MAPPING(DELETE_STORED_LINK_KEY)
OP_CODE_MAPPING(WRITE_LOCAL_NAME)
OP_CODE_MAPPING(READ_LOCAL_NAME)
OP_CODE_MAPPING(READ_CONNECTION_ACCEPT_TIMEOUT)
OP_CODE_MAPPING(WRITE_CONNECTION_ACCEPT_TIMEOUT)
OP_CODE_MAPPING(READ_PAGE_TIMEOUT)
OP_CODE_MAPPING(WRITE_PAGE_TIMEOUT)
OP_CODE_MAPPING(READ_SCAN_ENABLE)
OP_CODE_MAPPING(WRITE_SCAN_ENABLE)
OP_CODE_MAPPING(READ_PAGE_SCAN_ACTIVITY)
OP_CODE_MAPPING(WRITE_PAGE_SCAN_ACTIVITY)
OP_CODE_MAPPING(READ_INQUIRY_SCAN_ACTIVITY)
OP_CODE_MAPPING(WRITE_INQUIRY_SCAN_ACTIVITY)
OP_CODE_MAPPING(READ_AUTHENTICATION_ENABLE)
OP_CODE_MAPPING(WRITE_AUTHENTICATION_ENABLE)
OP_CODE_MAPPING(READ_CLASS_OF_DEVICE)
OP_CODE_MAPPING(WRITE_CLASS_OF_DEVICE)
OP_CODE_MAPPING(READ_VOICE_SETTING)
OP_CODE_MAPPING(WRITE_VOICE_SETTING)
OP_CODE_MAPPING(READ_AUTOMATIC_FLUSH_TIMEOUT)
OP_CODE_MAPPING(WRITE_AUTOMATIC_FLUSH_TIMEOUT)
OP_CODE_MAPPING(READ_NUM_BROADCAST_RETRANSMITS)
OP_CODE_MAPPING(WRITE_NUM_BROADCAST_RETRANSMITS)
OP_CODE_MAPPING(READ_HOLD_MODE_ACTIVITY)
OP_CODE_MAPPING(WRITE_HOLD_MODE_ACTIVITY)
OP_CODE_MAPPING(READ_TRANSMIT_POWER_LEVEL)
OP_CODE_MAPPING(READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE)
OP_CODE_MAPPING(WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE)
OP_CODE_MAPPING(SET_CONTROLLER_TO_HOST_FLOW_CONTROL)
OP_CODE_MAPPING(HOST_BUFFER_SIZE)
OP_CODE_MAPPING(HOST_NUM_COMPLETED_PACKETS)
OP_CODE_MAPPING(READ_LINK_SUPERVISION_TIMEOUT)
OP_CODE_MAPPING(WRITE_LINK_SUPERVISION_TIMEOUT)
OP_CODE_MAPPING(READ_NUMBER_OF_SUPPORTED_IAC)
OP_CODE_MAPPING(READ_CURRENT_IAC_LAP)
OP_CODE_MAPPING(WRITE_CURRENT_IAC_LAP)
OP_CODE_MAPPING(SET_AFH_HOST_CHANNEL_CLASSIFICATION)
OP_CODE_MAPPING(READ_INQUIRY_SCAN_TYPE)
OP_CODE_MAPPING(WRITE_INQUIRY_SCAN_TYPE)
OP_CODE_MAPPING(READ_INQUIRY_MODE)
OP_CODE_MAPPING(WRITE_INQUIRY_MODE)
OP_CODE_MAPPING(READ_PAGE_SCAN_TYPE)
OP_CODE_MAPPING(WRITE_PAGE_SCAN_TYPE)
OP_CODE_MAPPING(READ_AFH_CHANNEL_ASSESSMENT_MODE)
OP_CODE_MAPPING(WRITE_AFH_CHANNEL_ASSESSMENT_MODE)
OP_CODE_MAPPING(READ_LOCAL_VERSION_INFORMATION)
OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_FEATURES)
OP_CODE_MAPPING(READ_LOCAL_EXTENDED_FEATURES)
OP_CODE_MAPPING(READ_BUFFER_SIZE)
OP_CODE_MAPPING(READ_BD_ADDR)
OP_CODE_MAPPING(READ_FAILED_CONTACT_COUNTER)
OP_CODE_MAPPING(RESET_FAILED_CONTACT_COUNTER)
OP_CODE_MAPPING(READ_LINK_QUALITY)
OP_CODE_MAPPING(READ_RSSI)
OP_CODE_MAPPING(READ_AFH_CHANNEL_MAP)
OP_CODE_MAPPING(READ_CLOCK)
OP_CODE_MAPPING(READ_LOOPBACK_MODE)
OP_CODE_MAPPING(WRITE_LOOPBACK_MODE)
OP_CODE_MAPPING(ENABLE_DEVICE_UNDER_TEST_MODE)
OP_CODE_MAPPING(SETUP_SYNCHRONOUS_CONNECTION)
OP_CODE_MAPPING(ACCEPT_SYNCHRONOUS_CONNECTION)
OP_CODE_MAPPING(REJECT_SYNCHRONOUS_CONNECTION)
OP_CODE_MAPPING(READ_EXTENDED_INQUIRY_RESPONSE)
OP_CODE_MAPPING(WRITE_EXTENDED_INQUIRY_RESPONSE)
OP_CODE_MAPPING(REFRESH_ENCRYPTION_KEY)
OP_CODE_MAPPING(SNIFF_SUBRATING)
OP_CODE_MAPPING(READ_SIMPLE_PAIRING_MODE)
OP_CODE_MAPPING(WRITE_SIMPLE_PAIRING_MODE)
OP_CODE_MAPPING(READ_LOCAL_OOB_DATA)
OP_CODE_MAPPING(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL)
OP_CODE_MAPPING(WRITE_INQUIRY_TRANSMIT_POWER_LEVEL)
OP_CODE_MAPPING(IO_CAPABILITY_REQUEST_REPLY)
OP_CODE_MAPPING(USER_CONFIRMATION_REQUEST_REPLY)
OP_CODE_MAPPING(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(USER_PASSKEY_REQUEST_REPLY)
OP_CODE_MAPPING(USER_PASSKEY_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(REMOTE_OOB_DATA_REQUEST_REPLY)
OP_CODE_MAPPING(WRITE_SIMPLE_PAIRING_DEBUG_MODE)
OP_CODE_MAPPING(REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(SEND_KEYPRESS_NOTIFICATION)
OP_CODE_MAPPING(SET_EVENT_MASK_PAGE_2)
OP_CODE_MAPPING(IO_CAPABILITY_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY)
OP_CODE_MAPPING(READ_ENCRYPTION_KEY_SIZE)
OP_CODE_MAPPING(READ_DATA_BLOCK_SIZE)
OP_CODE_MAPPING(READ_LE_HOST_SUPPORT)
OP_CODE_MAPPING(WRITE_LE_HOST_SUPPORT)
OP_CODE_MAPPING(LE_SET_EVENT_MASK)
OP_CODE_MAPPING(LE_READ_BUFFER_SIZE_V1)
OP_CODE_MAPPING(LE_READ_LOCAL_SUPPORTED_FEATURES)
OP_CODE_MAPPING(LE_SET_RANDOM_ADDRESS)
OP_CODE_MAPPING(LE_SET_ADVERTISING_PARAMETERS)
OP_CODE_MAPPING(LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER)
OP_CODE_MAPPING(LE_SET_ADVERTISING_DATA)
OP_CODE_MAPPING(LE_SET_SCAN_RESPONSE_DATA)
OP_CODE_MAPPING(LE_SET_ADVERTISING_ENABLE)
OP_CODE_MAPPING(LE_SET_SCAN_PARAMETERS)
OP_CODE_MAPPING(LE_SET_SCAN_ENABLE)
OP_CODE_MAPPING(LE_CREATE_CONNECTION)
OP_CODE_MAPPING(LE_CREATE_CONNECTION_CANCEL)
OP_CODE_MAPPING(LE_READ_FILTER_ACCEPT_LIST_SIZE)
OP_CODE_MAPPING(LE_CLEAR_FILTER_ACCEPT_LIST)
OP_CODE_MAPPING(LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST)
OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST)
OP_CODE_MAPPING(LE_CONNECTION_UPDATE)
OP_CODE_MAPPING(LE_SET_HOST_CHANNEL_CLASSIFICATION)
OP_CODE_MAPPING(LE_READ_CHANNEL_MAP)
OP_CODE_MAPPING(LE_READ_REMOTE_FEATURES)
OP_CODE_MAPPING(LE_ENCRYPT)
OP_CODE_MAPPING(LE_RAND)
OP_CODE_MAPPING(LE_START_ENCRYPTION)
OP_CODE_MAPPING(LE_LONG_TERM_KEY_REQUEST_REPLY)
OP_CODE_MAPPING(LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(LE_READ_SUPPORTED_STATES)
OP_CODE_MAPPING(LE_RECEIVER_TEST)
OP_CODE_MAPPING(LE_TRANSMITTER_TEST)
OP_CODE_MAPPING(LE_TEST_END)
OP_CODE_MAPPING(ENHANCED_SETUP_SYNCHRONOUS_CONNECTION)
OP_CODE_MAPPING(ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION)
OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_CODECS_V1)
OP_CODE_MAPPING(READ_SECURE_CONNECTIONS_HOST_SUPPORT)
OP_CODE_MAPPING(WRITE_SECURE_CONNECTIONS_HOST_SUPPORT)
OP_CODE_MAPPING(READ_LOCAL_OOB_EXTENDED_DATA)
OP_CODE_MAPPING(WRITE_SECURE_CONNECTIONS_TEST_MODE)
OP_CODE_MAPPING(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY)
OP_CODE_MAPPING(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY)
OP_CODE_MAPPING(LE_SET_DATA_LENGTH)
OP_CODE_MAPPING(LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH)
OP_CODE_MAPPING(LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH)
OP_CODE_MAPPING(LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND)
OP_CODE_MAPPING(LE_GENERATE_DHKEY_COMMAND_V1)
OP_CODE_MAPPING(LE_ADD_DEVICE_TO_RESOLVING_LIST)
OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_RESOLVING_LIST)
OP_CODE_MAPPING(LE_CLEAR_RESOLVING_LIST)
OP_CODE_MAPPING(LE_READ_RESOLVING_LIST_SIZE)
OP_CODE_MAPPING(LE_READ_PEER_RESOLVABLE_ADDRESS)
OP_CODE_MAPPING(LE_READ_LOCAL_RESOLVABLE_ADDRESS)
OP_CODE_MAPPING(LE_SET_ADDRESS_RESOLUTION_ENABLE)
OP_CODE_MAPPING(LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT)
OP_CODE_MAPPING(LE_READ_MAXIMUM_DATA_LENGTH)
OP_CODE_MAPPING(LE_READ_PHY)
OP_CODE_MAPPING(LE_SET_DEFAULT_PHY)
OP_CODE_MAPPING(LE_SET_PHY)
OP_CODE_MAPPING(LE_ENHANCED_RECEIVER_TEST)
OP_CODE_MAPPING(LE_ENHANCED_TRANSMITTER_TEST)
OP_CODE_MAPPING(LE_SET_ADVERTISING_SET_RANDOM_ADDRESS)
OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_PARAMETERS)
OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_DATA)
OP_CODE_MAPPING(LE_SET_EXTENDED_SCAN_RESPONSE_DATA)
OP_CODE_MAPPING(LE_SET_EXTENDED_ADVERTISING_ENABLE)
OP_CODE_MAPPING(LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH)
OP_CODE_MAPPING(LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS)
OP_CODE_MAPPING(LE_REMOVE_ADVERTISING_SET)
OP_CODE_MAPPING(LE_CLEAR_ADVERTISING_SETS)
OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_PARAM)
OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_DATA)
OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_ENABLE)
OP_CODE_MAPPING(LE_SET_EXTENDED_SCAN_PARAMETERS)
OP_CODE_MAPPING(LE_SET_EXTENDED_SCAN_ENABLE)
OP_CODE_MAPPING(LE_EXTENDED_CREATE_CONNECTION)
OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_CREATE_SYNC)
OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL)
OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_TERMINATE_SYNC)
OP_CODE_MAPPING(LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST)
OP_CODE_MAPPING(LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST)
OP_CODE_MAPPING(LE_CLEAR_PERIODIC_ADVERTISING_LIST)
OP_CODE_MAPPING(LE_READ_PERIODIC_ADVERTISING_LIST_SIZE)
OP_CODE_MAPPING(LE_READ_TRANSMIT_POWER)
OP_CODE_MAPPING(LE_READ_RF_PATH_COMPENSATION_POWER)
OP_CODE_MAPPING(LE_WRITE_RF_PATH_COMPENSATION_POWER)
OP_CODE_MAPPING(LE_SET_PRIVACY_MODE)
OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE)
OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_SYNC_TRANSFER)
OP_CODE_MAPPING(LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER)
OP_CODE_MAPPING(LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS)
OP_CODE_MAPPING(LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS)
OP_CODE_MAPPING(LE_GENERATE_DHKEY_COMMAND)
OP_CODE_MAPPING(LE_MODIFY_SLEEP_CLOCK_ACCURACY)
OP_CODE_MAPPING(LE_READ_BUFFER_SIZE_V2)
OP_CODE_MAPPING(LE_READ_ISO_TX_SYNC)
OP_CODE_MAPPING(LE_SET_CIG_PARAMETERS)
OP_CODE_MAPPING(LE_SET_CIG_PARAMETERS_TEST)
OP_CODE_MAPPING(LE_CREATE_CIS)
OP_CODE_MAPPING(LE_REMOVE_CIG)
OP_CODE_MAPPING(LE_ACCEPT_CIS_REQUEST)
OP_CODE_MAPPING(LE_REJECT_CIS_REQUEST)
OP_CODE_MAPPING(LE_CREATE_BIG)
OP_CODE_MAPPING(LE_TERMINATE_BIG)
OP_CODE_MAPPING(LE_BIG_CREATE_SYNC)
OP_CODE_MAPPING(LE_BIG_TERMINATE_SYNC)
OP_CODE_MAPPING(LE_REQUEST_PEER_SCA)
OP_CODE_MAPPING(LE_SETUP_ISO_DATA_PATH)
OP_CODE_MAPPING(LE_REMOVE_ISO_DATA_PATH)
OP_CODE_MAPPING(LE_SET_HOST_FEATURE)
OP_CODE_MAPPING(LE_READ_ISO_LINK_QUALITY)
OP_CODE_MAPPING(LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL)
OP_CODE_MAPPING(LE_READ_REMOTE_TRANSMIT_POWER_LEVEL)
OP_CODE_MAPPING(LE_SET_PATH_LOSS_REPORTING_PARAMETERS)
OP_CODE_MAPPING(LE_SET_PATH_LOSS_REPORTING_ENABLE)
OP_CODE_MAPPING(LE_SET_TRANSMIT_POWER_REPORTING_ENABLE)
OP_CODE_MAPPING(SET_ECOSYSTEM_BASE_INTERVAL)
OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_CODECS_V2)
OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES)
OP_CODE_MAPPING(READ_LOCAL_SUPPORTED_CONTROLLER_DELAY)
OP_CODE_MAPPING(CONFIGURE_DATA_PATH)
OP_CODE_MAPPING(ENHANCED_FLUSH)
OP_CODE_MAPPING(LE_SET_DATA_RELATED_ADDRESS_CHANGES)
OP_CODE_MAPPING(LE_SET_DEFAULT_SUBRATE)
OP_CODE_MAPPING(LE_SUBRATE_REQUEST)
OP_CODE_MAPPING(SET_MIN_ENCRYPTION_KEY_SIZE)
// deprecated
case OpCode::ADD_SCO_CONNECTION:
return false;
// vendor specific
case OpCode::LE_GET_VENDOR_CAPABILITIES:
return vendor_capabilities_.is_supported_ == 0x01;
case OpCode::LE_MULTI_ADVT:
return vendor_capabilities_.max_advt_instances_ != 0x00;
case OpCode::LE_BATCH_SCAN:
return vendor_capabilities_.total_scan_results_storage_ != 0x00;
case OpCode::LE_ADV_FILTER:
return vendor_capabilities_.filtering_support_ == 0x01;
case OpCode::LE_ENERGY_INFO:
return vendor_capabilities_.activity_energy_info_support_ == 0x01;
case OpCode::LE_EXTENDED_SCAN_PARAMS:
return vendor_capabilities_.extended_scan_support_ == 0x01;
case OpCode::CONTROLLER_DEBUG_INFO:
return vendor_capabilities_.debug_logging_supported_ == 0x01;
case OpCode::CONTROLLER_A2DP_OPCODE:
return vendor_capabilities_.a2dp_source_offload_capability_mask_ != 0x00;
case OpCode::CONTROLLER_BQR:
return vendor_capabilities_.bluetooth_quality_report_support_ == 0x01;
// undefined in local_supported_commands_
case OpCode::READ_LOCAL_SUPPORTED_COMMANDS:
return true;
case OpCode::NONE:
return false;
}
return false;
}
- 所以如果要判断 当前 controller 是否支持 该命令,只需要调用 is_supported 函数即可。
bool Controller::IsSupported(bluetooth::hci::OpCode op_code) const {
return impl_->is_supported(op_code);
}
- 外部模块只需要调用 Controller::IsSupported 即可判断是否支持该命令。
2. aosp 中的作用:为什么它很重要?
在 Android 蓝牙协议栈(如 system/bt
)中,HCI_Read_Local_Supported_Commands
返回的这 64 字节位图广泛用于以下几个方面:
1. 功能检测与控制器能力决策
-
Android 蓝牙栈会根据该命令结果动态判断 Controller 支持哪些命令。
-
典型例子:LE Extended Advertising、Coded PHY、LE Periodic Advertising 等功能是否可用,直接影响上层是否启用某些 GAP/GATT 功能。
2. 初始化过程动态调整命令发送策略
- 在 stack 初始化时,controller 不支持某些命令则跳过它们的初始化调用,避免失败。
- 举例:是否发送
LeReadBufferSizeV2
命令前会先检查对应 bit 是否为 1。
if (is_supported(OpCode::LE_READ_BUFFER_SIZE_V2)) {
hci_->EnqueueCommand(
LeReadBufferSizeV2Builder::Create(),
handler->BindOnceOn(this, &Controller::impl::le_read_buffer_size_v2_handler));
}
3. 厂商定制逻辑与能力适配
-
有些厂商芯片即便宣称是 BT5.1,但可能缺失部分命令实现。
-
Android 通过查询这个位图 动态适配,避免调用未支持的命令导致错误。
4. 蓝牙兼容性 Debug
- 蓝牙连接或功能异常时,可通过 dumpsys 或 log 分析哪些命令是被支持的。
Supported_Commands
是诊断「为什么不能执行某个 HCI 操作」的关键。