diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 6cac718..41e2f46 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
GQueue *queue;
GSList *processed;
guint process_id;
+ GDestroyNotify destroy;
};
struct key_pressed {
avctp_browsing_pdu_cb cb;
void *user_data;
unsigned int id;
+ GDestroyNotify destroy;
};
static struct {
if (chan->process_id > 0)
g_source_remove(chan->process_id);
+ if (chan->destroy)
+ chan->destroy(chan);
+
g_free(chan->buffer);
g_queue_foreach(chan->queue, pending_destroy, NULL);
g_queue_free(chan->queue);
}
static struct avctp_channel *avctp_channel_create(struct avctp *session,
- GIOChannel *io)
+ GIOChannel *io,
+ GDestroyNotify destroy)
{
struct avctp_channel *chan;
chan->session = session;
chan->io = g_io_channel_ref(io);
chan->queue = g_queue_new();
+ chan->destroy = destroy;
return chan;
}
+static void handler_free(void *data)
+{
+ struct avctp_browsing_pdu_handler *handler = data;
+
+ if (handler->destroy)
+ handler->destroy(handler->user_data);
+
+ g_free(data);
+}
+
+static void avctp_destroy_browsing(void *data)
+{
+ struct avctp_channel *chan = data;
+
+ g_slist_free_full(chan->handlers, handler_free);
+
+ chan->handlers = NULL;
+}
+
static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
gpointer data)
{
DBG("AVCTP Browsing: connected to %s", address);
if (session->browsing == NULL)
- session->browsing = avctp_channel_create(session, chan);
+ session->browsing = avctp_channel_create(session, chan,
+ avctp_destroy_browsing);
session->browsing->imtu = imtu;
session->browsing->omtu = omtu;
DBG("AVCTP: connected to %s", address);
if (session->control == NULL)
- session->control = avctp_channel_create(session, chan);
+ session->control = avctp_channel_create(session, chan, NULL);
session->control->imtu = imtu;
session->control->omtu = omtu;
}
avctp_set_state(session, AVCTP_STATE_CONNECTING);
- session->control = avctp_channel_create(session, chan);
+ session->control = avctp_channel_create(session, chan, NULL);
src = adapter_get_address(device_get_adapter(dev->btd_dev));
dst = device_get_address(dev->btd_dev);
unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
avctp_browsing_pdu_cb cb,
- void *user_data)
+ void *user_data,
+ GDestroyNotify destroy)
{
struct avctp_channel *browsing = session->browsing;
struct avctp_browsing_pdu_handler *handler;
handler->cb = cb;
handler->user_data = user_data;
handler->id = ++id;
+ handler->destroy = destroy;
browsing->handlers = g_slist_append(browsing->handlers, handler);
return NULL;
}
- session->control = avctp_channel_create(session, io);
+ session->control = avctp_channel_create(session, io, NULL);
g_io_channel_unref(io);
return session;
return -EIO;
}
- session->browsing = avctp_channel_create(session, io);
+ session->browsing = avctp_channel_create(session, io,
+ avctp_destroy_browsing);
g_io_channel_unref(io);
return 0;
diff --git a/profiles/audio/avctp.h b/profiles/audio/avctp.h
index 6cbda92..411b093 100644
--- a/profiles/audio/avctp.h
+++ b/profiles/audio/avctp.h
unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
avctp_browsing_pdu_cb cb,
- void *user_data);
+ void *user_data,
+ GDestroyNotify destroy);
gboolean avctp_unregister_browsing_pdu_handler(unsigned int id);
int avctp_send_passthrough(struct avctp *session, uint8_t op);
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 6b61664..f83c3db 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
return NULL;
}
+static void destroy_browsing(void *data)
+{
+ struct avrcp *session = data;
+
+ session->browsing_id = 0;
+}
+
static void session_tg_init_browsing(struct avrcp *session)
{
session->browsing_id = avctp_register_browsing_pdu_handler(
session->conn,
handle_browsing_pdu,
- session);
+ session,
+ destroy_browsing);
}
static void session_tg_init_control(struct avrcp *session)
session->browsing_id = avctp_register_browsing_pdu_handler(
session->conn,
handle_browsing_pdu,
- session);
+ session,
+ destroy_browsing);
}
static void session_ct_init_control(struct avrcp *session)
break;
case AVCTP_STATE_CONNECTED:
- if (session == NULL)
+ if (session == NULL || session->control_id > 0)
break;
- if (session->browsing_id > 0)
- session->browsing_id = 0;
-
- if (session->control_id > 0)
- return;
-
session->init_control(session);
if (session->version >= 0x0104 &&