Here are quite a few patches for the SMPP module. Hope they are usefull.
1. using smpp_pdu_get_opt to get if optional params if set and ver = 0x34. For now only looking at the message_payload in MO msgs and the receipted_message_id in a submit_sm_resp
2. SSL support: smsc config var: is-ssl
3. dumping of smpp pdu for debug configurable per smsc: smsc config var dump-pdu
4. Added forced-sender config to override the source addr
5. Added throttle-sleep config defaults to SMPP_THROTTLING_SLEEP_TIME
6. Added throttling: smsc config var throughput
7. Added GSM_ADDR_TON_ABBREVIATED to the source auto detect TON and NPI code.
And two odd ones
8. One of our providers requires us to allways set the registered delivery flag in the SMPP PDU to include intermediate deliv acks if we want any delivery acks at all. We added reg-dlr.
if (smpp->reg_dlr_mask)
pdu->u.submit_sm.registered_delivery |= smpp->reg_dlr_mask;
9. Another one of our providers who shall remain nameless for now, insist on the following. A normal text message we have to use the ASCII rather than GSM charset. Ok but now this is where it gets weird. For any messages with a UDH that are not Unicode, so that would include simple concatenated messages, ringtones etc, we have to do 7 and 8 bit packing as is done in the smsc_at2 module. We have stolen the code from there and added a new smsc config var pack-7bit.
Nisan
--- ../../cvs/gateway/gw/smsc/smsc_smpp.c Thu Mar 20 10:23:57 2003 +++ ../../gateway-clickcvs/gw/smsc/smsc_smpp.c Wed Mar 26 21:59:32 2003 @@ -12,6 +12,10 @@ either) */ /* XXX numbering plans and type of number: check spec */ +#if defined(HAVE_LIBSSL) || defined(HAVE_WTLS_OPENSSL) +#include <openssl/opensslv.h> +#endif + #include "gwlib/gwlib.h" #include "msg.h" #include "smsc_p.h" @@ -31,16 +35,20 @@ #ifndef DEBUG /* This version doesn't dump. */ -static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu) +static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu, int do_dump) { } #else /* This version does dump. */ -static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu) +static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu, int do_dump) { debug("bb.sms.smpp", 0, "SMPP[%s]: %s", octstr_get_cstr(id), msg); + if (do_dump) smpp_pdu_dump(pdu); + else + debug("bb.sms.smpp", 0, "SMPP[%s]: type_name: %s", + octstr_get_cstr(id), pdu->type_name); } #endif @@ -51,6 +59,7 @@ #define SMPP_ENQUIRE_LINK_INTERVAL 30.0 #define SMPP_MAX_PENDING_SUBMITS 10 +#define SMPP_RECONNECT_DELAY 10.0 #define SMPP_DEFAULT_VERSION 0x34 #define SMPP_DEFAULT_PRIORITY 0 #define SMPP_THROTTLING_SLEEP_TIME 15 @@ -84,17 +93,22 @@ List *received_msgs; Counter *message_id_counter; Octstr *host; + int is_ssl; + int dump_pdu; Octstr *system_type; Octstr *username; Octstr *password; Octstr *address_range; Octstr *my_number; Octstr *service_type; + Octstr *forced_sender; int source_addr_ton; int source_addr_npi; int dest_addr_ton; int dest_addr_npi; int alt_dcs; + int pack_7bit; + int reg_dlr_mask; int transmit_port; int receive_port; int quitting; @@ -102,6 +116,8 @@ long max_pending_submits; int version; int priority; /* set default priority for messages */ + long throttle_sleep; + int throughput; time_t throttling_err_time; int smpp_msg_id_type; /* msg id in C string, hex or decimal */ int autodetect_addr; @@ -117,16 +133,21 @@ int source_addr_ton, int source_addr_npi, int dest_addr_ton, int dest_addr_npi, int alt_dcs, int enquire_link_interval, - int max_pending_submits, int version, int priority, - Octstr *my_number, int smpp_msg_id_type, - int autodetect_addr, Octstr *alt_charset, - Octstr *service_type) + int max_pending_submits, + int version, int priority, Octstr *my_number, + int smpp_msg_id_type, int autodetect_addr, + Octstr *alt_charset, Octstr *service_type, + int is_ssl, int dump_pdu, Octstr *forced_sender, + long throttle_sleep, int throughput, int reg_dlr_mask, + int pack_7bit) { SMPP *smpp; smpp = gw_malloc(sizeof(*smpp)); smpp->transmitter = -1; smpp->receiver = -1; + smpp->is_ssl = is_ssl; + smpp->dump_pdu = dump_pdu; smpp->msgs_to_send = list_create(); smpp->sent_msgs = dict_create(16, NULL); list_add_producer(smpp->msgs_to_send); @@ -143,7 +164,9 @@ smpp->dest_addr_ton = dest_addr_ton; smpp->dest_addr_npi = dest_addr_npi; smpp->alt_dcs = alt_dcs; + smpp->pack_7bit = pack_7bit; smpp->my_number = octstr_duplicate(my_number); + smpp->forced_sender = octstr_duplicate(forced_sender); smpp->service_type = octstr_duplicate(service_type); smpp->transmit_port = transmit_port; smpp->receive_port = receive_port; @@ -154,6 +177,9 @@ smpp->priority = priority; smpp->conn = conn; smpp->throttling_err_time = 0; + smpp->throttle_sleep = throttle_sleep; + smpp->throughput = throughput; + smpp->reg_dlr_mask = reg_dlr_mask; smpp->smpp_msg_id_type = smpp_msg_id_type; smpp->autodetect_addr = autodetect_addr; smpp->alt_charset = octstr_duplicate(alt_charset); @@ -176,6 +202,7 @@ octstr_destroy(smpp->service_type); octstr_destroy(smpp->address_range); octstr_destroy(smpp->my_number); + octstr_destroy(smpp->forced_sender); octstr_destroy(smpp->alt_charset); gw_free(smpp); } @@ -328,6 +355,11 @@ } + +static int smpp_encode8bituncompressed(Octstr *input, unsigned char *encoded); +static int smpp_encode7bituncompressed(Octstr *input, unsigned char *encoded, int offset); + + static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg) { SMPP_PDU *pdu; @@ -339,7 +371,11 @@ pdu = smpp_pdu_create(submit_sm, counter_increase(smpp->message_id_counter)); + if (smpp->forced_sender != NULL) + pdu->u.submit_sm.source_addr = octstr_duplicate(smpp->forced_sender); + else pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender); + pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver); /* Set the service type of the outgoing message */ @@ -354,7 +390,7 @@ smpp->source_addr_npi); } else { /* setup default values */ - pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */ + pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL; /* national */ pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */ } @@ -375,9 +411,19 @@ pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; } } + + //check for abbreviated numeric sender + if (((pdu->u.submit_sm.source_addr_ton == GSM_ADDR_TON_INTERNATIONAL) || + (pdu->u.submit_sm.source_addr_ton == GSM_ADDR_TON_NATIONAL )) + && (octstr_len(pdu->u.submit_sm.source_addr)<8)) + { + pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ABBREVIATED; + pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN; } /* Check for manual override of destination ton and npi values */ + } + if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) { pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton; pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi; @@ -385,7 +431,7 @@ octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton, smpp->dest_addr_npi); } else { - pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */ + pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL; /* international */ pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */ } @@ -425,6 +471,41 @@ * set data segments and length */ + if (octstr_len(msg->sms.udhdata)) { + //do we need to do 7bit packing? + if (smpp->pack_7bit == 1) { + if ((0x0F & pdu->u.submit_sm.data_coding) <2) + { + char encoded[1024]; + int offset=0; + int pos=0; + debug("bb.smpp",0,"USING 7bit"); + /* if alt-dcs and pack then ignore alt-dcs */ + pdu->u.submit_sm.data_coding = fields_to_dcs(msg, 0); + /* udh */ + if (octstr_len(msg->sms.udhdata)) { + pos += smpp_encode8bituncompressed(msg->sms.udhdata, &encoded[pos]); + } + + + if (octstr_len(msg->sms.udhdata)) { /* Have UDH */ + int nbits = octstr_len(msg->sms.udhdata) * 8; /* Includes UDH length byte */ + offset = (((nbits / 7) + 1) * 7 - nbits) % 7; /* Fill bits */ + } + + pos += smpp_encode7bituncompressed(msg->sms.msgdata, &encoded[pos], offset); + encoded[pos]=0x00; + + pdu->u.submit_sm.short_message = + octstr_format("%s", encoded); + octstr_hex_to_binary(pdu->u.submit_sm.short_message); + } else + pdu->u.submit_sm.short_message = + octstr_format("%S%S", msg->sms.udhdata, msg->sms.msgdata); + } else + pdu->u.submit_sm.short_message = + octstr_format("%S%S", msg->sms.udhdata, msg->sms.msgdata); + } else { pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata); /* @@ -432,6 +513,7 @@ * alt-charset in smsc group and if MT is not binary */ if (pdu->u.submit_sm.data_coding == 0) { + /* * convert to the given alternative charset * otherwise assume to convert to GSM 03.38 7-bit alphabet @@ -445,6 +527,10 @@ charset_latin1_to_gsm(pdu->u.submit_sm.short_message); } } + } + + pdu->u.submit_sm.sm_length = octstr_len(pdu->u.submit_sm.short_message); + /* prepend udh if present */ if (octstr_len(msg->sms.udhdata)) { @@ -496,6 +582,9 @@ if (msg->sms.dlr_mask & (DLR_SUCCESS|DLR_FAIL)) pdu->u.submit_sm.registered_delivery = 1; + if (smpp->reg_dlr_mask) + pdu->u.submit_sm.registered_delivery |= smpp->reg_dlr_mask; + octstr_destroy(relation_UTC_time); /* set priority */ @@ -520,7 +609,7 @@ *last_sent = date_universal_now(); pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter)); - dump_pdu("Sending enquire link:", smpp->conn->id, pdu); + dump_pdu("Sending enquire link:", smpp->conn->id, pdu, smpp->dump_pdu); os = smpp_pdu_pack(pdu); if (os) conn_write(conn, os); /* Write errors checked by caller. */ @@ -534,7 +623,7 @@ SMPP_PDU *pdu; Octstr *os; pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter)); - dump_pdu("Sending unbind:", smpp->conn->id, pdu); + dump_pdu("Sending unbind:", smpp->conn->id, pdu, smpp->dump_pdu); os = smpp_pdu_pack(pdu); conn_write(conn, os); octstr_destroy(os); @@ -542,12 +631,12 @@ } -static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu) +static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu, int do_dump) { Octstr *os; int ret; - dump_pdu("Sending PDU:", id, pdu); + dump_pdu("Sending PDU:", id, pdu, do_dump); os = smpp_pdu_pack(pdu); if (os) ret = conn_write(conn, os); /* Caller checks for write errors later */ @@ -578,9 +667,13 @@ os = octstr_format("%ld", pdu->u.submit_sm.sequence_number); dict_put(smpp->sent_msgs, os, msg); octstr_destroy(os); - send_pdu(conn, smpp->conn->id, pdu); + send_pdu(conn, smpp->conn->id, pdu, smpp->dump_pdu); smpp_pdu_destroy(pdu); + if (smpp->throughput) { + gwthread_sleep((double)(1.0/(double)smpp->throughput)); + } + ++(*pending_submits); } } @@ -596,6 +689,13 @@ SMPP_PDU *bind; Connection *conn; +#ifdef HAVE_LIBSSL + if (smpp->is_ssl) { + debug("bb.smpp", 0, "Transmitter Using SSL"); + conn = conn_open_ssl(smpp->host, smpp->transmit_port, NULL, smpp->conn->our_host ); + } + else +#endif conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", @@ -615,7 +715,7 @@ bind->u.bind_transmitter.interface_version = smpp->version; bind->u.bind_transmitter.address_range = octstr_duplicate(smpp->address_range); - send_pdu(conn, smpp->conn->id, bind); + send_pdu(conn, smpp->conn->id, bind, smpp->dump_pdu); smpp_pdu_destroy(bind); return conn; @@ -632,6 +732,13 @@ SMPP_PDU *bind; Connection *conn; +#ifdef HAVE_LIBSSL + if (smpp->is_ssl) { + debug("bb.smpp", 0, "Transceiver Using SSL"); + conn = conn_open_ssl(smpp->host, smpp->transmit_port, NULL, smpp->conn->our_host ); + } + else +#endif conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", @@ -649,7 +756,7 @@ bind->u.bind_transmitter.system_type = octstr_duplicate(smpp->system_type); bind->u.bind_transmitter.interface_version = smpp->version; bind->u.bind_transmitter.address_range = octstr_duplicate(smpp->address_range); - send_pdu(conn, smpp->conn->id, bind); + send_pdu(conn, smpp->conn->id, bind, smpp->dump_pdu); smpp_pdu_destroy(bind); return conn; @@ -666,6 +773,14 @@ SMPP_PDU *bind; Connection *conn; + +#ifdef HAVE_LIBSSL + if (smpp->is_ssl) { + debug("bb.smpp", 0, "Receiver Using SSL"); + conn = conn_open_ssl(smpp->host, smpp->receive_port, NULL, smpp->conn->our_host ); + } + else +#endif conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", @@ -685,7 +800,7 @@ bind->u.bind_receiver.interface_version = smpp->version; bind->u.bind_receiver.address_range = octstr_duplicate(smpp->address_range); - send_pdu(conn, smpp->conn->id, bind); + send_pdu(conn, smpp->conn->id, bind, smpp->dump_pdu); smpp_pdu_destroy(bind); return conn; @@ -768,6 +883,11 @@ else dlrstat = DLR_FAIL; + if (msgid == NULL && smpp->version == 0x34) + { + msgid = smpp_pdu_get_opt(pdu, SMPP_receipted_message_id); + } + if (msgid != NULL) { Octstr *tmp; @@ -828,9 +948,26 @@ } else /* MO-SMS */ { + Octstr *msg_payload; + + debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got MO", + octstr_get_cstr(smpp->conn->id)); + /* ensure the smsc-id is set */ msg = pdu_to_msg(smpp, pdu); + //check for optional payload and replace + + if (smpp->version == 0x34) + { + msg_payload = smpp_pdu_get_opt(pdu, SMPP_message_payload); + if (msg_payload != NULL) + { + octstr_destroy(msg->sms.msgdata); + msg->sms.msgdata = msg_payload; + } + } + /* Replace MO destination number with my-number */ if (octstr_len(smpp->my_number)) { octstr_destroy(msg->sms.receiver); @@ -1072,7 +1209,7 @@ } if (resp != NULL) { - send_pdu(conn, smpp->conn->id, resp); + send_pdu(conn, smpp->conn->id, resp, smpp->dump_pdu); smpp_pdu_destroy(resp); } } @@ -1150,7 +1287,7 @@ if (smpp->quitting) { send_unbind(smpp, conn); while ((ret = read_pdu(smpp, conn, &len, &pdu)) == 1) { - dump_pdu("Got PDU:", smpp->conn->id, pdu); + dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->dump_pdu); handle_pdu(smpp, conn, pdu, &pending_submits); smpp_pdu_destroy(pdu); } @@ -1165,7 +1302,7 @@ while ((ret = read_pdu(smpp, conn, &len, &pdu)) == 1) { /* Deal with the PDU we just got */ - dump_pdu("Got PDU:", smpp->conn->id, pdu); + dump_pdu("Got PDU:", smpp->conn->id, pdu, smpp->dump_pdu); handle_pdu(smpp, conn, pdu, &pending_submits); smpp_pdu_destroy(pdu); @@ -1175,7 +1312,7 @@ /* Make sure we send even if we read a lot */ if (transmitter && (!smpp->throttling_err_time || - ((time(NULL) - smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME + ((time(NULL) - smpp->throttling_err_time) > smpp->throttle_sleep && !(smpp->throttling_err_time = 0))) ) send_messages(smpp, conn, &pending_submits); @@ -1189,7 +1326,7 @@ if (transmitter && (!smpp->throttling_err_time || - ((time(NULL) - smpp->throttling_err_time) > SMPP_THROTTLING_SLEEP_TIME + ((time(NULL) - smpp->throttling_err_time) > smpp->throttle_sleep && !(smpp->throttling_err_time = 0))) ) send_messages(smpp, conn, &pending_submits); @@ -1282,23 +1419,30 @@ long dest_addr_ton; long dest_addr_npi; Octstr *my_number; + Octstr *forced_sender; Octstr *service_type; SMPP *smpp; int ok; int transceiver_mode; Octstr *smsc_id; int alt_dcs; + int pack_7bit; long enquire_link_interval; long max_pending_submits; long version; long priority; + long throttle_sleep; + long reg_dlr_mask; + long throughput; long smpp_msg_id_type; int autodetect_addr; Octstr *alt_charset; + long is_ssl; + long dump_pdu; my_number = alt_charset = NULL; transceiver_mode = 0; - alt_dcs = 0; + pack_7bit = alt_dcs = 0; autodetect_addr = 1; host = cfg_get(grp, octstr_imm("host")); @@ -1308,11 +1452,13 @@ receive_port = 0; cfg_get_bool(&transceiver_mode, grp, octstr_imm("transceiver-mode")); cfg_get_bool(&alt_dcs, grp, octstr_imm("alt-dcs")); + cfg_get_bool(&pack_7bit, grp, octstr_imm("pack-7bit")); username = cfg_get(grp, octstr_imm("smsc-username")); password = cfg_get(grp, octstr_imm("smsc-password")); system_type = cfg_get(grp, octstr_imm("system-type")); address_range = cfg_get(grp, octstr_imm("address-range")); my_number = cfg_get(grp, octstr_imm("my-number")); + forced_sender = cfg_get(grp, octstr_imm("forced-sender")); service_type = cfg_get(grp, octstr_imm("service-type")); system_id = cfg_get(grp, octstr_imm("system-id")); @@ -1337,6 +1483,19 @@ octstr_imm("max-pending-submits")) == -1) max_pending_submits = SMPP_MAX_PENDING_SUBMITS; + if (cfg_get_integer(&throttle_sleep, grp, + octstr_imm("throttle-sleep")) == -1) + throttle_sleep = SMPP_THROTTLING_SLEEP_TIME; + if (cfg_get_integer(&throughput, grp, + octstr_imm("throughput")) == -1) + throughput = 0; + + if (cfg_get_integer(®_dlr_mask, grp, + octstr_imm("reg-dlr-mask")) == -1) + reg_dlr_mask = 0; + + + /* Check that config is OK */ ok = 1; if (host == NULL) { @@ -1391,6 +1550,13 @@ if (cfg_get_integer(&priority, grp, octstr_imm("priority")) == -1) priority = SMPP_DEFAULT_PRIORITY; + if (cfg_get_integer(&is_ssl, grp, octstr_imm("is-ssl")) == -1) + is_ssl = 0; + + if (cfg_get_integer(&dump_pdu, grp, octstr_imm("dump-pdu")) == -1) + dump_pdu = 1; + + /* set the msg_id type variable for this SMSC */ if (cfg_get_integer(&smpp_msg_id_type, grp, octstr_imm("msg-id-type")) == -1) { /* @@ -1411,7 +1577,8 @@ dest_addr_npi, alt_dcs, enquire_link_interval, max_pending_submits, version, priority, my_number, smpp_msg_id_type, autodetect_addr, alt_charset, - service_type); + service_type, is_ssl, dump_pdu, forced_sender, + throttle_sleep, throughput, reg_dlr_mask, pack_7bit); conn->data = smpp; conn->name = octstr_format("SMPP:%S:%d/%d:%S:%S", @@ -1430,6 +1597,7 @@ octstr_destroy(system_type); octstr_destroy(address_range); octstr_destroy(my_number); + octstr_destroy(forced_sender); octstr_destroy(smsc_id); octstr_destroy(alt_charset); octstr_destroy(service_type); @@ -1470,4 +1638,113 @@ return 0; } + + +static int numtext(int num) +{ + return (num > 9) ? (num + 55) : (num + 48); +} + +static int smpp_encode7bituncompressed(Octstr *input, unsigned char *encoded, int offset) +{ + + unsigned char prevoctet, tmpenc; + int i; + int c = 1; + int r = 7; + int pos = 0; + int len; + unsigned char enc7bit[256]; + int j, encpos = 0; + 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); + len = octstr_len(input); + + /* + * prevoctet is set to the first character and we'll start the loop + * at the following char. + */ + prevoctet = octstr_get_char(input , 0); + for (i = 1; i < octstr_len(input); i++) { + /* + * a byte is encoded with what is left of the previous character + * and filled with as much as possible of the current one. + */ + tmpenc = prevoctet + ((octstr_get_char(input, i) & ermask[c]) << r); + enc7bit[encpos] = tmpenc; + encpos++; + c = (c > 6) ? 1 : c + 1; + r = (r < 2) ? 7 : r - 1; + + /* + * prevoctet becomes the part of the current octet that hasn't + * been copied to 'encoded' or the next char if the current has + * been completely copied already. + */ + prevoctet = (octstr_get_char(input, i) & elmask[r]) >> (c - 1); + if (r == 7) { + i++; + prevoctet = octstr_get_char(input, i); + } + } + + /* + * if the length of the message is a multiple of 8 then we + * are finished. Otherwise prevoctet still contains part of a + * character so we add it. + */ + if ((len / 8)*8 != len) { + enc7bit[encpos] = prevoctet; + encpos++; + } + + /* Now shift the buffer by the offset */ + if (offset > 0) { + unsigned char nextdrop, lastdrop; + + nextdrop = lastdrop = 0; + for (i = 0; i < encpos; i++) { + nextdrop = enc7bit[i] >> (8 - offset); /* This drops off by shifting */ + if (i == 0) + enc7bit[i] = enc7bit[i] << offset; /* This drops off by shifting */ + else + enc7bit[i] = (enc7bit[i] << offset) | lastdrop; + lastdrop = nextdrop; + } + + if (offset > ((len*7) % 8)) { + enc7bit [i] = nextdrop; + i++; + } + } else + i = encpos; + + for (j = 0; j < i; j++) { + encoded[pos] = numtext((enc7bit [j] & 240) >> 4); + pos++; + encoded[pos] = numtext(enc7bit [j] & 15); + pos++; + } + return pos; + +} + + + +static int smpp_encode8bituncompressed(Octstr *input, unsigned char *encoded) +{ + int len, i; + + len = octstr_len(input); + + for (i = 0; i < len; i++) { + /* each character is encoded in its hex representation (2 chars) */ + encoded[i*2] = numtext((octstr_get_char(input, i) & 240) >> 4); + encoded[i*2 + 1] = numtext(octstr_get_char(input, i) & 15); + } + return len*2; +} +