RE: SMPP data_sm implementation for MT messages

Michael Zervakis <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi Alex,

    You mean that you prefer  "&metadata=?smpp?pdu_type=data_sm" over 
this "&metadata=?smpp_data_sm?" . In this case we'll have to change 
meta_data.c->*meta_data_unpack(const Octstr *data) to omit 
pdu_type=data_sm since this is not a TLV group.

Regards,

Michael Zervakis

-----Original Message-----
From: Alexander Malysh [mailto:[email protected]] On Behalf Of 
Alexander Malysh
Sent: Friday, July 23, 2010 10:17 PM
To: Michael Zervakis
Cc: [email protected]; [email protected]
Subject: Re: SMPP data_sm implementation for MT messages

 

Hi Michael,

 

please read bellow carefully about how metadata should be formatted...

 

Thanks,

Alexander Malysh

 

Am 22.07.2010 um 18:01 schrieb Michael Zervakis:

 

 > Hi ,

 >

 >

 > This is a proposed implementation for sending data_sm PDUs that also 
enforces SMPP requirement for having sm_length=0 when using 
message_payload TLV. To send a data_sm PDU the sendsms request should be 
like meta-data?smsc-type=smpp_data_sm?.

 > *msg_to_pdu() was replaced by two functions *msg_to_sm_pdu() and 
*msg_to_datasm_pdu() for submit_sm and data_sm() PDUs respectively and 
handle_pdu() got a new case for incoming data_sm_resp PDU.

 >

 > BR,

 >

 > Michael Zervakis

 >

 >

 > -----Original Message-----

 > From: Alexander Malysh [mailto:[email protected]] On Behalf Of 
Alexander Malysh

 > Sent: Friday, November 27, 2009 5:04 PM

 > To: Michael Zervakis

 > Cc: Kannel Devel; Alejandro Guerrieri

 > Subject: Re: SMPP data_sm implementation for MT messages

 >

 >

 > where do you have message_payload extracted to user?

 >

 >

 > that is simple:

 >

 >

 > MT(data_sm) -> sendsms?text=ABC&metadata=?smpp?pdu_type=data_sm... -> 
data_sm.message_payload=ABC

 >

 > MT(submit_sm) -> sendsms?text=ABC... -> submit_sm.short_message=ABC

 >

 >

 > MO(data_sm) -> data_sm.message_payload=ABC -> 
receivesms?text=ABC&metadata=?smpp?pdu_type=data_sm

 >

 > MO(submit_sm) -> submit_sm.short_message=ABC -> receivesms?text=ABC

 >

 >

 > If user set for MT 
text=ABC&metadata=?smpp?pdu_type=data_sm&message_payload=XXX then it's 
undefined and

 >

 > we are free to choose which one to use and I would prefer to use text 
as message_payload...

 >

 >

 > Hope that's clear.

 >

 >

 > Thanks,

 >

 > Alexander Malysh

 >

 >

 > Am 27.11.2009 um 15:21 schrieb Michael Zervakis:

 >

 >

 > >

 >

 > > Let's assume that we follow Alex's recommendation 
"meta-data=?smpp?operation=data_sm&..." and if operation is omitted we 
use submit_sm as default.

 >

 > >

 >

 > >

 >

 > > We should clarify what should happen to "text=xxxx" if set and this 
should affect both submit_sm and data_sm operations as SMPP specs state 
that short_message and message_payload cannot coexist in a PDU 
(sm_length should be zero if message_payload is used). I can think of 
three cases here:

 >

 > >

 >

 > > 1) When "text" has a value and "message_payload" is not set. For 
submit_sm no need to change anything. For data_sm we append meta-data 
with message_payload and set the value of "text" to it (example: 
"text=XXXX&meta-data=?smpp?operation=data_sm").

 >

 > > 2) When both "text" and "message_payload" have values. For 
submit_sm operation "text" value is set to null (so "sm_length" is set 
to 0 and we don't break specs) and we use the provided "message_payload" 
value. For data_sm operation we simply ignore "text" value.

 >

 > >

 >

 > > 3) When "message_payload" has a value and "text" is not set. Normal 
case doesn't break specs.

 >

 > >

 >

 > >

 >

 > >

 >

 > >

 >

 > >

 >

 > >> -----Original Message-----

 >

 > >> From: Alexander Malysh [mailto:[email protected]] On Behalf Of

 >

 > > Alexander Malysh

 >

 > >> Sent: Friday, November 27, 2009 3:32 PM

 >

 > >> To: Michael Zervakis

 >

 > >> Cc: [email protected]; [email protected]

 >

 > >> Subject: Re: SMPP data_sm implementation for MT messages

 >

 > >

 >

 > >

 >

 > >> Hi,

 >

 > >

 >

 > >

 >

 > >> why not just use metadata=?smpp?operation=data_sm&... ?

 >

 > >

 >

 > >> then you can check in smsc_smpp whether submit_sm or data_sm 
should be used.

 >

 > >

 >

 > >

 >

 > >> Whether you have to use message_payload or short_message is

 >

 > > implementation details that

 >

 > >

 >

 > >> should not be exported to user interface.

 >

 > >

 >

 > >

 >

 > >> Thanks,

 >

 > >

 >

 > >> Alexander Malysh

 >

 > >

 >

 > >

 >

 > >> Am 27.11.2009 um 13:00 schrieb Michael Zervakis:

 >

 > >

 >

 > >

 >

 > >> > Data_sm PDU cannot contain a short_message field. Actually data_sm

 >

 > > contains only TLVs and instead of "short_message" field we should 
use TLV "message_payload" to send text. As a result text=xxxx is 
obsolete when sending data_sm PDU. If we use data=xxxx what would be the 
value of data since all necessary data will be included in 
"meta-data=?smpp?"  ?

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> >> -----Original Message-----

 >

 > >

 >

 > >> >> From: Alejandro Guerrieri [mailto:[email protected]]

 >

 > >

 >

 > >> >> Sent: Friday, November 27, 2009 12:04 PM

 >

 > >

 >

 > >> >> To: Michael Zervakis

 >

 > >

 >

 > >> >> Cc: [email protected]

 >

 > >

 >

 > >> >> Subject: Re: SMPP data_sm implementation for MT messages

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >What about using "data=xxxx" instead of "text=xxxx" ?

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >--

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >Alejandro Guerrieri

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >[email protected]

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >

 >

 > >

 >

 > >> > >

 >

 > >

 >

 > >> > >

 >

 > >

 >

 > >> > >On 27/11/2009, at 10:00, Michael Zervakis wrote:

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >

 >

 > >

 >

 > >> > >> Data_sm can be used as an alternate of submit_sm when 
transmitting

 >

 > >

 >

 > >> > >> optional parameters (meta-data) and some carriers require the 
use of

 >

 > >

 >

 > >> > >> data_sm for MT charging applications.

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> Since Kannel is not implementing this feature it's a good idea to

 >

 > >

 >

 > >> > >> start a discussion on how this could be implemented.

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >>

 >

 > >

 >

 > >> > >> First of all it's obvious that "static int send_messages()" at gw

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> \smsc\smsc_smpp.c must be able to differentiate msgs that 
need to be

 >

 > >

 >

 > >> > >> sent as data_sm.

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> I can think of two ways to achieve this:

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> 1) Alter MSG definition to inlcude a new parameter that 
defines type

 >

 > >

 >

 > >> > >> of message Data or normal SMS

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> Possible ways to use the new parameter could be the following

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> /cgi-bin/sendsms?from=1111&to=2222&<new 
parameter>=data&meta-data=?

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> smpp?key=value

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> /cgi-bin/senddata?from=1111&to=2222&meta-data=?smpp?key=value

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> 2) Leave MSG definition untouched and use meta-data to mark 
msg as

 >

 > >

 >

 > >> > >> data

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> /cgi-bin/sendsms?from=1111&to=2222&meta-data=?smpp?<new

 >

 > >

 >

 > >> > >> parameter>=data&key=value

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >>

 >

 > >

 >

 > >> > >> Finally a new function has to be defined at 
gw\smsc\smsc_smpp.c to

 >

 > >

 >

 > >> > >> build data_sm pdu from msg for example "static SMPP_PDU

 >

 > >

 >

 > >> > >> *dmsg_to_pdu(SMPP *smpp, Msg *msg)"

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >> and function "static int handle_pdu()" at gw\smsc\smsc_smpp.c 
has to

 >

 > >

 >

 > >> > >> be modified to include a case for data_sm_resp PDU.

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >>

 >

 > >

 >

 > >> > >> Any comments?

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >> > >>

 >

 > >

 >

 > >> > >>

 >

 > >

 >

 > >> >

 >

 > >

 >

 > >

 >

 >

 > Index: doc/userguide/userguide.xml

 > ===================================================================

 > --- doc/userguide/userguide.xml   (revision 4833)

 > +++ doc/userguide/userguide.xml   (working copy)

 > @@ -9781,12 +9781,14 @@

 >         </sect3>

 >       </sect2>

 >       <sect2>

 > -        <title>MT Messages</title>

 > +        <title>MT Messages SUBMIT_SM or DATA_SM</title>

 >         <para>To send into an MT messages the 
<literal>meta-data</literal> parameter should be used.</para>

 >

 >         <para>The format used to pass the data has 2 parts: The 
<literal>?smsc-type?</literal> (surrounded by question marks),

 > -        which specify the kind of smsc receiving the data (at the 
moment only <literal>smpp</literal> is implemented) and then a set of 
key/value

 > -        pairs with the data to be transmitted. Extra smsc-types can 
be added surrounded by question marks and followed by the key/value 
pairs.</para>

 > +        which specify the kind of smsc receiving the data and then a 
set of key/value pairs with the data to be transmitted.

 > +        Currently only SMPP is implemented with two possible values 
for <literal>?smsc-type?</literal>: <literal>smpp</literal>

 > +        for SUBMIT_SM PDUs and <literal>smpp_data_sm</literal>) for 
DATA_SM PDUs.

 > +        Extra smsc-types can be added surrounded by question marks 
and followed by the key/value pairs.</para>

 >

 >         <para>In other words,  the data should be coded using the 
following format, where URLENCODE() implies that the data between 
parentheses should

 >         be urlencoded:</para>

 > @@ -9800,14 +9802,26 @@

 >

 >           <sect3>

 >             <title>Examples</title>

 > -           <para>If we want to send the parameter "my-data" with 
value "Hello World" to an SMSC over SMPP, we'd use:</para>

 > +           <para>If we want to send the parameter "my-data" with 
value "Hello World" to an SMSC over SMPP using SUBMIT_SM PDU, we'd 
use:</para>

 >             <para>sendsms get-url:</para>

 >     
        <para><literal>http://localhost:13013/cgi-bin/sendsms?...&amp;meta-data=%3Fsmpp%3Fmy-data%3DHello%2BWorld</literal></para>

 > +            <para>Similarly if we want to send the above using 
DATA_SM PDU, we'd use:</para>

 > +           <para>sendsms get-url:</para>

 > +           
<para><literal>http://localhost:13013/cgi-bin/sendsms?...&amp;meta-data=%3Fsmpp_data_sm%3Fmy-data%3DHello%2BWorld</literal></para>

 >           <para>sendsms post:</para>

 >           <para>Send <literal>?smpp?my-data=Hello+World</literal> on 
the <literal>X-Kannel-Meta-Data</literal> header</para>

 > -          <para>XML:</para>

 > +          <para>XML: SUBMIT_SM</para>

 >           
<para><literal>&lt;meta-data&gt;?smpp?my-data=Hello+World&lt;/meta-data&gt;</literal></para>

 > +          <para>XML: DATA_SM</para>

 > +          
<para><literal>&lt;meta-data&gt;?smpp_data_sm?my-data=Hello+World&lt;/meta-data&gt;</literal></para>

 >           </sect3>

 > +

 > +          </sect3>

 > +            <title>SMPP TLV message_payload (0x0424)</title>

 > +            <para>SMPP message_payload TLV is an alternative to 
submit_sm short_message when sending messages longer than 255 octets.

 > +                  When sending submit_sm PDU with message_payload 
then short_message should be null. Kannel enforces this restriction

 > +                  by ignoring supplied values for 
<literal>text</literal> if <literal>message_payload</literal> TLV is 
present.</para>

 > +          </sect3>

 >       </sect2>

 >     </sect1>

 > </appendix>

 > Index: gw/smsc/smsc_smpp.c

 > ===================================================================

 > --- gw/smsc/smsc_smpp.c     (revision 4833)

 > +++ gw/smsc/smsc_smpp.c     (working copy)

 > @@ -747,14 +747,12 @@

 > }

 >

 >

 > -static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)

 > +static SMPP_PDU *msg_to_sm_pdu(SMPP_PDU *pdu, Msg *msg, SMPP *smpp)

 > {

 > -    SMPP_PDU *pdu;

 > +

 >     int validity;

 > -

 > -    pdu = smpp_pdu_create(submit_sm,

 > -                       counter_increase(smpp->message_id_counter));

 > -

 > +

 > +

 >     pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);

 >     pdu->u.submit_sm.destination_addr = 
octstr_duplicate(msg->sms.receiver);

 >

 > @@ -876,9 +874,41 @@

 >     /*

 >      * set data segments and length

 >      */

 > -

 > -    pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);

 > -

 > +   

 > +    /*

 > +     If a message contains both msg_data and meta_data and within 
meta_data is contained the tlv message_payload

 > +     then ignore smg_data field forward message's meta_data and 
print a warning message

 > +     */

 > +   

 > +   

 > +    if((octstr_len(msg->sms.msgdata)) && 
(octstr_len(msg->sms.meta_data)))

 > +    {  

 > +        debug("bb.sms.smpp", 0, "msg->sms.msgdata = [%s] and 
msg->sms.meta_data !=[%s]", 
octstr_get_cstr(msg->sms.msgdata),octstr_get_cstr(msg->sms.meta_data));

 > +       

 > +        if(octstr_search(msg->sms.meta_data, 
octstr_imm("message_payload"),0)!=-1)

 > +        {

 > +            pdu->u.submit_sm.short_message == NULL;

 > +            pdu->u.submit_sm.sm_length = 0;

 > +            warning(0, "SMPP[%s]: Ignoring msg->sms.msgdata = [%s] 
because msg->sms.meta_data(message_payload)= [%s] TLV message_payload 
was found ",

 > +                    
octstr_get_cstr(smpp->conn->id),octstr_get_cstr(msg->sms.msgdata),octstr_get_cstr(msg->sms.meta_data));

 > +           

 > +        }

 > +        else

 > +        {

 > +            pdu->u.submit_sm.short_message = 
octstr_duplicate(msg->sms.msgdata);

 > +            pdu->u.submit_sm.sm_length = 
octstr_len(pdu->u.submit_sm.short_message);

 > +           

 > +        }

 > +    }

 > +    else

 > +    {

 > +        pdu->u.submit_sm.short_message = 
octstr_duplicate(msg->sms.msgdata);

 > +        pdu->u.submit_sm.sm_length = 
octstr_len(pdu->u.submit_sm.short_message);

 > +       

 > +    }

 > +   

 > +    /*pdu->u.submit_sm.short_message = 
octstr_duplicate(msg->sms.msgdata);*/

 > +   

 >     /*

 >      * only re-encoding if using default smsc charset that is defined via

 >      * alt-charset in smsc group and if MT is not binary

 > @@ -908,9 +938,9 @@

 >     if (octstr_len(msg->sms.udhdata)) {

 >         octstr_insert(pdu->u.submit_sm.short_message, 
msg->sms.udhdata, 0);

 >     }

 > -

 > -    pdu->u.submit_sm.sm_length = 
octstr_len(pdu->u.submit_sm.short_message);

 > -

 > +

 >     /*

 >      * check for validity and defered settings

 >      * were message value has higher priiority then smsc config group 
value

 > @@ -958,6 +988,228 @@

 > }

 >

 >

 > +/* Function to create a data_sm pdu

 > +

 > + Pdu fields:

 > +

 > + (common to both sumbit_sm and data_sm)

 > + 1. command length

 > + 2. command id

 > + 3. command status

 > + 4. sequence number

 > + 5. service type

 > + 6. source_addr_ton

 > + 7. source_addr_npi

 > + 8. source_addr

 > + 9. dest_addr_ton

 > + 10. dest_addr_npi

 > + 11.destnation_addr

 > + 12. esm_class

 > + 13. registered_delivery

 > + 14. data_coding

 > + 15. Optional TLVs

 > +

 > + */

 > +

 > +static SMPP_PDU *msg_to_datasm_pdu(SMPP_PDU *pdu, Msg *msg, SMPP *smpp)

 > +{

 > +

 > +

 > +    pdu->u.data_sm.source_addr = octstr_duplicate(msg->sms.sender);

 > +

 > +    pdu->u.data_sm.destination_addr = 
octstr_duplicate(msg->sms.receiver);

 > +

 > +

 > +    /* Set the service type of the outgoing message. We'll use the 
config

 > +     * directive as default and 'binfo' as specific parameter. */

 > +    pdu->u.data_sm.service_type = octstr_len(msg->sms.binfo) ?

 > +    octstr_duplicate(msg->sms.binfo) : 
octstr_duplicate(smpp->service_type);

 > +

 > +

 > +

 > +    /* Check for manual override of source ton and npi values */

 > +    if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {

 > +        pdu->u.data_sm.source_addr_ton = smpp->source_addr_ton;

 > +        pdu->u.data_sm.source_addr_npi = smpp->source_addr_npi;

 > +        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source 
addr ton = %d, source add npi = %d",

 > +              octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,

 > +              smpp->source_addr_npi);

 > +    } else {

 > +        /* setup default values */

 > +        pdu->u.data_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* 
national */

 > +        pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN 
number plan */

 > +    }

 > +

 > +    if (pdu->u.data_sm.source_addr && smpp->autodetect_addr) {

 > +        /* lets see if its international or alphanumeric sender */

 > +        if (octstr_get_char(pdu->u.data_sm.source_addr, 0) == '+') {

 > +            if (!octstr_check_range(pdu->u.data_sm.source_addr, 1, 
256, gw_isdigit)) {

 > +                pdu->u.data_sm.source_addr_ton = 
GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */

 > +                pdu->u.data_sm.source_addr_npi = 
GSM_ADDR_NPI_UNKNOWN;    /* short code */

 > +                if (smpp->alt_addr_charset) {

 > +                    if 
(octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {

 > +                        /* @ would break PDU if converted into GSM*/

 > +                        octstr_replace(pdu->u.data_sm.source_addr, 
octstr_imm("@"), octstr_imm("?"));

 > +                        charset_utf8_to_gsm(pdu->u.data_sm.source_addr);

 > +                    } else if 
(charset_convert(pdu->u.data_sm.source_addr, SMPP_DEFAULT_CHARSET, 
octstr_get_cstr(smpp->alt_addr_charset)) != 0)

 > +                        error(0, "Failed to convert source_addr from 
charset <%s> to <%s>, will send as is.",

 > +                              SMPP_DEFAULT_CHARSET, 
octstr_get_cstr(smpp->alt_addr_charset));

 > +                }

 > +            } else {

 > +                /* numeric sender address with + in front -> 
international (remove the +) */

 > +                octstr_delete(pdu->u.data_sm.source_addr, 0, 1);

 > +                pdu->u.data_sm.source_addr_ton = 
GSM_ADDR_TON_INTERNATIONAL;

 > +            }

 > +        } else {

 > +            if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 
256, gw_isdigit)) {

 > +                pdu->u.data_sm.source_addr_ton = 
GSM_ADDR_TON_ALPHANUMERIC;

 > +                pdu->u.data_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;

 > +                if (smpp->alt_addr_charset) {

 > +                    if 
(octstr_str_case_compare(smpp->alt_addr_charset, "gsm") == 0) {

 > +                        /* @ would break PDU if converted into GSM */

 > +                        octstr_replace(pdu->u.data_sm.source_addr, 
octstr_imm("@"), octstr_imm("?"));

 > +                        charset_utf8_to_gsm(pdu->u.data_sm.source_addr);

 > +                    } else if 
(charset_convert(pdu->u.data_sm.source_addr, SMPP_DEFAULT_CHARSET, 
octstr_get_cstr(smpp->alt_addr_charset)) != 0)

 > +                        error(0, "Failed to convert source_addr from 
charset <%s> to <%s>, will send as is.",

 > +                              SMPP_DEFAULT_CHARSET, 
octstr_get_cstr(smpp->alt_addr_charset));

 > +                }

 > +            }

 > +        }

 > +    }

 > +

 > +

 > +    /* Check for manual override of destination ton and npi values */

 > +    if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {

 > +        pdu->u.data_sm.dest_addr_ton = smpp->dest_addr_ton;

 > +        pdu->u.data_sm.dest_addr_npi = smpp->dest_addr_npi;

 > +        debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr 
ton = %d, dest add npi = %d",

 > +              octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,

 > +              smpp->dest_addr_npi);

 > +    } else {

 > +        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* 
national */

 > +        pdu->u.data_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN 
number plan */

 > +    }

 > +

 > +    /*

 > +     * if its a international number starting with +, lets remove the

 > +     * '+' and set number type to international instead

 > +     */

 > +    if (octstr_get_char(pdu->u.data_sm.destination_addr,0) == '+') {

 > +        octstr_delete(pdu->u.data_sm.destination_addr, 0,1);

 > +        pdu->u.data_sm.dest_addr_ton = GSM_ADDR_TON_INTERNATIONAL;

 > +    }

 > +   

 > +    /* check length of src/dst address */

 > +    if (octstr_len(pdu->u.data_sm.destination_addr) > 20 ||

 > +        octstr_len(pdu->u.data_sm.source_addr) > 20) {

 > +        smpp_pdu_destroy(pdu);

 > +        return NULL;

 > +    }

 > +

 > +    /*

 > +     * set the data coding scheme (DCS) field

 > +     * check if we have a forced value for this from the smsc-group.

 > +     * Note: if message class is set, then we _must_ force alt_dcs 
otherwise

 > +     * dcs has reserved values (e.g. mclass=2, dcs=0x11). We check 
MWI flag

 > +     * first here, because MWI and MCLASS can not be set at the same 
time and

 > +     * function fields_to_dcs check MWI first, so we have no need to 
force alt_dcs

 > +     * if MWI is set.

 > +     */

 > +    if (msg->sms.mwi == MWI_UNDEF && msg->sms.mclass != MC_UNDEF)

 > +        pdu->u.data_sm.data_coding = fields_to_dcs(msg, 1); /* force 
alt_dcs */

 > +    else

 > +        pdu->u.data_sm.data_coding = fields_to_dcs(msg,

 > +                                                   (msg->sms.alt_dcs 
!= SMS_PARAM_UNDEFINED ?

 > +                                                    msg->sms.alt_dcs 
: smpp->conn->alt_dcs));

 > +

 > +

 > +    /*

 > +     * set the esm_class field

 > +     * default is store and forward, plus udh and rpi if requested

 > +     */

 > +    pdu->u.data_sm.esm_class = ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE;

 > +    if (octstr_len(msg->sms.udhdata))

 > +        pdu->u.data_sm.esm_class = pdu->u.submit_sm.esm_class |

 > +        ESM_CLASS_SUBMIT_UDH_INDICATOR;

 > +    if (msg->sms.rpi > 0)

 > +        pdu->u.data_sm.esm_class = pdu->u.submit_sm.esm_class |

 > +        ESM_CLASS_SUBMIT_RPI;

 > +

 > +

 > +    /* ask for the delivery reports if needed */

 > +    if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask))

 > +        pdu->u.data_sm.registered_delivery = 1;

 > +    else if (DLR_IS_FAIL(msg->sms.dlr_mask) && 
!DLR_IS_SUCCESS(msg->sms.dlr_mask))

 > +        pdu->u.data_sm.registered_delivery = 2;

 > +

 > +    if (DLR_IS_INTERMEDIATE(msg->sms.dlr_mask))

 > +        pdu->u.data_sm.registered_delivery += 16;

 > +

 > +

 > +

 > +    /* set more messages to send */

 > +    if (smpp->version > 0x33 && msg->sms.msg_left > 0)

 > +        pdu->u.data_sm.more_messages_to_send = 1;

 > +

 > +    dict_destroy(pdu->u.data_sm.tlv);

 > +

 > +    /* search within meta_data group for smpp_data_sm */

 > +    pdu->u.data_sm.tlv = meta_data_get_values(msg->sms.meta_data, 
"smpp_data_sm");

 > +

 > +    /*pdu->u.data_sm.data_coding = 1;*/

 > +

 > +

 > +    return pdu;

 > +}

 > +

 > +

 > +

 > +/* Procedure for deternining the type of pdu to build :

 > + 1. Submit_sm message will be build by the msg_to_pdu when the field 
meta_data is empty

 > + or when within the meta_data mesage field there is not a string of 
the form "pdu_type=data_sm".

 > + 2. Else when the meta_data is not empty and contains a string of 
the form "pdu_type=data_sm" the

 > + pdu that is going to be build will be a data_sm pdu.

 > + */

 > +

 > +static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg)

 > +{

 > +    SMPP_PDU *pdu;

 > +    unsigned long pdu_type =0;

 > +   

 > +    /* make sure we are not searching within a null string */

 > +    if(octstr_len(msg->sms.meta_data) == 0)

 > +    {   

 > +        pdu_type = submit_sm;

 > +        debug("bb.sms.smpp", 0, "msg_to_pdu : pdu_type = submit_sm");

 > +    }   

 > +    else if(octstr_search(msg->sms.meta_data, 
octstr_imm("?smpp_data_sm?"),0)==-1)

 > +    {

 > +        pdu_type = submit_sm;      

 > +        debug("bb.sms.smpp", 0, "msg_to_pdu : pdu_type = submit_sm");

 > +    }

 > +    else

 > +    {       

 > +        pdu_type = data_sm;   

 > +        debug("bb.sms.smpp", 0, "msg_to_pdu : pdu_type = data_sm");

 > +    }

 > +

 > +

 > +    /* kltsa : 07/07/2010 : submit_sm will now passed as parameter 
pdu_type */

 > +    pdu = 
smpp_pdu_create(pdu_type,counter_increase(smpp->message_id_counter));

 > +

 > +    switch (pdu_type)

 > +    {

 > +        case data_sm  : pdu = msg_to_datasm_pdu(pdu,msg,smpp);

 > +            break;/*add other cases here*/

 > +        default: pdu = msg_to_sm_pdu(pdu,msg,smpp);

 > +            break;

 > +    }

 > +

 > +    return pdu;

 > +}   

 > +

 > +

 > +

 > static int send_enquire_link(SMPP *smpp, Connection *conn, long 
*last_sent)

 > {

 >     SMPP_PDU *pdu;

 > @@ -1073,7 +1325,21 @@

 >         /* check for write errors */

 >         if (send_pdu(conn, smpp->conn->id, pdu) == 0) {

 >             struct smpp_msg *smpp_msg = smpp_msg_create(msg);

 > -            os = octstr_format("%ld", pdu->u.submit_sm.sequence_number);

 > +

 > +            /* Check for sequence number errors depending on pdu type */

 > +            if(pdu->type == submit_sm)

 > +            {

 > +                os = octstr_format("%ld", 
pdu->u.submit_sm.sequence_number);

 > +                debug("bb.sms.smpp", 0, "send_messages : pdu->type = 
submit_sm");

 > +            }

 > +            else if(pdu->type == data_sm)

 > +            {

 > +                os = octstr_format("%ld", 
pdu->u.data_sm.sequence_number);

 > +                debug("bb.sms.smpp", 0, "send_messages : pdu->type = 
data_sm");

 > +            }

 > +            else

 > +                error(0, "send_messages : :unknown pdu type = 
[%lu]!\n",pdu->type);

 > +

 >             dict_put(smpp->sent_msgs, os, smpp_msg);

 >             smpp_pdu_destroy(pdu);

 >             octstr_destroy(os);

 > @@ -1504,9 +1770,72 @@

 >                 msg->sms.smsc_id = octstr_duplicate(smpp->conn->id);

 >                 reason =  bb_smscconn_receive(smpp->conn, msg);

 >                 resp->u.data_sm_resp.command_status = 
smscconn_failure_reason_to_smpp_status(reason);

 > -           }

 > -           break;

 > -

 > +            }

 > +            break;

 > +        case data_sm_resp:

 > +            os = octstr_format("%ld", 
pdu->u.data_sm_resp.sequence_number);

 > +            smpp_msg = dict_remove(smpp->sent_msgs, os);

 > +            octstr_destroy(os);

 > +            if (smpp_msg == NULL) {

 > +                warning(0, "SMPP[%s]: SMSC sent data_sm_resp "

 > +                        "with wrong sequence number 0x%08lx",

 > +                        octstr_get_cstr(smpp->conn->id),

 > +                        pdu->u.data_sm_resp.sequence_number);

 > +                break;

 > +            }

 > +            msg = smpp_msg->msg;

 > +            smpp_msg_destroy(smpp_msg, 0);

 > +            if (pdu->u.data_sm_resp.command_status != 0) {

 > +                error(0, "SMPP[%s]: SMSC returned error code 0x%08lx 
(%s) "

 > +                      "in response to data_sm.",

 > +                      octstr_get_cstr(smpp->conn->id),

 > +                      pdu->u.data_sm_resp.command_status,

 > +                      
smpp_error_to_string(pdu->u.data_sm_resp.command_status));

 > +                reason = smpp_status_to_smscconn_failure_reason(

 > +                                                                
pdu->u.data_sm_resp.command_status);

 > +

 > +                /*

 > +                 * check to see if we got a "throttling error", in 
which case we'll just

 > +                 * sleep for a while

 > +                 */

 > +                if (pdu->u.data_sm_resp.command_status == 
SMPP_ESME_RTHROTTLED)

 > +                    time(&(smpp->throttling_err_time));

 > +                else

 > +                    smpp->throttling_err_time = 0;

 > +

 > +                bb_smscconn_send_failed(smpp->conn, msg, reason, 
octstr_format("0x%08lx/%s", pdu->u.data_sm_resp.command_status,

 > 
+                                                                               
smpp_error_to_string(pdu->u.data_sm_resp.command_status)));

 > +                --(*pending_submits);

 > +            } else {

 > +                Octstr *tmp;

 > +

 > +                /* check if msg_id is C string, decimal or hex for 
this SMSC */

 > +                if (smpp->smpp_msg_id_type == -1) {

 > +                    /* the default, C string */

 > +                    tmp = 
octstr_duplicate(pdu->u.data_sm_resp.message_id);

 > +                } else {

 > +                    if ((smpp->smpp_msg_id_type & 0x01) ||

 > +                        
(!octstr_check_range(pdu->u.data_sm_resp.message_id, 0,

 > +                                             
octstr_len(pdu->u.data_sm_resp.message_id), gw_isdigit))) {

 > +                        tmp = octstr_format("%llu", strtoll(  /* hex */

 > +                       
                                     octstr_get_cstr(pdu->u.data_sm_resp.message_id), 
NULL, 16));

 > +                    } else {

 > +                        tmp = octstr_format("%llu", strtoll(  /* 
decimal */

 > +                                            
                octstr_get_cstr(pdu->u.data_sm_resp.message_id), NULL, 10));

 > +                    }

 > +                }

 > +

 > +                /* SMSC ACK.. now we have the message id. */

 > +                if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask))

 > +                    dlr_add(smpp->conn->id, tmp, msg);

 > +

 > +                octstr_destroy(tmp);

 > +                bb_smscconn_sent(smpp->conn, msg, NULL);

 > +                --(*pending_submits);

 > +            } /* end if for SMSC ACK */

 > +            break;

 > +

 >         case deliver_sm:

 >            /*

 >             * If SMSCConn stopped then send temp. error code
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.