aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-01-04 07:23:45 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:20 -0500
commitff9ef5787046c3fd20cf9f7ca1cd70260c1eedb9 (patch)
treeba9d936fd1aa8b3a8f4fe0685b71007f9116f30c /net
parent30883512be0839349d29c7b0bc31016e0498cf8c (diff)
Bluetooth: Add discovery state tracking
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> Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c25
-rw-r--r--net/bluetooth/hci_event.c6
-rw-r--r--net/bluetooth/mgmt.c16
3 files changed, 44 insertions, 3 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 55509b0a810a..b68719230601 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)
355} 355}
356 356
357/* ---- Inquiry support ---- */ 357/* ---- Inquiry support ---- */
358
359void hci_discovery_set_state(struct hci_dev *hdev, int state)
360{
361 BT_DBG("%s state %u -> %u", hdev->name, hdev->discovery.state, state);
362
363 if (hdev->discovery.state == state)
364 return;
365
366 switch (state) {
367 case DISCOVERY_STOPPED:
368 mgmt_discovering(hdev, 0);
369 break;
370 case DISCOVERY_STARTING:
371 break;
372 case DISCOVERY_ACTIVE:
373 mgmt_discovering(hdev, 1);
374 break;
375 case DISCOVERY_STOPPING:
376 break;
377 }
378
379 hdev->discovery.state = state;
380}
381
358static void inquiry_cache_flush(struct hci_dev *hdev) 382static void inquiry_cache_flush(struct hci_dev *hdev)
359{ 383{
360 struct discovery_state *cache = &hdev->discovery; 384 struct discovery_state *cache = &hdev->discovery;
@@ -367,6 +391,7 @@ static void inquiry_cache_flush(struct hci_dev *hdev)
367 391
368 INIT_LIST_HEAD(&cache->unknown); 392 INIT_LIST_HEAD(&cache->unknown);
369 INIT_LIST_HEAD(&cache->resolve); 393 INIT_LIST_HEAD(&cache->resolve);
394 cache->state = DISCOVERY_STOPPED;
370} 395}
371 396
372struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 397struct 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 d4d20df9fbbf..43d69569a0d5 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)
65 clear_bit(HCI_INQUIRY, &hdev->flags); 65 clear_bit(HCI_INQUIRY, &hdev->flags);
66 66
67 hci_dev_lock(hdev); 67 hci_dev_lock(hdev);
68 mgmt_discovering(hdev, 0); 68 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
69 hci_dev_unlock(hdev); 69 hci_dev_unlock(hdev);
70 70
71 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); 71 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)
1119 set_bit(HCI_INQUIRY, &hdev->flags); 1119 set_bit(HCI_INQUIRY, &hdev->flags);
1120 1120
1121 hci_dev_lock(hdev); 1121 hci_dev_lock(hdev);
1122 mgmt_discovering(hdev, 1); 1122 hci_discovery_set_state(hdev, DISCOVERY_ACTIVE);
1123 hci_dev_unlock(hdev); 1123 hci_dev_unlock(hdev);
1124} 1124}
1125 1125
@@ -1507,7 +1507,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
1507 return; 1507 return;
1508 1508
1509 hci_dev_lock(hdev); 1509 hci_dev_lock(hdev);
1510 mgmt_discovering(hdev, 0); 1510 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1511 hci_dev_unlock(hdev); 1511 hci_dev_unlock(hdev);
1512} 1512}
1513 1513
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 894f11bc571d..590966ddfa63 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1918,6 +1918,12 @@ static int start_discovery(struct sock *sk, u16 index,
1918 goto failed; 1918 goto failed;
1919 } 1919 }
1920 1920
1921 if (hdev->discovery.state != DISCOVERY_STOPPED) {
1922 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1923 MGMT_STATUS_BUSY);
1924 goto failed;
1925 }
1926
1921 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0); 1927 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
1922 if (!cmd) { 1928 if (!cmd) {
1923 err = -ENOMEM; 1929 err = -ENOMEM;
@@ -1927,6 +1933,8 @@ static int start_discovery(struct sock *sk, u16 index,
1927 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); 1933 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
1928 if (err < 0) 1934 if (err < 0)
1929 mgmt_pending_remove(cmd); 1935 mgmt_pending_remove(cmd);
1936 else
1937 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
1930 1938
1931failed: 1939failed:
1932 hci_dev_unlock(hdev); 1940 hci_dev_unlock(hdev);
@@ -1950,6 +1958,12 @@ static int stop_discovery(struct sock *sk, u16 index)
1950 1958
1951 hci_dev_lock(hdev); 1959 hci_dev_lock(hdev);
1952 1960
1961 if (hdev->discovery.state != DISCOVERY_ACTIVE) {
1962 err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
1963 MGMT_STATUS_REJECTED);
1964 goto failed;
1965 }
1966
1953 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); 1967 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
1954 if (!cmd) { 1968 if (!cmd) {
1955 err = -ENOMEM; 1969 err = -ENOMEM;
@@ -1959,6 +1973,8 @@ static int stop_discovery(struct sock *sk, u16 index)
1959 err = hci_cancel_inquiry(hdev); 1973 err = hci_cancel_inquiry(hdev);
1960 if (err < 0) 1974 if (err < 0)
1961 mgmt_pending_remove(cmd); 1975 mgmt_pending_remove(cmd);
1976 else
1977 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
1962 1978
1963failed: 1979failed:
1964 hci_dev_unlock(hdev); 1980 hci_dev_unlock(hdev);