This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Vadim Yanitskiy gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/7677 VTY: add USSD processing back-end configuration This change is a preparation for the upcoming remote USSD processing back-end support. It extends the VTY in order to allow one to choose preferred USSD handler. At the moment, the following handlers are available: OsmoMSC# configure terminal OsmoMSC(config)# ussd OsmoMSC(config-ussd)# handler <TAB> none Do not handle USSD requests local Built-in USSD handlers (e.g. *#100#) Please note that the local back-end (good old *#100#) is still used by default due to the compatibility reasons. Change-Id: I0b3c5ccea4054113e8e23109b1ab68d9f0e18497 --- M include/osmocom/msc/gsm_data.h M include/osmocom/msc/ussd.h M include/osmocom/msc/vty.h M src/libmsc/msc_vty.c M src/libmsc/ussd.c M src/osmo-msc/msc_main.c M tests/msc_vlr/msc_vlr_tests.c 7 files changed, 170 insertions(+), 19 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/77/7677/1 diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h index f3e1b94..5194896 100644 --- a/include/osmocom/msc/gsm_data.h +++ b/include/osmocom/msc/gsm_data.h @@ -14,6 +14,7 @@ #include <osmocom/crypt/auth.h> #include <osmocom/sigtran/sccp_sap.h> +#include <osmocom/msc/ussd.h> #include <osmocom/msc/common.h> #include <osmocom/msc/common_cs.h> #include <osmocom/mgcp_client/mgcp_client.h> @@ -321,6 +322,11 @@ /* MSISDN to which to route MO emergency calls */ char *route_to_msisdn; } emergency; + + struct { + /* USSD handler, e.g. local */ + enum ussd_handler_type handler; + } ussd; }; struct osmo_esme; diff --git a/include/osmocom/msc/ussd.h b/include/osmocom/msc/ussd.h index b41eb8e..7ce27fe 100644 --- a/include/osmocom/msc/ussd.h +++ b/include/osmocom/msc/ussd.h @@ -2,5 +2,19 @@ #include <osmocom/core/msgb.h> +enum ussd_handler_type { + /* Do not handle USSD requests */ + USSD_HANDLER_NONE = 0, + /* Built-in USSD handlers (e.g. *#100#) */ + USSD_HANDLER_LOCAL, +}; + +/* Forward declarations to avoid mutual include */ +struct gsm_subscriber_connection; +struct gsm_network; + +int ussd_init(struct gsm_network *net); +void ussd_shutdown(struct gsm_network *net); + /* Handler function for mobile-originated USSD messages */ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg); diff --git a/include/osmocom/msc/vty.h b/include/osmocom/msc/vty.h index 6a55df7..068683f 100644 --- a/include/osmocom/msc/vty.h +++ b/include/osmocom/msc/vty.h @@ -23,6 +23,7 @@ SMPP_NODE, SMPP_ESME_NODE, HLR_NODE, + USSD_NODE, }; int bsc_vty_init_extra(void); diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c index 33613e9..3a1e512 100644 --- a/src/libmsc/msc_vty.c +++ b/src/libmsc/msc_vty.c @@ -47,6 +47,7 @@ #include <osmocom/msc/vlr.h> #include <osmocom/msc/transaction.h> #include <osmocom/msc/db.h> +#include <osmocom/msc/ussd.h> #include <osmocom/msc/sms_queue.h> #include <osmocom/msc/silent_call.h> #include <osmocom/msc/gsm_04_80.h> @@ -1380,6 +1381,61 @@ return CMD_SUCCESS; } +static struct cmd_node ussd_node = { + USSD_NODE, + "%s(config-ussd)# ", + 1, +}; + +DEFUN(cfg_ussd, cfg_ussd_cmd, + "ussd", "Configure USSD handling") +{ + vty->node = USSD_NODE; + return CMD_SUCCESS; +} + +#define USSD_HANDLERS "(none|local)" +#define USSD_HANDLERS_HELP \ + "Do not handle USSD requests\n" \ + "Built-in USSD handlers (e.g. *#100#)\n" + +DEFUN(cfg_ussd_handler, cfg_ussd_handler_cmd, + "handler " USSD_HANDLERS, + "USSD processing back-end\n" + USSD_HANDLERS_HELP) +{ + const char *handler_str = argv[0]; + + /* Parse handler type */ + if (!strcasecmp(handler_str, "none")) + gsmnet->ussd.handler = USSD_HANDLER_NONE; + else if (!strcasecmp(handler_str, "local")) + gsmnet->ussd.handler = USSD_HANDLER_LOCAL; + else { + vty_out(vty, "Incorrect USSD handler%s", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +static int config_write_ussd(struct vty *vty) +{ + vty_out(vty, "ussd%s", VTY_NEWLINE); + + vty_out(vty, " handler "); + switch (gsmnet->ussd.handler) { + case USSD_HANDLER_NONE: + vty_out(vty, "none%s", VTY_NEWLINE); + break; + case USSD_HANDLER_LOCAL: + vty_out(vty, "local%s", VTY_NEWLINE); + break; + } + + return CMD_SUCCESS; +} + void msc_vty_init(struct gsm_network *msc_network) { OSMO_ASSERT(gsmnet == NULL); @@ -1461,4 +1517,8 @@ install_node(&hlr_node, config_write_hlr); install_element(HLR_NODE, &cfg_hlr_remote_ip_cmd); install_element(HLR_NODE, &cfg_hlr_remote_port_cmd); + + install_element(CONFIG_NODE, &cfg_ussd_cmd); + install_node(&ussd_node, config_write_ussd); + install_element(USSD_NODE, &cfg_ussd_handler_cmd); } diff --git a/src/libmsc/ussd.c b/src/libmsc/ussd.c index e7f7e5d..4396f97 100644 --- a/src/libmsc/ussd.c +++ b/src/libmsc/ussd.c @@ -34,7 +34,11 @@ #include <osmocom/msc/debug.h> #include <osmocom/msc/osmo_msc.h> #include <osmocom/msc/vlr.h> +#include <osmocom/msc/ussd.h> #include <osmocom/msc/gsm_04_08.h> + +static int (*ussd_handler)(struct gsm_subscriber_connection *conn, + const struct ss_request *req) = NULL; /* Declarations of USSD strings to be recognised */ const char USSD_TEXT_OWN_NUMBER[] = "*#100#"; @@ -52,6 +56,43 @@ /* Need trailing CR as EOT character */ snprintf(response_string, sizeof(response_string), "Your extension is %s\r", own_number); return gsm0480_send_ussd_response(conn, response_string, req); +} + +static int ussd_handler_local(struct gsm_subscriber_connection *conn, + const struct ss_request *req) +{ + int rc; + + /* Interrogation or releaseComplete? */ + if (req->ussd_text[0] == '\0' || req->ussd_text[0] == 0xFF) { + if (req->ss_code > 0) { + /* Assume interrogateSS or modification of it and reject */ + rc = gsm0480_send_ussd_reject(conn, req); + return rc; + } + /* Still assuming a Release-Complete and returning */ + return 0; + } + + msc_subscr_conn_communicating(conn); + if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req->ussd_text)) { + DEBUGP(DMM, "USSD: Own number requested\n"); + rc = send_own_number(conn, req); + } else { + DEBUGP(DMM, "Unhandled USSD %s\n", req->ussd_text); + rc = gsm0480_send_ussd_reject(conn, req); + } + + return rc; +} + +static int ussd_handler_dummy(struct gsm_subscriber_connection *conn, + const struct ss_request *req) +{ + DEBUGP(DMM, "USSD support disabled, rejecting request\n"); + + /* FIXME: use a proper problem code */ + return gsm0480_send_ussd_reject(conn, req); } /* Entrypoint - handler function common to all mobile-originated USSDs */ @@ -77,25 +118,31 @@ return rc; } - /* Interrogation or releaseComplete? */ - if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) { - if (req.ss_code > 0) { - /* Assume interrogateSS or modification of it and reject */ - rc = gsm0480_send_ussd_reject(conn, &req); - return rc; - } - /* Still assuming a Release-Complete and returning */ - return 0; + OSMO_ASSERT(ussd_handler); + return ussd_handler(conn, &req); +} + +int ussd_init(struct gsm_network *net) +{ + /* Choose USSD connection handler */ + switch (net->ussd.handler) { + case USSD_HANDLER_LOCAL: + ussd_handler = ussd_handler_local; + break; + case USSD_HANDLER_NONE: + default: + ussd_handler = ussd_handler_dummy; + break; } - msc_subscr_conn_communicating(conn); - if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) { - DEBUGP(DMM, "USSD: Own number requested\n"); - rc = send_own_number(conn, &req); - } else { - DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text); - rc = gsm0480_send_ussd_reject(conn, &req); - } + return 0; +} - return rc; +void ussd_shutdown(struct gsm_network *net) +{ + /** + * Do nothing for now + * TODO: close connection with external USSD gateway + * TODO: close all active USSD connections + */ } diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c index 85a8fe1..d1f731f 100644 --- a/src/osmo-msc/msc_main.c +++ b/src/osmo-msc/msc_main.c @@ -55,6 +55,7 @@ #include <osmocom/msc/vty.h> #include <osmocom/msc/mncc.h> #include <osmocom/msc/rrlp.h> +#include <osmocom/msc/ussd.h> #include <osmocom/ctrl/control_if.h> #include <osmocom/ctrl/control_vty.h> #include <osmocom/ctrl/ports.h> @@ -215,12 +216,22 @@ mgcp_client_conf_init(&net->mgw.conf); + /* USSD: let's keep *#100# available by default */ + net->ussd.handler = USSD_HANDLER_LOCAL; + return net; } void msc_network_shutdown(struct gsm_network *net) { - /* nothing here yet */ + /** + * Prevent NULL pointer dereference, + * e.g. when called before initialization... + */ + OSMO_ASSERT(net); + + /* Shutdown USSD */ + ussd_shutdown(net); } static struct gsm_network *msc_network = NULL; @@ -620,6 +631,13 @@ return -1; } + /* Initialize USSD */ + rc = ussd_init(msc_network); + if (rc) { + printf("Failed to initialize USSD.\n"); + return -1; + } + /* seed the PRNG */ srand(time(NULL)); /* TODO: is this used for crypto?? Improve randomness, at least we diff --git a/tests/msc_vlr/msc_vlr_tests.c b/tests/msc_vlr/msc_vlr_tests.c index 7c54057..828963c 100644 --- a/tests/msc_vlr/msc_vlr_tests.c +++ b/tests/msc_vlr/msc_vlr_tests.c @@ -926,6 +926,9 @@ net->vlr->ops.tx_auth_rej = fake_vlr_tx_auth_rej; net->vlr->ops.set_ciph_mode = fake_vlr_tx_ciph_mode_cmd; + /* USSD: let's keep *#100# available by default */ + net->ussd.handler = USSD_HANDLER_LOCAL; + return net; } @@ -954,6 +957,8 @@ msc_subscr_conn_init(); + ussd_init(net); + clear_vlr(); if (optind >= argc) -- To view, visit https://gerrit.osmocom.org/7677 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0b3c5ccea4054113e8e23109b1ab68d9f0e18497 Gerrit-PatchSet: 1 Gerrit-Project: osmo-msc Gerrit-Branch: master Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>