[PATCH] add support of smsc-id for smpp-tlv group
Alexander Malysh <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi list,
seems I was to lazy and didn't implement smsc-id support for smpp-tlv
group :)
Attached is patch that corrects this.
The rule to look for smpp-tlv group is as follows:
1) by start we put smpp-tlv to smsc-id specific Dict if none given to
default smsc-id.
smsc-id may be a list splitted by ;
2) then if we need tlv by name/tag we look first for specific smsc-id
Dict and if tlv
not found for default smsc-id
Comments are welcome.
Thanks,
Alexander Malysh
smpp-tlv-smsc-id.diff
(application/octet-stream, 14.7 KB)
diff --git a/doc/userguide/userguide.xml b/doc/userguide/userguide.xml
index 2573966..4f414aa 100644
--- a/doc/userguide/userguide.xml
+++ b/doc/userguide/userguide.xml
@@ -9638,6 +9638,7 @@ name = my_tlv_name
tag = 0x1601
type = octetstring
length = 20
+smsc-id = a;b;c
</programlisting>
<informaltable frame="none">
@@ -9667,9 +9668,16 @@ length = 20
Maximum data length expected in bytes. Must match SMPP specifications for the TLV (or be agreed with the SMSC operator).
</entry></row>
+ <row><entry><literal>smsc-id</literal></entry>
+ <entry><literal>stringr</literal></entry>
+ <entry valign="bottom">
+ An optional smsc-id for which this TLV valid. If smsc-id is not given
+ then this TLV valid for all SMSCs.
+ To define list of smsc-id, just use ; as split char.
+ </entry></row>
- </tbody>
- </tgroup>
+ </tbody>
+ </tgroup>
</informaltable>
<sect2>
<title>MO Messages</title>
diff --git a/gw/smsc/smpp_pdu.c b/gw/smsc/smpp_pdu.c
index add0253..bf55b61 100644
--- a/gw/smsc/smpp_pdu.c
+++ b/gw/smsc/smpp_pdu.c
@@ -69,7 +69,8 @@
#define MIN_SMPP_PDU_LEN (4*4)
/* old value was (1024). We need more because message_payload can be up to 64K octets*/
#define MAX_SMPP_PDU_LEN (7424)
-
+/* we use ; in the middle because ; is split char in smsc-id and can'be in the smsc-id */
+#define DEFAULT_SMSC_ID "def;ault"
struct smpp_tlv {
Octstr *name;
@@ -78,9 +79,11 @@ struct smpp_tlv {
enum { SMPP_TLV_OCTETS = 0, SMPP_TLV_NULTERMINATED = 1, SMPP_TLV_INTEGER = 2 } type;
};
-
-static Dict *tlv_by_tag;
-static Dict *tlv_by_name;
+/* Dict(smsc_id, Dict(tag, tlv)) */
+static Dict *tlvs_by_tag;
+/* Dict(smsc_id, Dict(tag_name, tlv)) */
+static Dict *tlvs_by_name;
+static List *tlvs;
static int initialized;
@@ -92,6 +95,57 @@ static void smpp_tlv_destroy(struct smpp_tlv *tlv)
gw_free(tlv);
}
+static struct smpp_tlv *smpp_tlv_get_by_name(Octstr *smsc_id, Octstr *name)
+{
+ struct smpp_tlv *res = NULL;
+ Dict *tmp_dict;
+
+ if (tlvs_by_name == NULL || name == NULL)
+ return NULL;
+
+ if (smsc_id != NULL) {
+ tmp_dict = dict_get(tlvs_by_name, smsc_id);
+ if (tmp_dict != NULL)
+ res = dict_get(tmp_dict, name);
+ }
+ if (res == NULL) {
+ /* try default smsc_id */
+ smsc_id = octstr_imm(DEFAULT_SMSC_ID);
+ tmp_dict = dict_get(tlvs_by_name, smsc_id);
+ if (tmp_dict != NULL)
+ res = dict_get(tmp_dict, name);
+ }
+ return res;
+}
+
+static struct smpp_tlv *smpp_tlv_get_by_tag(Octstr *smsc_id, long tag)
+{
+ struct smpp_tlv *res = NULL;
+ Dict *tmp_dict;
+ Octstr *tmp;
+
+ if (tlvs_by_tag == NULL)
+ return NULL;
+
+ tmp = octstr_format("%ld", tag);
+
+ if (smsc_id != NULL) {
+ tmp_dict = dict_get(tlvs_by_tag, smsc_id);
+ if (tmp_dict != NULL)
+ res = dict_get(tmp_dict, tmp);
+ }
+ if (res == NULL) {
+ /* try default smsc_id */
+ smsc_id = octstr_imm(DEFAULT_SMSC_ID);
+ tmp_dict = dict_get(tlvs_by_tag, smsc_id);
+ if (tmp_dict != NULL)
+ res = dict_get(tmp_dict, tmp);
+ }
+
+ octstr_destroy(tmp);
+
+ return res;
+}
int smpp_pdu_init(Cfg *cfg)
{
@@ -101,13 +155,14 @@ int smpp_pdu_init(Cfg *cfg)
if (initialized)
return 0;
-
l = cfg_get_multi_group(cfg, octstr_imm("smpp-tlv"));
- tlv_by_tag = dict_create(gwlist_len(l) > 0 ? gwlist_len(l) : 1, (void(*)(void*))smpp_tlv_destroy);
- tlv_by_name = dict_create(gwlist_len(l) > 0 ? gwlist_len(l) : 1, NULL);
+ tlvs = gwlist_create();
+ tlvs_by_tag = dict_create(1024, (void(*)(void*))dict_destroy);
+ tlvs_by_name = dict_create(1024, (void(*)(void*))dict_destroy);
while (l != NULL && (grp = gwlist_extract_first(l)) != NULL) {
struct smpp_tlv *tlv;
- Octstr *tmp;
+ Octstr *tmp, *smsc_id;
+ List *l2;
tlv = gw_malloc(sizeof(*tlv));
if ((tlv->name = cfg_get(grp, octstr_imm("name"))) == NULL) {
@@ -143,19 +198,51 @@ int smpp_pdu_init(Cfg *cfg)
goto failed;
}
octstr_destroy(tmp);
- /* put into dict */
- if (!dict_put_once(tlv_by_name, tlv->name, tlv)) {
- error(0, "SMPP: Double TLV name %s found.", octstr_get_cstr(tlv->name));
- smpp_tlv_destroy(tlv);
- goto failed;
+
+ /* put to all TLVs */
+ gwlist_produce(tlvs, tlv);
+
+ smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
+ if (smsc_id != NULL) {
+ l2 = octstr_split(smsc_id, octstr_imm(";"));
+ octstr_destroy(smsc_id);
+ } else {
+ l2 = gwlist_create();
+ gwlist_produce(l2, octstr_create(DEFAULT_SMSC_ID));
}
- tmp = octstr_format("%ld", tlv->tag);
- if (!dict_put_once(tlv_by_tag, tmp, tlv)) {
- error(0, "SMPP: Double TLV tag %s found.", octstr_get_cstr(tmp));
+ while(l2 != NULL && (smsc_id = gwlist_extract_first(l2)) != NULL) {
+ Dict *tmp_dict;
+
+ debug("sms.smpp", 0, "adding smpp-tlv for smsc-id=%s", octstr_get_cstr(smsc_id));
+
+ tmp_dict = dict_get(tlvs_by_name, smsc_id);
+ if (tmp_dict == NULL) {
+ tmp_dict = dict_create(1024, NULL);
+ dict_put(tlvs_by_name, smsc_id, tmp_dict);
+ }
+ /* put into 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;
+ }
+
+ tmp_dict = dict_get(tlvs_by_tag, smsc_id);
+ if (tmp_dict == NULL) {
+ tmp_dict = dict_create(1024, NULL);
+ dict_put(tlvs_by_tag, smsc_id, tmp_dict);
+ }
+ tmp = octstr_format("%ld", tlv->tag);
+ if (!dict_put_once(tmp_dict, tmp, tlv)) {
+ error(0, "SMPP: Double TLV tag %s found.", octstr_get_cstr(tmp));
+ octstr_destroy(tmp);
+ octstr_destroy(smsc_id);
+ goto failed;
+ }
octstr_destroy(tmp);
- goto failed;
+ octstr_destroy(smsc_id);
}
- octstr_destroy(tmp);
+ gwlist_destroy(l2, octstr_destroy_item);
}
gwlist_destroy(l, NULL);
@@ -163,8 +250,9 @@ int smpp_pdu_init(Cfg *cfg)
return 0;
failed:
- dict_destroy(tlv_by_tag);
- dict_destroy(tlv_by_name);
+ gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy);
+ dict_destroy(tlvs_by_tag);
+ dict_destroy(tlvs_by_name);
return -1;
}
@@ -175,9 +263,11 @@ int smpp_pdu_shutdown(void)
return 0;
initialized = 0;
- dict_destroy(tlv_by_tag);
- dict_destroy(tlv_by_name);
- tlv_by_tag = tlv_by_name = NULL;
+ gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy);
+ tlvs = NULL;
+ dict_destroy(tlvs_by_tag);
+ dict_destroy(tlvs_by_name);
+ tlvs_by_tag = tlvs_by_name = NULL;
return 0;
}
@@ -287,7 +377,7 @@ void smpp_pdu_destroy(SMPP_PDU *pdu)
}
-Octstr *smpp_pdu_pack(SMPP_PDU *pdu)
+Octstr *smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu)
{
Octstr *os;
Octstr *temp;
@@ -349,7 +439,7 @@ Octstr *smpp_pdu_pack(SMPP_PDU *pdu)
struct smpp_tlv *tlv; \
keys = dict_keys(p->tlv); \
while(keys != NULL && (key = gwlist_extract_first(keys)) != NULL) { \
- tlv = dict_get(tlv_by_name, key); \
+ tlv = smpp_tlv_get_by_name(smsc_id, key); \
if (tlv == NULL) { \
error(0, "SMPP: Unknown TLV `%s', don't send.", octstr_get_cstr(key)); \
octstr_destroy(key); \
@@ -424,7 +514,7 @@ Octstr *smpp_pdu_pack(SMPP_PDU *pdu)
}
-SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len)
+SMPP_PDU *smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len)
{
SMPP_PDU *pdu;
unsigned long type;
@@ -454,16 +544,13 @@ SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len)
{ /* Read optional parameters */ \
while (pos + 4 <= len) { \
struct smpp_tlv *tlv; \
- Octstr *tmp; \
unsigned long opt_tag, opt_len; \
opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \
debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \
opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \
debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len); \
/* check configured TLVs */ \
- tmp = octstr_format("%ld", opt_tag); \
- tlv = dict_get(tlv_by_tag, tmp); \
- octstr_destroy(tmp); \
+ tlv = smpp_tlv_get_by_tag(smsc_id, opt_tag); \
if (tlv != NULL) debug("sms.smpp", 0, "Found configured optional parameter `%s'", octstr_get_cstr(tlv->name));
#define TLV_INTEGER(mname, octets) \
if (SMPP_##mname == opt_tag) { \
diff --git a/gw/smsc/smpp_pdu.h b/gw/smsc/smpp_pdu.h
index bd658bf..2143ebb 100644
--- a/gw/smsc/smpp_pdu.h
+++ b/gw/smsc/smpp_pdu.h
@@ -232,8 +232,8 @@ int smpp_pdu_shutdown(void);
SMPP_PDU *smpp_pdu_create(unsigned long type, unsigned long seq_no);
void smpp_pdu_destroy(SMPP_PDU *pdu);
int smpp_pdu_is_valid(SMPP_PDU *pdu); /* XXX */
-Octstr *smpp_pdu_pack(SMPP_PDU *pdu);
-SMPP_PDU *smpp_pdu_unpack(Octstr *data_without_len);
+Octstr *smpp_pdu_pack(Octstr *smsc_id, SMPP_PDU *pdu);
+SMPP_PDU *smpp_pdu_unpack(Octstr *smsc_id, Octstr *data_without_len);
void smpp_pdu_dump(SMPP_PDU *pdu);
long smpp_pdu_read_len(Connection *conn);
diff --git a/gw/smsc/smsc_smpp.c b/gw/smsc/smsc_smpp.c
index a41dbf3..c25257a 100644
--- a/gw/smsc/smsc_smpp.c
+++ b/gw/smsc/smsc_smpp.c
@@ -328,7 +328,7 @@ static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu)
}
*len = 0;
- *pdu = smpp_pdu_unpack(os);
+ *pdu = smpp_pdu_unpack(smpp->conn->id, os);
if (*pdu == NULL) {
error(0, "SMPP[%s]: PDU unpacking failed.",
octstr_get_cstr(smpp->conn->id));
@@ -970,7 +970,7 @@ static int send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent)
pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter));
dump_pdu("Sending enquire link:", smpp->conn->id, pdu);
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(smpp->conn->id, pdu);
if (os != NULL)
ret = conn_write(conn, os); /* Write errors checked by caller. */
else
@@ -990,7 +990,7 @@ static int send_gnack(SMPP *smpp, Connection *conn, long reason, unsigned long s
pdu = smpp_pdu_create(generic_nack, seq_num);
pdu->u.generic_nack.command_status = reason;
dump_pdu("Sending generic_nack:", smpp->conn->id, pdu);
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(smpp->conn->id, pdu);
if (os != NULL)
ret = conn_write(conn, os);
else
@@ -1009,7 +1009,7 @@ static int send_unbind(SMPP *smpp, Connection *conn)
pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter));
dump_pdu("Sending unbind:", smpp->conn->id, pdu);
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(smpp->conn->id, pdu);
if (os != NULL)
ret = conn_write(conn, os);
else
@@ -1027,7 +1027,7 @@ static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu)
int ret;
dump_pdu("Sending PDU:", id, pdu);
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(id, pdu);
if (os) {
/* Caller checks for write errors later */
ret = conn_write(conn, os);
diff --git a/test/drive_smpp.c b/test/drive_smpp.c
index 2ae5ede..ff013b6 100644
--- a/test/drive_smpp.c
+++ b/test/drive_smpp.c
@@ -236,7 +236,7 @@ static void handle_pdu(ESME *esme, SMPP_PDU *pdu)
if (handlers[i].type == pdu->type) {
resp = handlers[i].handler(esme, pdu);
if (resp != NULL) {
- os = smpp_pdu_pack(resp);
+ os = smpp_pdu_pack(NULL, resp);
conn_write(esme->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(resp);
@@ -272,7 +272,7 @@ static void send_smpp_thread(void *arg)
pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
if (esme->version > 0x33)
pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(NULL, pdu);
conn_write(esme->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(pdu);
@@ -283,7 +283,7 @@ static void send_smpp_thread(void *arg)
if ((id % enquire_interval) == 0) {
pdu = smpp_pdu_create(enquire_link, counter_increase(message_id_counter));
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(NULL, pdu);
conn_write(esme->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(pdu);
@@ -327,7 +327,7 @@ static void receive_smpp_thread(void *arg)
os = smpp_pdu_read_data(esme->conn, len);
if (os != NULL) {
len = 0;
- pdu = smpp_pdu_unpack(os);
+ pdu = smpp_pdu_unpack(NULL, os);
if (pdu == NULL) {
error(0, "PDU unpacking failed!");
octstr_dump(os, 0);
diff --git a/test/drive_smpp.conf b/test/drive_smpp.conf
index 0e4e32a..a8cb552 100644
--- a/test/drive_smpp.conf
+++ b/test/drive_smpp.conf
@@ -23,6 +23,7 @@ name = my_receipted_message_id
tag = 0x001E
type = octetstring
length = 65
+#smsc-id = smpp
group = smsbox
bearerbox-host = 127.0.0.1
diff --git a/test/test_smsc.c b/test/test_smsc.c
index 92d2670..66ee306 100644
--- a/test/test_smsc.c
+++ b/test/test_smsc.c
@@ -313,7 +313,7 @@ static void smpp_emu_writer(void *arg)
pdu->u.deliver_sm.source_addr = octstr_create("123");
pdu->u.deliver_sm.destination_addr = octstr_create("456");
pdu->u.deliver_sm.short_message = octstr_format("%ld", e->time);
- os = smpp_pdu_pack(pdu);
+ os = smpp_pdu_pack(NULL, pdu);
conn_write(p->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(pdu);
@@ -372,7 +372,7 @@ static void smpp_emu_handle_pdu(struct smpp_emu_arg *p, SMPP_PDU *pdu)
}
if (resp != NULL) {
- os = smpp_pdu_pack(resp);
+ os = smpp_pdu_pack(NULL, resp);
conn_write(p->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(resp);
@@ -408,7 +408,7 @@ static void smpp_emu_reader(void *arg)
os = smpp_pdu_read_data(p->conn, len);
if (os != NULL) {
len = 0;
- pdu = smpp_pdu_unpack(os);
+ pdu = smpp_pdu_unpack(NULL, os);
if (pdu == NULL) {
error(0, "PDU unpacking failed!");
octstr_dump(os, 0);
@@ -541,7 +541,7 @@ static void smsc_emu_submit_ack(Event *e)
Octstr *os;
resp = smpp_pdu_create(submit_sm_resp, e->sequence_number);
- os = smpp_pdu_pack(resp);
+ os = smpp_pdu_pack(NULL, resp);
conn_write(e->conn, os);
octstr_destroy(os);
smpp_pdu_destroy(resp);