diff options
-rw-r--r-- | src/xmpp/message.c | 60 | ||||
-rw-r--r-- | src/xmpp/message.h | 4 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 1 |
3 files changed, 65 insertions, 0 deletions
diff --git a/src/xmpp/message.c b/src/xmpp/message.c index adea5c10..8240402d 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -62,6 +62,12 @@ #include "xmpp/connection.h" #include "xmpp/xmpp.h" +typedef struct p_message_handle_t { + ProfMessageCallback func; + ProfMessageFreeCallback free_func; + void *userdata; +} ProfMessageHandler; + static int _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static void _handle_error(xmpp_stanza_t *const stanza); @@ -70,10 +76,13 @@ static void _handel_muc_user(xmpp_stanza_t *const stanza); static void _handle_conference(xmpp_stanza_t *const stanza); static void _handle_captcha(xmpp_stanza_t *const stanza); static void _handle_receipt_received(xmpp_stanza_t *const stanza); +static void _handle_pubsub_event(xmpp_stanza_t *const stanza); static void _handle_chat(xmpp_stanza_t *const stanza); static void _send_message_stanza(xmpp_stanza_t *const stanza); +static GHashTable *pubsub_event_handlers; + static int _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { @@ -118,6 +127,11 @@ _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *con _handle_receipt_received(stanza); } + xmpp_stanza_t *event = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_PUBSUB_EVENT); + if (event) { + _handle_pubsub_event(event); + } + _handle_chat(stanza); return 1; @@ -129,6 +143,33 @@ message_handlers_init(void) xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); xmpp_handler_add(conn, _message_handler, NULL, STANZA_NAME_MESSAGE, NULL, ctx); + + if (pubsub_event_handlers) { + GList *keys = g_hash_table_get_keys(pubsub_event_handlers); + GList *curr = keys; + while (curr) { + ProfMessageHandler *handler = g_hash_table_lookup(pubsub_event_handlers, curr->data); + if (handler->free_func && handler->userdata) { + handler->free_func(handler->userdata); + } + curr = g_list_next(curr); + } + g_list_free(keys); + g_hash_table_destroy(pubsub_event_handlers); + } + + pubsub_event_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); +} + +void +message_pubsub_event_handler_add(const char *const node, ProfMessageCallback func, ProfMessageFreeCallback free_func, void *userdata) +{ + ProfMessageHandler *handler = malloc(sizeof(ProfMessageHandler)); + handler->func = func; + handler->free_func = free_func; + handler->userdata = userdata; + + g_hash_table_insert(pubsub_event_handlers, strdup(node), handler); } char* @@ -624,6 +665,25 @@ _handle_receipt_received(xmpp_stanza_t *const stanza) jid_destroy(jidp); } +static void +_handle_pubsub_event(xmpp_stanza_t *const event) +{ + xmpp_stanza_t *child = xmpp_stanza_get_children(event); + if (child) { + const char *node = xmpp_stanza_get_attribute(event, STANZA_ATTR_NODE); + if (node) { + ProfMessageHandler *handler = g_hash_table_lookup(pubsub_event_handlers, node); + if (handler) { + int keep = handler->func(event, handler->userdata); + if (!keep) { + free(handler); + g_hash_table_remove(pubsub_event_handlers, node); + } + } + } + } +} + void _receipt_request_handler(xmpp_stanza_t *const stanza) { diff --git a/src/xmpp/message.h b/src/xmpp/message.h index dee9be2d..0c81ca39 100644 --- a/src/xmpp/message.h +++ b/src/xmpp/message.h @@ -35,6 +35,10 @@ #ifndef XMPP_MESSAGE_H #define XMPP_MESSAGE_H +typedef int(*ProfMessageCallback)(xmpp_stanza_t *const stanza, void *const userdata); +typedef void(*ProfMessageFreeCallback)(void *userdata); + void message_handlers_init(void); +void message_pubsub_event_handler_add(const char *const node, ProfMessageCallback func, ProfMessageFreeCallback free_func, void *userdata); #endif diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 9cca027d..df9c27ff 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -180,6 +180,7 @@ #define STANZA_NS_CONFERENCE "jabber:x:conference" #define STANZA_NS_CAPTCHA "urn:xmpp:captcha" #define STANZA_NS_PUBSUB "http://jabber.org/protocol/pubsub" +#define STANZA_NS_PUBSUB_EVENT "http://jabber.org/protocol/pubsub#event" #define STANZA_NS_CARBONS "urn:xmpp:carbons:2" #define STANZA_NS_HINTS "urn:xmpp:hints" #define STANZA_NS_FORWARD "urn:xmpp:forward:0" |