repost: [PATCH] SMPP: data_coding (deliver_sm) votes?!
Stipe Tolj <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Organization | Wapme Systems AG |
| Message-ID | <[email protected]> |
Hi list, the attached patch has been submited by Alan on 11-06-2002. Unfortunatly there were no votes for the patch to include it to cvs head. So please heads up! BTW, using iconv routines make dependency more tight. Currently we only depend on libxml2 for Kannel (even while it is not needed for sms gatewaying purposes). Using the routines in the patch we will result in another dependeny to iconv. Is this accepptable for you guys? Stipe [email protected] ------------------------------------------------------------------- Wapme Systems AG Vogelsanger Weg 80 40470 Düsseldorf Tel: +49-211-74845-0 Fax: +49-211-74845-299 E-Mail: [email protected] Internet: http://www.wapme-systems.de ------------------------------------------------------------------- wapme.net - wherever you are
data_coding.patch
(text/plain, 11 KB)
? charset.patch
? data_coding-patch
? data_coding.patch
? migrate.sh
? smsc_smpp.c-charset
? smsc_smpp.c-diff
? smsc_smpp.c-patch
? smsc_smpp.c-tcl
? smsc_smpp.patch
? doc/arch/arch.aux
? doc/arch/arch.dvi
? doc/arch/arch.log
? doc/arch/arch.tex
? doc/userguide/userguide.xml-patch
? gw/diff
? gw/smsc_at2.c.diff
Index: config.h.in
===================================================================
RCS file: /home/cvs/gateway/config.h.in,v
retrieving revision 1.42
diff -u -r1.42 config.h.in
--- config.h.in 9 Sep 2002 10:49:28 -0000 1.42
+++ config.h.in 6 Nov 2002 07:35:37 -0000
@@ -113,6 +113,9 @@
/* Define if you have <syslog.h>. */
#undef HAVE_SYSLOG_H
+/* Define if you have <iconv.h>. */
+#undef HAVE_ICONV_H
+
/* Define if you have and want to use the ssl library (-lssl) */
#undef HAVE_LIBSSL
Index: configure
===================================================================
RCS file: /home/cvs/gateway/configure,v
retrieving revision 1.105
diff -u -r1.105 configure
--- configure 9 Sep 2002 10:49:28 -0000 1.105
+++ configure 6 Nov 2002 07:35:38 -0000
@@ -1781,7 +1781,7 @@
fi
done
-for ac_hdr in pthread.h getopt.h syslog.h
+for ac_hdr in pthread.h getopt.h syslog.h iconv.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
Index: configure.in
===================================================================
RCS file: /home/cvs/gateway/configure.in,v
retrieving revision 1.107
diff -u -r1.107 configure.in
--- configure.in 9 Sep 2002 10:49:28 -0000 1.107
+++ configure.in 6 Nov 2002 07:35:39 -0000
@@ -95,7 +95,7 @@
AC_HEADER_STDC
AC_CHECK_HEADERS(sys/ioctl.h sys/time.h sys/types.h unistd.h sys/poll.h)
-AC_CHECK_HEADERS(pthread.h getopt.h syslog.h)
+AC_CHECK_HEADERS(pthread.h getopt.h syslog.h iconv.h)
dnl Checks for typedefs, structures, and compiler characteristics.
Index: gw/smsc/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc/smsc_smpp.c,v
retrieving revision 1.14
diff -u -r1.14 smsc_smpp.c
--- gw/smsc/smsc_smpp.c 17 Oct 2002 08:28:10 -0000 1.14
+++ gw/smsc/smsc_smpp.c 6 Nov 2002 07:35:39 -0000
@@ -102,6 +102,7 @@
time_t throttling_err_time;
int smpp_msg_id_type; /* msg id in C string, hex or decimal */
int autodetect_addr;
+ Octstr* alt_charset;
SMSCConn *conn;
} SMPP;
@@ -115,7 +116,8 @@
int alt_dcs, int enquire_link_interval,
int max_pending_submits, int reconnect_delay,
int version, int priority, Octstr *my_number,
- int smpp_msg_id_type, int autodetect_addr)
+ int smpp_msg_id_type, int autodetect_addr,
+ Octstr* alt_charset)
{
SMPP *smpp;
@@ -147,6 +149,7 @@
smpp->quitting = 0;
smpp->version = version;
smpp->priority = priority;
+ smpp->alt_charset = octstr_duplicate(alt_charset);
smpp->conn = conn;
smpp->throttling_err_time = 0;
smpp->smpp_msg_id_type = smpp_msg_id_type;
@@ -169,6 +172,8 @@
octstr_destroy(smpp->system_type);
octstr_destroy(smpp->address_range);
octstr_destroy(smpp->our_host);
+ octstr_destroy(smpp->my_number);
+ octstr_destroy(smpp->alt_charset);
gw_free(smpp);
}
}
@@ -223,7 +228,7 @@
}
-static Msg *pdu_to_msg(SMPP_PDU *pdu)
+static Msg *pdu_to_msg(SMPP *smpp, SMPP_PDU *pdu)
{
Msg *msg;
@@ -236,9 +241,44 @@
pdu->u.deliver_sm.destination_addr = NULL;
msg->sms.msgdata = pdu->u.deliver_sm.short_message;
pdu->u.deliver_sm.short_message = NULL;
- charset_gsm_to_latin1(msg->sms.msgdata);
+ dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
+
+ switch (pdu->u.deliver_sm.data_coding) {// handle default data coding
+ case 0x00: // default SMSC alphabet
+ if (smpp->alt_charset) { // try to convert from something interesting if specified so
+ if (octstr_compare(smpp->alt_charset, octstr_imm("binary")) != 0) // unless it was specified binary
+ if (charset_convert(msg->sms.msgdata, octstr_get_cstr(smpp->alt_charset), "ISO-8859-1") != 0)
+ error(0, "Failed to convert msgdata from %s to %s, will leave as is",
+ octstr_get_cstr(smpp->alt_charset), "ISO-8859-1");
+ msg->sms.coding = DC_8BIT;
+
+ } else { // assume GSM 03.38 7 bit alphabet
+ charset_gsm_to_latin1(msg->sms.msgdata);
+ msg->sms.coding = DC_7BIT;
+ }
+ break;
+ case 0x01: // ASCII or IA5 - not sure if I need to do anything
+ case 0x02: // 8 bit binary - do nothing
+ case 0x04: // 8 bit binary - do nothing
+ break;
+ case 0x03: // ISO-8859-1 - do nothing
+ msg->sms.coding = DC_8BIT; break;
+ case 0x05: // JIS - what do I do with that ?
+ break;
+ case 0x06: // Cyrllic - iso-8859-5, I'll convert to unicode
+ if (charset_convert(msg->sms.msgdata, "ISO-8859-5", "UCS-2BE") != 0)
+ error(0, "Failed to convert msgdata from cyrllic to UCS-2, will leave as is");
+ msg->sms.coding = DC_UCS2; break;
+ case 0x07: // Hebrew iso-8859-8, I'll convert to unicode
+ if (charset_convert(msg->sms.msgdata, "ISO-8859-8", "UCS-2BE") != 0)
+ error(0, "Failed to convert msgdata from hebrew to UCS-2, will leave as is");
+ msg->sms.coding = DC_UCS2; break;
+ case 0x08: // unicode UCS-2, yey
+ msg->sms.coding = DC_UCS2; break;
+ default: // don't much care about the others - you implement them if you feel like it
+ msg->sms.coding = DC_8BIT;
+ }
msg->sms.pid = pdu->u.deliver_sm.protocol_id;
- dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);
return msg;
}
@@ -359,8 +399,16 @@
octstr_format("%S%S", msg->sms.udhdata, msg->sms.msgdata);
} else {
pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);
- if (pdu->u.submit_sm.data_coding == 0 ) /* no reencoding for unicode! */
- charset_latin1_to_gsm(pdu->u.submit_sm.short_message);
+ if (pdu->u.submit_sm.data_coding == 0 ) /* no reencoding for unicode! */ {
+ if (smpp->alt_charset && octstr_compare(smpp->alt_charset, octstr_imm("binary")) != 0) {
+ if (charset_convert(pdu->u.submit_sm.short_message, "ISO-8859-1",
+ octstr_get_cstr(smpp->alt_charset)) != 0)
+ error(0, "Failed to convert msgdata from %s to %s will send as is",
+ "ISO-8859-1", octstr_get_cstr(smpp->alt_charset));
+ debug("smsc_smpp.c", 0, "alt_charset!=0");
+ } else
+ charset_latin1_to_gsm(pdu->u.submit_sm.short_message);
+ }
}
/*
@@ -724,7 +772,7 @@
} else /* MO-SMS */
{
/* ensure the smsc-id is set */
- msg = pdu_to_msg(pdu);
+ msg = pdu_to_msg(smpp, pdu);
/* Replace MO destination number with my-number */
if (octstr_len(smpp->my_number)) {
@@ -1126,6 +1174,7 @@
long max_pending_submits;
long reconnect_delay;
long version;
+ Octstr* alt_charset;
long priority;
long smpp_msg_id_type;
int autodetect_addr;
@@ -1234,13 +1283,17 @@
panic(0,"SMPP: Invlid value for msg-id-type directive in configuraton");
}
+
+ /* check for charset specific */
+ alt_charset = cfg_get(grp, octstr_imm("alt-charset"));
+
smpp = smpp_create(conn, host, port, receive_port, system_type,
username, password, address_range, our_host,
source_addr_ton, source_addr_npi, dest_addr_ton,
dest_addr_npi, alt_dcs, enquire_link_interval,
max_pending_submits, reconnect_delay,
version, priority, my_number, smpp_msg_id_type,
- autodetect_addr);
+ autodetect_addr, alt_charset);
conn->data = smpp;
conn->name = octstr_format("SMPP:%S:%d/%d:%S:%S",
@@ -1261,6 +1314,7 @@
octstr_destroy(our_host);
octstr_destroy(my_number);
octstr_destroy(smsc_id);
+ octstr_destroy(alt_charset);
conn->status = SMSCCONN_CONNECTING;
Index: gwlib/charset.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/charset.c,v
retrieving revision 1.11
diff -u -r1.11 charset.c
--- gwlib/charset.c 25 Jan 2002 11:49:05 -0000 1.11
+++ gwlib/charset.c 6 Nov 2002 07:35:39 -0000
@@ -7,6 +7,11 @@
*/
#include "gwlib/gwlib.h"
+#include <errno.h>
+
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
/* Map GSM default alphabet characters to ISO-Latin-1 characters.
* The greek characters at positions 16 and 18 through 26 are not
@@ -400,4 +405,50 @@
xmlBufferFree(frombuffer);
return ret;
+}
+
+int charset_convert(Octstr* string, char* charset_from, char* charset_to)
+{
+#if HAVE_ICONV_H
+ char *from_buf, *to_buf, *pointer;
+ size_t inbytes, outbytes;
+ int ret;
+ iconv_t cd;
+
+ if (!charset_from || !charset_to || !string) /* sanity check */
+ return -1;
+
+ cd = iconv_open(charset_to, charset_from);
+ /* Did I succeed in getting a conversion descriptor ? */
+ if (cd == (iconv_t)(-1)) {
+ /* I guess not */
+ error(0,"Failed to convert string from %s to %s - probably broken type names.",
+ charset_from, charset_to);
+ return -1;
+ }
+ from_buf = octstr_get_cstr(string);
+ /* allocate max sized buffer, assuming target encoding may be 4 byte unicode */
+ inbytes = octstr_len(string);
+ outbytes = sizeof(char) * octstr_len(string) * 4;
+ pointer = to_buf = gw_malloc(outbytes + 1);
+ memset(to_buf,0,outbytes+1);
+ ret = iconv(cd, (const char**)&from_buf, &inbytes, &pointer, &outbytes);
+ iconv_close(cd);
+ if (ret != -1) {
+ /* conversion succeeded */
+ octstr_delete(string,0,octstr_len(string));
+ octstr_append_cstr(string, to_buf);
+ if (ret)
+ debug("charset",0,"charset_convert did %d non-reversible conversions",ret);
+ ret = 0;
+ } else
+ error(0,"Failed to convert string from %s to %s, errno: %d",charset_from, charset_to, errno);
+ if (errno == EILSEQ)
+ {
+ debug("charset_convert",0,"found an invalid multibyte sequence at position %d",from_buf - octstr_get_cstr(string));
+ }
+ gw_free(to_buf);
+ return ret;
+#endif
+ return 0;
}
Index: gwlib/charset.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/charset.h,v
retrieving revision 1.6
diff -u -r1.6 charset.h
--- gwlib/charset.h 7 Dec 2001 13:48:57 -0000 1.6
+++ gwlib/charset.h 6 Nov 2002 07:35:39 -0000
@@ -72,4 +72,9 @@
*/
int charset_from_utf8(Octstr *utf8, Octstr **to, Octstr *charset_to);
+/* use iconv library to convert an Octstr in place, from source character set to
+ * destination character set
+ */
+int charset_convert(Octstr* string, char* charset_from, char* charset_to);
+
#endif