Hi, as no objections were here, commited to SVN.
Alex Am 24.09.2010 um 17:42 schrieb Alexander Malysh: > Hi Michael, > > just thought about your patch a little bit more and don't see why we need > uuid for each SMSCConn except for admin purpose. > But for this issue we don't need it. > > Please check attached patch that should fix this issue. > > Thanks, > Alexander Malysh > > <bug529.patch> > > 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 */ >