[PATCH] smppbox :: message_payload, SMPP conformity, docs update
Victor Luchitz <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello! Here I am attaching a patch which has been in the works for the last couple of weeks by me and Rene :) What the patch does is: 1) add support for message_payload TLV for deliver_sm packets. This TLV is used in case a smpp meta-flag "use_message_payload" is set 2) brings smppbox in conformity with SMPP v3.4 in regarding shedule_delivery_time and validiy_period fields in deliver_sm packets 3) if connected ESME requests delivery report for a submit_sm packet, smppbox will now also notify the ESME of SMSC failures, generated by the bearerbox 4) provides documentation updates Comments and suggestions are welcome. -- Best regards, Victor Luchitz
smppbox-combined-1.patch
(application/octet-stream, 12.5 KB)
Index: doc/userguide.xml
===================================================================
--- doc/userguide.xml (revision 44)
+++ doc/userguide.xml (working copy)
@@ -223,13 +223,27 @@
SMPP Users are defined in a flat text file, which is parsed at client
connection (binding) time. This means that users can be added, changed or
removed without restarting open smppbox. The file can be edited by any plain-text
- file editor.
+ file editor. Also it is possible to compile open smppbox with Unix PAM support
+ (pluggable authentication modules). See the corresponding options in the configuration
+ file.
</para>
<para>
It is possible to restrict ip addresses from which can be bound (connected)
per user. See the section on configuring open smppbox below.
</para>
+
+ <para>
+ Special efforts have been made to make open smppbox v3.4 compatible by means of TLV
+ (tagged length value) parameters. These parameters can be addressed via the meta-data
+ construction in Kannel. A special example of this: One can conditionally enable transmission
+ of short messages as a whole with length exceeding 140 octets, based on a meta-tag
+ "use_message_payload" in "smpp" group. In case this tag has been set and its value is not zero,
+ open smppbox will attempt to use the "message_payload" TLV instead of splitting the message
+ into multiple shorter ones with UDH-concatenation bit set. Note that this mechanism only
+ works for ESME's that declare support for SMPP versions 3.4 or greater. A simple usage example:
+ <ulink url="">http://localhost:13013/cgi-bin/sendsms?...&meta-data=%3Fsmpp%3Fuse_message_payload%3D1</ulink>.
+ </para>
</sect1>
<sect1>
@@ -862,23 +876,23 @@
variable defines all users that are able to bind as ESME to open smppbox.
The first three tokens of this file are the username, password and
foreign system-type that form the credentials on which the bind-
- method of the ESME are being matched with. The last token is optional
- and defines a source ip address to restrict logins to.
+ method of the ESME are being matched with. The last token and defines a
+ source ip address to restrict logins to.
An example with two example logins:
<programlisting>
- goodclient secret remote
+ goodclient secret remote *.*.*.*
franchise ourpassword localbox 127.0.0.1;213.110.120.33
</programlisting>
</para>
<para>
The first line defines a username ("goodclient"), a password ("secret")
- and an smsbox-id ("remote"). The second line defines also a username
+ and an smsbox-id ("remote"). People can log into this account, originating
+ from any ip address.i The second line defines also a username
("franchise"), password("ourpassword") and an smsbox-id ("localbox"),
but besides that there is a restriction on that user. It can only bind
from the ip addresses 127.0.0.1 and 213.110.120.33.
- If the ip address is omitted, then everybody is allowed to connect.
- If the ip address is given, then only that ip address is allowed to connect.
+ If ip address(es) is/are given, then only those ip addresses are allowed to connect.
It works exactly like connect-allow-ip and connect-deny-ip in Kannel.conf.
In that case, connect-deny-ip has a mask of "*.*.*.*".
</para>
@@ -906,13 +920,13 @@
This chapter explains where to find help with problems related to the gateway, and the preferred procedure for reporting bugs and sending corrections to them.
</para>
<para>
- The Kannel development mailing list is [email protected]. To subscribe, send mail to [email protected]. This is currently the best location for asking help and reporting bugs. Please include configuration file and version number.
+ The Kannel development mailing list is [email protected]. To subscribe, send mail to [email protected]. This is currently the best location for asking help and reporting bugs. Please include configuration file and version number.
</para>
</chapter>
<chapter id="upgrading-notes">
<title>Upgrading notes</title>
<para>
- There are currently no upgrading notes.
+ See the file <filename>UPGRADE</filename> in the source tree.
</para>
</chapter>
</book>
Index: gw/smppbox.c
===================================================================
--- gw/smppbox.c (revision 44)
+++ gw/smppbox.c (working copy)
@@ -595,7 +595,7 @@
{
SMPP_PDU *pdu, *pdu2;
List *pdulist = gwlist_create(), *parts;
- int validity, dlrtype, catenate;
+ int dlrtype, catenate;
int dlr_state = 7; /* UNKNOWN */
Msg *dlr;
char *text, *tmps, err[4] = { '0', '0', '0', '\0' };
@@ -603,7 +603,6 @@
struct tm tm_tmp;
Octstr *msgid, *msgid2, *dlr_status, *dlvrd;
/* split variables */
- List *list;
unsigned long msg_sequence, msg_count;
unsigned long submit_date;
int max_msgs;
@@ -765,6 +764,7 @@
tmps = strstr(tmps, " ");
text = tmps ? tmps + (1 * sizeof(char)) : "";
}
+
tmps = strstr(text, "text:");
if (tmps != NULL) {
text = tmps + (5 * sizeof(char));
@@ -818,7 +818,7 @@
if (box->version > 0x33) {
pdu->u.deliver_sm.receipted_message_id = octstr_duplicate(msgid);
pdu->u.deliver_sm.message_state = dlr_state;
- pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
+ pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
}
pdu->u.deliver_sm.short_message = octstr_format("id:%S sub:001 dlvrd:%S submit date:%s done date:%s stat:%S err:%s text:%12s", msgid, dlvrd, submit_date_c_str, done_date_c_str, dlr_status, err, text);
gwlist_append(pdulist, pdu);
@@ -876,25 +876,6 @@
pdu->u.deliver_sm.sm_length = octstr_len(pdu->u.deliver_sm.short_message);
- /*
- * check for validity and defered settings
- * were message value has higher priiority then smsc config group value
- */
- validity = msg->sms.validity >= 0 ? msg->sms.validity : box->validityperiod;
- if (validity >= 0) {
- struct tm tm = gw_gmtime(time(NULL) + validity * 60);
- pdu->u.deliver_sm.validity_period = octstr_format("%02d%02d%02d%02d%02d%02d000+",
- tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- }
-
- if (msg->sms.deferred >= 0) {
- struct tm tm = gw_gmtime(time(NULL) + msg->sms.deferred * 60);
- pdu->u.deliver_sm.schedule_delivery_time = octstr_format("%02d%02d%02d%02d%02d%02d000+",
- tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- }
-
/* set priority */
if (msg->sms.priority >= 0 && msg->sms.priority <= 3)
pdu->u.deliver_sm.priority_flag = msg->sms.priority;
@@ -918,43 +899,82 @@
else
msg_sequence = 0;
- list = sms_split(msg, header, footer, suffix, split_chars, catenate,
+ /* split sms */
+ parts = sms_split(msg, header, footer, suffix, split_chars, catenate,
msg_sequence, max_msgs, sms_max_length);
- msg_count = gwlist_len(list);
+ msg_count = gwlist_len(parts);
- debug("SMPP", 0, "message length %ld, sending %ld messages",
- octstr_len(msg->sms.msgdata), msg_count);
+ if ((msg_count > 1) && (box->version > 0x33)) {
+ Octstr *use_message_payload_meta;
+ long use_message_payload;
- while((msg2 = gwlist_extract_first(list)) != NULL) {
- pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
- pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
- pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
- pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
- pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
- pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
- pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
- pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
- pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
- pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
- if (msg_count > 0) {
- if (octstr_len(msg2->sms.udhdata) > 0) {
- pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class | ESM_CLASS_DELIVER_UDH_INDICATOR;
- pdu2->u.deliver_sm.short_message = octstr_cat(msg2->sms.udhdata, msg2->sms.msgdata);
- }
- else {
- pdu2->u.deliver_sm.short_message = octstr_duplicate(msg2->sms.msgdata);
- }
- }
- else {
- pdu2->u.deliver_sm.short_message = octstr_duplicate(msg2->sms.msgdata);
- }
- if (box->version > 0x33) {
- pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
- }
- gwlist_append(pdulist, pdu2);
- msg_destroy(msg2);
+ use_message_payload_meta = meta_data_get_value(msg->sms.meta_data, "smpp", octstr_imm("use_message_payload"));
+ use_message_payload = strtol(octstr_get_cstr(use_message_payload_meta), 0, 0);
+
+ if (use_message_payload) {
+ /* copy short message data to message_payload TLV */
+ pdu->u.deliver_sm.message_payload = octstr_duplicate(pdu->u.deliver_sm.short_message);
+ octstr_destroy(pdu->u.deliver_sm.short_message);
+ pdu->u.deliver_sm.short_message = NULL;
+ pdu->u.deliver_sm.sm_length = 0;
+
+ /* pass the message as a single pdu */
+ msg_count = 1;
+ }
+
+ octstr_destroy(use_message_payload_meta);
}
- smpp_pdu_destroy(pdu);
+
+ if (msg_count == 1) {
+ /* don't create split_parts of sms fit into one */
+ gwlist_destroy(parts, msg_destroy_item);
+ parts = NULL;
+ }
+
+ debug("SMPP", 0, "message length %ld, sending %ld message%s",
+ octstr_len(msg->sms.msgdata), msg_count, msg_count == 1 ? "" : "s");
+
+ if (parts) {
+ while((msg2 = gwlist_extract_first(parts)) != NULL) {
+ pdu2 = smpp_pdu_create(deliver_sm, counter_increase(box->smpp_pdu_counter));
+ pdu2->u.deliver_sm.source_addr_ton = pdu->u.deliver_sm.source_addr_ton;
+ pdu2->u.deliver_sm.source_addr_npi = pdu->u.deliver_sm.source_addr_npi;
+ pdu2->u.deliver_sm.dest_addr_ton = pdu->u.deliver_sm.dest_addr_ton;
+ pdu2->u.deliver_sm.dest_addr_npi = pdu->u.deliver_sm.dest_addr_npi;
+ pdu2->u.deliver_sm.data_coding = pdu->u.deliver_sm.data_coding;
+ pdu2->u.deliver_sm.protocol_id = pdu->u.deliver_sm.protocol_id;
+ pdu2->u.deliver_sm.source_addr = octstr_duplicate(pdu->u.deliver_sm.source_addr);
+ pdu2->u.deliver_sm.destination_addr = octstr_duplicate(pdu->u.deliver_sm.destination_addr);
+ pdu2->u.deliver_sm.service_type = octstr_duplicate(pdu->u.deliver_sm.service_type);
+
+ /* the following condition is currently always true */
+ /* uncomment in case we're doing a SAR-split instead */
+ if (/*octstr_len(msg2->sms.udhdata) > 0*/1) {
+ pdu2->u.deliver_sm.esm_class = pdu->u.deliver_sm.esm_class | ESM_CLASS_DELIVER_UDH_INDICATOR;
+ pdu2->u.deliver_sm.short_message = octstr_cat(msg2->sms.udhdata, msg2->sms.msgdata);
+ }
+ else {
+ pdu2->u.deliver_sm.short_message = octstr_duplicate(msg2->sms.msgdata);
+ }
+
+ if (box->version > 0x33) {
+ pdu2->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
+ }
+
+ gwlist_append(pdulist, pdu2);
+ msg_destroy(msg2);
+ }
+
+ smpp_pdu_destroy(pdu);
+ }
+ else {
+ if (box->version > 0x33) {
+ pdu->u.deliver_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
+ }
+
+ gwlist_append(pdulist, pdu);
+ }
+
return pdulist;
}
@@ -1113,12 +1133,12 @@
msg->sms.priority = pdu->u.submit_sm.priority_flag;
/* ask for the delivery reports if needed */
- switch (pdu->u.submit_sm.registered_delivery) {
+ switch (pdu->u.submit_sm.registered_delivery & 0x03) {
case 1:
- msg->sms.dlr_mask = (DLR_SUCCESS | DLR_FAIL);
+ msg->sms.dlr_mask = (DLR_SUCCESS | DLR_FAIL | DLR_SMSC_FAIL);
break;
case 2:
- msg->sms.dlr_mask = (DLR_FAIL);
+ msg->sms.dlr_mask = (DLR_FAIL | DLR_SMSC_FAIL);
break;
default:
msg->sms.dlr_mask = 0;
@@ -1595,7 +1615,7 @@
boxc->dest_addr_npi = smpp_dest_addr_npi;
boxc->alt_dcs = 0;
- boxc->validityperiod = 0;
+ boxc->validityperiod = -1;
boxc->priority = 0;
boxc->mo_recode = 0;