* [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-05 23:10 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 2/9] Bluetooth: Convert inquiry cache to use standard list types johan.hedberg
` (7 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
The HCI_MGMT flag needs to remain set even after closing an HCI device.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/hci_core.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6d38d80..52edc11 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -670,8 +670,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
mgmt_powered(hdev, 0);
hci_dev_unlock(hdev);
- /* Clear flags */
- hdev->flags = 0;
+ /* Clear flags, except persistent ones like HCI_MGMT */
+ hdev->flags &= BIT(HCI_MGMT);
hci_req_unlock(hdev);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag
2012-01-05 15:16 ` [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag johan.hedberg
@ 2012-01-05 23:10 ` Marcel Holtmann
2012-01-06 12:42 ` Johan Hedberg
0 siblings, 1 reply; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-05 23:10 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> The HCI_MGMT flag needs to remain set even after closing an HCI device.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/hci_core.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 6d38d80..52edc11 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -670,8 +670,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
> mgmt_powered(hdev, 0);
> hci_dev_unlock(hdev);
>
> - /* Clear flags */
> - hdev->flags = 0;
> + /* Clear flags, except persistent ones like HCI_MGMT */
> + hdev->flags &= BIT(HCI_MGMT);
>
> hci_req_unlock(hdev);
>
can we just move this away from hdev->flags into a hdev->dev_flags.
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag
2012-01-05 23:10 ` Marcel Holtmann
@ 2012-01-06 12:42 ` Johan Hedberg
2012-01-06 21:57 ` Marcel Holtmann
0 siblings, 1 reply; 22+ messages in thread
From: Johan Hedberg @ 2012-01-06 12:42 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
Hi Marcel,
On Thu, Jan 05, 2012, Marcel Holtmann wrote:
> > The HCI_MGMT flag needs to remain set even after closing an HCI device.
> >
> > Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> > ---
> > net/bluetooth/hci_core.c | 4 ++--
> > 1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index 6d38d80..52edc11 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -670,8 +670,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
> > mgmt_powered(hdev, 0);
> > hci_dev_unlock(hdev);
> >
> > - /* Clear flags */
> > - hdev->flags = 0;
> > + /* Clear flags, except persistent ones like HCI_MGMT */
> > + hdev->flags &= BIT(HCI_MGMT);
> >
> > hci_req_unlock(hdev);
> >
>
> can we just move this away from hdev->flags into a hdev->dev_flags.
Yes, that should be done (and not just for HCI_MGMT but also for other
related flags) but it should imo be in a separate patch. Simply moving
to dev_flags won't fix this particular bug since there's a similar
"hdev->dev_flags = 0;" inside hci_cc_reset() in hci_event.c.
Johan
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag
2012-01-06 12:42 ` Johan Hedberg
@ 2012-01-06 21:57 ` Marcel Holtmann
2012-01-08 20:21 ` Johan Hedberg
0 siblings, 1 reply; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 21:57 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
Hi Johan,
> > > The HCI_MGMT flag needs to remain set even after closing an HCI device.
> > >
> > > Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> > > ---
> > > net/bluetooth/hci_core.c | 4 ++--
> > > 1 files changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > index 6d38d80..52edc11 100644
> > > --- a/net/bluetooth/hci_core.c
> > > +++ b/net/bluetooth/hci_core.c
> > > @@ -670,8 +670,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
> > > mgmt_powered(hdev, 0);
> > > hci_dev_unlock(hdev);
> > >
> > > - /* Clear flags */
> > > - hdev->flags = 0;
> > > + /* Clear flags, except persistent ones like HCI_MGMT */
> > > + hdev->flags &= BIT(HCI_MGMT);
> > >
> > > hci_req_unlock(hdev);
> > >
> >
> > can we just move this away from hdev->flags into a hdev->dev_flags.
>
> Yes, that should be done (and not just for HCI_MGMT but also for other
> related flags) but it should imo be in a separate patch. Simply moving
> to dev_flags won't fix this particular bug since there's a similar
> "hdev->dev_flags = 0;" inside hci_cc_reset() in hci_event.c.
so I rather do the change to dev_flags first.
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag
2012-01-06 21:57 ` Marcel Holtmann
@ 2012-01-08 20:21 ` Johan Hedberg
0 siblings, 0 replies; 22+ messages in thread
From: Johan Hedberg @ 2012-01-08 20:21 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
Hi Marcel,
On Fri, Jan 06, 2012, Marcel Holtmann wrote:
> > > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > > > index 6d38d80..52edc11 100644
> > > > --- a/net/bluetooth/hci_core.c
> > > > +++ b/net/bluetooth/hci_core.c
> > > > @@ -670,8 +670,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
> > > > mgmt_powered(hdev, 0);
> > > > hci_dev_unlock(hdev);
> > > >
> > > > - /* Clear flags */
> > > > - hdev->flags = 0;
> > > > + /* Clear flags, except persistent ones like HCI_MGMT */
> > > > + hdev->flags &= BIT(HCI_MGMT);
> > > >
> > > > hci_req_unlock(hdev);
> > > >
> > >
> > > can we just move this away from hdev->flags into a hdev->dev_flags.
> >
> > Yes, that should be done (and not just for HCI_MGMT but also for other
> > related flags) but it should imo be in a separate patch. Simply moving
> > to dev_flags won't fix this particular bug since there's a similar
> > "hdev->dev_flags = 0;" inside hci_cc_reset() in hci_event.c.
>
> so I rather do the change to dev_flags first.
Alright, I'll do it that way around. Meanwhile I've applied the other
acked patches to my bluetooth-next tree.
Johan
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 2/9] Bluetooth: Convert inquiry cache to use standard list types
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
2012-01-05 15:16 ` [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:47 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 3/9] Bluetooth: Move Extended Inquiry Response defines to hci.h johan.hedberg
` (6 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This makes it possible to use the convenience functions provided for
standard kernel list types and it also makes it easier to extend the use
of the cache for the management interface where e.g. name resolving
control will be needed.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 10 ++++------
net/bluetooth/hci_core.c | 31 +++++++++++++++++--------------
net/bluetooth/hci_sysfs.c | 2 +-
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea9231f..91d1baf 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -44,14 +44,14 @@ struct inquiry_data {
};
struct inquiry_entry {
- struct inquiry_entry *next;
+ struct list_head list;
__u32 timestamp;
struct inquiry_data data;
};
struct inquiry_cache {
+ struct list_head list;
__u32 timestamp;
- struct inquiry_entry *list;
};
struct hci_conn_hash {
@@ -350,14 +350,12 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
static inline void inquiry_cache_init(struct hci_dev *hdev)
{
- struct inquiry_cache *c = &hdev->inq_cache;
- c->list = NULL;
+ INIT_LIST_HEAD(&hdev->inq_cache.list);
}
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
- struct inquiry_cache *c = &hdev->inq_cache;
- return c->list == NULL;
+ return list_empty(&hdev->inq_cache.list);
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 52edc11..39214e1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -357,15 +357,11 @@ struct hci_dev *hci_dev_get(int index)
/* ---- Inquiry support ---- */
static void inquiry_cache_flush(struct hci_dev *hdev)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
- struct inquiry_entry *next = cache->list, *e;
-
- BT_DBG("cache %p", cache);
+ struct inquiry_entry *p, *n;
- cache->list = NULL;
- while ((e = next)) {
- next = e->next;
- kfree(e);
+ list_for_each_entry_safe(p, n, &hdev->inq_cache.list, list) {
+ list_del(&p->list);
+ kfree(p);
}
}
@@ -376,10 +372,12 @@ 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)
+ list_for_each_entry(e, &cache->list, list) {
if (!bacmp(&e->data.bdaddr, bdaddr))
- break;
- return e;
+ return e;
+ }
+
+ return NULL;
}
void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
@@ -396,8 +394,7 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
if (!ie)
return;
- ie->next = cache->list;
- cache->list = ie;
+ list_add(&ie->list, &cache->list);
}
memcpy(&ie->data, data, sizeof(*data));
@@ -412,15 +409,21 @@ 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++) {
+ list_for_each_entry(e, &cache->list, list) {
struct inquiry_data *data = &e->data;
+
+ if (copied >= num)
+ break;
+
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++;
+ copied++;
}
BT_DBG("cache %p, copied %d", cache, copied);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 5210956..ed9ccee 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -388,7 +388,7 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
hci_dev_lock(hdev);
- for (e = cache->list; e; e = e->next) {
+ list_for_each_entry(e, &cache->list, list) {
struct inquiry_data *data = &e->data;
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
batostr(&data->bdaddr),
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 2/9] Bluetooth: Convert inquiry cache to use standard list types
2012-01-05 15:16 ` [PATCH 2/9] Bluetooth: Convert inquiry cache to use standard list types johan.hedberg
@ 2012-01-06 5:47 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:47 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> This makes it possible to use the convenience functions provided for
> standard kernel list types and it also makes it easier to extend the use
> of the cache for the management interface where e.g. name resolving
> control will be needed.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 10 ++++------
> net/bluetooth/hci_core.c | 31 +++++++++++++++++--------------
> net/bluetooth/hci_sysfs.c | 2 +-
> 3 files changed, 22 insertions(+), 21 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 3/9] Bluetooth: Move Extended Inquiry Response defines to hci.h
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
2012-01-05 15:16 ` [PATCH 1/9] Bluetooth: Fix persistency of the HCI_MGMT flag johan.hedberg
2012-01-05 15:16 ` [PATCH 2/9] Bluetooth: Convert inquiry cache to use standard list types johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:48 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 4/9] Bluetooth: Add initial mgmt_confirm_name support johan.hedberg
` (5 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
The EIR defines are needed also outside of mgmt.c (e.g. in hci_event.c
to check if EIR data has the complete name) so it's better to have them
in a single public place, i.e. hci.h.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci.h | 13 +++++++++++++
net/bluetooth/mgmt.c | 12 ------------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5b2fed5..ce5133b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -284,6 +284,19 @@ enum {
#define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00
#define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01
+/* Extended Inquiry Response field types */
+#define EIR_FLAGS 0x01 /* flags */
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_TX_POWER 0x0A /* transmit power level */
+#define EIR_DEVICE_ID 0x10 /* device ID */
+
/* ----- HCI Commands ---- */
#define HCI_OP_NOP 0x0000
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bc8e59d..851cb19 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -303,18 +303,6 @@ static u32 get_current_settings(struct hci_dev *hdev)
return settings;
}
-#define EIR_FLAGS 0x01 /* flags */
-#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
-#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
-#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
-#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
-#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
-#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
-#define EIR_NAME_SHORT 0x08 /* shortened local name */
-#define EIR_NAME_COMPLETE 0x09 /* complete local name */
-#define EIR_TX_POWER 0x0A /* transmit power level */
-#define EIR_DEVICE_ID 0x10 /* device ID */
-
#define PNP_INFO_SVCLASS_ID 0x1200
static u8 bluetooth_base_uuid[] = {
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 4/9] Bluetooth: Add initial mgmt_confirm_name support
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (2 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 3/9] Bluetooth: Move Extended Inquiry Response defines to hci.h johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:50 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 5/9] Bluetooth: Return updated name state with hci_inquiry_cache_update johan.hedberg
` (4 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This patch adds initial support for mgmt_confirm_name. It adds the
necessary tracking of the name state by extending the inquiry cache. The
actual name resolving operation (to be done once inquiry is finished) is
not yet part of this patch.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 29 ++++++++++++++----
net/bluetooth/hci_core.c | 58 ++++++++++++++++++++++++++++++-------
net/bluetooth/hci_event.c | 51 ++++++++++++++++++++++++++++-----
net/bluetooth/hci_sysfs.c | 2 +-
net/bluetooth/mgmt.c | 51 ++++++++++++++++++++++++++++++++-
5 files changed, 163 insertions(+), 28 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 91d1baf..2999b6e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -44,14 +44,23 @@ struct inquiry_data {
};
struct inquiry_entry {
- struct list_head list;
+ struct list_head all; /* inq_cache.all */
+ struct list_head list; /* unknown or resolve */
+ enum {
+ NAME_NOT_KNOWN,
+ NAME_NEEDED,
+ NAME_PENDING,
+ NAME_KNOWN,
+ } name_state;
__u32 timestamp;
struct inquiry_data data;
};
struct inquiry_cache {
- struct list_head list;
- __u32 timestamp;
+ struct list_head all; /* All devices found during inquiry */
+ struct list_head unknown; /* Name state not known */
+ struct list_head resolve; /* Name needs to be resolved */
+ __u32 timestamp;
};
struct hci_conn_hash {
@@ -350,12 +359,14 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
static inline void inquiry_cache_init(struct hci_dev *hdev)
{
- INIT_LIST_HEAD(&hdev->inq_cache.list);
+ INIT_LIST_HEAD(&hdev->inq_cache.all);
+ INIT_LIST_HEAD(&hdev->inq_cache.unknown);
+ INIT_LIST_HEAD(&hdev->inq_cache.resolve);
}
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
- return list_empty(&hdev->inq_cache.list);
+ return list_empty(&hdev->inq_cache.all);
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
@@ -371,7 +382,10 @@ 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_data *data);
+struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
+ bdaddr_t *bdaddr);
+void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+ bool name_known);
/* ----- HCI Connections ----- */
enum {
@@ -913,7 +927,8 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
u8 *randomizer, u8 status);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
- u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir);
+ u8 addr_type, u8 *dev_class, s8 rssi,
+ u8 cfm_name, u8 *eir);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 39214e1..9e36fb1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -357,12 +357,16 @@ struct hci_dev *hci_dev_get(int index)
/* ---- Inquiry support ---- */
static void inquiry_cache_flush(struct hci_dev *hdev)
{
+ struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *p, *n;
- list_for_each_entry_safe(p, n, &hdev->inq_cache.list, list) {
- list_del(&p->list);
+ list_for_each_entry_safe(p, n, &cache->all, all) {
+ list_del(&p->all);
kfree(p);
}
+
+ INIT_LIST_HEAD(&cache->unknown);
+ INIT_LIST_HEAD(&cache->resolve);
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
@@ -372,7 +376,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
- list_for_each_entry(e, &cache->list, list) {
+ list_for_each_entry(e, &cache->all, all) {
if (!bacmp(&e->data.bdaddr, bdaddr))
return e;
}
@@ -380,7 +384,24 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
return NULL;
}
-void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
+struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
+ bdaddr_t *bdaddr)
+{
+ struct inquiry_cache *cache = &hdev->inq_cache;
+ struct inquiry_entry *e;
+
+ BT_DBG("cache %p, %s", cache, batostr(bdaddr));
+
+ list_for_each_entry(e, &cache->unknown, list) {
+ if (!bacmp(&e->data.bdaddr, bdaddr))
+ return e;
+ }
+
+ return NULL;
+}
+
+void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+ bool name_known)
{
struct inquiry_cache *cache = &hdev->inq_cache;
struct inquiry_entry *ie;
@@ -388,13 +409,28 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data)
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
ie = hci_inquiry_cache_lookup(hdev, &data->bdaddr);
- if (!ie) {
- /* Entry not in the cache. Add new one. */
- ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
- if (!ie)
- return;
+ if (ie)
+ goto update;
+
+ /* Entry not in the cache. Add new one. */
+ ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
+ if (!ie)
+ return;
+
+ list_add(&ie->all, &cache->all);
+
+ if (name_known) {
+ ie->name_state = NAME_KNOWN;
+ } else {
+ ie->name_state = NAME_NOT_KNOWN;
+ list_add(&ie->list, &cache->unknown);
+ }
- list_add(&ie->list, &cache->list);
+update:
+ if (name_known && ie->name_state != NAME_KNOWN &&
+ ie->name_state != NAME_PENDING) {
+ ie->name_state = NAME_KNOWN;
+ list_del(&ie->list);
}
memcpy(&ie->data, data, sizeof(*data));
@@ -409,7 +445,7 @@ static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
struct inquiry_entry *e;
int copied = 0;
- list_for_each_entry(e, &cache->list, list) {
+ list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
if (copied >= num)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d37f5b2..abcdadf 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1533,9 +1533,9 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data.clock_offset = info->clock_offset;
data.rssi = 0x00;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data);
+ hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
- info->dev_class, 0, NULL);
+ info->dev_class, 0, 1, NULL);
}
hci_dev_unlock(hdev);
@@ -2572,10 +2572,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data);
+ hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- NULL);
+ 1, NULL);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
@@ -2589,10 +2589,10 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data);
+ hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- NULL);
+ 1, NULL);
}
}
@@ -2710,6 +2710,31 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s
BT_DBG("%s status %d", hdev->name, ev->status);
}
+static inline bool eir_has_complete_name(u8 *data, size_t data_len)
+{
+ u8 field_len;
+ size_t parsed;
+
+ for (parsed = 0; parsed < data_len - 1; parsed += field_len) {
+ field_len = data[0];
+
+ if (field_len == 0)
+ break;
+
+ parsed += field_len + 1;
+
+ if (parsed > data_len)
+ break;
+
+ if (data[1] == EIR_NAME_COMPLETE)
+ return true;
+
+ data += field_len + 1;
+ }
+
+ return false;
+}
+
static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct inquiry_data data;
@@ -2724,6 +2749,8 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
+ bool name_known;
+
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -2732,9 +2759,17 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x01;
- hci_inquiry_cache_update(hdev, &data);
+
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ name_known = eir_has_complete_name(info->data,
+ sizeof(info->data));
+ else
+ name_known = true;
+
+ hci_inquiry_cache_update(hdev, &data, name_known);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
- info->dev_class, info->rssi, info->data);
+ info->dev_class, info->rssi,
+ !name_known, info->data);
}
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ed9ccee..3600d78 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -388,7 +388,7 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
hci_dev_lock(hdev);
- list_for_each_entry(e, &cache->list, list) {
+ list_for_each_entry(e, &cache->all, all) {
struct inquiry_data *data = &e->data;
seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
batostr(&data->bdaddr),
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 851cb19..3977511 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1967,6 +1967,50 @@ failed:
return err;
}
+static int confirm_name(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct mgmt_cp_confirm_name *cp = (void *) data;
+ struct inquiry_entry *e;
+ struct hci_dev *hdev;
+ int err;
+
+ BT_DBG("hci%u", index);
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
+ MGMT_STATUS_INVALID_PARAMS);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
+ MGMT_STATUS_INVALID_PARAMS);
+
+ hci_dev_lock(hdev);
+
+ e = hci_inquiry_cache_lookup_unknown(hdev, &cp->bdaddr);
+ if (!e) {
+ err = cmd_status (sk, index, MGMT_OP_CONFIRM_NAME,
+ MGMT_STATUS_INVALID_PARAMS);
+ goto failed;
+ }
+
+ if (cp->name_known) {
+ e->name_state = NAME_KNOWN;
+ list_del(&e->list);
+ } else {
+ e->name_state = NAME_NEEDED;
+ list_move(&e->list, &hdev->inq_cache.resolve);
+ }
+
+ err = 0;
+
+failed:
+ hci_dev_unlock(hdev);
+
+ return err;
+}
+
static int block_device(struct sock *sk, u16 index, unsigned char *data,
u16 len)
{
@@ -2215,6 +2259,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
case MGMT_OP_STOP_DISCOVERY:
err = stop_discovery(sk, index);
break;
+ case MGMT_OP_CONFIRM_NAME:
+ err = confirm_name(sk, index, buf + sizeof(*hdr), len);
+ break;
case MGMT_OP_BLOCK_DEVICE:
err = block_device(sk, index, buf + sizeof(*hdr), len);
break;
@@ -2689,7 +2736,8 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
}
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
- u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir)
+ u8 addr_type, u8 *dev_class, s8 rssi,
+ u8 cfm_name, u8 *eir)
{
struct mgmt_ev_device_found ev;
@@ -2698,6 +2746,7 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = link_to_mgmt(link_type, addr_type);
ev.rssi = rssi;
+ ev.confirm_name = cfm_name;
if (eir)
memcpy(ev.eir, eir, sizeof(ev.eir));
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 4/9] Bluetooth: Add initial mgmt_confirm_name support
2012-01-05 15:16 ` [PATCH 4/9] Bluetooth: Add initial mgmt_confirm_name support johan.hedberg
@ 2012-01-06 5:50 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:50 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> This patch adds initial support for mgmt_confirm_name. It adds the
> necessary tracking of the name state by extending the inquiry cache. The
> actual name resolving operation (to be done once inquiry is finished) is
> not yet part of this patch.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 29 ++++++++++++++----
> net/bluetooth/hci_core.c | 58 ++++++++++++++++++++++++++++++-------
> net/bluetooth/hci_event.c | 51 ++++++++++++++++++++++++++++-----
> net/bluetooth/hci_sysfs.c | 2 +-
> net/bluetooth/mgmt.c | 51 ++++++++++++++++++++++++++++++++-
> 5 files changed, 163 insertions(+), 28 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 5/9] Bluetooth: Return updated name state with hci_inquiry_cache_update
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (3 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 4/9] Bluetooth: Add initial mgmt_confirm_name support johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:51 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 6/9] Bluetooth: Flush inquiry cache when starting mgmt triggered inquiry johan.hedberg
` (3 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
If user-space has already confirmed the name for a remote device we
shouldn't request confirmation again. The simplest way to do this is to
return the name state from hci_inquiry_cache_update (if it is anything
else than unknown then we do not need confirmation from user-space).
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_core.c | 9 +++++++--
net/bluetooth/hci_event.c | 21 ++++++++++++++-------
3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2999b6e..236f7f0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -384,7 +384,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr);
struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bdaddr_t *bdaddr);
-void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known);
/* ----- HCI Connections ----- */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9e36fb1..67b0bd6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -400,7 +400,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
return NULL;
}
-void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known)
{
struct inquiry_cache *cache = &hdev->inq_cache;
@@ -415,7 +415,7 @@ void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
/* Entry not in the cache. Add new one. */
ie = kzalloc(sizeof(struct inquiry_entry), GFP_ATOMIC);
if (!ie)
- return;
+ return false;
list_add(&ie->all, &cache->all);
@@ -436,6 +436,11 @@ update:
memcpy(&ie->data, data, sizeof(*data));
ie->timestamp = jiffies;
cache->timestamp = jiffies;
+
+ if (ie->name_state == NAME_NOT_KNOWN)
+ return false;
+
+ return true;
}
static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index abcdadf..828ff14 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1525,6 +1525,8 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_lock(hdev);
for (; num_rsp; num_rsp--, info++) {
+ bool name_known;
+
bacpy(&data.bdaddr, &info->bdaddr);
data.pscan_rep_mode = info->pscan_rep_mode;
data.pscan_period_mode = info->pscan_period_mode;
@@ -1533,9 +1535,10 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
data.clock_offset = info->clock_offset;
data.rssi = 0x00;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data, false);
+
+ name_known = hci_inquiry_cache_update(hdev, &data, false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
- info->dev_class, 0, 1, NULL);
+ info->dev_class, 0, !name_known, NULL);
}
hci_dev_unlock(hdev);
@@ -2551,6 +2554,7 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
{
struct inquiry_data data;
int num_rsp = *((__u8 *) skb->data);
+ bool name_known;
BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
@@ -2572,10 +2576,12 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data, false);
+
+ name_known = hci_inquiry_cache_update(hdev, &data,
+ false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- 1, NULL);
+ !name_known, NULL);
}
} else {
struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
@@ -2589,10 +2595,11 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct
data.clock_offset = info->clock_offset;
data.rssi = info->rssi;
data.ssp_mode = 0x00;
- hci_inquiry_cache_update(hdev, &data, false);
+ name_known = hci_inquiry_cache_update(hdev, &data,
+ false);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
- 1, NULL);
+ !name_known, NULL);
}
}
@@ -2766,7 +2773,7 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
else
name_known = true;
- hci_inquiry_cache_update(hdev, &data, name_known);
+ name_known = hci_inquiry_cache_update(hdev, &data, name_known);
mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
info->dev_class, info->rssi,
!name_known, info->data);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 5/9] Bluetooth: Return updated name state with hci_inquiry_cache_update
2012-01-05 15:16 ` [PATCH 5/9] Bluetooth: Return updated name state with hci_inquiry_cache_update johan.hedberg
@ 2012-01-06 5:51 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:51 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> If user-space has already confirmed the name for a remote device we
> shouldn't request confirmation again. The simplest way to do this is to
> return the name state from hci_inquiry_cache_update (if it is anything
> else than unknown then we do not need confirmation from user-space).
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 2 +-
> net/bluetooth/hci_core.c | 9 +++++++--
> net/bluetooth/hci_event.c | 21 ++++++++++++++-------
> 3 files changed, 22 insertions(+), 10 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 6/9] Bluetooth: Flush inquiry cache when starting mgmt triggered inquiry
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (4 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 5/9] Bluetooth: Return updated name state with hci_inquiry_cache_update johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:51 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 7/9] Bluetooth: Rename hdev->inq_cache to hdev->discovery johan.hedberg
` (2 subsequent siblings)
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
For the remote name state tracking for the management interface to work
the cache needs to be flushed whenever inquiry is started. The
hci_do_inquiry function is only used by the management interface so by
having the flushing done from it ensures that old ioctl based
functionality isn't affected.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/hci_core.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 67b0bd6..5c0a1e7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2611,6 +2611,8 @@ int hci_do_inquiry(struct hci_dev *hdev, u8 length)
if (test_bit(HCI_INQUIRY, &hdev->flags))
return -EINPROGRESS;
+ inquiry_cache_flush(hdev);
+
memset(&cp, 0, sizeof(cp));
memcpy(&cp.lap, lap, sizeof(cp.lap));
cp.length = length;
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 7/9] Bluetooth: Rename hdev->inq_cache to hdev->discovery
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (5 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 6/9] Bluetooth: Flush inquiry cache when starting mgmt triggered inquiry johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:54 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 8/9] Bluetooth: Add discovery state tracking johan.hedberg
2012-01-05 15:16 ` [PATCH 9/9] Bluetooth: Add name resolving support for mgmt based discovery johan.hedberg
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This struct is used for not just inquiry caching but also for general
device discovery state tracking so it's better to rename it to something
more appropriate.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 16 ++++++++--------
net/bluetooth/hci_core.c | 12 ++++++------
net/bluetooth/hci_sysfs.c | 2 +-
net/bluetooth/mgmt.c | 2 +-
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 236f7f0..5a566fd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -56,7 +56,7 @@ struct inquiry_entry {
struct inquiry_data data;
};
-struct inquiry_cache {
+struct discovery_state {
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
@@ -226,7 +226,7 @@ struct hci_dev {
struct list_head mgmt_pending;
- struct inquiry_cache inq_cache;
+ struct discovery_state discovery;
struct hci_conn_hash conn_hash;
struct list_head blacklist;
@@ -357,21 +357,21 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
#define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */
#define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */
-static inline void inquiry_cache_init(struct hci_dev *hdev)
+static inline void discovery_init(struct hci_dev *hdev)
{
- INIT_LIST_HEAD(&hdev->inq_cache.all);
- INIT_LIST_HEAD(&hdev->inq_cache.unknown);
- INIT_LIST_HEAD(&hdev->inq_cache.resolve);
+ INIT_LIST_HEAD(&hdev->discovery.all);
+ INIT_LIST_HEAD(&hdev->discovery.unknown);
+ INIT_LIST_HEAD(&hdev->discovery.resolve);
}
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
- return list_empty(&hdev->inq_cache.all);
+ return list_empty(&hdev->discovery.all);
}
static inline long inquiry_cache_age(struct hci_dev *hdev)
{
- struct inquiry_cache *c = &hdev->inq_cache;
+ struct discovery_state *c = &hdev->discovery;
return jiffies - c->timestamp;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5c0a1e7..82829c1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -357,7 +357,7 @@ struct hci_dev *hci_dev_get(int index)
/* ---- Inquiry support ---- */
static void inquiry_cache_flush(struct hci_dev *hdev)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *p, *n;
list_for_each_entry_safe(p, n, &cache->all, all) {
@@ -371,7 +371,7 @@ static void inquiry_cache_flush(struct hci_dev *hdev)
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
@@ -387,7 +387,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *b
struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bdaddr_t *bdaddr)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
BT_DBG("cache %p, %s", cache, batostr(bdaddr));
@@ -403,7 +403,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *ie;
BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
@@ -445,7 +445,7 @@ update:
static int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
{
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_info *info = (struct inquiry_info *) buf;
struct inquiry_entry *e;
int copied = 0;
@@ -1546,7 +1546,7 @@ int hci_register_dev(struct hci_dev *hdev)
init_waitqueue_head(&hdev->req_wait_q);
mutex_init(&hdev->req_lock);
- inquiry_cache_init(hdev);
+ discovery_init(hdev);
hci_conn_hash_init(hdev);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 3600d78..74b49e3 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -383,7 +383,7 @@ static struct device_type bt_host = {
static int inquiry_cache_show(struct seq_file *f, void *p)
{
struct hci_dev *hdev = f->private;
- struct inquiry_cache *cache = &hdev->inq_cache;
+ struct discovery_state *cache = &hdev->discovery;
struct inquiry_entry *e;
hci_dev_lock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3977511..894f11b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2000,7 +2000,7 @@ static int confirm_name(struct sock *sk, u16 index, unsigned char *data,
list_del(&e->list);
} else {
e->name_state = NAME_NEEDED;
- list_move(&e->list, &hdev->inq_cache.resolve);
+ list_move(&e->list, &hdev->discovery.resolve);
}
err = 0;
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 7/9] Bluetooth: Rename hdev->inq_cache to hdev->discovery
2012-01-05 15:16 ` [PATCH 7/9] Bluetooth: Rename hdev->inq_cache to hdev->discovery johan.hedberg
@ 2012-01-06 5:54 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:54 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> This struct is used for not just inquiry caching but also for general
> device discovery state tracking so it's better to rename it to something
> more appropriate.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 16 ++++++++--------
> net/bluetooth/hci_core.c | 12 ++++++------
> net/bluetooth/hci_sysfs.c | 2 +-
> net/bluetooth/mgmt.c | 2 +-
> 4 files changed, 16 insertions(+), 16 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 8/9] Bluetooth: Add discovery state tracking
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (6 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 7/9] Bluetooth: Rename hdev->inq_cache to hdev->discovery johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:53 ` Marcel Holtmann
2012-01-05 15:16 ` [PATCH 9/9] Bluetooth: Add name resolving support for mgmt based discovery johan.hedberg
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This patch adds proper state tracking to the device discovery process.
This makes it possible to return appropriate errors when trying to stop
a non-active discovery or start discovery when it is already ongoing.
Once name resolving is implemented this also makes it possible to know
what the right action to do is when a remote name lookup is cancelled.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 9 +++++++++
net/bluetooth/hci_core.c | 25 +++++++++++++++++++++++++
net/bluetooth/hci_event.c | 6 +++---
net/bluetooth/mgmt.c | 16 ++++++++++++++++
4 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 5a566fd..2f19de4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -57,6 +57,12 @@ struct inquiry_entry {
};
struct discovery_state {
+ enum {
+ DISCOVERY_STOPPED,
+ DISCOVERY_STARTING,
+ DISCOVERY_ACTIVE,
+ DISCOVERY_STOPPING,
+ } state;
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
@@ -359,11 +365,14 @@ extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
static inline void discovery_init(struct hci_dev *hdev)
{
+ hdev->discovery.state = DISCOVERY_STOPPED;
INIT_LIST_HEAD(&hdev->discovery.all);
INIT_LIST_HEAD(&hdev->discovery.unknown);
INIT_LIST_HEAD(&hdev->discovery.resolve);
}
+void hci_discovery_set_state(struct hci_dev *hdev, int state);
+
static inline int inquiry_cache_empty(struct hci_dev *hdev)
{
return list_empty(&hdev->discovery.all);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 82829c1..f3aaa3c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -355,6 +355,30 @@ struct hci_dev *hci_dev_get(int index)
}
/* ---- Inquiry support ---- */
+
+void hci_discovery_set_state(struct hci_dev *hdev, int state)
+{
+ BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
+
+ if (hdev->discovery.state == state)
+ return;
+
+ switch (state) {
+ case DISCOVERY_STOPPED:
+ mgmt_discovering(hdev, 0);
+ break;
+ case DISCOVERY_STARTING:
+ break;
+ case DISCOVERY_ACTIVE:
+ mgmt_discovering(hdev, 1);
+ break;
+ case DISCOVERY_STOPPING:
+ break;
+ }
+
+ hdev->discovery.state = state;
+}
+
static void inquiry_cache_flush(struct hci_dev *hdev)
{
struct discovery_state *cache = &hdev->discovery;
@@ -367,6 +391,7 @@ static void inquiry_cache_flush(struct hci_dev *hdev)
INIT_LIST_HEAD(&cache->unknown);
INIT_LIST_HEAD(&cache->resolve);
+ cache->state = DISCOVERY_STOPPED;
}
struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 828ff14..6213b5f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -65,7 +65,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
- mgmt_discovering(hdev, 0);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hci_dev_unlock(hdev);
hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
@@ -1119,7 +1119,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
set_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
- mgmt_discovering(hdev, 1);
+ hci_discovery_set_state(hdev, DISCOVERY_ACTIVE);
hci_dev_unlock(hdev);
}
@@ -1507,7 +1507,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
return;
hci_dev_lock(hdev);
- mgmt_discovering(hdev, 0);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hci_dev_unlock(hdev);
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 894f11b..590966d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1918,6 +1918,12 @@ static int start_discovery(struct sock *sk, u16 index,
goto failed;
}
+ if (hdev->discovery.state != DISCOVERY_STOPPED) {
+ err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
+ MGMT_STATUS_BUSY);
+ goto failed;
+ }
+
cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
if (!cmd) {
err = -ENOMEM;
@@ -1927,6 +1933,8 @@ static int start_discovery(struct sock *sk, u16 index,
err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
if (err < 0)
mgmt_pending_remove(cmd);
+ else
+ hci_discovery_set_state(hdev, DISCOVERY_STARTING);
failed:
hci_dev_unlock(hdev);
@@ -1950,6 +1958,12 @@ static int stop_discovery(struct sock *sk, u16 index)
hci_dev_lock(hdev);
+ if (hdev->discovery.state != DISCOVERY_ACTIVE) {
+ err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
+ MGMT_STATUS_REJECTED);
+ goto failed;
+ }
+
cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
if (!cmd) {
err = -ENOMEM;
@@ -1959,6 +1973,8 @@ static int stop_discovery(struct sock *sk, u16 index)
err = hci_cancel_inquiry(hdev);
if (err < 0)
mgmt_pending_remove(cmd);
+ else
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
failed:
hci_dev_unlock(hdev);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 8/9] Bluetooth: Add discovery state tracking
2012-01-05 15:16 ` [PATCH 8/9] Bluetooth: Add discovery state tracking johan.hedberg
@ 2012-01-06 5:53 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:53 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> This patch adds proper state tracking to the device discovery process.
> This makes it possible to return appropriate errors when trying to stop
> a non-active discovery or start discovery when it is already ongoing.
> Once name resolving is implemented this also makes it possible to know
> what the right action to do is when a remote name lookup is cancelled.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 9 +++++++++
> net/bluetooth/hci_core.c | 25 +++++++++++++++++++++++++
> net/bluetooth/hci_event.c | 6 +++---
> net/bluetooth/mgmt.c | 16 ++++++++++++++++
> 4 files changed, 53 insertions(+), 3 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 9/9] Bluetooth: Add name resolving support for mgmt based discovery
2012-01-05 15:16 [PATCH 0/9] Bluetooth: Legacy name discovery support for mgmt johan.hedberg
` (7 preceding siblings ...)
2012-01-05 15:16 ` [PATCH 8/9] Bluetooth: Add discovery state tracking johan.hedberg
@ 2012-01-05 15:16 ` johan.hedberg
2012-01-06 5:54 ` Marcel Holtmann
8 siblings, 1 reply; 22+ messages in thread
From: johan.hedberg @ 2012-01-05 15:16 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This patch adds the necessary logic to perform name lookups after
inquiry completes. This is done by checking for entries in the resolve
list after each inquiry complete and remote name complete HCI event.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci_core.h | 8 +++-
net/bluetooth/hci_core.c | 34 +++++++++++++++-
net/bluetooth/hci_event.c | 81 ++++++++++++++++++++++++++++++++++++--
net/bluetooth/mgmt.c | 37 +++++++++++++++--
4 files changed, 149 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2f19de4..a8680da 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -60,7 +60,8 @@ struct discovery_state {
enum {
DISCOVERY_STOPPED,
DISCOVERY_STARTING,
- DISCOVERY_ACTIVE,
+ DISCOVERY_INQUIRY,
+ DISCOVERY_RESOLVING,
DISCOVERY_STOPPING,
} state;
struct list_head all; /* All devices found during inquiry */
@@ -371,6 +372,8 @@ static inline void discovery_init(struct hci_dev *hdev)
INIT_LIST_HEAD(&hdev->discovery.resolve);
}
+bool hci_discovery_active(struct hci_dev *hdev);
+
void hci_discovery_set_state(struct hci_dev *hdev, int state);
static inline int inquiry_cache_empty(struct hci_dev *hdev)
@@ -393,6 +396,9 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
bdaddr_t *bdaddr);
struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
bdaddr_t *bdaddr);
+struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
+ bdaddr_t *bdaddr,
+ int state);
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f3aaa3c..803655f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -356,6 +356,17 @@ struct hci_dev *hci_dev_get(int index)
/* ---- Inquiry support ---- */
+bool hci_discovery_active(struct hci_dev *hdev)
+{
+ struct discovery_state *discov = &hdev->discovery;
+
+ if (discov->state == DISCOVERY_INQUIRY ||
+ discov->state == DISCOVERY_RESOLVING)
+ return true;
+
+ return false;
+}
+
void hci_discovery_set_state(struct hci_dev *hdev, int state)
{
BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
@@ -369,9 +380,11 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
break;
case DISCOVERY_STARTING:
break;
- case DISCOVERY_ACTIVE:
+ case DISCOVERY_INQUIRY:
mgmt_discovering(hdev, 1);
break;
+ case DISCOVERY_RESOLVING:
+ break;
case DISCOVERY_STOPPING:
break;
}
@@ -425,6 +438,25 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
return NULL;
}
+struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
+ bdaddr_t *bdaddr,
+ int state)
+{
+ struct discovery_state *cache = &hdev->discovery;
+ struct inquiry_entry *e;
+
+ BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
+
+ list_for_each_entry(e, &cache->resolve, list) {
+ if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
+ return e;
+ if (!bacmp(&e->data.bdaddr, bdaddr))
+ return e;
+ }
+
+ return NULL;
+}
+
bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
bool name_known)
{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6213b5f..43bbf32 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1119,7 +1119,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
set_bit(HCI_INQUIRY, &hdev->flags);
hci_dev_lock(hdev);
- hci_discovery_set_state(hdev, DISCOVERY_ACTIVE);
+ hci_discovery_set_state(hdev, DISCOVERY_INQUIRY);
hci_dev_unlock(hdev);
}
@@ -1271,6 +1271,50 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
return 1;
}
+static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
+{
+ struct hci_cp_remote_name_req cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ bacpy(&cp.bdaddr, &e->data.bdaddr);
+ cp.pscan_rep_mode = e->data.pscan_rep_mode;
+ cp.pscan_mode = e->data.pscan_mode;
+ cp.clock_offset = e->data.clock_offset;
+
+ return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
+}
+
+static void hci_resolve_next_name(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+ struct discovery_state *discov = &hdev->discovery;
+ struct inquiry_entry *e;
+
+ if (discov->state == DISCOVERY_STOPPING)
+ goto discov_complete;
+
+ if (discov->state != DISCOVERY_RESOLVING)
+ return;
+
+ e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
+ if (e) {
+ e->name_state = NAME_KNOWN;
+ list_del(&e->list);
+ }
+
+ if (list_empty(&discov->resolve))
+ goto discov_complete;
+
+ e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
+ if (hci_resolve_name(hdev, e) == 0) {
+ e->name_state = NAME_PENDING;
+ return;
+ }
+
+discov_complete:
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+}
+
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
{
struct hci_cp_remote_name_req *cp;
@@ -1289,6 +1333,9 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
+ if (test_bit(HCI_MGMT, &hdev->flags))
+ hci_resolve_next_name(hdev, &cp->bdaddr);
+
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
if (!conn)
goto unlock;
@@ -1496,6 +1543,8 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
+ struct discovery_state *discov = &hdev->discovery;
+ struct inquiry_entry *e;
BT_DBG("%s status %d", hdev->name, status);
@@ -1506,8 +1555,28 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
return;
+ if (!test_bit(HCI_MGMT, &hdev->flags))
+ return;
+
hci_dev_lock(hdev);
- hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+
+ if (discov->state != DISCOVERY_INQUIRY)
+ goto unlock;
+
+ if (list_empty(&discov->resolve)) {
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ goto unlock;
+ }
+
+ e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
+ if (e && hci_resolve_name(hdev, e) == 0) {
+ e->name_state = NAME_PENDING;
+ hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
+ } else {
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ }
+
+unlock:
hci_dev_unlock(hdev);
}
@@ -1807,8 +1876,12 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
hci_dev_lock(hdev);
- if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
- mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
+ if (test_bit(HCI_MGMT, &hdev->flags)) {
+ if (ev->status == 0)
+ mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
+
+ hci_resolve_next_name(hdev, &ev->bdaddr);
+ }
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 590966d..295cfc8 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1947,6 +1947,8 @@ static int stop_discovery(struct sock *sk, u16 index)
{
struct hci_dev *hdev;
struct pending_cmd *cmd;
+ struct hci_cp_remote_name_req_cancel cp;
+ struct inquiry_entry *e;
int err;
BT_DBG("hci%u", index);
@@ -1958,25 +1960,44 @@ static int stop_discovery(struct sock *sk, u16 index)
hci_dev_lock(hdev);
- if (hdev->discovery.state != DISCOVERY_ACTIVE) {
+ if (!hci_discovery_active(hdev)) {
err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
MGMT_STATUS_REJECTED);
- goto failed;
+ goto unlock;
}
cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
if (!cmd) {
err = -ENOMEM;
- goto failed;
+ goto unlock;
+ }
+
+ if (hdev->discovery.state == DISCOVERY_INQUIRY) {
+ err = hci_cancel_inquiry(hdev);
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+ else
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
+ goto unlock;
+ }
+
+ e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
+ if (!e) {
+ mgmt_pending_remove(cmd);
+ err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, NULL, 0);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ goto unlock;
}
- err = hci_cancel_inquiry(hdev);
+ bacpy(&cp.bdaddr, &e->data.bdaddr);
+ err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
+ sizeof(cp), &cp);
if (err < 0)
mgmt_pending_remove(cmd);
else
hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
-failed:
+unlock:
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -2004,6 +2025,12 @@ static int confirm_name(struct sock *sk, u16 index, unsigned char *data,
hci_dev_lock(hdev);
+ if (!hci_discovery_active(hdev)) {
+ err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
+ MGMT_STATUS_FAILED);
+ goto failed;
+ }
+
e = hci_inquiry_cache_lookup_unknown(hdev, &cp->bdaddr);
if (!e) {
err = cmd_status (sk, index, MGMT_OP_CONFIRM_NAME,
--
1.7.7.3
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PATCH 9/9] Bluetooth: Add name resolving support for mgmt based discovery
2012-01-05 15:16 ` [PATCH 9/9] Bluetooth: Add name resolving support for mgmt based discovery johan.hedberg
@ 2012-01-06 5:54 ` Marcel Holtmann
0 siblings, 0 replies; 22+ messages in thread
From: Marcel Holtmann @ 2012-01-06 5:54 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
Hi Johan,
> This patch adds the necessary logic to perform name lookups after
> inquiry completes. This is done by checking for entries in the resolve
> list after each inquiry complete and remote name complete HCI event.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h | 8 +++-
> net/bluetooth/hci_core.c | 34 +++++++++++++++-
> net/bluetooth/hci_event.c | 81 ++++++++++++++++++++++++++++++++++++--
> net/bluetooth/mgmt.c | 37 +++++++++++++++--
> 4 files changed, 149 insertions(+), 11 deletions(-)
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply [flat|nested] 22+ messages in thread