[RFC BlueZ v0 05/10] device: Use only one entry point for LE connections

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Until now, two functions were used for establishing LE connections,
device_connect_le() and device_browse_primary().

This commit changes the behaviour of device_browse_primary() to expect the
conenction to be already established, and if not to call device_connect_le().
This simplification allows for the 'att_callbacks' mechanism to be removed.
---
 src/device.c | 178 +++++++++++++++++------------------------------------------
 1 file changed, 50 insertions(+), 128 deletions(-)

diff --git a/src/device.c b/src/device.c
index bfc60fa..f2abcff 100644
--- a/src/device.c
+++ b/src/device.c
@@ -141,12 +141,6 @@ struct svc_callback {
 typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
 typedef void (*attio_success_cb) (gpointer user_data);
 
-struct att_callbacks {
-	attio_error_cb error;		/* Callback for error */
-	attio_success_cb success;	/* Callback for success */
-	gpointer user_data;
-};
-
 struct btd_device {
 	int ref_count;
 
@@ -214,8 +208,7 @@ static const uint16_t uuid_list[] = {
 	0
 };
 
-static int device_browse_primary(struct btd_device *device, DBusMessage *msg,
-							gboolean secure);
+static int device_browse_primary(struct btd_device *device, DBusMessage *msg);
 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg,
 							gboolean reverse);
 static void device_svc_resolved(struct btd_device *dev, DBusMessage *msg,
@@ -1185,7 +1178,7 @@ static int device_resolve_svc(struct btd_device *dev, DBusMessage *msg)
 	if (device_is_bredr(dev))
 		return device_browse_sdp(dev, msg, FALSE);
 	else
-		return device_browse_primary(dev, msg, FALSE);
+		return device_browse_primary(dev, msg);
 }
 
 static struct btd_profile *find_connectable_profile(struct btd_device *dev,
@@ -2838,14 +2831,14 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 						DEVICE_INTERFACE, "UUIDs");
 
 send_reply:
-	/* Browse has finished, some profiles may use device->browse to check
-	 * if browsing is still ongoing, so we mark it as finished, and free
+	/* Browse has finished, some code may use device->browse to check if
+	 * browsing is still ongoing, so we mark it as finished, and free
 	 * it later
 	 */
 	device->browse = NULL;
 
 	device_svc_resolved(device, req->msg, err);
-	req->msg = NULL; /* The reply was sent above */
+	req->msg = NULL; /* The reply was just sent */
 
 	if (!device->temporary)
 		store_device_info(device);
@@ -3173,10 +3166,35 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	find_included_services(device, services);
 }
 
+static void att_connect_error(struct btd_device *device, const GError *gerr)
+{
+	if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
+		return;
+
+	if (device_get_auto_connect(device)) {
+		DBG("Enabling automatic connections");
+		adapter_connect_list_add(device->adapter, device);
+	}
+}
+
+static void att_connect_success(struct btd_device *device)
+{
+	if (device->attios == NULL)
+		return;
+
+	/*
+	 * Remove the device from the connect_list and give the passive
+	 * scanning another chance to be restarted in case there are
+	 * other devices in the connect_list.
+	 */
+	adapter_connect_list_remove(device->adapter, device);
+
+	g_slist_foreach(device->attios, attio_connected, device->attrib);
+}
+
 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
-	struct att_callbacks *attcb = user_data;
-	struct btd_device *device = attcb->user_data;
+	struct btd_device *device = user_data;
 	DBusMessage *reply;
 	uint8_t io_cap;
 	GAttrib *attrib;
@@ -3188,8 +3206,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	if (gerr) {
 		DBG("%s", gerr->message);
 
-		if (attcb->error)
-			attcb->error(gerr, attcb->user_data);
+		att_connect_error(device, gerr);
 
 		err = -ECONNABORTED;
 		goto done;
@@ -3204,8 +3221,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	device->cleanup_id = g_io_add_watch(io, G_IO_HUP,
 					attrib_disconnected_cb, device);
 
-	if (attcb->success)
-		attcb->success(user_data);
+	att_connect_success(device);
 
 	if (!device->bonding)
 		goto done;
@@ -3225,10 +3241,12 @@ done:
 		bonding_request_free(device->bonding);
 	}
 
