Commit 94a43cc9 authored by Marcel Holtmann's avatar Marcel Holtmann

[Bluetooth] Use separate inquiry data structure

The inquiry results can return different fields and so create one
data structure that has place for every of these. Missing fields
are filled with default values.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent cfc894b6
......@@ -38,10 +38,20 @@ extern struct proc_dir_entry *proc_bt_hci;
/* HCI Core structures */
struct inquiry_data {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
__u8 pscan_mode;
__u8 dev_class[3];
__u16 clock_offset;
__s8 rssi;
};
struct inquiry_entry {
struct inquiry_entry *next;
__u32 timestamp;
struct inquiry_info info;
struct inquiry_data data;
};
struct inquiry_cache {
......@@ -199,7 +209,7 @@ static inline long inquiry_entry_age(struct inquiry_entry *e)
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_info *info);
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
/* ----- HCI Connections ----- */
enum {
......
......@@ -71,9 +71,9 @@ void hci_acl_connect(struct hci_conn *conn)
if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)) &&
inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
cp.pscan_rep_mode = ie->info.pscan_rep_mode;
cp.pscan_mode = ie->info.pscan_mode;
cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
cp.pscan_rep_mode = ie->data.pscan_rep_mode;
cp.pscan_mode = ie->data.pscan_mode;
cp.clock_offset = ie->data.clock_offset | __cpu_to_le16(0x8000);
}
cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
......
......@@ -313,19 +313,19 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
for (e = cache->list; e; e = e->next)
if (!bacmp(&e->info.bdaddr, bdaddr))
if (!bacmp(&e->data.bdaddr, bdaddr))
break;
return e;
}
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_info *info)
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *e;
BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
if (!(e = hci_inquiry_cache_lookup(hdev, &info->bdaddr))) {
if (!(e = hci_inquiry_cache_lookup(hdev, &data->bdaddr))) {
/* Entry not in the cache. Add new one. */
if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
return;
......@@ -334,7 +334,7 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_info *info)
cache->list = e;
}
memcpy(&e->info, info, sizeof(*info));
memcpy(&e->data, data, sizeof(*data));
e->timestamp = jiffies;
cache->timestamp = jiffies;
}
......@@ -346,8 +346,16 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
struct inquiry_entry *e;
int copied = 0;
for (e = cache->list; e && copied < num; e = e->next, copied++)
memcpy(info++, &e->info, sizeof(*info));
for (e = cache->list; e && copied < num; e = e->next, copied++) {
struct inquiry_data *data = &e->data;
bacpy(&info->bdaddr, &data->bdaddr);
info->pscan_rep_mode = data->pscan_rep_mode;
info->pscan_period_mode = data->pscan_period_mode;
info->pscan_mode = data->pscan_mode;
memcpy(info->dev_class, data->dev_class, 3);
info->clock_offset = data->clock_offset;
info++;
}
BT_DBG("cache %p, copied %d", cache, copied);
return copied;
......
......@@ -491,8 +491,18 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--)
hci_inquiry_cache_update(hdev, info++);
for (; num_rsp; num_rsp--) {
struct inquiry_data data;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
data.pscan_mode = info->pscan_mode;
memcpy(data.dev_class, info->dev_class, 3);
data.clock_offset = info->clock_offset;
data.rssi = 0x00;
info++;
hci_inquiry_cache_update(hdev, &data);
}
hci_dev_unlock(hdev);
}
......@@ -506,15 +516,16 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--) {
struct inquiry_info tmp;
bacpy(&tmp.bdaddr, &info->bdaddr);
tmp.pscan_rep_mode = info->pscan_rep_mode;
tmp.pscan_period_mode = info->pscan_period_mode;
tmp.pscan_mode = 0x00;
memcpy(tmp.dev_class, &info->dev_class, 3);
tmp.clock_offset = info->clock_offset;
struct inquiry_data data;
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
data.pscan_mode = 0x00;
memcpy(data.dev_class, info->dev_class, 3);
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
info++;
hci_inquiry_cache_update(hdev, &tmp);
hci_inquiry_cache_update(hdev, &data);
}
hci_dev_unlock(hdev);
}
......
......@@ -48,14 +48,14 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf)
hci_dev_lock_bh(hdev);
for (e = cache->list; e; e = e->next) {
struct inquiry_info *info = &e->info;
struct inquiry_data *data = &e->data;
bdaddr_t bdaddr;
baswap(&bdaddr, &info->bdaddr);
n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x 0x%.2x %u\n",
baswap(&bdaddr, &data->bdaddr);
n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %u\n",
batostr(&bdaddr),
info->pscan_rep_mode, info->pscan_period_mode, info->pscan_mode,
info->dev_class[2], info->dev_class[1], info->dev_class[0],
info->clock_offset, 0, e->timestamp);
data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode,
data->dev_class[2], data->dev_class[1], data->dev_class[0],
data->clock_offset, data->rssi, e->timestamp);
}
hci_dev_unlock_bh(hdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment