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"