Re: [PATCH] Bluetooth: Add local Extended Inquiry Response (EIR) support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Johan,

On Fri, Mar 25, 2011 at 9:25 AM,  <johan.hedberg@xxxxxxxxx> wrote:
> +static u8 bluetooth_base_uuid[] = {
> +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
> +                       0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
> +};
> +
> +static u16 get_uuid16(u8 *uuid128)
> +{
> +       u8 *b = bluetooth_base_uuid;
> +       u32 val;
> +       int i;
> +
> +       for (i = 4; i < 16; i++) {
> +               if (b[i] != uuid128[i])
> +                       return 0;

Don't you need to check bytes 0 and 1 as well, i.e. only bytes 2 and 3
are changed?

> +       }
> +
> +       memcpy(&val, uuid128, 4);
> +
> +       val = be32_to_cpu(val);

I noticed just know the those UUID handling functions from management
API are assuming UUIDs in network order. We will need to change this,
or take extra care when reusing them for Advertising Data and GATT
uuids.

> +       if (val > 0xffff)
> +               return 0;
> +
> +       return (u16) val;
> +}
> +
> +static void create_eir(struct hci_dev *hdev, u8 *data)
> +{
> +       u8 *ptr = data;
> +       u16 eir_len = 0;
> +       u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
> +       int i, truncated = 0;
> +       struct list_head *p;
> +       size_t name_len;
> +
> +       name_len = strlen(hdev->dev_name);
> +
> +       if (name_len > 0) {
> +               /* EIR Data type */
> +               if (name_len > 48) {
> +                       name_len = 48;
> +                       ptr[1] = EIR_NAME_SHORT;
> +               } else
> +                       ptr[1] = EIR_NAME_COMPLETE;
> +
> +               /* EIR Data length */
> +               ptr[0] = name_len + 1;
> +
> +               memcpy(ptr + 2, hdev->dev_name, name_len);
> +
> +               eir_len += (name_len + 2);
> +               ptr += (name_len + 2);
> +       }
> +
> +       memset(uuid16_list, 0, sizeof(uuid16_list));
> +
> +       /* Group all UUID16 types */
> +       list_for_each(p, &hdev->uuids) {
> +               struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list);
> +               u16 uuid16;
> +
> +               uuid16 = get_uuid16(uuid->uuid);
> +               if (uuid16 == 0)
> +                       return;
> +
> +               if (uuid16 < 0x1100)
> +                       continue;
> +
> +               if (uuid16 == PNP_INFO_SVCLASS_ID)
> +                       continue;
> +
> +               /* Stop if not enough space to put next UUID */
> +               if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
> +                       truncated = 1;
> +                       break;
> +               }
> +
> +               /* Check for duplicates */
> +               for (i = 0; uuid16_list[i] != 0; i++)
> +                       if (uuid16_list[i] == uuid16)
> +                               break;
> +
> +               if (uuid16_list[i] == 0) {
> +                       uuid16_list[i] = uuid16;
> +                       eir_len += sizeof(u16);
> +               }
> +       }
> +
> +       if (uuid16_list[0] != 0) {
> +               u8 *length = ptr;
> +
> +               /* EIR Data type */
> +               ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
> +
> +               ptr += 2;
> +               eir_len += 2;

Here you increment eir_len but does not use it anymore. Maybe it would
be nice to add some assert (BUG_ON ?) on it just to check for
programming errors if someone tries to change this code later.

> +
> +               for (i = 0; uuid16_list[i] != 0; i++) {
> +                       *ptr++ = (uuid16_list[i] & 0x00ff);
> +                       *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
> +               }
> +
> +               /* EIR Data length */
> +               *length = (i * sizeof(u16)) + 1;
> +       }
> +}
> +
> +static int update_eir(struct hci_dev *hdev)
> +{
> +       struct hci_cp_write_eir cp;
> +
> +       if (!(hdev->features[6] & LMP_EXT_INQ))
> +               return 0;
> +
> +       if (hdev->ssp_mode == 0)
> +               return 0;
> +
> +       if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
> +               return 0;
> +
> +       memset(&cp, 0, sizeof(cp));
> +
> +       create_eir(hdev, cp.data);
> +
> +       if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
> +               return 0;

What about making create_eir() return "int" and check for eir_len and
the end? That would avoid the memcmp() here.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux