From 0342b31ff80c5a29e398d85e247754382779ba8f Mon Sep 17 00:00:00 2001 From: shivamsinghydv Date: Sun, 29 Mar 2026 13:24:32 +0530 Subject: [PATCH] bluetooth: Extend EIR parsing with UUIDs, Device class, TX power and manufacturer data ParseEIR previously handled only EIR_NAME_SHORT (0x08) and EIR_NAME_COMPLETE (0x09), silently ignoring all other data types. Add handling for: - EIR_UUID16_INCOMPLETE (0x2) & EIR_UUID16_COMPLETE (0x3) - EIR_UUID32_INCOMPLETE (0x4) & EIR_UUID32_COMPLETE (0x5) - EIR_UUID128_INCOMPLETE (0x6) & EIR_UUID128_COMPLETE (0x7) - EIR_TX_POWER (0X0A): parsed as int8, added to reply as "tx_power" - EIR_CLASS_OF_DEVICE: Added to reply as dev_class (0x0D) - EIR_MANUFACTURER_DATA: Added to reply as "manufacturer_data" (0xFF) Change-Id: I80600ff3078e2a7bc41c614596013e633ada5c9c Reviewed-on: https://review.haiku-os.org/c/haiku/+/10613 Tested-by: Commit checker robot Reviewed-by: waddlesplash Haiku-Format: Haiku-format Bot --- headers/os/bluetooth/HCI/btHCI_event.h | 11 ++++ src/servers/bluetooth/LocalDeviceImpl.cpp | 61 +++++++++++++++++++++-- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/headers/os/bluetooth/HCI/btHCI_event.h b/headers/os/bluetooth/HCI/btHCI_event.h index 0a2b644ab7..7838c50e23 100644 --- a/headers/os/bluetooth/HCI/btHCI_event.h +++ b/headers/os/bluetooth/HCI/btHCI_event.h @@ -286,8 +286,19 @@ struct hci_ev_extended_inquiry_info { int8 rssi; uint8 eir[HCI_MAX_EIR_LENGTH]; } __attribute__((packed)); + +#define EIR_FLAGS 0x01 +#define EIR_UUID16_INCOMPLETE 0x02 +#define EIR_UUID16_COMPLETE 0x03 +#define EIR_UUID32_INCOMPLETE 0x04 +#define EIR_UUID32_COMPLETE 0x05 +#define EIR_UUID128_INCOMPLETE 0x06 +#define EIR_UUID128_COMPLETE 0x07 #define EIR_NAME_SHORT 0x08 #define EIR_NAME_COMPLETE 0x09 +#define EIR_TX_POWER 0x0A +#define EIR_CLASS_OF_DEVICE 0x0D +#define EIR_MANUFACTURER_DATA 0xFF #define HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 diff --git a/src/servers/bluetooth/LocalDeviceImpl.cpp b/src/servers/bluetooth/LocalDeviceImpl.cpp index 18f07f31a0..7434cf17d9 100644 --- a/src/servers/bluetooth/LocalDeviceImpl.cpp +++ b/src/servers/bluetooth/LocalDeviceImpl.cpp @@ -962,17 +962,46 @@ LocalDeviceImpl::ParseEIR(const uint8* eir, BMessage& reply) while (offset < HCI_MAX_EIR_LENGTH) { uint8 length = eir[offset]; - // break either when finished reading buffer or when next data value is zero if (length == 0 || offset + length >= HCI_MAX_EIR_LENGTH) break; - uint8 type = eir[offset + 1]; const uint8* data = &eir[offset + 2]; uint8 dataLen = length - 1; - - // TODO:Implement other EIR datatypes switch (type) { + case EIR_FLAGS: + if (dataLen >= 1) { + reply.AddUInt8("eir_flags", data[0]); + TRACE_BT("LocalDeviceImpl: Parsed EIR Flags: 0x%02X\n", data[0]); + } + break; + case EIR_UUID16_INCOMPLETE: + reply.AddBool("uuid16_complete", false); + case EIR_UUID16_COMPLETE: + for (uint8 i = 0; i + 1 < dataLen; i += 2) { + uint16 uuid = B_LENDIAN_TO_HOST_INT16(*(const uint16*)(data + i)); + reply.AddUInt16("uuid16", uuid); + TRACE_BT("LocalDeviceImpl: Parsed EIR UUID16: 0x%04X\n", uuid); + } + break; + case EIR_UUID32_INCOMPLETE: + reply.AddBool("uuid32_complete", false); + case EIR_UUID32_COMPLETE: + for (uint8 i = 0; i + 3 < dataLen; i += 4) { + uint32 uuid = B_LENDIAN_TO_HOST_INT32(*(const uint32*)(data + i)); + reply.AddUInt32("uuid32", uuid); + TRACE_BT("LocalDeviceImpl: Parsed EIR of UUID32: 0x%08" B_PRIx32 "\n", uuid); + } + break; + case EIR_UUID128_INCOMPLETE: + reply.AddBool("uuid128_complete", false); + case EIR_UUID128_COMPLETE: + for (uint8 i = 0; i + 15 < dataLen; i += 16) { + // UUID128 is stored as 16 bytes in little-endian format + reply.AddData("uuid128", B_ANY_TYPE, data + i, 16); + TRACE_BT("LocalDeviceImpl: Parsed EIR UUID128 \n"); + } + break; case EIR_NAME_SHORT: if (shortName.Length() == 0) { shortName.SetTo((const char*)data, dataLen); @@ -986,6 +1015,29 @@ LocalDeviceImpl::ParseEIR(const uint8* eir, BMessage& reply) completeName.String()); } break; + case EIR_TX_POWER: + if (dataLen >= 1) { + reply.AddInt8("tx_power", (int8)data[0]); + TRACE_BT("LocalDeviceImpl: Parsed EIR TX Power: %d dBm\n", (int8)data[0]); + } + break; + case EIR_CLASS_OF_DEVICE: + if (dataLen >= 3) { + reply.AddData("dev_class", B_ANY_TYPE, data, 3); + TRACE_BT("LocalDeviceImpl: Parsed EIR Class of Device: " + "0x%02X 0x%02X 0x%02X\n", + data[0], data[1], data[2]); + } + break; + case EIR_MANUFACTURER_DATA: + if (dataLen >= 2) { + reply.AddData("manufacturer_data", B_ANY_TYPE, data, dataLen); + uint16 company = data[0] | (data[1] << 8); + TRACE_BT("LocalDeviceImpl: Parsed EIR Manufacturer Data: " + "company=0x%04X len=%d\n", + company, dataLen); + } + break; default: TRACE_BT("LocalDeviceImpl: Ignored EIR Type: 0x%02X (Length: %d)\n", type, dataLen); break; @@ -1099,7 +1151,6 @@ LocalDeviceImpl::ConnectionComplete(struct hci_ev_conn_complete* event, if (event->status == BT_OK) { uint8 cod[3] = {0, 0, 0}; - // TODO: Review, this rDevice is leaked ConnectionIncoming* iConnection = new ConnectionIncoming( new RemoteDevice(event->bdaddr, cod));