falconia has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-hlr/+/34449?usp=email )

Change subject: SMS over GSUP: implement forwarding of MO SMS
......................................................................

SMS over GSUP: implement forwarding of MO SMS

MO-forwardSM.req messages are now forwarded to a connected SMSC
based on the SMSC address (SM-RP-DA) in the MO SM and the vty-defined
mapping from SMSC numeric addresses to IPA names.

Related: OS#6135
Depends: Iea5c29909c5be80f81dbbc2873656ff5cf590a5d (libosmocore)
Change-Id: Iaad4531922c41583d261c79f42561a1bdbe03521
---
M TODO-RELEASE
M include/osmocom/hlr/hlr_sms.h
M src/hlr.c
M src/hlr_sms.c
4 files changed, 111 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, approved




diff --git a/TODO-RELEASE b/TODO-RELEASE
index cbfda24..d8e3568 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
 # If any interfaces have been added since the last public release: c:r:a + 1.
 # If any interfaces have been removed or changed since the last public 
release: c:r:0.
 #library        what            description / commit summary line
+libosmogsm     >1.9.0          <osmocom/gsm/protocol/gsm_04_11.h> additions
diff --git a/include/osmocom/hlr/hlr_sms.h b/include/osmocom/hlr/hlr_sms.h
index 0570aca..727e408 100644
--- a/include/osmocom/hlr/hlr_sms.h
+++ b/include/osmocom/hlr/hlr_sms.h
@@ -27,3 +27,5 @@
 struct hlr_smsc_route *smsc_route_alloc(struct hlr *hlr, const char *num_addr,
                                        struct hlr_smsc *smsc);
 void smsc_route_free(struct hlr_smsc_route *rt);
+
+void forward_mo_sms(struct osmo_gsup_req *req);
diff --git a/src/hlr.c b/src/hlr.c
index 17acdab..501eabc 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -49,6 +49,7 @@
 #include <osmocom/hlr/rand.h>
 #include <osmocom/hlr/hlr_vty.h>
 #include <osmocom/hlr/hlr_ussd.h>
+#include <osmocom/hlr/hlr_sms.h>
 #include <osmocom/hlr/dgsm.h>
 #include <osmocom/hlr/proxy.h>
 #include <osmocom/hlr/lu_fsm.h>
@@ -556,6 +557,9 @@
        case OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST:
                rx_check_imei_req(req);
                break;
+       case OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST:
+               forward_mo_sms(req);
+               break;
        default:
                LOGP(DMAIN, LOGL_DEBUG, "Unhandled GSUP message type %s\n",
                     osmo_gsup_message_type_name(req->gsup.message_type));
diff --git a/src/hlr_sms.c b/src/hlr_sms.c
index 5866afa..672d6c9 100644
--- a/src/hlr_sms.c
+++ b/src/hlr_sms.c
@@ -26,6 +26,8 @@

 #include <osmocom/core/talloc.h>
 #include <osmocom/gsm/gsup.h>
+#include <osmocom/gsm/gsm48_ie.h>
+#include <osmocom/gsm/protocol/gsm_04_11.h>

 #include <osmocom/hlr/hlr.h>
 #include <osmocom/hlr/hlr_sms.h>
@@ -101,3 +103,90 @@
        llist_del(&rt->list);
        talloc_free(rt);
 }
