Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sms.c File Reference

#include "sms.h"
#include "dlr.h"

Include dependency graph for sms.c:

Include dependency graph

Go to the source code of this file.

Defines

#define CATENATE_UDH_LEN   5

Functions

int fields_to_dcs (Msg *msg, int mode)
int dcs_to_fields (Msg **msg, int dcs)
int sms_msgdata_len (Msg *msg)
int sms_swap (Msg *msg)
void prepend_catenation_udh (Msg *sms, int part_no, int num_messages, int msg_sequence)
Octstrextract_msgdata_part (Octstr *msgdata, Octstr *split_chars, int max_part_len)
Octstrextract_msgdata_part_by_coding (Msg *msg, Octstr *split_chars, int max_part_len)
Listsms_split (Msg *orig, Octstr *header, Octstr *footer, Octstr *nonlast_suffix, Octstr *split_chars, int catenate, unsigned long msg_sequence, int max_messages, int max_octets)
int sms_priority_compare (const void *a, const void *b)


Define Documentation

#define CATENATE_UDH_LEN   5
 

Definition at line 221 of file sms.c.

Referenced by prepend_catenation_udh().


Function Documentation

int dcs_to_fields Msg **  msg,
int  dcs
 

Definition at line 139 of file sms.c.

References DC_8BIT, and DC_UCS2.

Referenced by at2_pdu_decode_deliver_sm(), cimd2_accept_message(), data_sm_to_msg(), handle_operation(), oisd_accept_message(), and pdu_to_msg().

00140 {
00141     /* Non-MWI Mode 1 */
00142     if ((dcs & 0xF0) == 0xF0) { 
00143         dcs &= 0x07;
00144         (*msg)->sms.coding = (dcs & 0x04) ? DC_8BIT : DC_7BIT; /* grab bit 2 */
00145         (*msg)->sms.mclass = dcs & 0x03; /* grab bits 1,0 */
00146         (*msg)->sms.alt_dcs = 1; /* set 0xFX data coding */
00147     }
00148     
00149     /* Non-MWI Mode 0 */
00150     else if ((dcs & 0xC0) == 0x00) { 
00151         (*msg)->sms.alt_dcs = 0;
00152         (*msg)->sms.compress = ((dcs & 0x20) == 0x20) ? 1 : 0; /* grab bit 5 */
00153         (*msg)->sms.mclass = ((dcs & 0x10) == 0x10) ? dcs & 0x03 : MC_UNDEF; 
00154                         /* grab bit 0,1 if bit 4 is on */
00155         (*msg)->sms.coding = (dcs & 0x0C) >> 2; /* grab bit 3,2 */
00156     }
00157 
00158     /* MWI */
00159     else if ((dcs & 0xC0) == 0xC0) { 
00160         (*msg)->sms.alt_dcs = 0;
00161         (*msg)->sms.coding = ((dcs & 0x30) == 0x30) ? DC_UCS2 : DC_7BIT;
00162         if (!(dcs & 0x08))
00163             dcs |= 0x04; /* if bit 3 is active, have mwi += 4 */
00164         dcs &= 0x07;
00165         (*msg)->sms.mwi = dcs ; /* grab bits 1,0 */
00166     } 
00167     
00168     else {
00169         return 0;
00170     }
00171 
00172     return 1;
00173 }

Octstr* extract_msgdata_part Octstr msgdata,
Octstr split_chars,
int  max_part_len
[static]
 

Definition at line 247 of file sms.c.

References octstr_copy, octstr_delete(), octstr_get_char(), octstr_len(), and octstr_search_char().

Referenced by extract_msgdata_part_by_coding().

00249 {
00250     long i, len;
00251     Octstr *part;
00252 
00253     len = max_part_len;
00254     if (max_part_len < octstr_len(msgdata) && split_chars != NULL)
00255     for (i = max_part_len; i > 0; i--)
00256         if (octstr_search_char(split_chars,
00257                    octstr_get_char(msgdata, i - 1), 0) != -1) {
00258         len = i;
00259         break;
00260         }
00261     part = octstr_copy(msgdata, 0, len);
00262     octstr_delete(msgdata, 0, len);
00263     return part;
00264 }

Here is the call graph for this function:

