Linux bluetooth development
 help / color / mirror / Atom feed
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


  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