about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/config/accounts.c3
-rw-r--r--src/xmpp/presence.c184
-rw-r--r--src/xmpp/stanza.c77
-rw-r--r--src/xmpp/stanza.h7
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