Octstr* extract_msgdata_part_by_coding Msg msg,
Octstr split_chars,
int  max_part_len
[static]
 

Definition at line 267 of file sms.c.

References charset_gsm_to_utf8(), charset_gsm_truncate(), charset_utf8_to_gsm(), DC_8BIT, extract_msgdata_part(), octstr_destroy(), octstr_duplicate, and octstr_len().

Referenced by sms_split().

00269 {
00270     Octstr *temp = NULL, *temp_utf;
00271 
00272     if (msg->sms.coding == DC_8BIT || msg->sms.coding == DC_UCS2) {
00273         /* nothing to do here, just call the original extract_msgdata_part */
00274         return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len);
00275     }
00276 
00277     /* convert to and the from gsm, so we drop all non GSM chars */
00278     charset_utf8_to_gsm(msg->sms.msgdata);
00279     charset_gsm_to_utf8(msg->sms.msgdata);
00280 
00281     /* 
00282      * else we need to do something special. I'll just get charset_gsm_truncate to
00283      * cut the string to the required length and then count real characters. 
00284      */
00285      temp = octstr_duplicate(msg->sms.msgdata);
00286      charset_utf8_to_gsm(temp);
00287      charset_gsm_truncate(temp, max_part_len);
00288 
00289      /* calculate utf-8 length */
00290      temp_utf = octstr_duplicate(temp);
00291      charset_gsm_to_utf8(temp_utf);
00292      max_part_len = octstr_len(temp_utf);
00293 
00294      octstr_destroy(temp);
00295      octstr_destroy(temp_utf);
00296 
00297      /* now just call the original extract_msgdata_part with the new length */
00298      return extract_msgdata_part(msg->sms.msgdata, split_chars, max_part_len);
00299 }

Here is the call graph for this function:

int fields_to_dcs Msg msg,
int  mode
 

Definition at line 73 of file sms.c.

References DC_UCS2, octstr_len(), and SMS_PARAM_UNDEFINED.

Referenced by at2_pdu_encode(), brunet_send_sms(), msg_to_emimsg(), msg_to_pdu(), packet_encode_message(), urltrans_fill_escape_codes(), and xidris_send_sms().

00074 {
00075     int dcs=0;
00076 
00077     /* Coding defaults to 7BIT or to 8BIT if udh is set */
00078     if (msg->sms.coding == DC_UNDEF) {
00079     if (octstr_len(msg->sms.udhdata))
00080       msg->sms.coding = DC_8BIT;
00081     else
00082       msg->sms.coding = DC_7BIT;
00083     }
00084 
00085 
00086     /* MWI */
00087     if (msg->sms.mwi != MWI_UNDEF) {
00088     dcs = msg->sms.mwi;  /* sets bits 2, 1 and 0 */
00089 
00090     if (dcs & 0x04) 
00091         dcs = (dcs & 0x03) | 0xC0; /* MWI Inactive */
00092     else {
00093         dcs = (dcs & 0x03) | 0x08; /* MWI Active, sets bit 3 */
00094 
00095         if (! octstr_len(msg->sms.msgdata))
00096         dcs |= 0xC0;    /* Discard */
00097         else
00098         if (msg->sms.coding == DC_7BIT)
00099             dcs |= 0xD0;    /* 7bit */
00100         else
00101             dcs |= 0xE0;    /* UCS-2 */
00102             /* XXX Shouldn't happen to have mwi and dc=DC_8BIT! */
00103     }
00104     }
00105 
00106     /* Non-MWI */
00107     else {
00108     /* mode 0 or mode UNDEF */
00109     if (mode == 0 || mode == SMS_PARAM_UNDEFINED || msg->sms.coding == DC_UCS2 
00110         || msg->sms.compress == COMPRESS_ON) { 
00111         /* bits 7,6 are 0 */
00112         if (msg->sms.compress == COMPRESS_ON)
00113         dcs |= 0x20; /* sets bit 5 */
00114         if (msg->sms.mclass != MC_UNDEF)
00115         dcs |= (0x10 | msg->sms.mclass); /* sets bit 4,1,0 */
00116         if (msg->sms.coding != DC_UNDEF)
00117         dcs |= (msg->sms.coding << 2); /* sets bit 3,2 */
00118     } 
00119     
00120     /* mode 1 */
00121     else {
00122         dcs |= 0xF0; /* sets bits 7-3 */
00123         if(msg->sms.coding != DC_UNDEF)
00124         dcs |= (msg->sms.coding << 2); /* only DC_7BIT or DC_8BIT, sets bit 2*/
00125         if (msg->sms.mclass == MC_UNDEF)
00126                 dcs |= 1; /* default meaning: ME specific */
00127             else
00128                 dcs |= msg->sms.mclass; /* sets bit 1,0 */
00129     }
00130     }
00131 
00132     return dcs;
00133 }

