diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5c46e6d..5a50ade 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
g_slist_free(channel->notify);
g_slist_free(channel->indicate);
g_slist_free_full(channel->configs, attrib_free);
+ g_attrib_unref(channel->attrib);
g_free(channel);
}
NULL, NULL, NULL);
}
-int attrib_channel_attach(GAttrib *attrib, gboolean out)
+guint attrib_channel_attach(GAttrib *attrib, gboolean out)
{
struct gatt_channel *channel;
GIOChannel *io;
error("bt_io_get: %s", gerr->message);
g_error_free(gerr);
g_free(channel);
- return -EIO;
+ return 0;
}
if (channel->mtu > ATT_MAX_MTU)
clients = g_slist_append(clients, channel);
- return 0;
+ return channel->id;
+}
+
+static gint channel_id_cmp(gconstpointer data, gconstpointer user_data)
+{
+ const struct gatt_channel *channel = data;
+ guint id = GPOINTER_TO_UINT(user_data);
+
+ return channel->id - id;
+}
+
+gboolean attrib_channel_detach(guint id)
+{
+ struct gatt_channel *channel;
+ GSList *l;
+
+ l = g_slist_find_custom(clients, GUINT_TO_POINTER(id),
+ channel_id_cmp);
+ if (!l)
+ return FALSE;
+
+ channel = l->data;
+
+ g_attrib_unregister(channel->attrib, channel->id);
+
+ channel_disconnect(channel);
+
+ return TRUE;
}
static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
diff --git a/src/attrib-server.h b/src/attrib-server.h
index a72347c..943096c 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
uint32_t attrib_create_sdp(uint16_t handle, const char *name);
void attrib_free_sdp(uint32_t sdp_handle);
-int attrib_channel_attach(GAttrib *attrib, gboolean out);
+guint attrib_channel_attach(GAttrib *attrib, gboolean out);
+gboolean attrib_channel_detach(guint id);
diff --git a/src/device.c b/src/device.c
index c19e294..45c4a6a 100644
--- a/src/device.c
+++ b/src/device.c
GAttrib *attrib;
GSList *attios;
GSList *attios_offline;
+ guint attachid; /* Attrib server attach */
guint attioid;
gboolean connected;
att_auto_connect,
device);
+ attrib_channel_detach(device->attachid);
g_attrib_unref(device->attrib);
device->attrib = NULL;
}
device_probe_drivers(device, uuids);
if (device->attios == NULL && device->attios_offline == NULL) {
+ attrib_channel_detach(device->attachid);
g_attrib_unref(device->attrib);
device->attrib = NULL;
} else
}
attrib = g_attrib_new(io);
- if (attrib_channel_attach(attrib, TRUE) < 0)
+ device->attachid = attrib_channel_attach(attrib, TRUE);
+ if (device->attachid == 0)
error("Attribute server attach failure!");
if (req) {
device->attioid = 0;
}
+ if (device->attachid) {
+ attrib_channel_detach(device->attachid);
+ device->attachid = 0;
+ }
+
if (device->attrib) {
g_attrib_unref(device->attrib);
device->attrib = NULL;