about summary refs log tree commit diff stats
path: root/src/xmpp/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp/message.c')
-rw-r--r--src/xmpp/message.c109
1 files changed, 95 insertions, 14 deletions
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index a3da01ee..5663dbfc 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -79,60 +79,86 @@ message_add_handlers(void)
     HANDLE(STANZA_NS_CAPTCHA,    NULL,                   _captcha_handler);
 }
 
-void
+char *
 message_send_chat(const char * const barejid, const char * const msg)
 {
-    xmpp_stanza_t *message;
     xmpp_conn_t * const conn = connection_get_conn();
     xmpp_ctx_t * const ctx = connection_get_ctx();
 
     ChatSession *session = chat_session_get(barejid);
+    char *state = NULL;
+    char *jid = NULL;
     if (session) {
-        char *state = NULL;
         if (prefs_get_boolean(PREF_STATES) && session->send_states) {
             state = STANZA_NAME_ACTIVE;
         }
         Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource);
-        message = stanza_create_message(ctx, jidp->fulljid, STANZA_TYPE_CHAT, msg, state, false);
+        jid = strdup(jidp->fulljid);
         jid_destroy(jidp);
+
     } else {
-        char *state = NULL;
         if (prefs_get_boolean(PREF_STATES)) {
             state = STANZA_NAME_ACTIVE;
         }
-        message = stanza_create_message(ctx, barejid, STANZA_TYPE_CHAT, msg, state, false);
+        jid = strdup(barejid);
+    }
+
+    char *id = create_unique_id("msg");
+    xmpp_stanza_t *message = stanza_create_message(ctx, id, jid, STANZA_TYPE_CHAT, msg);
+    free(jid);
+
+    if (state) {
+        stanza_attach_state(ctx, message, state);
+    }
+    if (prefs_get_boolean(PREF_RECEIPTS)) {
+        stanza_attach_receipt_request(ctx, message);
     }
 
     xmpp_send(conn, message);
     xmpp_stanza_release(message);
+
+    return id;
 }
 
-void
+char *
 message_send_chat_encrypted(const char * const barejid, const char * const msg)
 {
-    xmpp_stanza_t *message;
     xmpp_conn_t * const conn = connection_get_conn();
     xmpp_ctx_t * const ctx = connection_get_ctx();
 
     ChatSession *session = chat_session_get(barejid);
+    char *state = NULL;
+    char *jid = NULL;
     if (session) {
-        char *state = NULL;
         if (prefs_get_boolean(PREF_STATES) && session->send_states) {
             state = STANZA_NAME_ACTIVE;
         }
         Jid *jidp = jid_create_from_bare_and_resource(session->barejid, session->resource);
-        message = stanza_create_message(ctx, jidp->fulljid, STANZA_TYPE_CHAT, msg, state, true);
+        jid = strdup(jidp->fulljid);
         jid_destroy(jidp);
     } else {
-        char *state = NULL;
         if (prefs_get_boolean(PREF_STATES)) {
             state = STANZA_NAME_ACTIVE;
         }
-        message = stanza_create_message(ctx, barejid, STANZA_TYPE_CHAT, msg, state, true);
+        jid = strdup(barejid);
+    }
+
+    char *id = create_unique_id("msg");
+    xmpp_stanza_t *message = stanza_create_message(ctx, id, barejid, STANZA_TYPE_CHAT, msg);
+    free(jid);
+
+    if (state) {
+        stanza_attach_state(ctx, message, state);
+    }
+    stanza_attach_carbons_private(ctx, message);
+    if (prefs_get_boolean(PREF_RECEIPTS)) {
+        stanza_attach_receipt_request(ctx, message);
     }
 
     xmpp_send(conn, message);
     xmpp_stanza_release(message);
+
+    return id;
 }
 
 void
@@ -140,7 +166,9 @@ message_send_private(const char * const fulljid, const char * const msg)
 {
     xmpp_conn_t * const conn = connection_get_conn();
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    xmpp_stanza_t *message = stanza_create_message(ctx, fulljid, STANZA_TYPE_CHAT, msg, NULL, false);
+    char *id = create_unique_id("prv");
+    xmpp_stanza_t *message = stanza_create_message(ctx, id, fulljid, STANZA_TYPE_CHAT, msg);
+    free(id);
 
     xmpp_send(conn, message);
     xmpp_stanza_release(message);
@@ -151,7 +179,9 @@ message_send_groupchat(const char * const roomjid, const char * const msg)
 {
     xmpp_conn_t * const conn = connection_get_conn();
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    xmpp_stanza_t *message = stanza_create_message(ctx, roomjid, STANZA_TYPE_GROUPCHAT, msg, NULL, false);
+    char *id = create_unique_id("muc");
+    xmpp_stanza_t *message = stanza_create_message(ctx, id, roomjid, STANZA_TYPE_GROUPCHAT, msg);
+    free(id);
 
     xmpp_send(conn, message);
     xmpp_stanza_release(message);
@@ -441,6 +471,29 @@ _groupchat_handler(xmpp_conn_t * const conn,
     return 1;
 }
 
+void
+_message_send_receipt(const char * const fulljid, const char * const message_id)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *message = xmpp_stanza_new(ctx);
+    char *id = create_unique_id("receipt");
+    xmpp_stanza_set_name(message, STANZA_NAME_MESSAGE);
+    xmpp_stanza_set_id(message, id);
+    xmpp_stanza_set_attribute(message, STANZA_ATTR_TO, fulljid);
+
+    xmpp_stanza_t *receipt = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(receipt, "received");
+    xmpp_stanza_set_ns(receipt, STANZA_NS_RECEIPTS);
+    xmpp_stanza_set_attribute(receipt, STANZA_ATTR_ID, message_id);
+
+    xmpp_stanza_add_child(message, receipt);
+    xmpp_stanza_release(receipt);
+
+    xmpp_send(conn, message);
+    xmpp_stanza_release(message);
+}
+
 static int
 _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     void * const userdata)
@@ -451,6 +504,24 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         return 1;
     }
 
+    // check if message receipt
+    xmpp_stanza_t *receipt = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS);
+    if (receipt) {
+        char *name = xmpp_stanza_get_name(receipt);
+        if (g_strcmp0(name, "received") == 0) {
+            char *id = xmpp_stanza_get_attribute(receipt, STANZA_ATTR_ID);
+            if (id) {
+                char *fulljid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+                if (fulljid) {
+                    Jid *jidp = jid_create(fulljid);
+                    handle_message_receipt(jidp->barejid, id);
+                    jid_destroy(jidp);
+                }
+
+            }
+        }
+    }
+
     // check if carbon message
     xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS);
     if(carbons) {
@@ -538,6 +609,7 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         // determine if the notifications happened whilst offline
         GTimeVal tv_stamp;
         gboolean delayed = stanza_get_delay(stanza, &tv_stamp);
+        char *id = xmpp_stanza_get_id(stanza);
 
         // check for and deal with message
         xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
@@ -549,6 +621,15 @@ _chat_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
                 } else {
                     handle_incoming_message(jid->barejid, jid->resourcepart, message);
                 }
+                if (id) {
+                    xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS);
+                    if (receipts) {
+                        char *receipts_name = xmpp_stanza_get_name(receipts);
+                        if (g_strcmp0(receipts_name, "request") == 0) {
+                            _message_send_receipt(jid->fulljid, id);
+                        }
+                    }
+                }
                 xmpp_free(ctx, message);
             }
         }