Here is the call graph for this function:

void prepend_catenation_udh Msg sms,
int  part_no,
int  num_messages,
int  msg_sequence
[static]
 

Definition at line 224 of file sms.c.

References CATENATE_UDH_LEN, octstr_append_char(), octstr_create, octstr_format_append(), octstr_len(), octstr_set_char(), and sms.

Referenced by sms_split().

00226 {
00227     if (sms->sms.udhdata == NULL)
00228         sms->sms.udhdata = octstr_create("");
00229     if (octstr_len(sms->sms.udhdata) == 0)
00230     octstr_append_char(sms->sms.udhdata, CATENATE_UDH_LEN);
00231     octstr_format_append(sms->sms.udhdata, "%c\3%c%c%c", 
00232                          0, msg_sequence, num_messages, part_no);
00233 
00234      /* Set the number of messages left, if any */
00235      if (part_no < num_messages)
00236         sms->sms.msg_left = num_messages - part_no;
00237      else
00238         sms->sms.msg_left = 0;
00239     /* 
00240      * Now that we added the concatenation information the
00241      * length is all wrong. we need to recalculate it. 
00242      */
00243     octstr_set_char(sms->sms.udhdata, 0, octstr_len(sms->sms.udhdata) - 1 );
00244 }

Here is the call graph for this function:

int sms_msgdata_len Msg msg  ) 
 

Definition at line 180 of file sms.c.

References charset_utf8_to_gsm(), octstr_destroy(), octstr_duplicate, and octstr_len().

Referenced by at2_pdu_encode(), and sms_split().

00181 {
00182     int ret = 0;
00183     Octstr* msgdata = NULL;
00184     
00185     /* got a bad input */
00186     if (!msg || !msg->sms.msgdata) 
00187         return -1;
00188 
00189     if (msg->sms.coding == DC_7BIT) {
00190         msgdata = octstr_duplicate(msg->sms.msgdata);
00191         charset_utf8_to_gsm(msgdata);
00192         ret = octstr_len(msgdata);
00193         octstr_destroy(msgdata);
00194     } else 
00195         ret = octstr_len(msg->sms.msgdata);
00196 
00197     return ret;
00198 }

Here is the call graph for this function:

int sms_priority_compare const void *  a,
const void *  b
 

Compare priority and time of two sms's.

Returns:
-1 of a < b; 0 a = b; 1 a > b

Definition at line 388 of file sms.c.

References gw_assert, msg_type, and sms.

Referenced by smsc_at2_create(), and smsc_emi2_create().

00389 {
00390     int ret;
00391     Msg *msg1 = (Msg*)a, *msg2 = (Msg*)b;
00392     gw_assert(msg_type(msg1) == sms);
00393     gw_assert(msg_type(msg2) == sms);
00394     
00395     if (msg1->sms.priority > msg2->sms.priority)
00396         ret = 1;
00397     else if (msg1->sms.priority < msg2->sms.priority)
00398         ret = -1;
00399     else {
00400         if (msg1->sms.time > msg2->sms.time)
00401             ret = 1;
00402         else if (msg1->sms.time < msg2->sms.time)
00403             ret = -1;
00404         else
00405             ret = 0;
00406     }
00407     
00408     return ret;
00409 }

List* sms_split Msg orig,
Octstr header,
Octstr footer,
Octstr nonlast_suffix,
Octstr split_chars,
int  catenate,
unsigned long  msg_sequence,
int  max_messages,
int  max_octets
 

Definition at line 302 of file sms.c.