+
+/***********************************************************************
+ * forwarding of MO SMS to SMSCs based on SM-RP-DA
+ ***********************************************************************/
+
+static const struct hlr_smsc *find_smsc_route(const char *smsc_addr)
+{
+       const struct hlr_smsc_route *rt;
+
+       rt = smsc_route_find(g_hlr, smsc_addr);
+       if (rt)
+               return rt->smsc;
+       return g_hlr->smsc_default;
+}
+
+static void respond_with_sm_rp_cause(struct osmo_gsup_req *req,
+                                    uint8_t sm_rp_cause)
+{
+       struct osmo_gsup_message rsp_msg = { };
+
+       rsp_msg.sm_rp_cause = &sm_rp_cause;
+       osmo_gsup_req_respond(req, &rsp_msg, true, true);
+}
+
+/* Short Message from MSC/VLR towards SMSC */
+void forward_mo_sms(struct osmo_gsup_req *req)
+{
+       uint8_t gsm48_decode_buffer[GSM411_SMSC_ADDR_MAX_OCTETS];
+       char smsc_addr[GSM411_SMSC_ADDR_MAX_DIGITS+1];
+       const struct hlr_smsc *smsc;
+       struct osmo_cni_peer_id dest_peer;
+
+       /* Make sure SM-RP-DA (SMSC address) is present */
+       if (req->gsup.sm_rp_da == NULL || !req->gsup.sm_rp_da_len) {
+               osmo_gsup_req_respond_err(req, GMM_CAUSE_INV_MAND_INFO,
+                                         "missing SM-RP-DA");
+               return;
+       }
+
+       if (req->gsup.sm_rp_da_type != OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR) {
+               osmo_gsup_req_respond_err(req, GMM_CAUSE_INV_MAND_INFO,
+                                         "SM-RP-DA type is not SMSC");
+               return;
+       }
+
+       /* Enforce the length constrainst on SM-RP-DA, as specified in
+        * GSM 04.11 section 8.2.5.2.  Also enforce absence of ToN/NPI
+        * extension octets at the same time. */
+       if (req->gsup.sm_rp_da_len < GSM411_SMSC_ADDR_MIN_OCTETS ||
+           req->gsup.sm_rp_da_len > GSM411_SMSC_ADDR_MAX_OCTETS ||
+           !(req->gsup.sm_rp_da[0] & 0x80)) {
+               /* This form of bogosity originates from the MS,
+                * not from OsmoMSC or any other Osmocom network elements! */
+               LOGP(DLSMS, LOGL_NOTICE,
+                    "Rx '%s' (IMSI-%s) contains invalid SM-RP-DA from MS\n",
+                    osmo_gsup_message_type_name(req->gsup.message_type),
+                    req->gsup.imsi);
+               respond_with_sm_rp_cause(req, GSM411_RP_CAUSE_SEMANT_INC_MSG);
+               return;
+       }
+
+       /* Decode SMSC address from SM-RP-DA */
+       gsm48_decode_buffer[0] = req->gsup.sm_rp_da_len - 1;
+       memcpy(gsm48_decode_buffer + 1, req->gsup.sm_rp_da + 1,
+               req->gsup.sm_rp_da_len - 1);
+       gsm48_decode_bcd_number2(smsc_addr, sizeof(smsc_addr),
+                                gsm48_decode_buffer,
+                                req->gsup.sm_rp_da_len, 0);
+
+       /* Look for a route to this SMSC */
+       smsc = find_smsc_route(smsc_addr);
+       if (smsc == NULL) {
+               LOGP(DLSMS, LOGL_NOTICE,
+                    "Failed to find a route for '%s' (IMSI-%s, 
SMSC-Addr-%s)\n",
+                    osmo_gsup_message_type_name(req->gsup.message_type),
+                    req->gsup.imsi, smsc_addr);
+               respond_with_sm_rp_cause(req,
+                                        GSM411_RP_CAUSE_MO_NUM_UNASSIGNED);
+               return;
+       }
+
+       /* We got the IPA name of our SMSC - forward the message */
+       osmo_cni_peer_id_set(&dest_peer, OSMO_CNI_PEER_ID_IPA_NAME,
+                            (const uint8_t *) smsc->name,
+                            strlen(smsc->name) + 1);
+       osmo_gsup_forward_to_local_peer(req->cb_data, &dest_peer, req, NULL);
+}

--
To view, visit https://gerrit.osmocom.org/c/osmo-hlr/+/34449?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hlr
Gerrit-Branch: master
Gerrit-Change-Id: Iaad4531922c41583d261c79f42561a1bdbe03521
Gerrit-Change-Number: 34449
Gerrit-PatchSet: 4
Gerrit-Owner: falconia <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: falconia <[email protected]>
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to