He did sent at as an attachment. At least I got it as such. == Rene
-----Original Message----- From: devel-boun...@kannel.org [mailto:devel-boun...@kannel.org] On Behalf Of Alexander Malysh Sent: Tuesday, 14 September, 2010 17:44 To: Michael Zervakis Cc: devel@kannel.org 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:malys...@googlemail.com] On Behalf Of Alexander Malysh > Sent: Tuesday, September 14, 2010 1:02 AM > To: Michael Zervakis > Cc: devel@kannel.org; aguerri...@kannel.org > 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:aguerri...@kannel.org] > > > Sent: Monday, September 13, 2010 8:25 PM > > > To: Alexander Malysh > > > Cc: Michael Zervakis; malys...@googlemail.com; devel@kannel.org > > > 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 > > > > > > aguerri...@kannel.org > > > > > > > > > > > > > > > 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:malys...@googlemail.com] On Behalf Of Alexander Malysh > > > > > > >> Sent: Sunday, September 12, 2010 1:06 PM > > > > > > >> To: Michael Zervakis > > > > > > >> Cc: devel@kannel.org; pon...@appcell.net > > > > > > >> 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: devel-boun...@kannel.org [mailto:devel-boun...@kannel.org] On Behalf Of Konstantin Vayner > > > > > > >> > > > > > > >>> Sent: Thursday, December 17, 2009 12:28 PM > > > > > > >> > > > > > > >>> To: Alexander Malysh > > > > > > >> > > > > > > >>> Cc: devel@kannel.org > > > > > > >> > > > > > > >>> 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 <amal...@kannel.org> 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 <amal...@kannel.org> 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 */