References DC_8BIT, DLR_IS_ENABLED, extract_msgdata_part_by_coding(), gwlist_append(), gwlist_create, gwlist_get(), msg_destroy(), msg_duplicate(), octstr_append(), octstr_destroy(), octstr_insert(), octstr_len(), prepend_catenation_udh(), sms_msgdata_len(), and uuid_generate().

Referenced by dispatch_datagram(), send_message(), and smscconn_send().

00306 {
00307     long max_part_len, udh_len, hf_len, nlsuf_len;
00308     unsigned long total_messages, msgno;
00309     long last;
00310     List *list;
00311     Msg *part, *temp;
00312 
00313     hf_len = octstr_len(header) + octstr_len(footer);
00314     nlsuf_len = octstr_len(nonlast_suffix);
00315     udh_len = octstr_len(orig->sms.udhdata);
00316 
00317     /* First check whether the message is under one-part maximum */
00318     if (orig->sms.coding == DC_8BIT || orig->sms.coding == DC_UCS2)
00319         max_part_len = max_octets - udh_len - hf_len;
00320     else
00321         max_part_len = (max_octets - udh_len) * 8 / 7 - hf_len;
00322 
00323     if (sms_msgdata_len(orig) > max_part_len && catenate) {
00324         /* Change part length to take concatenation overhead into account */
00325         if (udh_len == 0)
00326             udh_len = 1;  /* Add the udh total length octet */
00327         udh_len += CATENATE_UDH_LEN;
00328         if (orig->sms.coding == DC_8BIT || orig->sms.coding == DC_UCS2)
00329             max_part_len = max_octets - udh_len - hf_len;
00330         else
00331             max_part_len = (max_octets - udh_len) * 8 / 7 - hf_len;
00332     }
00333 
00334     /* ensure max_part_len is never negativ */
00335     max_part_len = max_part_len > 0 ? max_part_len : 0;
00336 
00337     temp = msg_duplicate(orig);
00338     msgno = 0;
00339     list = gwlist_create();
00340 
00341     last = 0;
00342     do {
00343         msgno++;
00344         part = msg_duplicate(orig);
00345 
00346         /* 
00347          * if its a DLR request message getting split, 
00348          * only ask DLR for the first one 
00349          */
00350         if ((msgno > 1) && DLR_IS_ENABLED(part->sms.dlr_mask)) {
00351             octstr_destroy(part->sms.dlr_url);
00352             part->sms.dlr_url = NULL;
00353             part->sms.dlr_mask = 0;
00354         }
00355         octstr_destroy(part->sms.msgdata);
00356         if (sms_msgdata_len(temp) <= max_part_len || msgno == max_messages)
00357             last = 1;
00358 
00359         part->sms.msgdata = 
00360             extract_msgdata_part_by_coding(temp, split_chars,
00361                                            max_part_len - nlsuf_len);
00362         /* create new id for every part, except last */
00363         if (!last)
00364             uuid_generate(part->sms.id);
00365 
00366         if (header)
00367             octstr_insert(part->sms.msgdata, header, 0);
00368         if (footer)
00369             octstr_append(part->sms.msgdata, footer);
00370         if (!last && nonlast_suffix)
00371             octstr_append(part->sms.msgdata, nonlast_suffix);
00372         gwlist_append(list, part);
00373     } while (!last);
00374 
00375     total_messages = msgno;
00376     msg_destroy(temp);
00377     if (catenate && total_messages > 1) {
00378         for (msgno = 1; msgno <= total_messages; msgno++) {
00379             part = gwlist_get(list, msgno - 1);
00380             prepend_catenation_udh(part, msgno, total_messages, msg_sequence);
00381         }
00382     }
00383 
00384     return list;
00385 }

Here is the call graph for this function:

int sms_swap Msg msg  ) 
 

Definition at line 201 of file sms.c.

Referenced by obey_request_thread().

00202 {
00203     Octstr *sender = NULL;
00204 
00205     if (msg->sms.sender != NULL && msg->sms.receiver != NULL) {
00206         sender = msg->sms.sender;
00207         msg->sms.sender = msg->sms.receiver;
00208         msg->sms.receiver = sender;
00209 
00210         return 1;
00211     }
00212 
00213     return 0;
00214 }

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.