<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10245">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">USSD: Add basic dispatch + decode of GSUP-encapsulated SS/USSD<br><br>We don't want any SS session to run for more than 30s. The timeout<br>is currently not refreshed.<br><br>If we need more comprehensive timeout handling, using osmo_fsm for SS<br>sessions might make sense.<br><br>Change-Id: I5c9fb6b619402d2a23fea9db99590143d85ac11a<br>---<br>M src/hlr.c<br>M src/hlr.h<br>M src/hlr_ussd.c<br>M src/hlr_ussd.h<br>4 files changed, 323 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/45/10245/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/hlr.c b/src/hlr.c</span><br><span>index 79c4c86..74b65c4 100644</span><br><span>--- a/src/hlr.c</span><br><span>+++ b/src/hlr.c</span><br><span>@@ -42,6 +42,7 @@</span><br><span> #include "rand.h"</span><br><span> #include "luop.h"</span><br><span> #include "hlr_vty.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "hlr_ussd.h"</span><br><span> </span><br><span> struct hlr *g_hlr;</span><br><span> static int quit = 0;</span><br><span>@@ -402,6 +403,13 @@</span><br><span> LOGP(DMAIN, LOGL_ERROR, "Deleting subscriber data for IMSI %s\n",</span><br><span> gsup.imsi);</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_MSGT_PROC_SS_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_MSGT_PROC_SS_RESULT:</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_proc_ss_req(conn, &gsup);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_MSGT_PROC_SS_ERROR:</span><br><span style="color: hsl(120, 100%, 40%);">+ rx_proc_ss_error(conn, &gsup);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case OSMO_GSUP_MSGT_INSERT_DATA_ERROR:</span><br><span> case OSMO_GSUP_MSGT_INSERT_DATA_RESULT:</span><br><span> case OSMO_GSUP_MSGT_LOCATION_CANCEL_ERROR:</span><br><span>@@ -560,6 +568,7 @@</span><br><span> </span><br><span> g_hlr = talloc_zero(hlr_ctx, struct hlr);</span><br><span> INIT_LLIST_HEAD(&g_hlr->euse_list);</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&g_hlr->ss_sessions);</span><br><span> </span><br><span> rc = osmo_init_logging2(hlr_ctx, &hlr_log_info);</span><br><span> if (rc < 0) {</span><br><span>diff --git a/src/hlr.h b/src/hlr.h</span><br><span>index 938f7f9..7112352 100644</span><br><span>--- a/src/hlr.h</span><br><span>+++ b/src/hlr.h</span><br><span>@@ -43,6 +43,8 @@</span><br><span> </span><br><span> struct llist_head euse_list;</span><br><span> struct hlr_euse *euse_default;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head ss_sessions;</span><br><span> };</span><br><span> </span><br><span> extern struct hlr *g_hlr;</span><br><span>diff --git a/src/hlr_ussd.c b/src/hlr_ussd.c</span><br><span>index 785eafd..41fba34 100644</span><br><span>--- a/src/hlr_ussd.c</span><br><span>+++ b/src/hlr_ussd.c</span><br><span>@@ -1,4 +1,4 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* OsmoHLR VTY implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+/* OsmoHLR SS/USSD implementation */</span><br><span> </span><br><span> /* (C) 2018 Harald Welte <laforge@gnumonks.org></span><br><span> *</span><br><span>@@ -21,11 +21,22 @@</span><br><span> </span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsup.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm0480.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/gsm_04_80.h></span><br><span> #include <stdint.h></span><br><span> #include <string.h></span><br><span> </span><br><span> #include "hlr.h"</span><br><span> #include "hlr_ussd.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gsup_server.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gsup_router.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "logging.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * core data structures expressing config from VTY</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span> </span><br><span> struct hlr_euse *euse_find(struct hlr *hlr, const char *name)</span><br><span> {</span><br><span>@@ -91,3 +102,293 @@</span><br><span> llist_del(&rt->list);</span><br><span> talloc_free(rt);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hlr_euse *ussd_euse_find_7bit_gsm(struct hlr *hlr, const char *ussd_code)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(euse, &hlr->euse_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse_route *rt;</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(rt, &euse->routes, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strncmp(ussd_code, rt->prefix, strlen(rt->prefix))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_DEBUG, "Found EUSE %s (prefix %s) for USSD Code '%s'\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rt->euse->name, rt->prefix, ussd_code);</span><br><span style="color: hsl(120, 100%, 40%);">+ return rt->euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_DEBUG, "Could not find Route/EUSE for USSD Code '%s'\n", ussd_code);</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * handling functions for individual GSUP messages</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ss_session {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* link us to hlr->ss_sessions */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* imsi of this session */</span><br><span style="color: hsl(120, 100%, 40%);">+ char imsi[GSM23003_IMSI_MAX_DIGITS+2];</span><br><span style="color: hsl(120, 100%, 40%);">+ /* ID of this session (unique per IMSI) */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t session_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* state of the session */</span><br><span style="color: hsl(120, 100%, 40%);">+ enum osmo_gsup_session_state state;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* time-out when we will delete the session */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_timer_list timeout;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* external USSD Entity responsible for this session */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr_euse *euse;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we don't keep a pointer to the osmo_gsup_{route,conn} towards the MSC/VLR here,</span><br><span style="color: hsl(120, 100%, 40%);">+ * as this might change during inter-VLR hand-over, and we simply look-up the serving MSC/VLR</span><br><span style="color: hsl(120, 100%, 40%);">+ * every time we receive an USSD component from the EUSE */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ss_session *ss_session_find(struct hlr *hlr, const char *imsi, uint32_t session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ss_session *ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(ss, &hlr->ss_sessions, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(ss->imsi, imsi) && ss->session_id == session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+ return ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ss_session_free(struct ss_session *ss)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_del(&ss->timeout);</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_del(&ss->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(ss);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ss_session_timeout(void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ss_session *ss = data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_NOTICE, "%s/0x%08x: SS Session Timeout, destroying\n", ss->imsi, ss->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: should we send a ReturnError component to the MS? */</span><br><span style="color: hsl(120, 100%, 40%);">+ ss_session_free(ss);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ss_session *ss_session_alloc(struct hlr *hlr, const char *imsi, uint32_t session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ss_session *ss;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!ss_session_find(hlr, imsi, session_id));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ss = talloc_zero(hlr, struct ss_session);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(ss);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_STRLCPY_ARRAY(ss->imsi, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ ss->session_id = session_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_setup(&ss->timeout, ss_session_timeout, ss);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* NOTE: The timeout is currently global and not refreshed with subsequent messages</span><br><span style="color: hsl(120, 100%, 40%);">+ * within the SS/USSD session. So 30s after the initial SS message, the session will</span><br><span style="color: hsl(120, 100%, 40%);">+ * timeout! */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_timer_schedule(&ss->timeout, 30, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add_tail(&ss->list, &hlr->ss_sessions);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ss;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * handling functions for individual GSUP messages</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool ss_op_is_ussd(uint8_t opcode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (opcode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM0480_OP_CODE_PROCESS_USS_DATA:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM0480_OP_CODE_PROCESS_USS_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM0480_OP_CODE_USS_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM0480_OP_CODE_USS_NOTIFY:</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* is this GSUP connection an EUSE (true) or not (false)? */</span><br><span style="color: hsl(120, 100%, 40%);">+static bool conn_is_euse(struct osmo_gsup_conn *conn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_gsup_conn_ccm_get(conn, &addr, IPAC_IDTAG_SERNR);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc <= 5)</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strncmp((char *)addr, "EUSE-", 5))</span><br><span style="color: hsl(120, 100%, 40%);">+ return true;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct hlr_euse *euse_by_conn(struct osmo_gsup_conn *conn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr *hlr = conn->server->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &addr, IPAC_IDTAG_SERNR);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc <= 5)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strncmp(addr, "EUSE-", 5))</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return euse_find(hlr, addr+5);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int handle_ss(struct ss_session *ss, const struct osmo_gsup_message *gsup,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ss_request *req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t comp_type = gsup->ss_info[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_INFO, "%s: SS CompType=%s, OpCode=%s\n", gsup->imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm0480_comp_type_name(comp_type), gsm0480_op_code_name(req->opcode));</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int handle_ussd(struct osmo_gsup_conn *conn, struct ss_session *ss,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_gsup_message *gsup, const struct ss_request *req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t comp_type = gsup->ss_info[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg_out;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool is_euse_originated = conn_is_euse(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_INFO, "%s: USSD CompType=%s, OpCode=%s '%s'\n", gsup->imsi,</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm0480_comp_type_name(comp_type), gsm0480_op_code_name(req->opcode),</span><br><span style="color: hsl(120, 100%, 40%);">+ req->ussd_text);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg_out = msgb_alloc_headroom(1024+16, 16, "GSUP USSD FW");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(msg_out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ss->euse) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_NOTICE, "%s: USSD for unknown code '%s'\n", gsup->imsi, req->ussd_text);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: send proper error */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_euse_originated) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Received from EUSE, Forward to VLR */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_encode(msg_out, gsup);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: resolve this based on the database vlr_addr */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_addr_send(conn->server, (uint8_t *)"MSC-00-00-00-00-00-00", 22, msg_out);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Received from VLR, Forward to EUSE */</span><br><span style="color: hsl(120, 100%, 40%);">+ char addr[128];</span><br><span style="color: hsl(120, 100%, 40%);">+ strcpy(addr, "EUSE-");</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_strlcpy(addr+5, ss->euse->name, sizeof(addr)-5);</span><br><span style="color: hsl(120, 100%, 40%);">+ conn = gsup_route_find(conn->server, (uint8_t *)addr, strlen(addr)+1);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!conn) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Cannot find conn for EUSE %s\n", addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: send proper error */</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_encode(msg_out, gsup);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_conn_send(conn, msg_out);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* this function is called for any SS_REQ/SS_RESP messages from both the MSC/VLR side as well</span><br><span style="color: hsl(120, 100%, 40%);">+ * as from the EUSE side */</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_proc_ss_req(struct osmo_gsup_conn *conn, const struct osmo_gsup_message *gsup)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hlr *hlr = conn->server->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ss_session *ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ss_request req = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_INFO, "%s: Process SS (0x%08x, %s)\n", gsup->imsi, gsup->session_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_session_state_name(gsup->session_state));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* decode and find out what kind of SS message it is */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (gsup->ss_info && gsup->ss_info_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (gsm0480_parse_facility_ie(gsup->ss_info, gsup->ss_info_len, &req)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s: Unable to parse SS request for 0x%08x: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup->imsi, gsup->session_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_hexdump(gsup->ss_info, gsup->ss_info_len));</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (gsup->session_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SESSION_STATE_BEGIN:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Check for overlapping Session ID usage */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ss_session_find(hlr, gsup->imsi, gsup->session_id)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s/0x%08x: BEGIN with non-uinque session ID!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ss = ss_session_alloc(hlr, gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ss) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s: Unable to allocate SS session for 0x%08x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ss_op_is_ussd(req.opcode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conn_is_euse(conn)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* EUSE->VLR: MT USSD. EUSE is known ('conn'), VLR is to be resolved */</span><br><span style="color: hsl(120, 100%, 40%);">+ ss->euse = euse_by_conn(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* VLR->EUSE: MO USSD. VLR is known ('conn'), EUSE is to be resolved */</span><br><span style="color: hsl(120, 100%, 40%);">+ ss->euse = ussd_euse_find_7bit_gsm(hlr, (const char *) req.ussd_text);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch unstructured SS to routing */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ussd(conn, ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch non-call SS to internal code */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ss(ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SESSION_STATE_CONTINUE:</span><br><span style="color: hsl(120, 100%, 40%);">+ ss = ss_session_find(hlr, gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ss) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s: CONTINUE for unknwon SS session 0x%08x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ss_op_is_ussd(req.opcode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch unstructured SS to routing */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ussd(conn, ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch non-call SS to internal code */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ss(ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SESSION_STATE_END:</span><br><span style="color: hsl(120, 100%, 40%);">+ ss = ss_session_find(hlr, gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ss) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s: END for unknwon SS session 0x%08x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ gsup->imsi, gsup->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ss_op_is_ussd(req.opcode)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch unstructured SS to routing */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ussd(conn, ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* dispatch non-call SS to internal code */</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_ss(ss, gsup, &req);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ss_session_free(ss);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "%s: Unknown SS State %d\n", gsup->imsi, gsup->session_state);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto out_err;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+out_err:</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_proc_ss_error(struct osmo_gsup_conn *conn, const struct osmo_gsup_message *gsup)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_NOTICE, "%s: Process SS ERROR (0x%08x, %s)\n", gsup->imsi, gsup->session_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_gsup_session_state_name(gsup->session_state));</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/hlr_ussd.h b/src/hlr_ussd.h</span><br><span>index 05d2099..433a7f2 100644</span><br><span>--- a/src/hlr_ussd.h</span><br><span>+++ b/src/hlr_ussd.h</span><br><span>@@ -1,5 +1,9 @@</span><br><span> #include <stdint.h></span><br><span> #include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsup.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "gsup_server.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_gsup_conn;</span><br><span> </span><br><span> struct hlr_euse_route {</span><br><span> /* hlr_euse.routes */</span><br><span>@@ -18,6 +22,9 @@</span><br><span> const char *description;</span><br><span> /* list of hlr_euse_route */</span><br><span> struct llist_head routes;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* GSUP connection to the EUSE, if any */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_gsup_conn *conn;</span><br><span> };</span><br><span> </span><br><span> </span><br><span>@@ -28,3 +35,6 @@</span><br><span> struct hlr_euse_route *euse_route_find(struct hlr_euse *euse, const char *prefix);</span><br><span> struct hlr_euse_route *euse_route_prefix_alloc(struct hlr_euse *euse, const char *prefix);</span><br><span> void euse_route_del(struct hlr_euse_route *rt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_proc_ss_req(struct osmo_gsup_conn *conn, const struct osmo_gsup_message *gsup);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_proc_ss_error(struct osmo_gsup_conn *conn, const struct osmo_gsup_message *gsup);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10245">change 10245</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10245"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-hlr </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5c9fb6b619402d2a23fea9db99590143d85ac11a </div>
<div style="display:none"> Gerrit-Change-Number: 10245 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>