summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-07-13 10:42:17 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-07-13 10:42:17 +0200
commit14a434b9d660cb92382f418739b8329b44640496 (patch)
tree7ec734baa04e92d68992d8e82121c30ae03a5b94
parentb69518f3834b60901ab5750b6ce3b623d9479c1e (diff)
parent7c19c6b4064b10511fa5f5327030c21616905d94 (diff)
Merge branch 'zecke/features/smpp-route'
-rw-r--r--openbsc/src/libmsc/gsm_04_11.c117
-rw-r--r--openbsc/src/libmsc/smpp_openbsc.c5
-rw-r--r--openbsc/src/libmsc/smpp_smsc.h11
-rw-r--r--openbsc/src/libmsc/smpp_vty.c22
-rw-r--r--openbsc/tests/vty_test_runner.py22
5 files changed, 136 insertions, 41 deletions
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index 1b2a42c..c2cec26 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -57,8 +57,6 @@
#ifdef BUILD_SMPP
#include "smpp_smsc.h"
-extern int smpp_try_deliver(struct gsm_sms *sms,
- struct gsm_subscriber_connection *conn);
#endif
void *tall_gsms_ctx;
@@ -277,6 +275,81 @@ static int gsm340_gen_sms_deliver_tpdu(struct msgb *msg, struct gsm_sms *sms)
return msg->len - old_msg_len;
}
+int sms_route_mt_sms(struct gsm_subscriber_connection *conn, struct msgb *msg,
+ struct gsm_sms *gsms, uint8_t sms_mti)
+{
+ int rc;
+
+#ifdef BUILD_SMPP
+ int smpp_first = smpp_route_smpp_first(gsms, conn);
+
+ /*
+ * Route through SMPP first before going to the local database. In case
+ * of a unroutable message and no local subscriber, SMPP will be tried
+ * twice. In case of an unknown subscriber continue with the normal
+ * delivery of the SMS.
+ */
+ if (smpp_first) {
+ rc = smpp_try_deliver(gsms, conn);
+ if (rc == 1)
+ goto try_local;
+ if (rc < 0) {
+ rc = 21; /* cause 21: short message transfer rejected */
+ /* FIXME: handle the error somehow? */
+ }
+ return rc;
+ }
+
+try_local:
+#endif
+
+ /* determine gsms->receiver based on dialled number */
+ gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group,
+ gsms->dst.addr);
+ if (!gsms->receiver) {
+#ifdef BUILD_SMPP
+ /* Avoid a second look-up */
+ if (smpp_first)
+ return 1; /* cause 1: unknown subscriber */
+
+ rc = smpp_try_deliver(gsms, conn);
+ if (rc == 1) {
+ rc = 1; /* cause 1: unknown subscriber */
+ osmo_counter_inc(conn->bts->network->stats.sms.no_receiver);
+ } else if (rc < 0) {
+ rc = 21; /* cause 21: short message transfer rejected */
+ /* FIXME: handle the error somehow? */
+ }
+#else
+ rc = 1; /* cause 1: unknown subscriber */
+ osmo_counter_inc(conn->bts->network->stats.sms.no_receiver);
+#endif
+ return rc;
+ }
+
+ switch (sms_mti) {
+ case GSM340_SMS_SUBMIT_MS2SC:
+ /* MS is submitting a SMS */
+ rc = gsm340_rx_sms_submit(msg, gsms);
+ break;
+ case GSM340_SMS_COMMAND_MS2SC:
+ case GSM340_SMS_DELIVER_REP_MS2SC:
+ LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti);
+ rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+ break;
+ default:
+ LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti);
+ rc = GSM411_RP_CAUSE_IE_NOTEXIST;
+ break;
+ }
+
+ if (!rc && !gsms->receiver)
+ rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
+
+ return rc;
+}
+
+
/* process an incoming TPDU (called from RP-DATA)
* return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *msg)
@@ -392,45 +465,7 @@ static int gsm340_rx_tpdu(struct gsm_subscriber_connection *conn, struct msgb *m
/* FIXME: This looks very wrong */
send_signal(0, NULL, gsms, 0);
- /* determine gsms->receiver based on dialled number */
- gsms->receiver = subscr_get_by_extension(conn->bts->network->subscr_group,
- gsms->dst.addr);
- if (!gsms->receiver) {
-#ifdef BUILD_SMPP
- rc = smpp_try_deliver(gsms, conn);
- if (rc == 1) {
- rc = 1; /* cause 1: unknown subscriber */
- osmo_counter_inc(conn->bts->network->stats.sms.no_receiver);
- } else if (rc < 0) {
- rc = 21; /* cause 21: short message transfer rejected */
- /* FIXME: handle the error somehow? */
- }
-#else
- rc = 1; /* cause 1: unknown subscriber */
- osmo_counter_inc(conn->bts->network->stats.sms.no_receiver);
-#endif
- goto out;
- }
-
- switch (sms_mti) {
- case GSM340_SMS_SUBMIT_MS2SC:
- /* MS is submitting a SMS */
- rc = gsm340_rx_sms_submit(msg, gsms);
- break;
- case GSM340_SMS_COMMAND_MS2SC:
- case GSM340_SMS_DELIVER_REP_MS2SC:
- LOGP(DLSMS, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti);
- rc = GSM411_RP_CAUSE_IE_NOTEXIST;
- break;
- default:
- LOGP(DLSMS, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti);
- rc = GSM411_RP_CAUSE_IE_NOTEXIST;
- break;
- }
-
- if (!rc && !gsms->receiver)
- rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
-
+ rc = sms_route_mt_sms(conn, msg, gsms, sms_mti);
out:
sms_free(gsms);
diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c
index b17222f..057a9d0 100644
--- a/openbsc/src/libmsc/smpp_openbsc.c
+++ b/openbsc/src/libmsc/smpp_openbsc.c
@@ -539,6 +539,11 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
static struct smsc *g_smsc;
+int smpp_route_smpp_first(struct gsm_sms *sms, struct gsm_subscriber_connection *conn)
+{
+ return g_smsc->smpp_first;
+}
+
int smpp_try_deliver(struct gsm_sms *sms, struct gsm_subscriber_connection *conn)
{
struct osmo_esme *esme;
diff --git a/openbsc/src/libmsc/smpp_smsc.h b/openbsc/src/libmsc/smpp_smsc.h
index 21d28dd..3dd6562 100644
--- a/openbsc/src/libmsc/smpp_smsc.h
+++ b/openbsc/src/libmsc/smpp_smsc.h
@@ -92,6 +92,7 @@ struct smsc {
uint16_t listen_port;
char system_id[SMPP_SYS_ID_LEN+1];
int accept_all;
+ int smpp_first;
struct osmo_smpp_acl *def_route;
void *priv;
};
@@ -131,4 +132,14 @@ int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
int smpp_vty_init(void);
int smpp_determine_scheme(uint8_t dcs, uint8_t *data_coding, int *mode);
+
+
+
+struct gsm_sms;
+struct gsm_subscriber_connection;
+
+int smpp_route_smpp_first(struct gsm_sms *sms,
+ struct gsm_subscriber_connection *conn);
+int smpp_try_deliver(struct gsm_sms *sms,
+ struct gsm_subscriber_connection *conn);
#endif
diff --git a/openbsc/src/libmsc/smpp_vty.c b/openbsc/src/libmsc/smpp_vty.c
index 75427a9..c0695fe 100644
--- a/openbsc/src/libmsc/smpp_vty.c
+++ b/openbsc/src/libmsc/smpp_vty.c
@@ -58,6 +58,24 @@ DEFUN(cfg_smpp, cfg_smpp_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_smpp_first, cfg_smpp_first_cmd,
+ "smpp-first",
+ "Try SMPP routes before the subscriber DB\n")
+{
+ struct smsc *smsc = smsc_from_vty(vty);
+ smsc->smpp_first = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_smpp_first, cfg_no_smpp_first_cmd,
+ "no smpp-first",
+ NO_STR "Try SMPP before routes before the subscriber DB\n")
+{
+ struct smsc *smsc = smsc_from_vty(vty);
+ smsc->smpp_first = 0;
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_smpp_port, cfg_smpp_port_cmd,
"local-tcp-port <1-65535>",
"Set the local TCP port on which we listen for SMPP\n"
@@ -125,6 +143,8 @@ static int config_write_smpp(struct vty *vty)
vty_out(vty, " system-id %s%s", smsc->system_id, VTY_NEWLINE);
vty_out(vty, " policy %s%s",
smsc->accept_all ? "accept-all" : "closed", VTY_NEWLINE);
+ vty_out(vty, " %ssmpp-first%s",
+ smsc->smpp_first ? "" : "no ", VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -512,6 +532,8 @@ int smpp_vty_init(void)
vty_install_default(SMPP_NODE);
install_element(CONFIG_NODE, &cfg_smpp_cmd);
+ install_element(SMPP_NODE, &cfg_smpp_first_cmd);
+ install_element(SMPP_NODE, &cfg_no_smpp_first_cmd);
install_element(SMPP_NODE, &cfg_smpp_port_cmd);
install_element(SMPP_NODE, &cfg_smpp_sys_id_cmd);
install_element(SMPP_NODE, &cfg_smpp_policy_cmd);
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py
index 4cd4665..1aedcf2 100644
--- a/openbsc/tests/vty_test_runner.py
+++ b/openbsc/tests/vty_test_runner.py
@@ -154,6 +154,28 @@ class TestVTYNITB(TestVTYGenericBSC):
res = self.vty.command("list")
return "smpp" in res
+ def testSmppFirst(self):
+ if not self.checkForSmpp():
+ return
+
+ # enable the configuration
+ self.vty.enable()
+ self.vty.command("configure terminal")
+ self.vty.command("smpp")
+
+ # check the default
+ res = self.vty.command("write terminal")
+ self.assert_(res.find(' no smpp-first') > 0)
+
+ self.vty.verify("smpp-first", [''])
+ res = self.vty.command("write terminal")
+ self.assert_(res.find(' smpp-first') > 0)
+ self.assertEquals(res.find('no smpp-first'), -1)
+
+ self.vty.verify("no smpp-first", [''])
+ res = self.vty.command("write terminal")
+ self.assert_(res.find('no smpp-first') > 0)
+
def testVtyTree(self):
self.vty.enable()
self.assertTrue(self.vty.verify("configure terminal", ['']))