Hi,

Please find attached a small patch to enable support for RFC3994 based isComposing status messages. This is the istyping feature that let's you see when the other user is composing a message.

The patch is against the CVS as of a couple of days ago.

Cheers,
Aki
diff -Naur ssip-gst/src/ssip.c ssip-gst-patched/src/ssip.c
--- ssip-gst/src/ssip.c 2005-12-21 16:31:35.000000000 +0200
+++ ssip-gst-patched/src/ssip.c 2005-12-29 01:28:55.000000000 +0200
@@ -127,6 +127,7 @@
 static const char* ssip_list_icon(GaimAccount *account, GaimBuddy *buddy);
 static void ssip_login(GaimAccount *account);
 static GList *ssip_node_menu(GaimBlistNode *node);
+static int ssip_send_typing(GaimConnection *gc, const char *name, int typing);
 static int ssip_send_im(GaimConnection *gc, const char *who,
                             const char *message, GaimConvImFlags flags);
 
@@ -382,21 +383,54 @@
   GaimAccount *account = ssip->s_account;
   GaimConnection *gc = gaim_account_get_connection(account);
   GString *b = NULL;
+  xmlnode *typing;
+  xmlnode *state;
+  xmlnode *refresh;
+  int timeout = 0;
+  
+  if (strncmp(sip->sip_content_type->c_type, "text/plain", 16) == 0) {
 
-  if (strncmp(sip->sip_content_type->c_type, "text/plain", 16) != 0) {
-    /* xxx -- send content type not supported */
-    return;
-  }
+    /* Buddy from url */
+    b = url_as_gstring(sip->sip_from->a_url);
+    serv_got_im(gc, b->str, sip->sip_payload->pl_data, 0, time(NULL));
+    g_string_free(b, FALSE), b = NULL;
 
-  /* Buddy from url */
-  b = url_as_gstring(sip->sip_from->a_url);
-  serv_got_im(gc, b->str, sip->sip_payload->pl_data, 0, time(NULL));
-  g_string_free(b, FALSE), b = NULL;
+    return;
+  } else if (strncmp(sip->sip_content_type->c_type, 
+                    "application/im-iscomposing+xml", 30) == 0) {
 
-  return;
+    /* Parse isComposing indications */
+    typing = xmlnode_from_str(sip->sip_payload->pl_data, 
+                             sip->sip_payload->pl_len);
+      
+    if (typing) {
+      state = xmlnode_get_child(typing, "state");
+      refresh = xmlnode_get_child(typing, "refresh");
+      timeout = refresh ? atoi(xmlnode_get_data(refresh)) : 0;
+      if (state) {
+       b = url_as_gstring(sip->sip_from->a_url);
+       if (strstr(xmlnode_get_data(state), "active"))
+         serv_got_typing(gc, b->str, timeout, GAIM_TYPING);
+       else
+         serv_got_typing_stopped(gc, b->str);
+       g_string_free(b, FALSE), b = NULL;
+      }
+    } 
+    else
+       gaim_debug_misc(__func__, 
+                       "Error parsing isComposing status message.\n");
+    xmlnode_free(typing);
+    return;
+  } else {
+    gaim_debug_misc(__func__, "Received unknown MIME type.\n");
+    
+    /* Sending an error response to an unknown message MIME type */
+    nua_respond(nh, 415, "Unsupported MIME type", TAG_END());
+    
+    return;
+  }
 }
 
-
 /* ====================================================================== */
 void ssip_i_subscription(int status, char const *phrase, nua_t *nua,
                         ssip_t *ssip, nua_handle_t *nh, ssip_oper_t *op,
@@ -1105,6 +1139,44 @@
   }
 }
 
+/* ====================================================================== */
+static int ssip_send_typing(GaimConnection *gc, const char *name, 
+                           int typing) {
+  GaimAccount *account = gc->account;
+  char const *user = gaim_account_get_username(account);
+  ssip_t *ssip = gc->proto_data;
+  ssip_oper_t *op = NULL;
+  char *status;
+
+  op = ssip_oper_create(ssip, SIP_METHOD_MESSAGE, name, TAG_END());
+
+  gaim_debug_misc(__func__, "username: %s\n", user);
+  gaim_debug_misc(__func__, "Sending isComposing status message to %s\n", 
+                 name); 
+
+  /* Create the status message */
+  status = su_sprintf(ssip->s_home,
+                     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                     "<isComposing 
xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\">"
+                     "<state>%s</state>"
+                     "<contenttype>text/plain</contenttype>"
+                     "<refresh>60</refresh>"  
+                     "</isComposing>",
+                     typing == GAIM_TYPING ? "active" : "idle");
+
+  /* FIXME: if the other end returns (had returned previously) 
+     a 415, then we shouldn't send this any longer... */
+  
+  /* Send the isComposing status message using a message handle */
+  nua_message(op->op_handle,
+             SIPTAG_FROM_STR(ssip->s_from),
+             SIPTAG_TO_STR(name),
+             SIPTAG_CONTENT_TYPE_STR("application/im-iscomposing+xml"),
+             SIPTAG_PAYLOAD_STR(status),
+             TAG_END());
+  
+  return 1;
+} 
 
 /* ====================================================================== */
 static int ssip_send_im(GaimConnection *gc, const char *who,
@@ -1466,7 +1538,7 @@
        ssip_close,                             /* close */
        ssip_send_im,                           /* send_im */
        NULL,                                   /* set_info */
-       NULL,                                   /* send_typing */
+       ssip_send_typing,                       /* send_typing */
        NULL,                                   /* get_info */
        NULL, //nullprpl_set_away,              /* set_away */
        NULL,                                   /* set_idle */
diff -Naur ssip-gst/src/ssip_internal.h ssip-gst-patched/src/ssip_internal.h
--- ssip-gst/src/ssip_internal.h        2005-12-21 16:31:35.000000000 +0200
+++ ssip-gst-patched/src/ssip_internal.h        2005-12-29 00:31:24.000000000 
+0200
@@ -37,6 +37,7 @@
 #include "prpl.h"
 #include "accountopt.h"
 #include "notify.h"
+#include "xmlnode.h"
 
 #include "debug.h"
 #include "version.h"

Reply via email to