diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-01-04 07:23:45 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-13 10:01:20 -0500 |
commit | ff9ef5787046c3fd20cf9f7ca1cd70260c1eedb9 (patch) | |
tree | ba9d936fd1aa8b3a8f4fe0685b71007f9116f30c /net | |
parent | 30883512be0839349d29c7b0bc31016e0498cf8c (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.c | 25 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 6 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 16 |
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 | |||
359 | void 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 | |||
358 | static void inquiry_cache_flush(struct hci_dev *hdev) | 382 | static 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 | ||
372 | struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) | 397 | 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 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 | ||
1931 | failed: | 1939 | failed: |
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 | ||
1963 | failed: | 1979 | failed: |
1964 | hci_dev_unlock(hdev); | 1980 | hci_dev_unlock(hdev); |