diff --git a/hci/include/bt_hci_bdroid.h b/hci/include/bt_hci_bdroid.h index aa193d058..aceebc0b5 100644 --- a/hci/include/bt_hci_bdroid.h +++ b/hci/include/bt_hci_bdroid.h @@ -63,6 +63,7 @@ typedef enum { #define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */ #define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */ #define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */ +#define MSG_STACK_TO_LM_DIAG 0x2c00 /* Diagnostics */ /* Local Bluetooth Controller ID for BR/EDR */ #define LOCAL_BR_EDR_CONTROLLER_ID 0 diff --git a/hci/include/hci_hal.h b/hci/include/hci_hal.h index 53595c02a..c90898e8a 100644 --- a/hci/include/hci_hal.h +++ b/hci/include/hci_hal.h @@ -29,7 +29,8 @@ typedef enum { DATA_TYPE_COMMAND = 1, DATA_TYPE_ACL = 2, DATA_TYPE_SCO = 3, - DATA_TYPE_EVENT = 4 + DATA_TYPE_EVENT = 4, + DATA_TYPE_DIAG = 7 } serial_data_type_t; typedef void (*data_ready_cb)(serial_data_type_t type); diff --git a/hci/include/hci_internals.h b/hci/include/hci_internals.h index 6b9fb014b..c453b5655 100644 --- a/hci/include/hci_internals.h +++ b/hci/include/hci_internals.h @@ -26,3 +26,5 @@ #define HCI_SCO_PREAMBLE_SIZE 3 // 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4) #define HCI_EVENT_PREAMBLE_SIZE 2 +// 1 byte for diagnostic command type +#define HCI_DIAG_PREAMBLE_SIZE 2 diff --git a/hci/include/hci_layer.h b/hci/include/hci_layer.h index acb86de60..069118c12 100644 --- a/hci/include/hci_layer.h +++ b/hci/include/hci_layer.h @@ -47,6 +47,7 @@ static const char HCI_MODULE[] = "hci_module"; #define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */ #define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */ #define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */ +#define MSG_STACK_TO_LM_DIAG 0x2c00 /* Diagnostics */ /* Local Bluetooth Controller ID for BR/EDR */ #define LOCAL_BR_EDR_CONTROLLER_ID 0 diff --git a/hci/src/btsnoop.cc b/hci/src/btsnoop.cc index a109ad09a..c36bd05fd 100644 --- a/hci/src/btsnoop.cc +++ b/hci/src/btsnoop.cc @@ -58,7 +58,8 @@ typedef enum { kCommandPacket = 1, kAclPacket = 2, kScoPacket = 3, - kEventPacket = 4 + kEventPacket = 4, + kDiagPacket = 7 } packet_type_t; // Epoch in microseconds since 01/01/0000. @@ -81,7 +82,7 @@ static char* get_btsnoop_log_path(char* log_path); static char* get_btsnoop_last_log_path(char* last_log_path, char* log_path); static void open_next_snoop_file(); static void btsnoop_write_packet(packet_type_t type, uint8_t* packet, - bool is_received, uint64_t timestamp_us); + bool is_received, uint64_t timestamp_us, uint32_t length_he); // Module lifecycle functions @@ -135,19 +136,22 @@ static void capture(const BT_HDR* buffer, bool is_received) { switch (buffer->event & MSG_EVT_MASK) { case MSG_HC_TO_STACK_HCI_EVT: - btsnoop_write_packet(kEventPacket, p, false, timestamp_us); + btsnoop_write_packet(kEventPacket, p, false, timestamp_us, 0); break; case MSG_HC_TO_STACK_HCI_ACL: case MSG_STACK_TO_HC_HCI_ACL: - btsnoop_write_packet(kAclPacket, p, is_received, timestamp_us); + btsnoop_write_packet(kAclPacket, p, is_received, timestamp_us, 0); break; case MSG_HC_TO_STACK_HCI_SCO: case MSG_STACK_TO_HC_HCI_SCO: - btsnoop_write_packet(kScoPacket, p, is_received, timestamp_us); + btsnoop_write_packet(kScoPacket, p, is_received, timestamp_us, 0); break; case MSG_STACK_TO_HC_HCI_CMD: - btsnoop_write_packet(kCommandPacket, p, true, timestamp_us); + btsnoop_write_packet(kCommandPacket, p, true, timestamp_us, 0); break; + case MSG_STACK_TO_LM_DIAG: + btsnoop_write_packet(kDiagPacket, p, is_received, timestamp_us, buffer->len + 1); //1 byte header 0x07 + data + break; } } @@ -235,8 +239,7 @@ static uint64_t htonll(uint64_t ll) { } static void btsnoop_write_packet(packet_type_t type, uint8_t* packet, - bool is_received, uint64_t timestamp_us) { - uint32_t length_he = 0; + bool is_received, uint64_t timestamp_us, uint32_t length_he) { uint32_t flags = 0; switch (type) { @@ -256,6 +259,9 @@ static void btsnoop_write_packet(packet_type_t type, uint8_t* packet, length_he = packet[1] + 3; flags = 3; break; + case kDiagPacket: + flags = 3; + break; } btsnoop_header_t header; diff --git a/hci/src/hci_inject.cc b/hci/src/hci_inject.cc index 70194a5e0..d7d08cb18 100644 --- a/hci/src/hci_inject.cc +++ b/hci/src/hci_inject.cc @@ -39,6 +39,7 @@ typedef enum { HCI_PACKET_ACL_DATA = 2, HCI_PACKET_SCO_DATA = 3, HCI_PACKET_EVENT = 4, + HCI_PACKET_DIAG = 7 } hci_packet_t; typedef struct { @@ -118,6 +119,8 @@ static int hci_packet_to_event(hci_packet_t packet) { return MSG_STACK_TO_HC_HCI_ACL; case HCI_PACKET_SCO_DATA: return MSG_STACK_TO_HC_HCI_SCO; + case HCI_PACKET_DIAG: + return MSG_STACK_TO_LM_DIAG; default: LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet); return -1; diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc index d1fa92031..549fad723 100644 --- a/hci/src/hci_layer.cc +++ b/hci/src/hci_layer.cc @@ -159,6 +159,11 @@ void sco_data_received(BT_HDR* packet) { packet_fragmenter->reassemble_and_dispatch(packet); } +void diag_data_received(BT_HDR* packet) { + btsnoop->capture(packet, true); + packet_fragmenter->reassemble_and_dispatch(packet); +} + // Module lifecycle functions static future_t* hci_module_shut_down(); diff --git a/hci/src/hci_layer_android.cc b/hci/src/hci_layer_android.cc index 0598ca132..26fe3785e 100644 --- a/hci/src/hci_layer_android.cc +++ b/hci/src/hci_layer_android.cc @@ -51,6 +51,7 @@ extern void hci_event_received(const tracked_objects::Location& from_here, BT_HDR* packet); extern void acl_event_received(BT_HDR* packet); extern void sco_data_received(BT_HDR* packet); +extern void diag_data_received(BT_HDR* packet); android::sp btHci; @@ -98,6 +99,12 @@ class BluetoothHciCallbacks : public IBluetoothHciCallbacks { return Void(); } + Return diagDataReceived(const hidl_vec& data) { + BT_HDR* packet = WrapPacketAndCopy(MSG_STACK_TO_LM_DIAG, data); + diag_data_received(packet); + return Void(); + } + const allocator_t* buffer_allocator; }; @@ -137,6 +144,9 @@ void hci_transmit(BT_HDR* packet) { case MSG_STACK_TO_HC_HCI_SCO: btHci->sendScoData(data); break; + case MSG_STACK_TO_LM_DIAG: + btHci->sendDiagData(data); + break; default: LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event); break; diff --git a/hci/src/hci_layer_linux.cc b/hci/src/hci_layer_linux.cc index aa37f781a..c2a6eec77 100644 --- a/hci/src/hci_layer_linux.cc +++ b/hci/src/hci_layer_linux.cc @@ -89,7 +89,8 @@ enum HciPacketType { HCI_PACKET_TYPE_COMMAND = 1, HCI_PACKET_TYPE_ACL_DATA = 2, HCI_PACKET_TYPE_SCO_DATA = 3, - HCI_PACKET_TYPE_EVENT = 4 + HCI_PACKET_TYPE_EVENT = 4, + HCI_PACKET_TYPE_DIAG = 7 }; extern void initialization_complete(); @@ -97,6 +98,7 @@ extern void hci_event_received(const tracked_objects::Location& from_here, BT_HDR* packet); extern void acl_event_received(BT_HDR* packet); extern void sco_data_received(BT_HDR* packet); +extern void diag_data_received(BT_HDR* packet); static int bt_vendor_fd = -1; static int hci_interface; @@ -145,6 +147,10 @@ void monitor_socket(int ctrl_fd, int fd) { packet->event = MSG_HC_TO_STACK_HCI_EVT; hci_event_received(FROM_HERE, packet); break; + case HCI_PACKET_TYPE_DIAG: + packet->event = MSG_STACK_TO_LM_DIAG; + diag_data_received(FROM_HERE, packet); + break; default: LOG(FATAL) << "Unexpected event type: " << +type; break; diff --git a/test/rootcanal/service.cc b/test/rootcanal/service.cc index e08f73583..831b4276e 100644 --- a/test/rootcanal/service.cc +++ b/test/rootcanal/service.cc @@ -30,11 +30,11 @@ using ::android::hardware::joinRpcThreadpool; using ::android::sp; int main(int /* argc */, char** /* argv */) { - sp bluetooth = new BluetoothHci; - configureRpcThreadpool(1, true); - android::status_t status = bluetooth->registerAsService(); - if (status == android::OK) - joinRpcThreadpool(); - else - ALOGE("Could not register as a service!"); +// sp bluetooth = new BluetoothHci; +// configureRpcThreadpool(1, true); +// android::status_t status = bluetooth->registerAsService(); +// if (status == android::OK) +// joinRpcThreadpool(); +// else +// ALOGE("Could not register as a service!"); } diff --git a/vendor_libs/linux/interface/bluetooth_hci.cc b/vendor_libs/linux/interface/bluetooth_hci.cc index 8507f7a10..21c93a9dd 100644 --- a/vendor_libs/linux/interface/bluetooth_hci.cc +++ b/vendor_libs/linux/interface/bluetooth_hci.cc @@ -284,7 +284,8 @@ Return BluetoothHci::initialize( hci_fd, [cb](const hidl_vec& packet) { cb->hciEventReceived(packet); }, [cb](const hidl_vec& packet) { cb->aclDataReceived(packet); }, - [cb](const hidl_vec& packet) { cb->scoDataReceived(packet); }); + [cb](const hidl_vec& packet) { cb->scoDataReceived(packet); }, + [cb](const hidl_vec& packet) { cb->diagDataReceived(packet); }); fd_watcher_.WatchFdForNonBlockingReads( hci_fd, [h4_hci](int fd) { h4_hci->OnDataReady(fd); }); @@ -328,6 +329,11 @@ Return BluetoothHci::sendScoData(const hidl_vec& data) { return Void(); } +Return BluetoothHci::sendDiagData(const hidl_vec& data) { + sendDataToController(HCI_DATA_TYPE_DIA, data); + return Void(); +} + void BluetoothHci::sendDataToController(const uint8_t type, const hidl_vec& data) { hci_handle_->Send(type, data.data(), data.size()); diff --git a/vendor_libs/linux/interface/bluetooth_hci.h b/vendor_libs/linux/interface/bluetooth_hci.h index 5dc1c0a55..eadbba751 100644 --- a/vendor_libs/linux/interface/bluetooth_hci.h +++ b/vendor_libs/linux/interface/bluetooth_hci.h @@ -44,6 +44,7 @@ class BluetoothHci : public IBluetoothHci { Return sendHciCommand(const hidl_vec& packet) override; Return sendAclData(const hidl_vec& data) override; Return sendScoData(const hidl_vec& data) override; + Return sendDiagData(const hidl_vec& data) override; Return close() override; private: @@ -55,6 +56,7 @@ class BluetoothHci : public IBluetoothHci { const uint8_t HCI_DATA_TYPE_COMMAND = 1; const uint8_t HCI_DATA_TYPE_ACL = 2; const uint8_t HCI_DATA_TYPE_SCO = 3; + const uint8_t HCI_DATA_TYPE_DIA = 7; int waitHciDev(int hci_interface); int findRfKill(void); diff --git a/vendor_libs/linux/interface/h4_protocol.cc b/vendor_libs/linux/interface/h4_protocol.cc index e7acff46d..19d8199bf 100644 --- a/vendor_libs/linux/interface/h4_protocol.cc +++ b/vendor_libs/linux/interface/h4_protocol.cc @@ -67,6 +67,9 @@ void H4Protocol::OnPacketReady() { case HCI_PACKET_TYPE_SCO_DATA: sco_cb_(hci_packetizer_.GetPacket()); break; + case HCI_PACKET_TYPE_DIAG: + diag_cb_(hci_packetizer_.GetPacket()); + break; default: { bool bad_packet_type = true; CHECK(!bad_packet_type); diff --git a/vendor_libs/linux/interface/h4_protocol.h b/vendor_libs/linux/interface/h4_protocol.h index 612b0dbb6..e312ffb9b 100644 --- a/vendor_libs/linux/interface/h4_protocol.h +++ b/vendor_libs/linux/interface/h4_protocol.h @@ -33,11 +33,12 @@ using PacketReadCallback = std::function&)>; class H4Protocol { public: H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb, - PacketReadCallback sco_cb) + PacketReadCallback sco_cb, PacketReadCallback diag_cb) : uart_fd_(fd), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb), + diag_cb_(diag_cb), hci_packetizer_([this]() { OnPacketReady(); }) {} size_t Send(uint8_t type, const uint8_t* data, size_t length); @@ -52,6 +53,7 @@ class H4Protocol { PacketReadCallback event_cb_; PacketReadCallback acl_cb_; PacketReadCallback sco_cb_; + PacketReadCallback diag_cb_; HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN}; HciPacketizer hci_packetizer_; diff --git a/vendor_libs/linux/interface/hci_internals.h b/vendor_libs/linux/interface/hci_internals.h index 1e1f3001c..07ab42cd8 100644 --- a/vendor_libs/linux/interface/hci_internals.h +++ b/vendor_libs/linux/interface/hci_internals.h @@ -24,7 +24,8 @@ enum HciPacketType { HCI_PACKET_TYPE_COMMAND = 1, HCI_PACKET_TYPE_ACL_DATA = 2, HCI_PACKET_TYPE_SCO_DATA = 3, - HCI_PACKET_TYPE_EVENT = 4 + HCI_PACKET_TYPE_EVENT = 4, + HCI_PACKET_TYPE_DIAG = 7 }; // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1) diff --git a/vendor_libs/linux/interface/hci_packetizer.cc b/vendor_libs/linux/interface/hci_packetizer.cc index 0c0a979e7..d6eea900a 100644 --- a/vendor_libs/linux/interface/hci_packetizer.cc +++ b/vendor_libs/linux/interface/hci_packetizer.cc @@ -27,13 +27,14 @@ namespace { const size_t preamble_size_for_type[] = { 0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE, - HCI_EVENT_PREAMBLE_SIZE}; + HCI_EVENT_PREAMBLE_SIZE, 0, 0, 2}; //TODO HCI_DIAG_PREAMBLE_SIZE const size_t packet_length_offset_for_type[] = { 0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO, - HCI_LENGTH_OFFSET_EVT}; + HCI_LENGTH_OFFSET_EVT, 0, 0, 0}; size_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) { size_t offset = packet_length_offset_for_type[type]; + if (type == HCI_PACKET_TYPE_DIAG) return 63; //TODO if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset]; return (((preamble[offset + 1]) << 8) | preamble[offset]); }