mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2025-01-14 15:33:47 +08:00
Modify get_eir_uuids() to parse other EIR data
Currently, EIR parsing (name, UUIDs, flags etc.) is done in various places. This leads to duplicated checks and does not support parsing multiple AD/EIR structures on a single transfer. These changes modify get_eir_uuids() to parse other EIR data types and avoid passing raw EIR data to higher layers. To accomplish this, get_eir_uuids() was renamed to parse_eir_data(), and a new (internal) "struct eir_data" was introduced to store the parsed data. This first commit only handles the services UUIDs, following patches will move other EIR parsing to it until everything is done inside parse_eir_data().
This commit is contained in:
parent
accbcf5a7f
commit
a39ada57c8
49
src/event.c
49
src/event.c
@ -58,6 +58,10 @@
|
||||
#include "event.h"
|
||||
#include "sdpd.h"
|
||||
|
||||
struct eir_data {
|
||||
GSList *services;
|
||||
};
|
||||
|
||||
static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
|
||||
struct btd_adapter **adapter,
|
||||
struct btd_device **device,
|
||||
@ -303,14 +307,14 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
|
||||
device_simple_pairing_complete(device, status);
|
||||
}
|
||||
|
||||
static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
static int parse_eir_data(struct eir_data *eir, uint8_t *eir_data,
|
||||
size_t eir_length)
|
||||
{
|
||||
uint16_t len = 0;
|
||||
size_t total;
|
||||
size_t uuid16_count = 0;
|
||||
size_t uuid32_count = 0;
|
||||
size_t uuid128_count = 0;
|
||||
GSList *list = NULL;
|
||||
uint8_t *uuid16 = NULL;
|
||||
uint8_t *uuid32 = NULL;
|
||||
uint8_t *uuid128 = NULL;
|
||||
@ -318,8 +322,9 @@ static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
char *uuid_str;
|
||||
unsigned int i;
|
||||
|
||||
/* No EIR data to parse */
|
||||
if (eir_data == NULL || eir_length == 0)
|
||||
return list;
|
||||
return 0;
|
||||
|
||||
while (len < eir_length - 1) {
|
||||
uint8_t field_len = eir_data[0];
|
||||
@ -352,12 +357,13 @@ static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
|
||||
/* Bail out if got incorrect length */
|
||||
if (len > eir_length)
|
||||
return list;
|
||||
return -EINVAL;
|
||||
|
||||
total = uuid16_count + uuid32_count + uuid128_count;
|
||||
|
||||
/* No UUIDs were parsed, so skip code below */
|
||||
if (!total)
|
||||
return list;
|
||||
return 0;
|
||||
|
||||
/* Generate uuids in SDP format (EIR data is Little Endian) */
|
||||
service.type = SDP_UUID16;
|
||||
@ -367,7 +373,7 @@ static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
val16 = (val16 << 8) + uuid16[0];
|
||||
service.value.uuid16 = val16;
|
||||
uuid_str = bt_uuid2string(&service);
|
||||
list = g_slist_append(list, uuid_str);
|
||||
eir->services = g_slist_append(eir->services, uuid_str);
|
||||
uuid16 += 2;
|
||||
}
|
||||
|
||||
@ -381,7 +387,7 @@ static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
|
||||
service.value.uuid32 = val32;
|
||||
uuid_str = bt_uuid2string(&service);
|
||||
list = g_slist_append(list, uuid_str);
|
||||
eir->services = g_slist_append(eir->services, uuid_str);
|
||||
uuid32 += 4;
|
||||
}
|
||||
|
||||
@ -393,17 +399,18 @@ static GSList *get_eir_uuids(uint8_t *eir_data, size_t eir_length)
|
||||
service.value.uuid128.data[k] = uuid128[16 - k - 1];
|
||||
|
||||
uuid_str = bt_uuid2string(&service);
|
||||
list = g_slist_append(list, uuid_str);
|
||||
eir->services = g_slist_append(eir->services, uuid_str);
|
||||
uuid128 += 16;
|
||||
}
|
||||
|
||||
return list;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
|
||||
{
|
||||
struct btd_adapter *adapter;
|
||||
GSList *services = NULL;
|
||||
struct eir_data eir_data;
|
||||
int err;
|
||||
|
||||
adapter = manager_find_adapter(local);
|
||||
if (adapter == NULL) {
|
||||
@ -412,9 +419,13 @@ void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
|
||||
}
|
||||
|
||||
/* Extract UUIDs from advertising data if any */
|
||||
services = get_eir_uuids(info->data, info->length);
|
||||
memset(&eir_data, 0, sizeof(eir_data));
|
||||
err = parse_eir_data(&eir_data, info->data, info->length);
|
||||
if (err < 0)
|
||||
error("Error parsing advertising data: %s (%d)",
|
||||
strerror(-err), -err);
|
||||
|
||||
adapter_update_device_from_info(adapter, info, services);
|
||||
adapter_update_device_from_info(adapter, info, eir_data.services);
|
||||
}
|
||||
|
||||
void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
@ -427,8 +438,8 @@ void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
struct remote_dev_info *dev, match;
|
||||
uint8_t name_type = 0x00;
|
||||
name_status_t name_status;
|
||||
GSList *services = NULL;
|
||||
int state;
|
||||
struct eir_data eir_data;
|
||||
int state, err;
|
||||
dbus_bool_t legacy;
|
||||
unsigned char features[8];
|
||||
|
||||
@ -457,7 +468,10 @@ void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
}
|
||||
|
||||
/* Extract UUIDs from extended inquiry response if any */
|
||||
services = get_eir_uuids(data, EIR_DATA_LENGTH);
|
||||
memset(&eir_data, 0, sizeof(eir_data));
|
||||
err = parse_eir_data(&eir_data, data, EIR_DATA_LENGTH);
|
||||
if (err < 0)
|
||||
error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
|
||||
|
||||
memset(&match, 0, sizeof(struct remote_dev_info));
|
||||
bacpy(&match.bdaddr, peer);
|
||||
@ -467,7 +481,8 @@ void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
if (dev) {
|
||||
adapter_update_found_devices(adapter, peer, rssi, class,
|
||||
NULL, NULL, dev->legacy,
|
||||
services, NAME_NOT_REQUIRED);
|
||||
eir_data.services,
|
||||
NAME_NOT_REQUIRED);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -519,7 +534,7 @@ void btd_event_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
|
||||
|
||||
/* add in the list to track name sent/pending */
|
||||
adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
|
||||
legacy, services, name_status);
|
||||
legacy, eir_data.services, name_status);
|
||||
|
||||
g_free(name);
|
||||
g_free(alias);
|
||||
|
Loading…
Reference in New Issue
Block a user