changeset 19641:eb0933e158a4

Add non-US SMS support for ICQ. This is a patch from DB42. Fixes #2913. Sweet.
author Mark Doliner <mark@kingant.net>
date Tue, 04 Sep 2007 08:04:06 +0000
parents 1a16d474c459
children c0f503c18f7e
files libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/family_icq.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h
diffstat 4 files changed, 77 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icbm.c	Tue Sep 04 07:20:16 2007 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Tue Sep 04 08:04:06 2007 +0000
@@ -2101,7 +2101,11 @@
 	args.uin = byte_stream_getle32(&meat);
 	args.type = byte_stream_getle8(&meat);
 	args.flags = byte_stream_getle8(&meat);
-	args.msglen = byte_stream_getle16(&meat);
+	if (args.type == 0x1a)
+		/* There seems to be a problem with the length in SMS msgs from server, this fixed it */
+		args.msglen = block->length - 6;
+	else
+		args.msglen = byte_stream_getle16(&meat);
 	args.msg = (gchar *)byte_stream_getraw(&meat, args.msglen);
 
 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
--- a/libpurple/protocols/oscar/family_icq.c	Tue Sep 04 07:20:16 2007 +0000
+++ b/libpurple/protocols/oscar/family_icq.c	Tue Sep 04 08:04:06 2007 +0000
@@ -340,7 +340,6 @@
 }
 #endif
 
-#if 0
 /*
  * Send an SMS message.  This is the non-US way.  The US-way is to IM
  * their cell phone number (+19195551234).
@@ -369,6 +368,7 @@
 	const char *timestr;
 	time_t t;
 	struct tm *tm;
+	gchar *stripped;
 
 	if (!od || !(conn = flap_connection_findbygroup(od, 0x0015)))
 		return -EINVAL;
@@ -380,22 +380,24 @@
 	tm = gmtime(&t);
 	timestr = purple_utf8_strftime("%a, %d %b %Y %T %Z", tm);
 
+	stripped = purple_markup_strip_html(msg);
+
 	/* The length of xml included the null terminating character */
-	xmllen = 225 + strlen(name) + strlen(msg) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
+	xmllen = 209 + strlen(name) + strlen(stripped) + strlen(od->sn) + strlen(alias) + strlen(timestr) + 1;
 
 	xml = g_new(char, xmllen);
-	snprintf(xml, xmllen, "<icq_sms_message>\n"
-		"\t<destination>%s</destination>\n"
-		"\t<text>%s</text>\n"
-		"\t<codepage>1252</codepage>\n"
-		"\t<senders_UIN>%s</senders_UIN>\n"
-		"\t<senders_name>%s</senders_name>\n"
-		"\t<delivery_receipt>Yes</delivery_receipt>\n"
-		"\t<time>%s</time>\n"
-		"</icq_sms_message>\n",
-		name, msg, od->sn, alias, timestr);
+	snprintf(xml, xmllen, "<icq_sms_message>"
+		"<destination>%s</destination>"
+		"<text>%s</text>"
+		"<codepage>1252</codepage>"
+		"<senders_UIN>%s</senders_UIN>"
+		"<senders_name>%s</senders_name>"
+		"<delivery_receipt>Yes</delivery_receipt>"
+		"<time>%s</time>"
+		"</icq_sms_message>",
+		name, stripped, od->sn, alias, timestr);
 
-	bslen = 37 + xmllen;
+	bslen = 36 + xmllen;
 
 	frame = flap_frame_new(od, 0x02, 10 + 4 + bslen);
 
@@ -412,7 +414,7 @@
 	byte_stream_putle16(&frame->data, snacid); /* eh. */
 
 	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
-	byte_stream_putle16(&frame->data, 0x8214);
+	byte_stream_putle16(&frame->data, 0x1482);
 	byte_stream_put16(&frame->data, 0x0001);
 	byte_stream_put16(&frame->data, 0x0016);
 	byte_stream_put32(&frame->data, 0x00000000);
