RE: [PATCH] fix bug #529 (sms-resend-* ignored for concatenated messages)

"Rene Kluwen" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
He did sent at as an attachment. At least I got it as such.

== Rene

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf
Of Alexander Malysh
Sent: Tuesday, 14 September, 2010 17:44
To: Michael Zervakis
Cc: [email protected]
Subject: Re: [PATCH] fix bug #529 (sms-resend-* ignored for concatenated
messages)

could you please send your patch as attachment ?

Thanks,
Alexander Malysh

Am 14.09.2010 um 16:09 schrieb Michael Zervakis:

> 
> Hi,
> 
> I moved smscconn_uuid to struct split_parts. Please check.
> 
> BR,
> 
> -----Original Message-----
> From: Alexander Malysh [mailto:[email protected]] On Behalf Of
Alexander Malysh
> Sent: Tuesday, September 14, 2010 1:02 AM
> To: Michael Zervakis
> Cc: [email protected]; [email protected]
> Subject: Re: [PATCH] fix bug #529 (sms-resend-* ignored for concatenated
messages)
> 
> 
> Hi Michael,
> 
> 
> you don't have to alter Msg struct. Just add smscconn_uuid to struct
split_parts in gw/msg.h.
> 
> 
> Thanks,
> 
> Alexander Malysh
> 
> 
> Am 13.09.2010 um 21:31 schrieb Michael Zervakis:
> 
> 
> >
> 
> >
> 
> > Hi,
> 
> >
> 
> > I forgot to mention that msg->msg_ConnId uuid is not saved in store
since it's useless because if the process restarts the whole Msg will be
resend. At least this solution will apply sms-resend-* directives for long
sms.
> 
> >
> 
> > BR,
> 
> >
> 
> > -----Original Message-----
> 
> > From: Alejandro Guerrieri [mailto:[email protected]]
> 
> > Sent: Monday, September 13, 2010 8:25 PM
> 
> > To: Alexander Malysh
> 
> > Cc: Michael Zervakis; [email protected]; [email protected]
> 
> > Subject: Re: [PATCH] fix bug #529 (sms-resend-* ignored for concatenated
messages)
> 
> >
> 
> >
> 
> > The uuid would be different each time you start the service right?
> 
> >
> 
> >
> 
> > What would happen if Kannel is restarted and there were pending parts to
send? The new uuid wouldn't match with the pending segments.
> 
> >
> 
> >
> 
> > Regards,
> 
> >
> 
> > --
> 
> >
> 
> > Alejandro Guerrieri
> 
> >
> 
> > [email protected]
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > On 13/09/2010, at 19:16, Alexander Malysh wrote:
> 
> >
> 
> >
> 
> > > Hi,
> 
> >
> 
> > >
> 
> >
> 
> > > great idea to use uuid to uniquely identify smscconn. we can use this
for http admin as well.
> 
> >
> 
> > >
> 
> >
> 
> > > Thanks,
> 
> >
> 
> > > Alexander Malysh
> 
> >
> 
> > >
> 
> >
> 
> > > Am 13.09.2010 um 19:04 schrieb Michael Zervakis:
> 
> >
> 
> > >
> 
> >
> 
> > >> Hi,
> 
> >
> 
> > >>
> 
> >
> 
> > >> I figured out that we can use the same mechanism as in Msg struct to
uniquelly identify each SMSCconn. In the attached patch the smscconn struct
was modified to include a uuid_t field and Msg struct to store the smscconn
uuid_t if we get a temporary error. Smsc_rout2 was also modified to respect
msg->msg_ConnId if set.
> 
> >
> 
> > >>
> 
> >
> 
> > >> SMSC-A -> splits (2 parts) -> 1 part sent OK -> 2 part get temp.
error -> write the conn->uuid_t and put it into global queue for resend  ->
router reads msg->msg_ConnId and sends failed part via same connection (if
still active)
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> -----Original Message-----
> 
> >
> 
> > >> From: Alexander Malysh [mailto:[email protected]] On Behalf Of
Alexander Malysh
> 
> >
> 
> > >> Sent: Sunday, September 12, 2010 1:06 PM
> 
> >
> 
> > >> To: Michael Zervakis
> 
> >
> 
> > >> Cc: [email protected]; [email protected]
> 
> >
> 
> > >> Subject: Re: [PATCH] fix bug #529 (sms-resend-* ignored for
concatenated messages)
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> Hi,
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> as I already wrote, this patch is not enough. Please see ML wy...
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> Thanks,
> 
> >
> 
> > >>
> 
> >
> 
> > >> Alexander Malysh
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> Am 09.09.2010 um 19:04 schrieb Michael Zervakis:
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Hi,
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> This patch is a possible solution fog Bug #529. The Msg definition
was modified so we can store the conn->id originally selected by router.
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> SMSC-A -> splits (2 parts) -> 1 part sent OK -> 2 part get temp.
error -> write the conn->id and put it into global queue for resend  ->
router reads msg->sms.msg_ConnId and sends failed part via same connection
(if still active)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Regards,
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> From: [email protected] [mailto:[email protected]] On
Behalf Of Konstantin Vayner
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Sent: Thursday, December 17, 2009 12:28 PM
> 
> >
> 
> > >>
> 
> >
> 
> > >>> To: Alexander Malysh
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Cc: [email protected]
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Subject: Re: [PATCH] fix bug #529 (sms-resend-* ignored for
concatenated messages)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> why remembering smsc-id in sms.smsc_id is not enough?
> 
> >
> 
> > >>
> 
> >
> 
> > >>> how does smsbox remember routing when i submit a message with
predefined smsc id from http (sendsms) ?
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> On Thu, Dec 17, 2009 at 12:10 PM, Alexander Malysh
<[email protected]> wrote:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Am 17.12.2009 um 10:43 schrieb Konstantin Vayner:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> so the best option would be to requeue the part via same smsc, right
?
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> yes, but it's not easy todo. You have to remember SMSC pointer not
only SMSC-name/id and then teach all routing parts
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> to respect it...
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> cause requeueing all parts may also get extra messages to the
handset despite it not being able to reconstruct (not to mention the extra
money ;) )
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> On Thu, Dec 17, 2009 at 11:33 AM, Alexander Malysh
<[email protected]> wrote:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Hi,
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> unfortunately this will not work as expected (the rule is: _all_
parts if multipart message have to be send via the same SMSC)...
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> example:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>          SMSC-A -> splits (2 parts) -> 1 part sent OK -> 2 part get
temp. error -> you put it into global queue for resend -> 2 part sent via
SMSC-B -> handset rejects it
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> We have only two possibility here:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> 1) if temp error occurs put the _whole_ message into resend queue
and resend then _all_ parts (very easy todo)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> 2) remember smsc which was used for first parts and resend it via
the same smsc (complicated but save money :) )
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Thanks,
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Alexander Malysh
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Am 16.12.2009 um 18:17 schrieb Konstantin Vayner:
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Bug report: http://redmine.kannel.org/issues/show/529
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Quote from gw/bb_smscconn.c :
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> static void handle_split(SMSCConn *conn, Msg *msg, long reason)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> {
> 
> >
> 
> > >>
> 
> >
> 
> > >>>  struct split_parts *split = msg->sms.split_parts;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>  /*
> 
> >
> 
> > >>
> 
> >
> 
> > >>>   * If temporarely failed, try again immediately but only if
connection active.
> 
> >
> 
> > >>
> 
> >
> 
> > >>>   * Because if connection is not active we will loop for ever here
consuming 100% CPU
> 
> >
> 
> > >>
> 
> >
> 
> > >>>   * time due to internal queue cleanup in smsc module that call
bb_smscconn_failed.
> 
> >
> 
> > >>
> 
> >
> 
> > >>>   */
> 
> >
> 
> > >>
> 
> >
> 
> > >>>  if (reason == SMSCCONN_FAILED_TEMPORARILY && smscconn_status(conn)
== SMSCCONN_ACTIVE &&
> 
> >
> 
> > >>
> 
> >
> 
> > >>>      smscconn_send(conn, msg) == 0) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>>      /* destroy this message because it will be duplicated in smsc
module */
> 
> >
> 
> > >>
> 
> >
> 
> > >>>      msg_destroy(msg);
> 
> >
> 
> > >>
> 
> >
> 
> > >>>      return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>  }
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> (end quote)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> So, if an smsc is alive and throws temporary error every time you
try to submit such a message, we enter endless loop of attempting to resend
it....
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Suggested patch follows (also attached).
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Sorry its not cvs diff - having firewall issues accessing pserver
now so i ran diff vs snapshot generated yesterday
> 
> >
> 
> > >>
> 
> >
> 
> > >>> I will be able to produce a normal cvs diff tomorrow morning if it
is needed
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> --- kannel-snapshot/gw/bb_smscconn.c    2009-11-15
16:12:28.000000000 +0200
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +++ gateway-cvs/gw/bb_smscconn.c        2009-12-16
19:47:32.000000000 +0200
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -203,18 +203,6 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>>   struct split_parts *split = msg->sms.split_parts;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>      /*
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -     * If temporarely failed, try again immediately but only if
connection active.
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -     * Because if connection is not active we will loop for ever
here consuming 100% CPU
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -     * time due to internal queue cleanup in smsc module that call
bb_smscconn_failed.
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -     */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -    if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE &&
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        smscconn_send(conn, msg) == 0) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        /* destroy this message because it will be duplicated in
smsc module */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        msg_destroy(msg);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -   -    /*
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    * if the reason is not a success and status is still success
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    * then set status of a split to the reason.
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    * Note: reason 'malformed','discarded' or 'rejected' has higher
priority!
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -303,7 +291,7 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>> void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason,
Octstr *reply)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -    if (sms->sms.split_parts != NULL) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    if (reason != SMSCCONN_FAILED_TEMPORARILY &&
sms->sms.split_parts != NULL) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>>       handle_split(conn, sms, reason);
> 
> >
> 
> > >>
> 
> >
> 
> > >>>       octstr_destroy(reply);
> 
> >
> 
> > >>
> 
> >
> 
> > >>>       return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> <bb_smscconn.diff>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Index: gw/bb_smscconn.c
> 
> >
> 
> > >>
> 
> >
> 
> > >>> ===================================================================
> 
> >
> 
> > >>
> 
> >
> 
> > >>> --- gw/bb_smscconn.c  (revision 4838)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +++ gw/bb_smscconn.c  (working copy)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -207,11 +207,34 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>>     * Because if connection is not active we will loop for ever here
consuming 100% CPU
> 
> >
> 
> > >>
> 
> >
> 
> > >>>     * time due to internal queue cleanup in smsc module that call
bb_smscconn_failed.
> 
> >
> 
> > >>
> 
> >
> 
> > >>>     */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -    if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE &&
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        smscconn_send(conn, msg) == 0) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    /*if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE &&
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +        smscconn_send(conn, msg) == 0) { */
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        /* destroy this message because it will be duplicated in smsc
module */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> -        msg_destroy(msg);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    /*    msg_destroy(msg);
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    }*/
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +     
> > >>> + 
> > >>> +
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       if (sms_resend_retry >= 0 && msg->sms.resend_try >=
sms_resend_retry) /*check how many times the split message has been sent */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       {
> 
> >
> 
> > >>> +          warning(0, "SMPP[%s] :Maximum retries for message [%s]
exceeded resend %ld times, discarding it!", octstr_get_cstr(conn->id),
octstr_get_cstr(msg->sms.msgdata),msg->sms.resend_try);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          handle_split(conn, msg, SMSCCONN_FAILED_DISCARDED);
> 
> >
> 
> > >>> +          /* msg_destroy(msg); */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       
> > >>> +       warning(0, "SMPP[%s] :Split message failed temporarily
sending back to sms_router", octstr_get_cstr(conn->id));
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    
> > >>> +       msg->sms.resend_try = (msg->sms.resend_try > 0 ?
msg->sms.resend_try + 1 : 1);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       debug("bb.sms.splits", 0, "SMPP[%s] :Resend counter of
message set to %ld", octstr_get_cstr(conn->id),msg->sms.resend_try);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       time(&msg->sms.resend_time);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       msg->sms.msg_ConnId = octstr_duplicate(conn->id);
> 
> >
> 
> > >>> +     
> > >>> +       gwlist_produce(outgoing_sms, msg); /* write it back to
global queue */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       return;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    /*
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -1229,6 +1252,28 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    bp_load = bo_load = queue_length = 0;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    conn = NULL;
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    /* if msg was a failed part then route to the defined SMSC
connection */
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    if (msg->sms.msg_ConnId != NULL)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    { 
> > >>> +       for (i=0; i < gwlist_len(smsc_list); i++)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          conn = gwlist_get(smsc_list,  i);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          smscconn_info(conn, &info);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          queue_length += (info.queued > 0 ? info.queued : 0);
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       
> > >>> +          if(octstr_compare(msg->sms.msg_ConnId, conn->id) == 0)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          {
> 
> >
> 
> > >>> +             if((smscconn_usable(conn,msg) != -1) && (info.status
== SMSCCONN_ACTIVE && info.queued < max_queue))
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +             {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +                best_preferred = conn;
> 
> >
> 
> > >>> +                debug("bb.sms",0,"Message with pre-set connection
to SMSC[%s] found",octstr_get_cstr(msg->sms.msg_ConnId));
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +                continue;
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +             }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +          }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +       }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    else
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    {
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    for (i=0; i < gwlist_len(smsc_list); i++) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    conn = gwlist_get(smsc_list,  (i+s) % gwlist_len(smsc_list));
> 
> >
> 
> > >>
> 
> >
> 
> > >>>
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -1265,6 +1310,8 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        bo_load = info.load;
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>> + 
> > >>>    queue_length += gwlist_len(outgoing_sms);
> 
> >
> 
> > >>
> 
> >
> 
> > >>>    if (max_outgoing_sms_qlength > 0 && !resend &&
> 
> >
> 
> > >>
> 
> >
> 
> > >>>         queue_length > gwlist_len(smsc_list) *
max_outgoing_sms_qlength) {
> 
> >
> 
> > >>
> 
> >
> 
> > >>> Index: gw/msg-decl.h
> 
> >
> 
> > >>
> 
> >
> 
> > >>> ===================================================================
> 
> >
> 
> > >>
> 
> >
> 
> > >>> --- gw/msg-decl.h     (revision 4838)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +++ gw/msg-decl.h     (working copy)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> @@ -85,6 +85,7 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        OCTSTR(msgdata)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        INTEGER(time)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        OCTSTR(smsc_id)
> 
> >
> 
> > >>
> 
> >
> 
> > >>> +        OCTSTR(msg_ConnId); /* field required to reroute
concatenated Msg parts via the same SMSC connection. Bug 529*/
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        OCTSTR(smsc_number)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        OCTSTR(foreign_id)
> 
> >
> 
> > >>
> 
> >
> 
> > >>>        OCTSTR(service)
> 
> >
> 
> > >>
> 
> >
> 
> > >>
> 
> >
> 
> > >> Index: bb_smscconn.c
> 
> >
> 
> > >> ===================================================================
> 
> >
> 
> > >> --- bb_smscconn.c    (revision 4843)
> 
> >
> 
> > >> +++ bb_smscconn.c    (working copy)
> 
> >
> 
> > >> @@ -201,17 +201,46 @@
> 
> >
> 
> > >> static void handle_split(SMSCConn *conn, Msg *msg, long reason)
> 
> >
> 
> > >> {
> 
> >
> 
> > >>    struct split_parts *split = msg->sms.split_parts;
> 
> >
> 
> > >> +    char id[UUID_STR_LEN + 1];
> 
> >
> 
> > >>
> 
> >
> 
> > >> +  
> > >>    /*
> 
> >
> 
> > >>     * If temporarely failed, try again immediately but only if
connection active.
> 
> >
> 
> > >>     * Because if connection is not active we will loop for ever here
consuming 100% CPU
> 
> >
> 
> > >>     * time due to internal queue cleanup in smsc module that call
bb_smscconn_failed.
> 
> >
> 
> > >>     */
> 
> >
> 
> > >> -    if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE &&
> 
> >
> 
> > >> -        smscconn_send(conn, msg) == 0) {
> 
> >
> 
> > >> +    /*if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE &&
> 
> >
> 
> > >> +        smscconn_send(conn, msg) == 0) { */
> 
> >
> 
> > >>        /* destroy this message because it will be duplicated in smsc
module */
> 
> >
> 
> > >> -        msg_destroy(msg);
> 
> >
> 
> > >> +    /*    msg_destroy(msg);
> 
> >
> 
> > >>        return;
> 
> >
> 
> > >> +    }*/
> 
> >
> 
> > >> +      
> > >> +  
> > >> +    if (reason == SMSCCONN_FAILED_TEMPORARILY &&
smscconn_status(conn) == SMSCCONN_ACTIVE)
> 
> >
> 
> > >> +    {
> 
> >
> 
> > >> +       if (sms_resend_retry >= 0 && msg->sms.resend_try >=
sms_resend_retry) /*check how many times the split message has been sent */
> 
> >
> 
> > >> +       {
> 
> > >> +          uuid_unparse(msg->sms.id, id);
> 
> >
> 
> > >> +          warning(0, "SMPP[%s] :Maximum retries for message [%s]
exceeded resend %ld times, discarding it!", octstr_get_cstr(conn->id), id,
msg->sms.resend_try);
> 
> >
> 
> > >> +          handle_split(conn, msg, SMSCCONN_FAILED_DISCARDED);
> 
> > >> +          return;
> 
> >
> 
> > >> +       }
> 
> >
> 
> > >> +                  
> > >> +      
> > >> +       uuid_unparse(msg->sms.id, id);
> 
> >
> 
> > >> +       warning(0, "SMPP[%s] :Split message [%s] failed temporary
sending it to sms_router but with fixed connection",
octstr_get_cstr(conn->id), id);
> 
> > >> +       
> > >> +       msg->sms.resend_try = (msg->sms.resend_try > 0 ?
msg->sms.resend_try + 1 : 1); /* inc its retries */
> 
> >
> 
> > >> +       debug("bb.sms.splits", 0, "SMPP[%s] :Resend counter of
message [%s]  set to %ld", octstr_get_cstr(conn->id), id,
msg->sms.resend_try);
> 
> >
> 
> > >> +       time(&msg->sms.resend_time); /* take resend time - this will
be used in sms_router */
> 
> >
> 
> > >> +            
> > >> +      
> > >> +       if(uuid_is_null(msg->msg_ConnId) == 1)
> 
> >
> 
> > >> +         uuid_copy(msg->msg_ConnId, conn->smscconn_uuid);
> 
> >
> 
> > >> +      
> > >> +       gwlist_produce(outgoing_sms, msg); /* send it back to global
queue */
> 
> >
> 
> > >> +       return;
> 
> >
> 
> > >>    }
> 
> >
> 
> > >>
> 
> >
> 
> > >>    /*
> 
> >
> 
> > >> @@ -1187,8 +1216,8 @@
> 
> >
> 
> > >>    long bp_load, bo_load;
> 
> >
> 
> > >>    int i, s, ret, bad_found, full_found;
> 
> >
> 
> > >>    long max_queue, queue_length;
> 
> >
> 
> > >> -    char *uf;
> 
> >
> 
> > >> -
> 
> >
> 
> > >> +    char *uf, id[UUID_STR_LEN + 1];
> 
> >
> 
> > >> +  
> > >>    /* XXX handle ack here? */
> 
> >
> 
> > >>    if (msg_type(msg) != sms) {
> 
> >
> 
> > >>        error(0, "Attempt to route non SMS message through
smsc2_rout!");
> 
> >
> 
> > >> @@ -1229,6 +1258,29 @@
> 
> >
> 
> > >>    bp_load = bo_load = queue_length = 0;
> 
> >
> 
> > >>
> 
> >
> 
> > >>    conn = NULL;
> 
> >
> 
> > >> +    /*if msg was a split and failed temporary then use stored
connection */
> 
> >
> 
> > >> +    if(uuid_is_null(msg->msg_ConnId) != 1)
> 
> >
> 
> > >> +    {  
> > >> +       for (i=0; i < gwlist_len(smsc_list); i++)
> 
> >
> 
> > >> +       {
> 
> >
> 
> > >> +          conn = gwlist_get(smsc_list,  i);
> 
> >
> 
> > >> +          smscconn_info(conn, &info);
> 
> >
> 
> > >> +          queue_length += (info.queued > 0 ? info.queued : 0);
> 
> >
> 
> > >> +        
> > >> +          if(uuid_compare(msg->msg_ConnId, conn->smscconn_uuid) ==
0)
> 
> >
> 
> > >> +          {
> 
> > >> +             if((smscconn_usable(conn,msg) != -1) && (info.status ==
SMSCCONN_ACTIVE && info.queued < max_queue))
> 
> >
> 
> > >> +             {
> 
> >
> 
> > >> +                best_preferred = conn;
> 
> > >> +                uuid_unparse(msg->sms.id, id);
> 
> >
> 
> > >> +                debug("bb.sms",0,"Message [%s] with pre-set
connection found", id);
> 
> >
> 
> > >> +                continue;
> 
> >
> 
> > >> +             }
> 
> >
> 
> > >> +          }
> 
> >
> 
> > >> +       }
> 
> >
> 
> > >> +    }
> 
> >
> 
> > >> +    else
> 
> >
> 
> > >> +    {
> 
> >
> 
> > >>    for (i=0; i < gwlist_len(smsc_list); i++) {
> 
> >
> 
> > >>    conn = gwlist_get(smsc_list,  (i+s) % gwlist_len(smsc_list));
> 
> >
> 
> > >>
> 
> >
> 
> > >> @@ -1265,6 +1317,8 @@
> 
> >
> 
> > >>        bo_load = info.load;
> 
> >
> 
> > >>    }
> 
> >
> 
> > >>    }
> 
> >
> 
> > >> +    }
> 
> >
> 
> > >> +  
> > >>    queue_length += gwlist_len(outgoing_sms);
> 
> >
> 
> > >>    if (max_outgoing_sms_qlength > 0 && !resend &&
> 
> >
> 
> > >>         queue_length > gwlist_len(smsc_list) *
max_outgoing_sms_qlength) {
> 
> >
> 
> > >> Index: msg.c
> 
> >
> 
> > >> ===================================================================
> 
> >
> 
> > >> --- msg.c      (revision 4843)
> 
> >
> 
> > >> +++ msg.c      (working copy)
> 
> >
> 
> > >> @@ -98,6 +98,7 @@
> 
> >
> 
> > >>    msg = gw_malloc_trace(sizeof(Msg), file, line, func);
> 
> >
> 
> > >>
> 
> >
> 
> > >>    msg->type = type;
> 
> >
> 
> > >> +    uuid_clear(msg->msg_ConnId);
> 
> >
> 
> > >> #define INTEGER(name) p->name = MSG_PARAM_UNDEFINED;
> 
> >
> 
> > >> #define OCTSTR(name) p->name = NULL;
> 
> >
> 
> > >> #define UUID(name) uuid_generate(p->name);
> 
> >
> 
> > >> @@ -113,7 +114,7 @@
> 
> >
> 
> > >>    Msg *new;
> 
> >
> 
> > >>
> 
> >
> 
> > >>    new = msg_create(msg->type);
> 
> >
> 
> > >> -
> 
> >
> 
> > >> +    uuid_copy(new->msg_ConnId, msg->msg_ConnId);
> 
> >
> 
> > >> #define INTEGER(name) p->name = q->name;
> 
> >
> 
> > >> #define OCTSTR(name) \
> 
> >
> 
> > >>    if (q->name == NULL) p->name = NULL; \
> 
> >
> 
> > >> Index: msg.h
> 
> >
> 
> > >> ===================================================================
> 
> >
> 
> > >> --- msg.h      (revision 4843)
> 
> >
> 
> > >> +++ msg.h      (working copy)
> 
> >
> 
> > >> @@ -78,7 +78,7 @@
> 
> >
> 
> > >>
> 
> >
> 
> > >> typedef struct {
> 
> >
> 
> > >>    enum msg_type type;
> 
> >
> 
> > >> -
> 
> >
> 
> > >> +    uuid_t msg_ConnId;     
> > >>    #define INTEGER(name) long name;
> 
> >
> 
> > >>    #define OCTSTR(name) Octstr *name;
> 
> >
> 
> > >>    #define UUID(name) uuid_t name;
> 
> >
> 
> > >> Index: smscconn.c
> 
> >
> 
> > >> ===================================================================
> 
> >
> 
> > >> --- smscconn.c (revision 4843)
> 
> >
> 
> > >> +++ smscconn.c (working copy)
> 
> >
> 
> > >> @@ -157,13 +157,16 @@
> 
> >
> 
> > >>    Octstr *denied_prefix_regex;
> 
> >
> 
> > >>    Octstr *preferred_prefix_regex;
> 
> >
> 
> > >>    Octstr *tmp;
> 
> >
> 
> > >> -
> 
> >
> 
> > >> +    char id[UUID_STR_LEN + 1];
> 
> >
> 
> > >> +      
> > >>    if (grp == NULL)
> 
> >
> 
> > >>    return NULL;
> 
> >
> 
> > >>
> 
> >
> 
> > >>    conn = gw_malloc(sizeof(*conn));
> 
> >
> 
> > >>    memset(conn, 0, sizeof(*conn));
> 
> >
> 
> > >>
> 
> >
> 
> > >> +    uuid_generate(conn->smscconn_uuid);
> 
> >
> 
> > >> +          
> > >>    conn->why_killed = SMSCCONN_ALIVE;
> 
> >
> 
> > >>    conn->status = SMSCCONN_CONNECTING;
> 
> >
> 
> > >>    conn->connect_time = -1;
> 
> >
> 
> > >> @@ -295,7 +298,10 @@
> 
> >
> 
> > >>    gw_assert(conn->send_msg != NULL);
> 
> >
> 
> > >>
> 
> >
> 
> > >>    bb_smscconn_ready(conn);
> 
> >
> 
> > >> -
> 
> >
> 
> > >> +  
> > >> +    uuid_unparse(conn->smscconn_uuid, id);
> 
> >
> 
> > >> +    debug("smscconn",0,"Adding smsc connection [%s] with id [%s]",
octstr_get_cstr(conn->id), id);
> 
> >
> 
> > >> +  
> > >>    return conn;
> 
> >
> 
> > >> }
> 
> >
> 
> > >>
> 
> >
> 
> > >> Index: smscconn_p.h
> 
> >
> 
> > >> ===================================================================
> 
> >
> 
> > >> --- smscconn_p.h     (revision 4843)
> 
> >
> 
> > >> +++ smscconn_p.h     (working copy)
> 
> >
> 
> > >> @@ -146,6 +146,8 @@
> 
> >
> 
> > >> #include "smscconn.h"
> 
> >
> 
> > >>
> 
> >
> 
> > >> struct smscconn {
> 
> >
> 
> > >> +    /* variable added in order to uniquely identify each smsc
connection */
> 
> >
> 
> > >> +    uuid_t smscconn_uuid;
> 
> >
> 
> > >>    /* variables set by appropriate SMSCConn driver */
> 
> >
> 
> > >>    smscconn_status_t status;           /* see smscconn.h */
> 
> >
> 
> > >>    int   load;             /* load factor, 0 = no load */
> 
> >
> 
> > >
> 
> >
> 
> > >
> 
> >
> 
> >
> 
> 
> Index: gw/bb_smscconn.c
> ===================================================================
> --- gw/bb_smscconn.c	(revision 4843)
> +++ gw/bb_smscconn.c	(working copy)
> @@ -201,17 +201,46 @@
> static void handle_split(SMSCConn *conn, Msg *msg, long reason)
> {
>     struct split_parts *split = msg->sms.split_parts;
> +    char id[UUID_STR_LEN + 1];
> 
> +    
>     /*
>      * If temporarely failed, try again immediately but only if connection
active.
>      * Because if connection is not active we will loop for ever here
consuming 100% CPU
>      * time due to internal queue cleanup in smsc module that call
bb_smscconn_failed.
>      */
> -    if (reason == SMSCCONN_FAILED_TEMPORARILY && smscconn_status(conn) ==
SMSCCONN_ACTIVE &&
> -        smscconn_send(conn, msg) == 0) {
> +    /*if (reason == SMSCCONN_FAILED_TEMPORARILY && smscconn_status(conn)
== SMSCCONN_ACTIVE &&
> +        smscconn_send(conn, msg) == 0) { */
>         /* destroy this message because it will be duplicated in smsc
module */
> -        msg_destroy(msg);
> +    /*    msg_destroy(msg);
>         return;
> +    }*/
> +        
> +    
> +    if (reason == SMSCCONN_FAILED_TEMPORARILY && smscconn_status(conn) ==
SMSCCONN_ACTIVE)
> +    {
> +       if (sms_resend_retry >= 0 && msg->sms.resend_try >=
sms_resend_retry)
> +       {  
> +          uuid_unparse(msg->sms.id, id);
> +          warning(0, "SMSC [%s]: Maximum retries for message [%s]
exceeded resend %ld times, discarding it!", octstr_get_cstr(conn->id), id,
msg->sms.resend_try); 
> +          handle_split(conn, msg, SMSCCONN_FAILED_DISCARDED);  
> +          return;
> +       }
> +                    
> +        
> +       uuid_unparse(msg->sms.id, id);
> +       warning(0, "SMSC [%s]: Split message [%s] failed temporary
appending smsc uuid", octstr_get_cstr(conn->id), id);  
> +       
> +       msg->sms.resend_try = (msg->sms.resend_try > 0 ?
msg->sms.resend_try + 1 : 1);
> +       debug("bb.sms.splits", 0, "SMSC[%s]: Resend counter of message
[%s] set to %ld", octstr_get_cstr(conn->id), id, msg->sms.resend_try);
> +       time(&msg->sms.resend_time); 
> +              
> +        
> +       if(uuid_is_null(split->msg_ConnId) == 1)
> +         uuid_copy(split->msg_ConnId, conn->smscconn_uuid);
> +       
> +       gwlist_produce(outgoing_sms, msg); /* send it back to global queue
*/ 
> +       return;
>     }
> 
>     /*
> @@ -1187,8 +1216,9 @@
>     long bp_load, bo_load;
>     int i, s, ret, bad_found, full_found;
>     long max_queue, queue_length;
> -    char *uf;
> -
> +    char *uf, id[UUID_STR_LEN + 1];
> +    struct split_parts *split = msg->sms.split_parts;
> +    
>     /* XXX handle ack here? */
>     if (msg_type(msg) != sms) {
>         error(0, "Attempt to route non SMS message through smsc2_rout!");
> @@ -1229,6 +1259,32 @@
>     bp_load = bo_load = queue_length = 0;
> 
>     conn = NULL;
> +    /* if msg was a split and failed temporary then use last known
connection */
> +    if(split != NULL)
> +    {    
> +       if(uuid_is_null(split->msg_ConnId) != 1)
> +       {    
> +          for (i=0; i < gwlist_len(smsc_list); i++)
> +          {
> +             conn = gwlist_get(smsc_list,  i);
> +             smscconn_info(conn, &info);
> +             queue_length += (info.queued > 0 ? info.queued : 0); 
> +          
> +             if(uuid_compare(split->msg_ConnId, conn->smscconn_uuid) ==
0)
> +             {  
> +                if((smscconn_usable(conn,msg) != -1) && (info.status ==
SMSCCONN_ACTIVE && info.queued < max_queue))
> +                {
> +                   best_preferred = conn;  
> +                   uuid_unparse(msg->sms.id, id);
> +                   debug("bb.sms",0,"Message [%s] with pre-set smsc uuid
found", id);
> +                   continue; /* break; */ 
> +                } 
> +             }  
> +          } 
> +       } 
> +    } 
> +    else
> +    {
>     for (i=0; i < gwlist_len(smsc_list); i++) {
> 	conn = gwlist_get(smsc_list,  (i+s) % gwlist_len(smsc_list));
> 
> @@ -1265,6 +1321,8 @@
> 	    bo_load = info.load;
> 	}
>     }
> +    }
> +    
>     queue_length += gwlist_len(outgoing_sms);
>     if (max_outgoing_sms_qlength > 0 && !resend &&
>          queue_length > gwlist_len(smsc_list) * max_outgoing_sms_qlength)
{
> Index: gw/msg.h
> ===================================================================
> --- gw/msg.h	(revision 4843)
> +++ gw/msg.h	(working copy)
> @@ -85,12 +85,14 @@
> 	#define VOID(name) void *name;
> 	#define MSG(type, stmt) struct type stmt type;
> 	#include "msg-decl.h"
> +    
> } Msg;
> 
> struct split_parts {
>     Msg *orig;
>     Counter *parts_left;
>     long status;
> +    uuid_t msg_ConnId;
> };
> 
> /* enums for Msg fields */
> Index: gw/smscconn.c
> ===================================================================
> --- gw/smscconn.c	(revision 4843)
> +++ gw/smscconn.c	(working copy)
> @@ -157,13 +157,16 @@
>     Octstr *denied_prefix_regex;
>     Octstr *preferred_prefix_regex;
>     Octstr *tmp;
> -
> +    char id[UUID_STR_LEN + 1];
> +        
>     if (grp == NULL)
> 	return NULL;
> 
>     conn = gw_malloc(sizeof(*conn));
>     memset(conn, 0, sizeof(*conn));
> 
> +    uuid_generate(conn->smscconn_uuid);
> +            
>     conn->why_killed = SMSCCONN_ALIVE;
>     conn->status = SMSCCONN_CONNECTING;
>     conn->connect_time = -1;
> @@ -295,7 +298,10 @@
>     gw_assert(conn->send_msg != NULL);
> 
>     bb_smscconn_ready(conn);
> -
> +    
> +    uuid_unparse(conn->smscconn_uuid, id);
> +    debug("smscconn",0,"Adding smsc connection [%s] with uuid [%s]",
octstr_get_cstr(conn->id), id);
> +    
>     return conn;
> }
> 
> Index: gw/smscconn_p.h
> ===================================================================
> --- gw/smscconn_p.h	(revision 4843)
> +++ gw/smscconn_p.h	(working copy)
> @@ -146,6 +146,8 @@
> #include "smscconn.h"
> 
> struct smscconn {
> +    /* variable added in order to uniquely identify each smsc connection
*/ 
> +    uuid_t smscconn_uuid;
>     /* variables set by appropriate SMSCConn driver */
>     smscconn_status_t status;		/* see smscconn.h */
>     int 	load;	       	/* load factor, 0 = no load */
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.