-	if (device->connect) {
-		if (!device->svc_resolved)
-			device_browse_primary(device, NULL, FALSE);
+	/* The connection was caused by a device_browse_primary() */
+	if (device->gatt_discov)
+		gatt_discover_primary(device->attrib, NULL, primary_cb,
+						btd_device_ref(device));
 
+	if (device->connect) {
 		if (err < 0)
 			reply = btd_error_failed(device->connect,
 							strerror(-err));
@@ -3239,45 +3257,11 @@ done:
 		dbus_message_unref(device->connect);
 		device->connect = NULL;
 	}
-
-	g_free(attcb);
-}
-
-static void att_error_cb(const GError *gerr, gpointer user_data)
-{
-	struct btd_device *device = user_data;
-
-	if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
-		return;
-
-	if (device_get_auto_connect(device)) {
-		DBG("Enabling automatic connections");
-		adapter_connect_list_add(device->adapter, device);
-	}
-}
-
-static void att_success_cb(gpointer user_data)
-{
-	struct att_callbacks *attcb = user_data;
-	struct btd_device *device = attcb->user_data;
-
-	if (device->attios == NULL)
-		return;
-
-	/*
-	 * Remove the device from the connect_list and give the passive
-	 * scanning another chance to be restarted in case there are
-	 * other devices in the connect_list.
-	 */
-	adapter_connect_list_remove(device->adapter, device);
-
-	g_slist_foreach(device->attios, attio_connected, device->attrib);
 }
 
 int device_connect_le(struct btd_device *dev)
 {
 	struct btd_adapter *adapter = dev->adapter;
-	struct att_callbacks *attcb;
 	BtIOSecLevel sec_level;
 	GIOChannel *io;
 	GError *gerr = NULL;
@@ -3291,11 +3275,6 @@ int device_connect_le(struct btd_device *dev)
 
 	DBG("Connection attempt to: %s", addr);
 
-	attcb = g_new0(struct att_callbacks, 1);
-	attcb->error = att_error_cb;
-	attcb->success = att_success_cb;
-	attcb->user_data = dev;
-
 	if (dev->paired)
 		sec_level = BT_IO_SEC_MEDIUM;
 	else
@@ -3305,7 +3284,7 @@ int device_connect_le(struct btd_device *dev)
 	 * This connection will help us catch any PDUs that comes before
 	 * pairing finishes
 	 */
-	io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
+	io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
 			BT_IO_OPT_SOURCE_BDADDR, adapter_get_address(adapter),
 			BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
 			BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
@@ -3325,7 +3304,6 @@ int device_connect_le(struct btd_device *dev)
 
 		error("ATT bt_io_connect(%s): %s", addr, gerr->message);
 		g_error_free(gerr);
-		g_free(attcb);
 		return -EIO;
 	}
 
@@ -3335,78 +3313,16 @@ int device_connect_le(struct btd_device *dev)
 	return 0;
 }
 
-static void att_browse_error_cb(const GError *gerr, gpointer user_data)
-{
-	struct btd_device *device = user_data;
-	struct gatt_discovery *disc = device->gatt_discov;
-
-	if (disc->msg) {
-		DBusMessage *reply;
-
-		reply = btd_error_failed(disc->msg, gerr->message);
-		g_dbus_send_message(dbus_conn, reply);
-	}
-
-	device->gatt_discov = NULL;
-	gatt_discovery_free(disc);
-}
-
-static void att_browse_cb(gpointer user_data)
-{
-	struct att_callbacks *attcb = user_data;
-	struct btd_device *device = attcb->user_data;
-
-	gatt_discover_primary(device->attrib, NULL, primary_cb,
-							device->browse);
-}
-
-static int device_browse_primary(struct btd_device *device, DBusMessage *msg,
-								gboolean secure)
+static int device_browse_primary(struct btd_device *device, DBusMessage *msg)
 {
-	struct btd_adapter *adapter = device->adapter;
-	struct att_callbacks *attcb;
 	struct gatt_discovery *disc;
-	BtIOSecLevel sec_level;
 
 	if (device->gatt_discov)
 		return -EBUSY;
 
 	disc = g_new0(struct gatt_discovery, 1);
-
 	device->gatt_discov = disc;
 
-	if (device->attrib) {
-		gatt_discover_primary(device->attrib, NULL, primary_cb,
-						btd_device_ref(device));
-		goto done;
-	}
-
-	sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
-
-	attcb = g_new0(struct att_callbacks, 1);
-	attcb->error = att_browse_error_cb;
-	attcb->success = att_browse_cb;
-	attcb->user_data = device;
-
-	device->att_io = bt_io_connect(att_connect_cb,
-				attcb, NULL, NULL,
-				BT_IO_OPT_SOURCE_BDADDR,
-				adapter_get_address(adapter),
-				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
-				BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
-				BT_IO_OPT_CID, ATT_CID,
-				BT_IO_OPT_SEC_LEVEL, sec_level,
-				BT_IO_OPT_INVALID);
-
-	if (device->att_io == NULL) {
-		gatt_discovery_free(disc);
-		device->gatt_discov = NULL;
-		g_free(attcb);
-		return -EIO;
-	}
-
-done:
-
 	if (msg) {
 		const char *sender = dbus_message_get_sender(msg);
 
@@ -3418,6 +3334,12 @@ done:
 					device, NULL);
 	}
 
+	if (device->attrib == NULL)
+		return device_connect_le(device);
+
+	gatt_discover_primary(device->attrib, NULL, primary_cb,
+						btd_device_ref(device));
+
 	return 0;
 }
 
@@ -3615,7 +3537,7 @@ static gboolean start_discovery(gpointer user_data)
 	if (device_is_bredr(device))
 		device_browse_sdp(device, NULL, TRUE);
 	else
-		device_browse_primary(device, NULL, FALSE);
+		device_browse_primary(device, NULL);
 
 	device->discov_timer = 0;
 
@@ -3685,7 +3607,7 @@ void device_bonding_complete(struct btd_device *device, uint8_t status)
 		if (device_is_bredr(device))
 			device_browse_sdp(device, bonding->msg, FALSE);
 		else
-			device_browse_primary(device, bonding->msg, FALSE);
+			device_browse_primary(device, bonding->msg);
 
 		bonding_request_free(bonding);
 	} else if (!device->svc_resolved) {
@@ -4109,7 +4031,7 @@ void btd_device_gatt_set_service_changed(struct btd_device *device,
 			prim->changed = TRUE;
 	}
 
-	device_browse_primary(device, NULL, FALSE);
+	device_browse_primary(device, NULL);
 }
 
 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
-- 
1.8.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux