attrib-server: Remove GAttrib disconnect callback

This patch replaces the usage of GAttrib disconnection callback by
GIOChannel watch to track ATTIO channel disconnection aiming to achieve
less dependencies between attrib server, device and GAttrib.
This commit is contained in:
Claudio Takahasi 2012-02-09 12:56:06 -03:00 committed by Johan Hedberg
parent 9dde2d5703
commit 4e751d06bc
3 changed files with 21 additions and 13 deletions

View File

@ -75,6 +75,7 @@ struct gatt_channel {
guint id;
gboolean encrypted;
struct gatt_server *server;
guint cleanup_id;
};
struct group_elem {
@ -107,8 +108,11 @@ static void attrib_free(void *data)
static void channel_free(struct gatt_channel *channel)
{
g_attrib_unref(channel->attrib);
if (channel->cleanup_id)
g_source_remove(channel->cleanup_id);
g_attrib_unref(channel->attrib);
g_free(channel);
}
@ -859,15 +863,21 @@ static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
return enc_mtu_resp(old_mtu, pdu, len);
}
static void channel_disconnect(void *user_data)
static void channel_remove(struct gatt_channel *channel)
{
struct gatt_channel *channel = user_data;
channel->server->clients = g_slist_remove(channel->server->clients,
channel);
channel_free(channel);
}
static gboolean channel_watch_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
channel_remove(user_data);
return FALSE;
}
static void channel_handler(const uint8_t *ipdu, uint16_t len,
gpointer user_data)
{
@ -992,7 +1002,7 @@ done:
NULL, NULL, NULL);
}
guint attrib_channel_attach(GAttrib *attrib, gboolean out)
guint attrib_channel_attach(GAttrib *attrib)
{
struct gatt_server *server;
struct btd_device *device;
@ -1050,9 +1060,8 @@ guint attrib_channel_attach(GAttrib *attrib, gboolean out)
channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_REQS,
channel_handler, channel, NULL);
if (out == FALSE)
g_attrib_set_disconnect_function(channel->attrib,
channel_disconnect, channel);
channel->cleanup_id = g_io_add_watch(io, G_IO_HUP, channel_watch_cb,
channel);
server->clients = g_slist_append(server->clients, channel);
@ -1099,8 +1108,7 @@ gboolean attrib_channel_detach(GAttrib *attrib, guint id)
channel = l->data;
g_attrib_unregister(channel->attrib, channel->id);
channel_disconnect(channel);
channel_remove(channel);
return TRUE;
}
@ -1115,7 +1123,7 @@ static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
}
attrib = g_attrib_new(io);
attrib_channel_attach(attrib, FALSE);
attrib_channel_attach(attrib);
g_io_channel_unref(io);
g_attrib_unref(attrib);
}

View File

@ -36,5 +36,5 @@ int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid,
uint32_t attrib_create_sdp(struct btd_adapter *adapter, uint16_t handle,
const char *name);
void attrib_free_sdp(uint32_t sdp_handle);
guint attrib_channel_attach(GAttrib *attrib, gboolean out);
guint attrib_channel_attach(GAttrib *attrib);
gboolean attrib_channel_detach(GAttrib *attrib, guint id);

View File

@ -1839,7 +1839,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
}
attrib = g_attrib_new(io);
device->attachid = attrib_channel_attach(attrib, TRUE);
device->attachid = attrib_channel_attach(attrib);
if (device->attachid == 0)
error("Attribute server attach failure!");