summaryrefslogtreecommitdiff
path: root/gobex/gobex.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2011-07-05 22:51:32 +0300
committerMarcel Holtmann <marcel@holtmann.org>2012-12-04 22:21:59 +0100
commit3f41b8b20107bbd3413ee13570f0a2559ebdbb1e (patch)
tree8a249796d8ae07f56e5b3b48be6954c9f7154953 /gobex/gobex.c
parent6cfe881554ba2f7e5e1dd8cef8277a297ef90dba (diff)
downloadbluez-3f41b8b20107bbd3413ee13570f0a2559ebdbb1e.tar.gz
gobex: Add per-opcode request handlers
Diffstat (limited to 'gobex/gobex.c')
-rw-r--r--gobex/gobex.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/gobex/gobex.c b/gobex/gobex.c
index 1b0b67ff5..1c74ec0ca 100644
--- a/gobex/gobex.c
+++ b/gobex/gobex.c
@@ -65,6 +65,8 @@ struct _GObex {
GQueue *tx_queue;
+ GSList *req_handlers;
+
GObexRequestFunc req_func;
gpointer req_func_data;
@@ -85,6 +87,12 @@ struct pending_pkt {
gboolean cancelled;
};
+struct req_handler {
+ guint8 opcode;
+ GObexRequestFunc func;
+ gpointer user_data;
+};
+
struct connect_data {
guint8 version;
guint8 flags;
@@ -481,6 +489,39 @@ void g_obex_set_disconnect_function(GObex *obex, GObexFunc func,
obex->disconn_func_data = user_data;
}
+gint g_obex_add_request_function(GObex *obex, guint8 opcode,
+ GObexRequestFunc func,
+ gpointer user_data)
+{
+ struct req_handler *handler;
+
+ handler = g_new0(struct req_handler, 1);
+ handler->opcode = opcode;
+ handler->func = func;
+ handler->user_data = user_data;
+
+ obex->req_handlers = g_slist_prepend(obex->req_handlers, handler);
+
+ return GPOINTER_TO_INT(handler);
+}
+
+gboolean g_obex_remove_request_function(GObex *obex, gint id)
+{
+ struct req_handler *handler;
+ GSList *match;
+
+ match = g_slist_find(obex->req_handlers, GINT_TO_POINTER(id));
+ if (match == NULL)
+ return FALSE;
+
+ handler = match->data;
+
+ obex->req_handlers = g_slist_delete_link(obex->req_handlers, match);
+ g_free(handler);
+
+ return TRUE;
+}
+
static void parse_connect_data(GObex *obex, GObexPacket *pkt)
{
const struct connect_data *data;
@@ -538,11 +579,32 @@ static void handle_response(GObex *obex, GError *err, GObexPacket *rsp)
enable_tx(obex);
}
+static gint req_handler_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct req_handler *handler = a;
+ const guint8 *opcode = b;
+
+ return (gint) handler->opcode - (gint) *opcode;
+}
+
static void handle_request(GObex *obex, GObexPacket *req)
{
+ GSList *match;
+ guint8 opcode;
+
if (g_obex_packet_get_operation(req, NULL) == G_OBEX_OP_CONNECT)
parse_connect_data(obex, req);
+ opcode = g_obex_packet_get_operation(req, NULL);
+
+ match = g_slist_find_custom(obex->req_handlers, &opcode,
+ req_handler_cmp);
+ if (match) {
+ struct req_handler *handler = match->data;
+ handler->func(obex, req, handler->user_data);
+ return;
+ }
+
if (obex->req_func)
obex->req_func(obex, req, obex->req_func_data);
}
@@ -795,6 +857,8 @@ void g_obex_unref(GObex *obex)
if (!last_ref)
return;
+ g_slist_free_full(obex->req_handlers, g_free);
+
g_queue_foreach(obex->tx_queue, (GFunc) pending_pkt_free, NULL);
g_queue_free(obex->tx_queue);