diff -udr gateway/gw/shared.c patched/gw/shared.c
--- gateway/gw/shared.c	Fri Dec 28 01:00:33 2001
+++ patched/gw/shared.c	Tue Jan 15 18:32:42 2002
@@ -245,6 +245,38 @@
     return part;
 }
 
+static Octstr *extract_msgdata_part_by_coding(Msg *msg, Octstr *split_chars,
+											  int max_part_len)
+{
+	Octstr* tempData = NULL;
+	int pos, esc_count;
+
+	if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2)
+	{	/* nothing to do here, just call the original extract_msgdata_part */
+		return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len);
+	}
+
+	/* else we need to do something special. I'll just get charset_gsm_truncate to 
+	   cut the string to the required length and then count real characters. */
+	
+	tempData = octstr_duplicate(msg->sms.msgdata);
+	charset_latin1_to_gsm(tempData);
+	charset_gsm_truncate(tempData,max_part_len);
+	
+	pos = esc_count = 0;
+
+	while ((pos = octstr_search_char(tempData,27,pos)) != -1)
+	{
+		++pos;
+		++esc_count;
+	}
+
+	octstr_destroy(tempData);
+
+	/* now just call the original extract_msgdata_part with the new length*/
+	return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len - esc_count);
+}
+
 
 List *sms_split(Msg *orig, Octstr *header, Octstr *footer, 
 		       Octstr *nonlast_suffix, Octstr *split_chars, 
@@ -256,6 +288,7 @@
     List *list;
     Msg *part;
     Octstr *msgdata;
+    Msg *tempOrig;
 
     hf_len = octstr_len(header) + octstr_len(footer);
     nlsuf_len = octstr_len(nonlast_suffix);
@@ -266,7 +299,7 @@
 	max_part_len = max_octets - udh_len - hf_len;
     else
 	max_part_len = max_octets * 8 / 7 - (udh_len * 8 + 6) / 7 - hf_len;
-    if (octstr_len(orig->sms.msgdata) > max_part_len && catenate) {
+    if (sms_msgdata_len(orig) > max_part_len && catenate) {
 	/* Change part length to take concatenation overhead into account */
 	if (udh_len == 0)
 	    udh_len = 1;  /* To add the udh total length octet */
@@ -277,7 +310,10 @@
 	    max_part_len = max_octets * 8 / 7 - (udh_len * 8 + 6) / 7 - hf_len;
     }
 
+    /*
     msgdata = octstr_duplicate(orig->sms.msgdata);
+    */
+    tempOrig = msg_duplicate(orig);
     msgno = 0;
     list = list_create();
     do {
@@ -291,12 +327,12 @@
            part->sms.dlr_mask = 0;
         }
 	octstr_destroy(part->sms.msgdata);
-	if (octstr_len(msgdata) <= max_part_len || msgno == max_messages) {
-	    part->sms.msgdata = octstr_copy(msgdata, 0, max_part_len);
+	if (sms_msgdata_len(tempOrig) <= max_part_len || msgno == max_messages) {
+	    part->sms.msgdata = octstr_copy(tempOrig->sms.msgdata, 0, max_part_len);
 	    last = 1;
 	}
 	else {
-	    part->sms.msgdata = extract_msgdata_part(msgdata, split_chars,
+	    part->sms.msgdata = extract_msgdata_part_by_coding(tempOrig, split_chars,
 						     max_part_len - nlsuf_len);
 	    last = 0;
 	}
@@ -309,7 +345,10 @@
 	list_append(list, part);
     } while (!last);
     total_messages = msgno;
+    /*
     octstr_destroy(msgdata);
+    */
+    msg_destroy(tempOrig);
     if (catenate && total_messages > 1) {
         for (msgno = 1; msgno <= total_messages; msgno++) {
 	    part = list_get(list, msgno - 1);
diff -udr gateway/gw/sms.c patched/gw/sms.c
--- gateway/gw/sms.c	Wed Sep 19 18:59:37 2001
+++ patched/gw/sms.c	Tue Jan 15 18:34:04 2002
@@ -108,3 +108,29 @@
 
     return 1;
 }
+
+/*
+ *	compute length of an Octstr after it will be converted to GSM 03.38 
+ *	7 bit alphabet - escaped characters would be counted as two septets
+ */
+int sms_msgdata_len(Msg* msg) {
+
+	int ret = 0;
+	Octstr* tempData = NULL;
+	
+	/* got a bad input */
+	if (!msg || !msg->sms.msgdata) 
+		return -1;
+
+	if (msg->sms.coding == DC_7BIT) 
+	{
+		tempData = octstr_duplicate(msg->sms.msgdata);
+		charset_latin1_to_gsm(tempData);
+		ret = octstr_len(tempData);
+		octstr_destroy(tempData);
+	}
+	else 
+		ret = octstr_len(msg->sms.msgdata);
+
+	return ret;
+}
diff -udr gateway/gw/sms.h patched/gw/sms.h
--- gateway/gw/sms.h	Sat Sep  1 21:55:27 2001
+++ patched/gw/sms.h	Tue Jan 15 18:34:04 2002
@@ -65,4 +65,13 @@
  */
 int dcs_to_fields(Msg **msg, int mode);
 
+/*
+ *	compute length of the message data in Msg after it will be converted 
+ *	to the proper coding. 
+ *	if coding is 7 bit, then sms_msgdata_len will return the number of 
+ *	septets this message will convert to, taking into account GSM 03.38
+ *	escape sequences of special chars, which would count as two septets.
+ */
+int sms_msgdata_len(Msg *msg);
+
 #endif
diff -udr gateway/gw/smsc_at2.c patched/gw/smsc_at2.c
--- gateway/gw/smsc_at2.c	Tue Jan 15 12:16:53 2002
+++ patched/gw/smsc_at2.c	Tue Jan 15 19:54:26 2002
@@ -1343,7 +1343,7 @@
 	    sprintf(command, "%s%s", sc, pdu);
 	    at2_write(privdata,command);
 	    at2_write_ctrlz(privdata);
-	    ret = at2_wait_modem_command(privdata, 10, 0);
+	    ret = at2_wait_modem_command(privdata, 20, 0, NULL); /* 10 secs isn't enough sometimes, with slow modems */
 	    debug("bb.at", 0, "send command status: %d", ret);
 	    if(ret != 0) /* OK only */
 	    	continue;
@@ -1352,7 +1352,8 @@
 	}
 	if(ret != 0)
 	{
-	    counter_increase(privdata->conn->failed);
+		/* no need to do that, since bb_smscconn_send_failed() will inc the counter on SMSCCONN_FAILED_MALFORMED
+	    counter_increase(privdata->conn->failed); */
 	    bb_smscconn_send_failed(privdata->conn,msg,SMSCCONN_FAILED_MALFORMED);
 	}
     }
@@ -1490,14 +1491,11 @@
     pos++;
 
     /* user data length - include length of UDH if it exists*/
-    if (msg->sms.coding != DC_8BIT && msg->sms.coding != DC_UCS2) {
-	/* if the coding is 7 bit chars, we need to convert to gsm 03.38 7 bit alphabet here,
-	   as some characters are encoded into two septets, and hence the length of the UD 
-	   will be changed */
-	charset_latin1_to_gsm(msg->sms.msgdata);
-    }
-    len = octstr_len(msg->sms.msgdata);
-
+		/* if the coding is 7 bit chars, I want to count the number of septets that
+		   will result from a conversion of the message to the GSM 03.38 7 bit
+		   alphabet */
+	len = sms_msgdata_len(msg);
+		
     if(octstr_len(msg->sms.udhdata)) {
         if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
             len += octstr_len(msg->sms.udhdata);
@@ -1557,7 +1555,7 @@
 	int ermask[8] = { 0, 1, 3, 7, 15, 31, 63, 127 };
 	int elmask[8] = { 0, 64, 96, 112, 120, 124, 126, 127 };
 
-        /* charset_latin1_to_gsm(input); disabled : we do this in at2_pdu_encode() now */
+        charset_latin1_to_gsm(input);
         len = octstr_len(input);
 
         /* prevoctet is set to the first character and we'll start the loop
