diff options
author | James Booth <boothj5@gmail.com> | 2013-02-03 20:09:56 +0000 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2013-02-03 20:09:56 +0000 |
commit | 1cea320a0cff2a763a47322283886facfd9c9c29 (patch) | |
tree | 3fa253c81835d809965c9f8a1bcb7abd3004584e | |
parent | 059f3e24784a7a7af4c9b9fe49be7e437c3bb2ed (diff) | |
download | profani-tty-1cea320a0cff2a763a47322283886facfd9c9c29.tar.gz |
Send entity capabilities and status when joining room
-rw-r--r-- | src/config/accounts.c | 3 | ||||
-rw-r--r-- | src/xmpp/presence.c | 184 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 77 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 7 |
4 files changed, 161 insertions, 110 deletions
diff --git a/src/config/accounts.c b/src/config/accounts.c index b94f27c2..c51e01f5 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -428,6 +428,9 @@ accounts_get_priority_for_presence_type(const char * const account_name, result = 0; break; } + + if (result < JABBER_PRIORITY_MIN || result > JABBER_PRIORITY_MAX) + result = 0; return result; } diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 0d50a080..f30a701c 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -43,6 +43,7 @@ static int _presence_handler(xmpp_conn_t * const conn, static char* _handle_presence_caps(xmpp_stanza_t * const stanza); static int _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza); +static const char * _get_presence_stanza_string_from_type(jabber_presence_t presence_type); void presence_init(void) @@ -105,127 +106,27 @@ presence_free_sub_requests(void) } void -presence_join_room(Jid *jid) -{ - xmpp_ctx_t *ctx = jabber_get_ctx(); - xmpp_conn_t *conn = jabber_get_conn(); - xmpp_stanza_t *presence = stanza_create_room_join_presence(ctx, jid->fulljid); - xmpp_send(conn, presence); - xmpp_stanza_release(presence); - - muc_join_room(jid->barejid, jid->resourcepart); -} - -void -presence_change_room_nick(const char * const room, const char * const nick) -{ - xmpp_ctx_t *ctx = jabber_get_ctx(); - xmpp_conn_t *conn = jabber_get_conn(); - char *full_room_jid = create_fulljid(room, nick); - xmpp_stanza_t *presence = stanza_create_room_newnick_presence(ctx, full_room_jid); - xmpp_send(conn, presence); - xmpp_stanza_release(presence); - - free(full_room_jid); -} - -void -presence_leave_chat_room(const char * const room_jid) -{ - xmpp_ctx_t *ctx = jabber_get_ctx(); - xmpp_conn_t *conn = jabber_get_conn(); - char *nick = muc_get_room_nick(room_jid); - - xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, - nick); - xmpp_send(conn, presence); - xmpp_stanza_release(presence); -} - -void presence_update(jabber_presence_t presence_type, const char * const msg, int idle) { xmpp_ctx_t *ctx = jabber_get_ctx(); xmpp_conn_t *conn = jabber_get_conn(); - int pri; - char *show, *last; + int pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), + presence_type); + const char *show = _get_presence_stanza_string_from_type(presence_type); // don't send presence when disconnected if (jabber_get_connection_status() != JABBER_CONNECTED) return; - pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), - presence_type); - if (pri < JABBER_PRIORITY_MIN || pri > JABBER_PRIORITY_MAX) - pri = 0; - jabber_conn_set_presence_type(presence_type); jabber_conn_set_presence_message(msg); jabber_conn_set_priority(pri); - switch(presence_type) - { - case PRESENCE_AWAY: - show = STANZA_TEXT_AWAY; - last = STANZA_TEXT_AWAY; - break; - case PRESENCE_DND: - show = STANZA_TEXT_DND; - last = STANZA_TEXT_DND; - break; - case PRESENCE_CHAT: - show = STANZA_TEXT_CHAT; - last = STANZA_TEXT_CHAT; - break; - case PRESENCE_XA: - show = STANZA_TEXT_XA; - last = STANZA_TEXT_XA; - break; - default: // PRESENCE_ONLINE - show = NULL; - last = STANZA_TEXT_ONLINE; - break; - } - - xmpp_stanza_t *presence = stanza_create_presence(ctx, show, msg); - - // servers must treat no priority as 0 - if (pri != 0) { - xmpp_stanza_t *priority, *value; - char pri_str[10]; - - snprintf(pri_str, sizeof(pri_str), "%d", pri); - priority = xmpp_stanza_new(ctx); - value = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(priority, STANZA_NAME_PRIORITY); - xmpp_stanza_set_text(value, pri_str); - xmpp_stanza_add_child(priority, value); - xmpp_stanza_add_child(presence, priority); - } - - if (idle > 0) { - xmpp_stanza_t *query = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(query, STANZA_NAME_QUERY); - xmpp_stanza_set_ns(query, STANZA_NS_LASTACTIVITY); - char idle_str[10]; - snprintf(idle_str, sizeof(idle_str), "%d", idle); - xmpp_stanza_set_attribute(query, STANZA_ATTR_SECONDS, idle_str); - xmpp_stanza_add_child(presence, query); - } - - // add caps - xmpp_stanza_t *caps = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(caps, STANZA_NAME_C); - xmpp_stanza_set_ns(caps, STANZA_NS_CAPS); - xmpp_stanza_t *query = caps_create_query_response_stanza(ctx); - - char *sha1 = caps_create_sha1_str(query); - xmpp_stanza_set_attribute(caps, STANZA_ATTR_HASH, "sha-1"); - xmpp_stanza_set_attribute(caps, STANZA_ATTR_NODE, "http://www.profanity.im"); - xmpp_stanza_set_attribute(caps, STANZA_ATTR_VER, sha1); - xmpp_stanza_add_child(presence, caps); + stanza_attach_priority(ctx, presence, pri); + stanza_attach_last_activity(ctx, presence, idle); + stanza_attach_caps(ctx, presence); xmpp_send(conn, presence); @@ -245,12 +146,62 @@ presence_update(jabber_presence_t presence_type, const char * const msg, xmpp_stanza_release(presence); - FREE_SET_NULL(sha1); - // set last presence for account + const char *last = show; + if (last == NULL) { + last = STANZA_TEXT_ONLINE; + } accounts_set_last_presence(jabber_get_account_name(), last); } +void +presence_join_room(Jid *jid) +{ + xmpp_ctx_t *ctx = jabber_get_ctx(); + xmpp_conn_t *conn = jabber_get_conn(); + jabber_presence_t presence_type = jabber_get_presence_type(); + const char *show = _get_presence_stanza_string_from_type(presence_type); + char *status = jabber_get_presence_message(); + int pri = accounts_get_priority_for_presence_type(jabber_get_account_name(), + presence_type); + + xmpp_stanza_t *presence = stanza_create_room_join_presence(ctx, jid->fulljid, show, status); + stanza_attach_priority(ctx, presence, pri); + stanza_attach_caps(ctx, presence); + + xmpp_send(conn, presence); + xmpp_stanza_release(presence); + + muc_join_room(jid->barejid, jid->resourcepart); +} + +void +presence_change_room_nick(const char * const room, const char * const nick) +{ + xmpp_ctx_t *ctx = jabber_get_ctx(); + xmpp_conn_t *conn = jabber_get_conn(); + char *full_room_jid = create_fulljid(room, nick); + xmpp_stanza_t *presence = stanza_create_room_newnick_presence(ctx, full_room_jid); + xmpp_send(conn, presence); + xmpp_stanza_release(presence); + + free(full_room_jid); +} + +void +presence_leave_chat_room(const char * const room_jid) +{ + xmpp_ctx_t *ctx = jabber_get_ctx(); + xmpp_conn_t *conn = jabber_get_conn(); + char *nick = muc_get_room_nick(room_jid); + + xmpp_stanza_t *presence = stanza_create_room_leave_presence(ctx, room_jid, + nick); + xmpp_send(conn, presence); + xmpp_stanza_release(presence); +} + + static int _presence_handler(xmpp_conn_t * const conn, @@ -513,3 +464,20 @@ _room_presence_handler(const char * const jid, xmpp_stanza_t * const stanza) return 1; } +static const char * +_get_presence_stanza_string_from_type(jabber_presence_t presence_type) +{ + switch(presence_type) + { + case PRESENCE_AWAY: + return STANZA_TEXT_AWAY; + case PRESENCE_DND: + return STANZA_TEXT_DND; + case PRESENCE_CHAT: + return STANZA_TEXT_CHAT; + case PRESENCE_XA: + return STANZA_TEXT_XA; + default: // PRESENCE_ONLINE + return NULL; + } +} diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 5b0aab3f..5a19a576 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -28,6 +28,7 @@ #include "common.h" #include "xmpp/stanza.h" +#include "xmpp/capabilities.h" static int _field_compare(FormField *f1, FormField *f2); @@ -86,7 +87,8 @@ stanza_create_message(xmpp_ctx_t *ctx, const char * const recipient, xmpp_stanza_t * stanza_create_room_join_presence(xmpp_ctx_t *ctx, - const char * const full_room_jid) + const char * const full_room_jid, const char * const show, + const char * const status) { xmpp_stanza_t *presence = xmpp_stanza_new(ctx); xmpp_stanza_set_name(presence, STANZA_NAME_PRESENCE); @@ -98,6 +100,28 @@ stanza_create_room_join_presence(xmpp_ctx_t *ctx, xmpp_stanza_add_child(presence, x); + if (show != NULL) { + xmpp_stanza_t *show_stanza = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(show_stanza, STANZA_NAME_SHOW); + xmpp_stanza_t *text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(text, show); + xmpp_stanza_add_child(show_stanza, text); + xmpp_stanza_add_child(presence, show_stanza); + xmpp_stanza_release(text); + xmpp_stanza_release(show_stanza); + } + + if (status != NULL) { + xmpp_stanza_t *status_stanza = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(status_stanza, STANZA_NAME_STATUS); + xmpp_stanza_t *text = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(text, status); + xmpp_stanza_add_child(status_stanza, text); + xmpp_stanza_add_child(presence, status_stanza); + xmpp_stanza_release(text); + xmpp_stanza_release(status_stanza); + } + return presence; } @@ -601,6 +625,57 @@ stanza_destroy_form(DataForm *form) } } +void +stanza_attach_priority(xmpp_ctx_t *ctx, xmpp_stanza_t *presence, int pri) +{ + if (pri != 0) { + xmpp_stanza_t *priority, *value; + char pri_str[10]; + + snprintf(pri_str, sizeof(pri_str), "%d", pri); + priority = xmpp_stanza_new(ctx); + value = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(priority, STANZA_NAME_PRIORITY); + xmpp_stanza_set_text(value, pri_str); + xmpp_stanza_add_child(priority, value); + xmpp_stanza_add_child(presence, priority); + xmpp_stanza_release(priority); + } +} + +void +stanza_attach_last_activity(xmpp_ctx_t *ctx, xmpp_stanza_t *presence, int idle) +{ + if (idle > 0) { + xmpp_stanza_t *query = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(query, STANZA_NAME_QUERY); + xmpp_stanza_set_ns(query, STANZA_NS_LASTACTIVITY); + char idle_str[10]; + snprintf(idle_str, sizeof(idle_str), "%d", idle); + xmpp_stanza_set_attribute(query, STANZA_ATTR_SECONDS, idle_str); + xmpp_stanza_add_child(presence, query); + xmpp_stanza_release(query); + } +} + +void +stanza_attach_caps(xmpp_ctx_t *ctx, xmpp_stanza_t *presence) +{ + xmpp_stanza_t *caps = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(caps, STANZA_NAME_C); + xmpp_stanza_set_ns(caps, STANZA_NS_CAPS); + xmpp_stanza_t *query = caps_create_query_response_stanza(ctx); + + char *sha1 = caps_create_sha1_str(query); + xmpp_stanza_set_attribute(caps, STANZA_ATTR_HASH, "sha-1"); + xmpp_stanza_set_attribute(caps, STANZA_ATTR_NODE, "http://www.profanity.im"); + xmpp_stanza_set_attribute(caps, STANZA_ATTR_VER, sha1); + xmpp_stanza_add_child(presence, caps); + xmpp_stanza_release(caps); + xmpp_stanza_release(query); + FREE_SET_NULL(sha1); +} + static int _field_compare(FormField *f1, FormField *f2) { diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index ab5f79a5..f3d25cb2 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -112,7 +112,8 @@ xmpp_stanza_t* stanza_create_message(xmpp_ctx_t *ctx, const char * const message, const char * const state); xmpp_stanza_t* stanza_create_room_join_presence(xmpp_ctx_t *ctx, - const char * const full_room_jid); + const char * const full_room_jid, const char * const show, + const char * const status); xmpp_stanza_t* stanza_create_room_newnick_presence(xmpp_ctx_t *ctx, const char * const full_room_jid); @@ -149,4 +150,8 @@ gboolean stanza_is_version_request(xmpp_stanza_t * const stanza); DataForm * stanza_create_form(xmpp_stanza_t * const stanza); void stanza_destroy_form(DataForm *form); +void stanza_attach_priority(xmpp_ctx_t *ctx, xmpp_stanza_t *presence, int pri); +void stanza_attach_last_activity(xmpp_ctx_t *ctx, xmpp_stanza_t *presence, int idle); +void stanza_attach_caps(xmpp_ctx_t *ctx, xmpp_stanza_t *presence); + #endif |