diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-07-13 10:42:17 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-07-13 10:42:17 +0200 |
commit | 14a434b9d660cb92382f418739b8329b44640496 (patch) | |
tree | 7ec734baa04e92d68992d8e82121c30ae03a5b94 /openbsc | |
parent | b69518f3834b60901ab5750b6ce3b623d9479c1e (diff) | |
parent | 7c19c6b4064b10511fa5f5327030c21616905d94 (diff) |
Merge branch 'zecke/features/smpp-route'
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/libmsc/gsm_04_11.c | 117 | ||||
-rw-r--r-- | openbsc/src/libmsc/smpp_openbsc.c | 5 | ||||
-rw-r--r-- | openbsc/src/libmsc/smpp_smsc.h | 11 | ||||
-rw-r--r-- | openbsc/src/libmsc/smpp_vty.c | 22 | ||||
-rw-r--r-- | openbsc/tests/vty_test_runner.py | 22 |
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 1b2a42c4f..c2cec26cd 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 b17222fb4..057a9d048 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 21d28dda6..3dd656242 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 75427a9c0..c0695fe7a 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 4cd46653e..1aedcf21c 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", [''])) |