@@ -423,14 +425,15 @@
 	byte_stream_put16(&frame->data, 0x0000);
 	byte_stream_put16(&frame->data, xmllen);
 	byte_stream_putstr(&frame->data, xml);
+	byte_stream_put8(&frame->data, 0x00);
 
 	flap_connection_send(conn, frame);
 
 	g_free(xml);
+	g_free(stripped);
 
 	return 0;
 }
-#endif
 
 static void aim_icq_freeinfo(struct aim_icq_info *info) {
 	int i;
--- a/libpurple/protocols/oscar/oscar.c	Tue Sep 04 07:20:16 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Tue Sep 04 08:04:06 2007 +0000
@@ -2486,8 +2486,48 @@
 			}
 		} break;
 
-		case 0x1a: { /* Someone has sent you a greeting card or requested buddies? */
-			/* This is boring and silly. */
+		case 0x1a: { /* Handle SMS or someone has sent you a greeting card or requested buddies? */
+			ByteStream qbs;
+			int smstype, taglen, smslen;
+			char *tagstr = NULL, *smsmsg = NULL;
+			xmlnode *xmlroot = NULL, *xmltmp = NULL;
+			gchar *uin = NULL, *message = NULL;
+
+			/* From libicq2000-0.3.2/src/ICQ.cpp */
+			byte_stream_init(&qbs, (guint8 *)args->msg, args->msglen);
+			byte_stream_advance(&qbs, 21);
+			smstype = byte_stream_getle16(&qbs);
+			taglen = byte_stream_getle32(&qbs);
+			tagstr = byte_stream_getstr(&qbs, taglen);
+			byte_stream_advance(&qbs, 3);
+			byte_stream_advance(&qbs, 4);
+			smslen = byte_stream_getle32(&qbs);
+			smsmsg = byte_stream_getstr(&qbs, smslen);
+
+			/* Check if this is an SMS being sent from server */
+			if ((smstype == 0) && (!strcmp(tagstr, "ICQSMS")) && (smsmsg != NULL))
+			{
+				xmlroot = xmlnode_from_str(smsmsg, -1);
+				if (xmlroot != NULL)
+				{
+					xmltmp = xmlnode_get_child(xmlroot, "sender");
+					if (xmltmp != NULL)
+						uin = xmlnode_get_data(xmltmp);
+
+					xmltmp = xmlnode_get_child(xmlroot, "text");
+					if (xmltmp != NULL)
+						message = xmlnode_get_data(xmltmp);
+
+					if ((uin != NULL) && (message != NULL))
+							serv_got_im(gc, uin, message, 0, time(NULL));
+
+					g_free(uin);
+					g_free(message);
+					xmlnode_free(xmlroot);
+				}
+			}
+			g_free(tagstr);
+			g_free(smsmsg);
 		} break;
 
 		default: {
@@ -4154,6 +4194,17 @@
 	account = purple_connection_get_account(gc);
 	ret = 0;
 
+	if (od->icq && aim_sn_is_sms(name)) {
+		/*
+		 * We're sending to a phone number and this is ICQ,
+		 * so send the message as an SMS using aim_icq_sendsms()
+		 */
+		int ret;
+		purple_debug_info("oscar", "Sending SMS to %s.\n", name);
+		ret = aim_icq_sendsms(od, name, message, purple_account_get_username(account));
+		return (ret >= 0 ? 1 : ret);
+	}
+
 	if (imflags & PURPLE_MESSAGE_AUTO_RESP)
 		tmp1 = purple_str_sub_away_formatters(message, name);
 	else
--- a/libpurple/protocols/oscar/oscar.h	Tue Sep 04 07:20:16 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Tue Sep 04 08:04:06 2007 +0000
@@ -1320,6 +1320,7 @@
 int aim_icq_getsimpleinfo(OscarData *od, const char *uin);
 int aim_icq_getalias(OscarData *od, const char *uin);
 int aim_icq_getallinfo(OscarData *od, const char *uin);
+int aim_icq_sendsms(OscarData *od, const char *name, const char *msg, const char *alias);