From: Andre Guedes <andre.guedes@openbossa.org>
To: linux-bluetooth@vger.kernel.org
Cc: Andre Guedes <andre.guedes@openbossa.org>
Subject: [RFC 11/16] Implement start_discovery hciops callback
Date: Fri, 29 Apr 2011 21:27:27 -0300 [thread overview]
Message-ID: <1304123252-14464-12-git-send-email-andre.guedes@openbossa.org> (raw)
In-Reply-To: <1304123252-14464-1-git-send-email-andre.guedes@openbossa.org>
---
plugins/hciops.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 965e9de..23e8915 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -56,11 +56,26 @@
#define DISCOV_INQ 1
#define DISCOV_SCAN 2
+#define TIMEOUT_BR_LE_SCAN 5120 /* TGAP(100)/2 */
+#define TIMEOUT_LE_SCAN 10240 /* TGAP(gen_disc_scan_min) */
+
+#define LENGTH_BR_INQ 0x08
+#define LENGTH_BR_LE_INQ 0x04
+
+static int hciops_start_scanning(int index, int timeout);
+
static int child_pipe[2] = { -1, -1 };
static guint child_io_id = 0;
static guint ctl_io_id = 0;
+enum adapter_type {
+ BR_EDR,
+ LE_ONLY,
+ BR_EDR_LE,
+ UNKNOWN,
+};
+
/* Commands sent by kernel on starting an adapter */
enum {
PENDING_BDADDR,
@@ -151,27 +166,74 @@ static inline int get_state(int index)
return dev->discov_state;
}
+static inline gboolean is_resolvname_enabled(void)
+{
+ return main_opts.name_resolv ? TRUE : FALSE;
+}
+
static void set_state(int index, int state)
{
+ struct btd_adapter *adapter;
struct dev_info *dev = &devs[index];
if (dev->discov_state == state)
return;
+ adapter = manager_find_adapter_by_id(index);
+ if (!adapter) {
+ error("No matching adapter found");
+ return;
+ }
+
dev->discov_state = state;
DBG("hci%d: new state %d", index, dev->discov_state);
switch (dev->discov_state) {
case DISCOV_HALTED:
+ if (adapter_get_state(adapter) == STATE_SUSPENDED)
+ return;
+
+ if (is_resolvname_enabled() &&
+ adapter_has_discov_sessions(adapter))
+ adapter_set_state(adapter, STATE_RESOLVNAME);
+ else
+ adapter_set_state(adapter, STATE_IDLE);
break;
case DISCOV_INQ:
- break;
case DISCOV_SCAN:
+ adapter_set_state(adapter, STATE_DISCOV);
break;
}
}
+static inline gboolean is_le_capable(int index)
+{
+ struct dev_info *dev = &devs[index];
+
+ return (main_opts.le && dev->features[4] & LMP_LE &&
+ dev->extfeatures[0] & LMP_HOST_LE) ? TRUE : FALSE;
+}
+
+static inline gboolean is_bredr_capable(int index)
+{
+ struct dev_info *dev = &devs[index];
+
+ return (dev->features[4] & LMP_NO_BREDR) == 0 ? TRUE : FALSE;
+}
+
+static int get_adapter_type(int index)
+{
+ if (is_le_capable(index) && is_bredr_capable(index))
+ return BR_EDR_LE;
+ else if (is_le_capable(index))
+ return LE_ONLY;
+ else if (is_bredr_capable(index))
+ return BR_EDR;
+
+ return UNKNOWN;
+}
+
static int ignore_device(struct hci_dev_info *di)
{
return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR;
@@ -1831,12 +1893,30 @@ static void read_local_oob_data_complete(int index, uint8_t status,
static inline void inquiry_complete_evt(int index, uint8_t status)
{
+ int adapter_type;
+ struct btd_adapter *adapter;
+
if (status) {
error("Inquiry Failed with status 0x%02x", status);
return;
}
- set_state(index, DISCOV_HALTED);
+ adapter = manager_find_adapter_by_id(index);
+ if (!adapter) {
+ error("No matching adapter found");
+ return;
+ }
+
+ adapter_type = get_adapter_type(index);
+
+ if (adapter_type == BR_EDR_LE &&
+ adapter_has_discov_sessions(adapter)) {
+ int err = hciops_start_scanning(index, TIMEOUT_BR_LE_SCAN);
+ if (err < 0)
+ set_state(index, DISCOV_HALTED);
+ } else {
+ set_state(index, DISCOV_HALTED);
+ }
}
static inline void cc_inquiry_cancel(int index, uint8_t status)
@@ -3159,8 +3239,18 @@ static int hciops_cancel_resolve_name(int index, bdaddr_t *bdaddr)
static int hciops_start_discovery(int index)
{
- DBG("index %d", index);
- return -ENOSYS;
+ int adapter_type = get_adapter_type(index);
+
+ switch (adapter_type) {
+ case BR_EDR_LE:
+ return hciops_start_inquiry(index, LENGTH_BR_LE_INQ, FALSE);
+ case BR_EDR:
+ return hciops_start_inquiry(index, LENGTH_BR_INQ, FALSE);
+ case LE_ONLY:
+ return hciops_start_scanning(index, TIMEOUT_LE_SCAN);
+ default:
+ return -EINVAL;
+ }
}
static int hciops_stop_discovery(int index)
--
1.7.1
next prev parent reply other threads:[~2011-04-30 0:27 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-30 0:27 [RFC 00/16] Discovery procedure refactoring Andre Guedes
2011-04-30 0:27 ` [RFC 01/16] Add discovery callbacks to btd_adapter_ops Andre Guedes
2011-04-30 0:27 ` [RFC 02/16] Replace inquiry/scanning calls by discovery calls Andre Guedes
2011-04-30 0:27 ` [RFC 03/16] Add 'discov_state' field to struct dev_info Andre Guedes
2011-04-30 0:27 ` [RFC 04/16] Code cleanup event.c Andre Guedes
2011-04-30 0:27 ` [RFC 05/16] Remove Periodic Inquiry support in hciops Andre Guedes
2011-05-02 7:38 ` Luiz Augusto von Dentz
2011-05-02 22:35 ` Andre Guedes
2011-04-30 0:27 ` [RFC 06/16] Change DiscoverSchedulerInterval default value Andre Guedes
2011-05-02 7:48 ` Luiz Augusto von Dentz
2011-05-02 22:37 ` Andre Guedes
2011-04-30 0:27 ` [RFC 07/16] Add 'timeout' param to start_scanning callback Andre Guedes
2011-04-30 0:27 ` [RFC 08/16] Refactoring adapter_set_state() Andre Guedes
2011-04-30 0:27 ` [RFC 09/16] Remove 'suspend' param from stop_discovery() Andre Guedes
2011-05-02 8:42 ` Luiz Augusto von Dentz
2011-05-02 22:38 ` Andre Guedes
2011-04-30 0:27 ` [RFC 10/16] Add extfeatures to struct dev_info Andre Guedes
2011-04-30 0:27 ` Andre Guedes [this message]
2011-04-30 0:27 ` [RFC 12/16] Remove obsolete code Andre Guedes
2011-04-30 0:27 ` [RFC 13/16] Implement stop_discovery hciops callback Andre Guedes
2011-04-30 0:27 ` [RFC 14/16] Implement mgmt start and stop discovery Andre Guedes
2011-04-30 0:27 ` [RFC 15/16] Remove inquiry and scanning callbacks from btd_adapter_ops Andre Guedes
2011-04-30 0:27 ` [RFC 16/16] Remove 'periodic' param from hciops_start_inquiry() Andre Guedes
2011-05-02 8:39 ` [RFC 00/16] Discovery procedure refactoring Luiz Augusto von Dentz
2011-05-02 14:01 ` Anderson Lizardo
2011-05-02 22:32 ` Andre Guedes
2011-05-05 8:26 ` Johan Hedberg
2011-05-10 14:03 ` Andre Guedes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1304123252-14464-12-git-send-email-andre.guedes@openbossa.org \
--to=andre.guedes@openbossa.org \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox