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?...&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?...&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><meta-data>?smpp?my-data=Hello+World</meta-data></literal></para>
> + <para>XML: DATA_SM</para>
> +
<para><literal><meta-data>?smpp_data_sm?my-data=Hello+World</meta-data></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