Bluetooth: Change eir_has_data_type() to more generic eir_get_data()
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 5 Jan 2016 11:19:31 +0000 (13:19 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 5 Jan 2016 16:02:49 +0000 (17:02 +0100)
To make the EIR parsing helper more general purpose, make it return
the found data and its length rather than just saying whether the data
was present or not.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index c95e0326c41a374012a17bd88086d70402d5267f..372e2a7c4adadecb6417f16fbc750aa1890f9f6d 100644 (file)
@@ -1283,31 +1283,41 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
        mutex_unlock(&hci_cb_list_lock);
 }
 
-static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
+static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type,
+                                size_t *data_len)
 {
        size_t parsed = 0;
 
-       if (data_len < 2)
-               return false;
+       if (eir_len < 2)
+               return NULL;
 
-       while (parsed < data_len - 1) {
-               u8 field_len = data[0];
+       while (parsed < eir_len - 1) {
+               u8 field_len = eir[0];
 
                if (field_len == 0)
                        break;
 
                parsed += field_len + 1;
 
-               if (parsed > data_len)
+               if (parsed > eir_len)
                        break;
 
-               if (data[1] == type)
-                       return true;
+               if (eir[1] != type) {
+                       eir += field_len + 1;
+                       continue;
+               }
+
+               /* Zero length data */
+               if (field_len == 1)
+                       return NULL;
 
-               data += field_len + 1;
+               if (data_len)
+                       *data_len = field_len - 1;
+
+               return &eir[2];
        }
 
-       return false;
+       return NULL;
 }
 
 static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
index 7554da5b7a8fdf85b1658a5a08086fc07e433095..c162af5d16bf3d4367a058f920d95cb1747ab925 100644 (file)
@@ -3833,9 +3833,9 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
                data.ssp_mode           = 0x01;
 
                if (hci_dev_test_flag(hdev, HCI_MGMT))
-                       name_known = eir_has_data_type(info->data,
-                                                      sizeof(info->data),
-                                                      EIR_NAME_COMPLETE);
+                       name_known = eir_get_data(info->data,
+                                                 sizeof(info->data),
+                                                 EIR_NAME_COMPLETE, NULL);
                else
                        name_known = true;
 
index 621f6fdd0dd1442b8aa5b37d74e5c516cc8e2503..3297a4ecc05ecd4e7ecbce29047a2c1d38992447 100644 (file)
@@ -7266,7 +7266,8 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
                /* Copy EIR or advertising data into event */
                memcpy(ev->eir, eir, eir_len);
 
-       if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
+       if (dev_class && !eir_get_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
+                                      NULL))
                eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
                                          dev_class, 3);