From e3feacddd6667fd8e111d0ee54846c6aeabe3a7d Mon Sep 17 00:00:00 2001 From: Olivier LE MOAL Date: Mon, 2 Feb 2015 11:10:05 +0100 Subject: [PATCH] Add XEP-0280 support --- src/server_events.c | 5 +++++ src/server_events.h | 1 + src/xmpp/connection.c | 1 + src/xmpp/iq.c | 10 ++++++++++ src/xmpp/message.c | 38 ++++++++++++++++++++++++++++++++++++++ src/xmpp/stanza.c | 18 ++++++++++++++++++ src/xmpp/stanza.h | 5 +++++ src/xmpp/xmpp.h | 1 + 8 files changed, 79 insertions(+) diff --git a/src/server_events.c b/src/server_events.c index fbf534ac..bf880a9d 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -296,6 +296,11 @@ handle_incoming_private_message(char *fulljid, char *message) ui_incoming_private_msg(fulljid, message, NULL); } +void +handle_carbon(char *barejid, char *message){ + ui_outgoing_chat_msg("me", barejid, message); +} + void handle_incoming_message(char *barejid, char *resource, char *message) { diff --git a/src/server_events.h b/src/server_events.h index 6a12dc6e..3ec6a332 100644 --- a/src/server_events.h +++ b/src/server_events.h @@ -101,6 +101,7 @@ void handle_group_remove(const char * const contact, void handle_roster_remove(const char * const barejid); void handle_roster_add(const char * const barejid, const char * const name); void handle_autoping_cancel(void); +void handle_carbon(char *barejid, char *message); void handle_message_error(const char * const from, const char * const type, const char * const err_msg); void handle_presence_error(const char *from, const char * const type, diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 915525e4..8bb7c74c 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -463,6 +463,7 @@ _connection_handler(xmpp_conn_t * const conn, message_add_handlers(); presence_add_handlers(); iq_add_handlers(); + iq_enable_carbons(); roster_request(); bookmark_request(); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 7fedf0ed..071b07c5 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -152,6 +152,16 @@ iq_room_list_request(gchar *conferencejid) xmpp_stanza_release(iq); } +void +iq_enable_carbons() +{ + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_enable_carbons(ctx); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); +} + void iq_disco_info_request(gchar *jid) { diff --git a/src/xmpp/message.c b/src/xmpp/message.c index e96c1a74..4f341f6a 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -423,6 +423,44 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } + // check if carbon message + xmpp_stanza_t *received = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); + if(received != NULL){ + xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(received, STANZA_NS_FORWARD); + xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE); + + xmpp_ctx_t *ctx = connection_get_ctx(); + + gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO); + gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM); + + Jid *jid_from = jid_create(from); + Jid *jid_to = jid_create(to); + Jid *my_jid = jid_create(jabber_get_fulljid()); + + // check for and deal with message + xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY); + if (body != NULL) { + char *message = xmpp_stanza_get_text(body); + if (message != NULL) { + // if we are the recipient, treat as standard incoming message + if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){ + handle_incoming_message(jid_from->barejid, jid_from->resourcepart, message); + } + // else treat as a sent message + else{ + handle_carbon(jid_to->barejid, message); + } + xmpp_free(ctx, message); + } + } + + jid_destroy(jid_from); + jid_destroy(jid_to); + jid_destroy(my_jid); + return 1; + } + // ignore handled namespaces xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 4f1d412d..06177800 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -198,6 +198,24 @@ stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char * const jid, } #endif +xmpp_stanza_t * +stanza_enable_carbons(xmpp_ctx_t *ctx){ + xmpp_stanza_t *iq = xmpp_stanza_new(ctx); + char *id = create_unique_id(NULL); + + xmpp_stanza_set_name(iq, STANZA_NAME_IQ); + xmpp_stanza_set_type(iq, STANZA_TYPE_SET); + xmpp_stanza_set_id(iq, id); + + xmpp_stanza_t *carbon_enable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(carbon_enable, STANZA_NAME_ENABLE); + xmpp_stanza_set_ns(carbon_enable, STANZA_NS_CARBONS); + + xmpp_stanza_add_child(iq, carbon_enable); + + return iq; +} + xmpp_stanza_t * stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state) { diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 84282401..0c5a2b01 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -77,6 +77,7 @@ #define STANZA_NAME_VALUE "value" #define STANZA_NAME_DESTROY "destroy" #define STANZA_NAME_ACTOR "actor" +#define STANZA_NAME_ENABLE "enable" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -154,6 +155,8 @@ #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_CARBONS "urn:xmpp:carbons:2" +#define STANZA_NS_FORWARD "urn:xmpp:forward:0" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" @@ -178,6 +181,8 @@ typedef enum { xmpp_stanza_t* stanza_create_bookmarks_storage_request(xmpp_ctx_t *ctx); +xmpp_stanza_t * stanza_enable_carbons(xmpp_ctx_t *ctx); + xmpp_stanza_t* stanza_create_chat_state(xmpp_ctx_t *ctx, const char * const fulljid, const char * const state); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index a004a4bf..41355e30 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -172,6 +172,7 @@ void presence_update(resource_presence_t status, const char * const msg, gboolean presence_sub_request_exists(const char * const bare_jid); // iq functions +void iq_enable_carbons(); void iq_send_software_version(const char * const fulljid); void iq_room_list_request(gchar *conferencejid); void iq_disco_info_request(gchar *jid);