Hi list,
we have a fairly robust construct to add optional TLVs for SMPP SMSCs
via the meta-data construct, when messages are injected via smsbox's
sendsms HTTP interface.
Though, it would be nice if we could set "constant default" values for
smsc-ids that would be set as optional TLVs, even if no values in
msg->sms.meta_data are provided.
The attached patch implements such a functionality, by allowing to define:
group = smpp-tlv
name = charging-id
tag = 0x2010
type = octetstring
length = 10
smsc-id = "smpp_deadend"
const = "xyz"
and adding the 'const' directive that can set a constant value.
So, if there is no TLV coming via the msg->sms.meta_data part, then the
constant is set for that particular TLV.
Comments welcome. If no objections, will commit to SVN trunk the coming
days.
--
Best Regards,
Stipe Tolj
-------------------------------------------------------------------
Düsseldorf, NRW, Germany
Kannel Foundation tolj.org system architecture
http://www.kannel.org/ http://www.tolj.org/
st...@kannel.org s...@tolj.org
-------------------------------------------------------------------
Index: doc/userguide/userguide.xml
===================================================================
--- doc/userguide/userguide.xml (revision 5187)
+++ doc/userguide/userguide.xml (working copy)
@@ -10639,6 +10639,12 @@
To define list of smsc-id, just use ; as split char.
</entry></row>
+ <row><entry><literal>const</literal></entry>
+ <entry><literal>string</literal></entry>
+ <entry valign="bottom">
+ An optional constant value which is used if no TLV value is set via
meta-data.
+ </entry></row>
+
</tbody>
</tgroup>
</informaltable>
Index: gw/smsc/smpp_pdu.c
===================================================================
--- gw/smsc/smpp_pdu.c (revision 5174)
+++ gw/smsc/smpp_pdu.c (working copy)
@@ -76,6 +76,7 @@
Octstr *name;
long tag;
long length;
+ Octstr *constant;
enum { SMPP_TLV_OCTETS = 0, SMPP_TLV_NULTERMINATED = 1, SMPP_TLV_INTEGER =
2 } type;
};
@@ -83,6 +84,7 @@
static Dict *tlvs_by_tag;
/* Dict(smsc_id, Dict(tag_name, tlv)) */
static Dict *tlvs_by_name;
+static Dict *tlvs_by_const;
static List *tlvs;
static int initialized;
@@ -92,9 +94,41 @@
if (tlv == NULL)
return;
octstr_destroy(tlv->name);
+ octstr_destroy(tlv->constant);
gw_free(tlv);
}
+
+void smpp_tlv_add_constant(Octstr *smsc_id, Dict **tlvs)
+{
+ Dict *constant;
+ List *keys;
+ Octstr *key;
+ struct smpp_tlv *tlv;
+
+ constant = dict_get(tlvs_by_const, smsc_id);
+ if (constant == NULL)
+ return;
+
+ keys = dict_keys(constant);
+ while ((key = gwlist_extract_first(keys)) != NULL) {
+ /* only add if not available already */
+ tlv = dict_get(constant, key);
+ if (tlv->constant) {
+ if (*tlvs) {
+ if (dict_get(*tlvs, key) == NULL)
+ dict_put(*tlvs, key, octstr_duplicate(tlv->constant));
+ } else {
+ *tlvs = dict_create(1024, octstr_destroy_item);
+ dict_put(*tlvs, key, octstr_duplicate(tlv->constant));
+ }
+ }
+ octstr_destroy(key);
+ }
+ gwlist_destroy(keys, NULL);
+}
+
+
static struct smpp_tlv *smpp_tlv_get_by_name(Octstr *smsc_id, Octstr *name)
{
struct smpp_tlv *res = NULL;
@@ -159,6 +193,7 @@
tlvs = gwlist_create();
tlvs_by_tag = dict_create(1024, (void(*)(void*))dict_destroy);
tlvs_by_name = dict_create(1024, (void(*)(void*))dict_destroy);
+ tlvs_by_const = dict_create(1024, (void(*)(void*))dict_destroy);
while (l != NULL && (grp = gwlist_extract_first(l)) != NULL) {
struct smpp_tlv *tlv;
Octstr *tmp, *smsc_id;
@@ -170,6 +205,7 @@
smpp_tlv_destroy(tlv);
goto failed;
}
+ tlv->constant = cfg_get(grp, octstr_imm("const"));
if (cfg_get_integer(&tlv->tag, grp, octstr_imm("tag")) == -1) {
error(0, "SMPP: Unable to get tag for smpp-tlv.");
smpp_tlv_destroy(tlv);
@@ -215,6 +251,7 @@
debug("sms.smpp", 0, "adding smpp-tlv for smsc-id=%s",
octstr_get_cstr(smsc_id));
+ /* name */
tmp_dict = dict_get(tlvs_by_name, smsc_id);
if (tmp_dict == NULL) {
tmp_dict = dict_create(1024, NULL);
@@ -227,6 +264,7 @@
goto failed;
}
+ /* tag */
tmp_dict = dict_get(tlvs_by_tag, smsc_id);
if (tmp_dict == NULL) {
tmp_dict = dict_create(1024, NULL);
@@ -240,6 +278,21 @@
octstr_destroy(smsc_id);
goto failed;
}
+
+ /* const */
+ if (tlv->constant != NULL) {
+ tmp_dict = dict_get(tlvs_by_const, smsc_id);
+ if (tmp_dict == NULL) {
+ tmp_dict = dict_create(1024, NULL);
+ dict_put(tlvs_by_const, smsc_id, tmp_dict);
+ }
+ if (!dict_put_once(tmp_dict, tlv->name, tlv)) {
+ error(0, "SMPP: Double TLV name %s found.",
octstr_get_cstr(tlv->name));
+ octstr_destroy(smsc_id);
+ goto failed;
+ }
+ }
+
octstr_destroy(tmp);
octstr_destroy(smsc_id);
}
Index: gw/smsc/smpp_pdu.h
===================================================================
--- gw/smsc/smpp_pdu.h (revision 5172)
+++ gw/smsc/smpp_pdu.h (working copy)
@@ -247,4 +247,7 @@
*/
const char *smpp_error_to_string(enum SMPP_ERROR_MESSAGES error);
+/* add constant TLVs to TLV dictionary */
+void smpp_tlv_add_constant(Octstr *smsc_id, Dict **tlvs);
+
#endif
Index: gw/smsc/smsc_smpp.c
===================================================================
--- gw/smsc/smsc_smpp.c (revision 5189)
+++ gw/smsc/smsc_smpp.c (working copy)
@@ -1151,6 +1151,9 @@
dict_destroy(pdu->u.submit_sm.tlv);
pdu->u.submit_sm.tlv = meta_data_get_values(msg->sms.meta_data, "smpp");
+ /* add any configured constant TLVs */
+ smpp_tlv_add_constant(smpp->conn->id, &(pdu->u.submit_sm.tlv));
+
return pdu;
}
Index: gwlib/cfg.def
===================================================================
--- gwlib/cfg.def (revision 5187)
+++ gwlib/cfg.def (working copy)
@@ -689,6 +689,7 @@
OCTSTR(length)
OCTSTR(type)
OCTSTR(smsc-id)
+ OCTSTR(const)
)