diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-07-05 22:51:32 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-12-04 22:21:59 +0100 |
commit | 3f41b8b20107bbd3413ee13570f0a2559ebdbb1e (patch) | |
tree | 8a249796d8ae07f56e5b3b48be6954c9f7154953 /gobex/gobex.c | |
parent | 6cfe881554ba2f7e5e1dd8cef8277a297ef90dba (diff) | |
download | bluez-3f41b8b20107bbd3413ee13570f0a2559ebdbb1e.tar.gz |
gobex: Add per-opcode request handlers
Diffstat (limited to 'gobex/gobex.c')
-rw-r--r-- | gobex/gobex.c | 64 |
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); |