diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2005-11-19 12:12:18 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2005-11-19 12:12:18 +0100 | 
| commit | 3e1de874e95dae74e970c1c574cf64bda28e04f7 (patch) | |
| tree | 04e35820f6c04ba93fb531a95a495fb4f6492350 /protocols | |
| parent | 0b2e8435e67b8c9ad94ebf63455d2285474aa656 (diff) | |
Applied AIM typing notification patch from Hanji.
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/oscar/im.c | 86 | ||||
| -rw-r--r-- | protocols/oscar/im.h | 2 | ||||
| -rw-r--r-- | protocols/oscar/oscar.c | 31 | 
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;  } | 
