Implement cancel primary discovery session
Extend bt_cancel_discovery function to cancel an ongoing Discover
All Primary Services procedure.
diff --git a/src/device.c b/src/device.c
index cec2153..d20a6d4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -186,8 +186,7 @@
adapter_get_address(adapter, &src);
- if (device->type != DEVICE_TYPE_LE)
- bt_cancel_discovery(&src, &device->bdaddr);
+ bt_cancel_discovery(&src, &device->bdaddr);
device->browse = NULL;
browse_request_free(req);
@@ -1530,11 +1529,11 @@
goto done;
}
- services_changed(req->device);
- device_set_temporary(req->device, FALSE);
- device_probe_drivers(req->device, services);
+ services_changed(device);
+ device_set_temporary(device, FALSE);
+ device_probe_drivers(device, services);
- create_device_reply(req->device, req);
+ create_device_reply(device, req);
done:
device->browse = NULL;
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 8181f4d..6505249 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -51,12 +51,15 @@
bdaddr_t src;
bdaddr_t dst;
GAttrib *attrib;
+ GIOChannel *io;
bt_primary_t cb;
bt_destroy_t destroy;
gpointer user_data;
GSList *uuids;
};
+static GSList *gattrib_list = NULL;
+
struct cached_sdp_session {
bdaddr_t src;
bdaddr_t dst;
@@ -68,12 +71,18 @@
static void gattrib_context_free(struct gattrib_context *ctxt)
{
+ gattrib_list = g_slist_remove(gattrib_list, ctxt);
if (ctxt->destroy)
ctxt->destroy(ctxt->user_data);
g_slist_foreach(ctxt->uuids, (GFunc) g_free, NULL);
g_slist_free(ctxt->uuids);
g_attrib_unref(ctxt->attrib);
+ if (ctxt->io) {
+ g_io_channel_unref(ctxt->io);
+ g_io_channel_shutdown(ctxt->io, FALSE, NULL);
+ }
+
g_free(ctxt);
}
@@ -138,7 +147,6 @@
bdaddr_t dst;
sdp_session_t *session;
bt_callback_t cb;
- bt_primary_t prim_cb;
bt_destroy_t destroy;
gpointer user_data;
uuid_t uuid;
@@ -373,21 +381,16 @@
bacmp(&ctxt->src, &search->src));
}
-int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+static gint gattrib_find_by_bdaddr(gconstpointer data, gconstpointer user_data)
{
- struct search_context search, *ctxt;
- GSList *match;
+ const struct gattrib_context *ctxt = data, *search = user_data;
- memset(&search, 0, sizeof(search));
- bacpy(&search.src, src);
- bacpy(&search.dst, dst);
+ return (bacmp(&ctxt->dst, &search->dst) &&
+ bacmp(&ctxt->src, &search->src));
+}
- /* Ongoing SDP Discovery */
- match = g_slist_find_custom(context_list, &search, find_by_bdaddr);
- if (!match)
- return -ENODATA;
-
- ctxt = match->data;
+static int cancel_sdp(struct search_context *ctxt)
+{
if (!ctxt->session)
return -ENOTCONN;
@@ -398,9 +401,48 @@
sdp_close(ctxt->session);
search_context_cleanup(ctxt);
+
return 0;
}
+static int cancel_gattrib(struct gattrib_context *ctxt)
+{
+ if (ctxt->attrib)
+ g_attrib_cancel_all(ctxt->attrib);
+
+ gattrib_context_free(ctxt);
+
+ return 0;
+}
+
+int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ struct search_context sdp_ctxt;
+ struct gattrib_context gatt_ctxt;
+ GSList *match;
+
+ memset(&sdp_ctxt, 0, sizeof(sdp_ctxt));
+ bacpy(&sdp_ctxt.src, src);
+ bacpy(&sdp_ctxt.dst, dst);
+
+ /* Ongoing SDP Discovery */
+ match = g_slist_find_custom(context_list, &sdp_ctxt, find_by_bdaddr);
+ if (match)
+ return cancel_sdp(match->data);
+
+ memset(&gatt_ctxt, 0, sizeof(gatt_ctxt));
+ bacpy(&gatt_ctxt.src, src);
+ bacpy(&gatt_ctxt.dst, dst);
+
+ /* Ongoing Discover All Primary Services */
+ match = g_slist_find_custom(gattrib_list, &gatt_ctxt,
+ gattrib_find_by_bdaddr);
+ if (match == NULL)
+ return -ENOTCONN;
+
+ return cancel_gattrib(match->data);
+}
+
static void primary_cb(guint8 status, const guint8 *pdu, guint16 plen,
gpointer user_data)
{
@@ -471,6 +513,7 @@
return;
}
+ ctxt->attrib = g_attrib_new(io);
gatt_discover_primary(ctxt->attrib, 0x0001, 0xffff, NULL, primary_cb,
ctxt);
}
@@ -513,9 +556,9 @@
return -EIO;
}
- ctxt->attrib = g_attrib_new(io);
+ ctxt->io = io;
- g_io_channel_unref(io);
+ gattrib_list = g_slist_append(gattrib_list, ctxt);
return 0;
}