diff --git a/src/device.c b/src/device.c
index d356631..e94b222 100644
--- a/src/device.c
+++ b/src/device.c
guint listener_id;
};
+struct included_search {
+ struct browse_req *req;
+ GSList *services;
+ GSList *current;
+};
+
struct attio_data {
guint id;
attio_connect_cb cfunc;
device->services = NULL;
}
-static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+static void register_all_services(struct browse_req *req, GSList *services)
{
- struct browse_req *req = user_data;
struct btd_device *device = req->device;
- if (status) {
- if (req->msg) {
- DBusMessage *reply;
- reply = btd_error_failed(req->msg,
- att_ecode2str(status));
- g_dbus_send_message(btd_get_dbus_connection(), reply);
- }
- goto done;
- }
-
device_set_temporary(device, FALSE);
if (device->services)
store_services(device);
-done:
device->browse = NULL;
browse_request_free(req);
}
+static int service_by_range_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct gatt_primary *prim = a;
+ const struct att_range *range = b;
+
+ return memcmp(&prim->range, range, sizeof(*range));
+}
+
+static void find_included_cb(GSList *includes, uint8_t status,
+ gpointer user_data)
+{
+ struct included_search *search = user_data;
+ struct btd_device *device = search->req->device;
+ struct gatt_primary *prim;
+ GSList *l;
+
+ if (includes == NULL)
+ goto done;
+
+ for (l = includes; l; l = l->next) {
+ struct gatt_included *incl = l->data;
+
+ if (g_slist_find_custom(search->services, &incl->range,
+ service_by_range_cmp))
+ continue;
+
+ prim = g_new0(struct gatt_primary, 1);
+ memcpy(prim->uuid, incl->uuid, sizeof(prim->uuid));
+ memcpy(&prim->range, &incl->range, sizeof(prim->range));
+
+ search->services = g_slist_append(search->services, prim);
+ }
+
+done:
+ search->current = search->current->next;
+ if (search->current == NULL) {
+ register_all_services(search->req, search->services);
+ g_slist_free(search->services);
+ g_free(search);
+ return;
+ }
+
+ prim = search->current->data;
+ gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+ find_included_cb, search);
+}
+
+static void find_included_services(struct browse_req *req, GSList *services)
+{
+ struct btd_device *device = req->device;
+ struct included_search *search;
+ struct gatt_primary *prim;
+
+ if (services == NULL)
+ return;
+
+ search = g_new0(struct included_search, 1);
+ search->req = req;
+ search->services = g_slist_copy(services);
+ search->current = search->services;
+
+ prim = search->current->data;
+ gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+ find_included_cb, search);
+
+}
+
+static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+{
+ struct browse_req *req = user_data;
+
+ if (status) {
+ struct btd_device *device = req->device;
+
+ if (req->msg) {
+ DBusMessage *reply;
+ reply = btd_error_failed(req->msg,
+ att_ecode2str(status));
+ g_dbus_send_message(btd_get_dbus_connection(), reply);
+ }
+
+ device->browse = NULL;
+ browse_request_free(req);
+ return;
+ }
+
+ find_included_services(req, services);
+}
+
static void bonding_request_free(struct bonding_req *bonding)
{
struct btd_device *device;