Find attached my patch for SMPP bits and pieces.
It is a combined patch (sorry) including:
1. configurable TON and NPI (modified from Alex Judd>
2. unbind when shutting down
3. configurable default priority for SMS messages
4. configurable throughput to limit (throttle) sending SMS rate to SMPP SMSC
5. Makefile.in changes, added install -d $(DESTDIR)$(... etc...
facilitating consistent builds using RPM non-root)
(I apologise for some of the spacing differences...)
On Thursday, 2002-03-21 at 08:43:56 AM, Benjamin Lee scribbled:
> Well, actually nothing smart... we were sleeping when we received a
> THROTTLE off packet from the SMSC but this behaviour isn't actually
> specified in the protocol as far as I know; and such a sleep may or may not
> help with the connection to the SMSC.
>
> The throughtput is set in the .conf file with:
>
> throughput = 20
>
> 20 being 20 messages per second.
>
> On Wednesday, 2002-03-20 at 11:26:05 PM, Kita Ndara scribbled:
> > What's the principle? Do you detect certain types of
> > errors and re-queue? I can do some testing on my end
> > too, see if it helps more generally.
> >
> > Let's see it!
> >
> > Thanks.
> >
> > --- Benjamin Lee <[EMAIL PROTECTED]> wrote: > I
> > finally got around to doing a throughput patch for
> > > SMPP... I'll post it
> > > shortly.
> > >
> > > On Wednesday, 2002-03-20 at 10:29:26 PM, Kita Ndara
> > > scribbled:
> > > > Hi
> > > > I have another issue. When I use kannel to
> > > originate
> > > > messages to many phone numbers, sometimes the SMSC
> > > > (Comverse) returns errors and rejects some of the
> > > > messages. If I slow down the rate at which I'm
> > > > submitting the messages to the SMSC, then it works
> > > > fine. Is there a way for kannel to kind of
> > > > automatically back off from sending too fast in
> > > such
> > > > cases?
> > > >
> > > > Thanks.
> > > >
> > > > =====
> > > > Bruce Ndara
> > > > York Messaging
> > > >
> > > > __________________________________________________
> > > > Do You Yahoo!?
> > > > Everything you'll ever need on one web page
> > > > from News and Sport to Email and Music Charts
> > > > http://uk.my.yahoo.com
> > >
> > > --
> > > Benjamin Lee
> > >
> > > 71-75 City Rd, South Melbourne, VIC 3006 Australia
> > > http://www.dotwap.com/
> > > Phone +61 3 9698 1840 Mobile +61 414 717 573 Fax
> > > +61 3 9698 1841
> >
> > __________________________________________________
> > Do You Yahoo!?
> > Everything you'll ever need on one web page
> > from News and Sport to Email and Music Charts
> > http://uk.my.yahoo.com
>
> --
> Benjamin Lee
>
> 71-75 City Rd, South Melbourne, VIC 3006 Australia http://www.dotwap.com/
> Phone +61 3 9698 1840 Mobile +61 414 717 573 Fax +61 3 9698 1841
--
Benjamin Lee
71-75 City Rd, South Melbourne, VIC 3006 Australia http://www.dotwap.com/
Phone +61 3 9698 1840 Mobile +61 414 717 573 Fax +61 3 9698 1841
Index: Makefile.in
===================================================================
RCS file: /home/cvs/gateway/Makefile.in,v
retrieving revision 1.56
diff -u -r1.56 Makefile.in
--- Makefile.in 23 Jan 2002 18:33:00 -0000 1.56
+++ Makefile.in 22 Mar 2002 04:12:46 -0000
@@ -228,12 +228,12 @@
dummy:
install: all
- $(INSTALL) -d $(bindir)
+ $(INSTALL) -d $(DESTDIR)$(bindir)
for prog in $(binprogs); do \
$(INSTALL) $$prog \
$(DESTDIR)$(bindir)/`basename $$prog`$(suffix); \
done
- $(INSTALL) -d $(sbindir)
+ $(INSTALL) -d $(DESTDIR)$(sbindir)
for prog in $(sbinprogs); do \
$(INSTALL) $$prog \
$(DESTDIR)$(sbindir)/`basename $$prog`$(suffix); \
Index: gw/smpp_pdu.def
===================================================================
RCS file: /home/cvs/gateway/gw/smpp_pdu.def,v
retrieving revision 1.3
diff -u -r1.3 smpp_pdu.def
--- gw/smpp_pdu.def 8 Nov 2001 08:41:23 -0000 1.3
+++ gw/smpp_pdu.def 22 Mar 2002 04:12:48 -0000
@@ -162,6 +162,10 @@
HEADER
)
+PDU(generic_nack_resp,
+ 0x80000000,
+ HEADER
+)
#undef PDU
#undef INTEGER
Index: gw/smsc_smpp.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc_smpp.c,v
retrieving revision 1.51
diff -u -r1.51 smsc_smpp.c
--- gw/smsc_smpp.c 29 Jan 2002 21:38:36 -0000 1.51
+++ gw/smsc_smpp.c 22 Mar 2002 04:12:48 -0000
@@ -70,6 +70,12 @@
Octstr *username;
Octstr *password;
Octstr *address_range;
+ int source_addr_ton;
+ int source_addr_npi;
+ int dest_addr_ton;
+ int dest_addr_npi;
+ int throughput; /* limit sending rate */
+ int priority; /* set default priority for messages */
int transmit_port;
int receive_port;
int quitting;
@@ -80,7 +86,10 @@
static SMPP *smpp_create(SMSCConn *conn, Octstr *host, int transmit_port,
int receive_port, Octstr *system_type,
Octstr *username, Octstr *password,
- Octstr *address_range)
+ Octstr *address_range, int source_addr_ton,
+ int source_addr_npi, int dest_addr_ton,
+ int dest_addr_npi,
+ int throughput, int priority)
{
SMPP *smpp;
@@ -97,6 +106,14 @@
smpp->username = octstr_duplicate(username);
smpp->password = octstr_duplicate(password);
smpp->address_range = octstr_duplicate(address_range);
+ smpp->source_addr_ton = source_addr_ton;
+ smpp->source_addr_npi = source_addr_npi;
+ smpp->dest_addr_ton = dest_addr_ton;
+ smpp->dest_addr_npi = dest_addr_npi;
+
+ smpp->throughput = throughput;
+ smpp->priority = priority;
+
smpp->transmit_port = transmit_port;
smpp->receive_port = receive_port;
smpp->quitting = 0;
@@ -207,33 +224,45 @@
pdu = smpp_pdu_create(submit_sm,
counter_increase(smpp->message_id_counter));
- pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
- pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
- pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
- pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
-
pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);
pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);
+
+ /* Check for manual override of source ton and npi values */
+ if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {
+ pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;
+ pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;
+ } else {
+ pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+ pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
- /* lets see if its international or alphanumeric sender */
- if( octstr_get_char(pdu->u.submit_sm.source_addr,0) == '+') {
- if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {
- pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum
*/
- pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
- }
- else {
- /* numeric sender address with + in front -> international*/
- octstr_delete(pdu->u.submit_sm.source_addr,0,1);
- pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
- }
- }
- else {
- if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {
- pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
- pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
- }
+ /* lets see if its international or alphanumeric sender */
+ if( octstr_get_char(pdu->u.submit_sm.source_addr,0) == '+') {
+ if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256,
+gw_isdigit)) {
+ pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /*
+alphanum */
+ pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
+ }
+ else {
+ /* numeric sender address with + in front -> international*/
+ octstr_delete(pdu->u.submit_sm.source_addr,0,1);
+ pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;
+ }
+ }
+ else {
+ if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {
+ pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;
+ pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;
+ }
+ }
+ }
+
+ /* Check for manual override of destination ton and npi values */
+ if(smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {
+ pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;
+ pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;
+ } else {
+ pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */
+ pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */
}
-
/* if its a international number starting with +, lets remove the
'+' and set number type to international instead */
@@ -251,12 +280,23 @@
} else {
pdu->u.submit_sm.short_message = octstr_duplicate(msg->sms.msgdata);
if(pdu->u.submit_sm.data_coding == 0 ) /*no reencoding for unicode! */
- charset_latin1_to_gsm(pdu->u.submit_sm.short_message);
+ charset_latin1_to_gsm(pdu->u.submit_sm.short_message);
}
/* ask for the delivery reports if needed */
if (msg->sms.dlr_mask & (DLR_SUCCESS|DLR_FAIL))
pdu->u.submit_sm.registered_delivery = 1;
+
+ if ( smpp->priority > 0 && smpp->priority < 5 ) {
+
+ pdu->u.submit_sm.priority_flag = smpp->priority;
+
+ } else {
+ /* default priority is 0 */
+ pdu->u.submit_sm.priority_flag = 0;
+
+ }
+
return pdu;
}
@@ -280,6 +320,21 @@
}
+static void send_unbind(SMPP *smpp, Connection *conn)
+{
+ SMPP_PDU *pdu;
+ Octstr *os;
+
+ pdu = smpp_pdu_create(unbind,
+ counter_increase(smpp->message_id_counter));
+ dump_pdu("Sending unbind:", pdu);
+ os = smpp_pdu_pack(pdu);
+ conn_write(conn, os); /* Write errors checked by caller. */
+ octstr_destroy(os);
+ smpp_pdu_destroy(pdu);
+}
+
+
static int send_pdu(Connection *conn, SMPP_PDU *pdu)
{
Octstr *os;
@@ -298,11 +353,23 @@
Msg *msg;
SMPP_PDU *pdu;
Octstr *os;
+
+ unsigned long delay = 0; /* sleep delay for throttling */
if (*pending_submits == -1)
return;
while (*pending_submits < SMPP_MAX_PENDING_SUBMITS) {
+
+ if ( smpp->throughput != 0 ) {
+ delay = 1000000 / smpp->throughput;
+ }
+
+ debug("bb.sms.smpp", 0, "SMPP: delay: %d", delay);
+
+ /* throttle */
+ usleep(delay);
+
/* Get next message, quit if none to be sent */
msg = list_extract_first(smpp->msgs_to_send);
if (msg == NULL)
@@ -623,6 +690,18 @@
}
break;
+ case generic_nack_resp:
+ {
+ error(0, "SMPP: NACK PDU type 0x%08lx, "
+ "code 0x%08lx.",
+ pdu->type, pdu->u.generic_nack_resp.command_status);
+
+ }
+ break;
+
+ case unbind_resp:
+ break;
+
default:
error(0, "SMPP: Unknown PDU type 0x%08lx, ignored.",
pdu->type);
@@ -697,6 +776,27 @@
for (;;) {
timeout = last_enquire_sent + SMPP_ENQUIRE_LINK_INTERVAL
- date_universal_now();
+
+ /* unbind... */
+ if (smpp->quitting) {
+ /* if we are quitting */
+
+ send_unbind(smpp, conn);
+
+ /* handle unbind_resp */
+ while ((ret = read_pdu(conn, &len, &pdu)) == 1) {
+ /* Deal with the PDU we just got */
+ dump_pdu("Got PDU:", pdu);
+ handle_pdu(smpp, conn, pdu, &pending_submits);
+ smpp_pdu_destroy(pdu);
+ }
+
+ debug("bb.sms.smpp", 0, "SMPP: %s: break and shutting down",
+__PRETTY_FUNCTION__);
+
+ /* the next if statement will do the real quit */
+ }
+ /* end unbind */
+
if (smpp->quitting || conn_wait(conn, timeout) == -1)
break;
@@ -804,6 +904,13 @@
Octstr *system_id;
Octstr *system_type;
Octstr *address_range;
+ long source_addr_ton;
+ long source_addr_npi;
+ long dest_addr_ton;
+ long dest_addr_npi;
+ long throughput;
+ long priority;
+
SMPP *smpp;
int ok;
@@ -817,6 +924,24 @@
system_type = cfg_get(grp, octstr_imm("system-type"));
address_range = cfg_get(grp, octstr_imm("address-range"));
+ /* if the ton and npi values are forced, set them, else set them to -1 */
+ cfg_get_integer(&source_addr_ton, grp, octstr_imm("source-addr-ton"));
+ cfg_get_integer(&source_addr_npi, grp, octstr_imm("source-addr-npi"));
+ cfg_get_integer(&dest_addr_ton, grp, octstr_imm("dest-addr-ton"));
+ cfg_get_integer(&dest_addr_npi, grp, octstr_imm("dest-addr-npi"));
+
+ /* throughput limits the rate at which messages are sent to the SMPP SMSC */
+ /* if it is not specified, set to 0, which means no limit */
+ if ( cfg_get_integer(&throughput, grp, octstr_imm("throughput")) == -1 ) {
+ throughput = 0;
+ }
+ debug("bb.sms.smpp", 0, "SMPP: throughtput: %d", throughput);
+
+ if ( cfg_get_integer(&priority, grp, octstr_imm("priority")) == -1 ) {
+ priority = 0;
+ }
+ debug("bb.sms.smpp", 0, "SMPP: priority: %d", priority);
+
system_id = cfg_get(grp, octstr_imm("system-id"));
if (system_id != NULL) {
warning(0, "SMPP: obsolete system-id variable is set, "
@@ -845,7 +970,9 @@
return -1;
smpp = smpp_create(conn, host, port, receive_port, system_type,
- username, password, address_range);
+ username, password, address_range, source_addr_ton,
+ source_addr_npi, dest_addr_ton, dest_addr_npi,
+ throughput, priority);
conn->data = smpp;
conn->name = octstr_format("SMPP:%S:%d/%d:%S:%S",
host, port,
Index: gw/smsc_wrapper.c
===================================================================
RCS file: /home/cvs/gateway/gw/smsc_wrapper.c,v
retrieving revision 1.26
diff -u -r1.26 smsc_wrapper.c
--- gw/smsc_wrapper.c 28 Jul 2001 03:18:23 -0000 1.26
+++ gw/smsc_wrapper.c 22 Mar 2002 04:12:48 -0000
@@ -181,7 +181,7 @@
debug("bb.sms", 0, "smscconn_sender (%s): sending message",
octstr_get_cstr(conn->name));
-
+
ret = smscenter_submit_msg(wrap->smsc, msg);
if (ret == -1) {
bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_REJECTED);
Index: gwlib/cfg.def
===================================================================
RCS file: /home/cvs/gateway/gwlib/cfg.def,v
retrieving revision 1.46
diff -u -r1.46 cfg.def
--- gwlib/cfg.def 21 Mar 2002 03:54:32 -0000 1.46
+++ gwlib/cfg.def 22 Mar 2002 04:12:48 -0000
@@ -194,6 +194,11 @@
OCTSTR(retry)
OCTSTR(my-number)
OCTSTR(sms-center)
+ OCTSTR(source-addr-ton)
+ OCTSTR(source-addr-npi)
+ OCTSTR(dest-addr-ton)
+ OCTSTR(dest-addr-npi)
+ OCTSTR(priority)
)