aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2005-11-19 12:12:18 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2005-11-19 12:12:18 +0100
commit3e1de874e95dae74e970c1c574cf64bda28e04f7 (patch)
tree04e35820f6c04ba93fb531a95a495fb4f6492350
parent0b2e8435e67b8c9ad94ebf63455d2285474aa656 (diff)
Applied AIM typing notification patch from Hanji.
-rw-r--r--protocols/oscar/im.c86
-rw-r--r--protocols/oscar/im.h2
-rw-r--r--protocols/oscar/oscar.c31
3 files changed, 118 insertions, 1 deletions
diff --git a/protocols/oscar/im.c b/protocols/oscar/im.c
index 99661846..4ceb0716 100644
--- a/protocols/oscar/im.c
+++ b/protocols/oscar/im.c
@@ -1995,6 +1995,90 @@ static int msgack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_m
return ret;
}
+/*
+ * Subtype 0x0014 - Send a mini typing notification (mtn) packet.
+ *
+ * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer,
+ * and Gaim 0.60 and newer.
+ *
+ */
+int aim_im_sendmtn(aim_session_t *sess, guint16 type1, const char *sn, guint16 type2)
+{
+ aim_conn_t *conn;
+ aim_frame_t *fr;
+ aim_snacid_t snacid;
+
+ if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002)))
+ return -EINVAL;
+
+ if (!sn)
+ return -EINVAL;
+
+ if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+11+strlen(sn)+2)))
+ return -ENOMEM;
+
+ snacid = aim_cachesnac(sess, 0x0004, 0x0014, 0x0000, NULL, 0);
+ aim_putsnac(&fr->data, 0x0004, 0x0014, 0x0000, snacid);
+
+ /*
+ * 8 days of light
+ * Er, that is to say, 8 bytes of 0's
+ */
+ aimbs_put16(&fr->data, 0x0000);
+ aimbs_put16(&fr->data, 0x0000);
+ aimbs_put16(&fr->data, 0x0000);
+ aimbs_put16(&fr->data, 0x0000);
+
+ /*
+ * Type 1 (should be 0x0001 for mtn)
+ */
+ aimbs_put16(&fr->data, type1);
+
+ /*
+ * Dest sn
+ */
+ aimbs_put8(&fr->data, strlen(sn));
+ aimbs_putraw(&fr->data, sn, strlen(sn));
+
+ /*
+ * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn)
+ */
+ aimbs_put16(&fr->data, type2);
+
+ aim_tx_enqueue(sess, fr);
+
+ return 0;
+}
+
+/*
+ * Subtype 0x0014 - Receive a mini typing notification (mtn) packet.
+ *
+ * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer,
+ * and Gaim 0.60 and newer.
+ *
+ */
+static int mtn_receive(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
+{
+ int ret = 0;
+ aim_rxcallback_t userfunc;
+ char *sn;
+ guint8 snlen;
+ guint16 type1, type2;
+
+ aim_bstream_advance(bs, 8); /* Unknown - All 0's */
+ type1 = aimbs_get16(bs);
+ snlen = aimbs_get8(bs);
+ sn = aimbs_getstr(bs, snlen);
+ type2 = aimbs_get16(bs);
+
+ if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
+ ret = userfunc(sess, rx, type1, sn, type2);
+
+ g_free(sn);
+
+ return ret;
+}
+
static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{
@@ -2010,6 +2094,8 @@ static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx,
return clientautoresp(sess, mod, rx, snac, bs);
else if (snac->subtype == 0x000c)
return msgack(sess, mod, rx, snac, bs);
+ else if (snac->subtype == 0x0014)
+ return mtn_receive(sess, mod, rx, snac, bs);
return 0;
}
diff --git a/protocols/oscar/im.h b/protocols/oscar/im.h
index 061ff5b5..42a8a6b1 100644
--- a/protocols/oscar/im.h
+++ b/protocols/oscar/im.h
@@ -13,6 +13,7 @@
#define AIM_CB_MSG_MISSEDCALL 0x000a
#define AIM_CB_MSG_CLIENTAUTORESP 0x000b
#define AIM_CB_MSG_ACK 0x000c
+#define AIM_CB_MSG_MTN 0x0014
#define AIM_CB_MSG_DEFAULT 0xffff
#define AIM_IMFLAGS_AWAY 0x0001 /* mark as an autoreply */
@@ -193,6 +194,7 @@ aim_conn_t *aim_directim_initiate(aim_session_t *, const char *destsn);
aim_conn_t *aim_directim_connect(aim_session_t *, const char *sn, const char *addr, const guint8 *cookie);
int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type);
+int aim_im_sendmtn(aim_session_t *sess, guint16 type1, const char *sn, guint16 type2);
int aim_send_im_ch2_statusmessage(aim_session_t *sess, const char *sender, const guint8 *cookie, const char *message, const guint8 state, const guint16 dc);
#endif /* __OSCAR_IM_H__ */
diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c
index 160d23ea..5dda3e90 100644
--- a/protocols/oscar/oscar.c
+++ b/protocols/oscar/oscar.c
@@ -220,7 +220,7 @@ static int gaim_offlinemsgdone (aim_session_t *, aim_frame_t *, ...);
static int gaim_ssi_parserights (aim_session_t *, aim_frame_t *, ...);
static int gaim_ssi_parselist (aim_session_t *, aim_frame_t *, ...);
static int gaim_ssi_parseack (aim_session_t *, aim_frame_t *, ...);
-
+static int gaim_parsemtn (aim_session_t *, aim_frame_t *, ...);
static int gaim_icqinfo (aim_session_t *, aim_frame_t *, ...);
static int gaim_parseaiminfo (aim_session_t *, aim_frame_t *, ...);
@@ -557,6 +557,7 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) {
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST, gaim_ssi_parselist, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK, gaim_ssi_parseack, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0);
+ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0);
((struct oscar_data *)gc->proto_data)->conn = bosconn;
for (i = 0; i < (int)strlen(info->bosip); i++) {
@@ -1677,6 +1678,7 @@ static int gaim_icbm_param_info(aim_session_t *sess, aim_frame_t *fr, ...) {
va_end(ap);
/* Maybe senderwarn and recverwarn should be user preferences... */
+ params->flags = 0x0000000b;
params->maxmsglen = 8000;
params->minmsginterval = 0;
@@ -2434,6 +2436,25 @@ static int gaim_parseaiminfo(aim_session_t *sess, aim_frame_t *fr, ...)
return 1;
}
+int gaim_parsemtn(aim_session_t *sess, aim_frame_t *fr, ...)
+{
+ struct gaim_connection * gc = sess->aux_data;
+ va_list ap;
+ guint16 type1, type2;
+ char * sn;
+
+ va_start(ap, fr);
+ type1 = va_arg(ap, int);
+ sn = va_arg(ap, char*);
+ type2 = va_arg(ap, int);
+ va_end(ap);
+
+ if(type2 == 0x0001 || type2 == 0x0002)
+ serv_got_typing(gc, sn, 0);
+
+ return 1;
+}
+
static char *oscar_get_status_string( struct gaim_connection *gc, int number )
{
struct oscar_data *od = gc->proto_data;
@@ -2462,6 +2483,12 @@ static char *oscar_get_status_string( struct gaim_connection *gc, int number )
}
}
+int oscar_send_typing(struct gaim_connection *gc, char * who, int typing)
+{
+ struct oscar_data *od = gc->proto_data;
+ return( aim_im_sendmtn(od->sess, 1, who, typing ? 0x0002 : 0x0000) );
+}
+
static struct prpl *my_protocol = NULL;
void oscar_init(struct prpl *ret) {
@@ -2484,5 +2511,7 @@ void oscar_init(struct prpl *ret) {
ret->cmp_buddynames = aim_sncmp;
ret->get_status_string = oscar_get_status_string;
+ ret->send_typing = oscar_send_typing;
+
my_protocol = ret;
}