Vadim Yanitskiy has uploaded this change for review. ( 
https://gerrit.osmocom.org/11920


Change subject: libmsc/gsm_04_11.c: accept MT SMS messages over GSUP
......................................................................

libmsc/gsm_04_11.c: accept MT SMS messages over GSUP

Change-Id: I57357982ca0e51f6722c24a4aa1d0fb3e6caef88
Depends-on: (core) Ic37f3b2114b8095cfce22977e67133b9103942e3
Related: OS#3587
---
M include/osmocom/msc/gsm_04_11.h
M include/osmocom/msc/gsm_04_11_gsup.h
M src/libmsc/gsm_04_08.c
M src/libmsc/gsm_04_11.c
M src/libmsc/gsm_04_11_gsup.c
5 files changed, 177 insertions(+), 3 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/20/11920/1

diff --git a/include/osmocom/msc/gsm_04_11.h b/include/osmocom/msc/gsm_04_11.h
index 3997ab2..4310115 100644
--- a/include/osmocom/msc/gsm_04_11.h
+++ b/include/osmocom/msc/gsm_04_11.h
@@ -42,6 +42,10 @@
 int gsm411_send_sms(struct gsm_network *net,
                    struct vlr_subscr *vsub,
                    struct gsm_sms *sms);
+int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
+                       size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,
+                       size_t sm_rp_ud_len, const uint8_t *sm_rp_ud);
+
 void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);

 int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref);
diff --git a/include/osmocom/msc/gsm_04_11_gsup.h 
b/include/osmocom/msc/gsm_04_11_gsup.h
index 82f575d..9c6f2fb 100644
--- a/include/osmocom/msc/gsm_04_11_gsup.h
+++ b/include/osmocom/msc/gsm_04_11_gsup.h
@@ -13,3 +13,9 @@
        uint8_t sm_rp_mr, uint8_t *sm_rp_da, uint8_t sm_rp_da_len);
 int gsm411_gsup_mo_handler(struct vlr_subscr *vsub,
        struct osmo_gsup_message *gsup_msg);
+
+int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr);
+int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,
+       uint8_t sm_rp_mr, uint8_t cause);
+int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,
+       struct osmo_gsup_message *gsup_msg);
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 161585c..87e4cb1 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -1792,6 +1792,11 @@
                DEBUGP(DMSC, "Routed to GSM 04.11 MO handler\n");
                return gsm411_gsup_mo_handler(vsub, gsup_msg);

+       /* GSM 04.11 code implementing MT SMS */
+       case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST:
+               DEBUGP(DMSC, "Routed to GSM 04.11 MT handler\n");
+               return gsm411_gsup_mt_handler(vsub, gsup_msg);
+
        default:
                LOGP(DMM, LOGL_ERROR, "No handler found for %s, dropping 
message...\n",
                        osmo_gsup_message_type_name(gsup_msg->message_type));
diff --git a/src/libmsc/gsm_04_11.c b/src/libmsc/gsm_04_11.c
index 93c2ea7..efaf2ae 100644
--- a/src/libmsc/gsm_04_11.c
+++ b/src/libmsc/gsm_04_11.c
@@ -159,9 +159,11 @@
                        GSM411_MMSMS_REL_IND, NULL, 0);

                /* Notify the SMSqueue and free stored SMS */
-               send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);
-               trans->sms.sms = NULL;
-               sms_free(sms);
+               if (sms != NULL) { /* gsm411_send_rp_data() doesn't set 
trans->sms.sms */
+                       send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);
+                       trans->sms.sms = NULL;
+                       sms_free(sms);
+               }

                /* Destroy this transaction */
                trans_free(trans);
@@ -798,6 +800,9 @@
         * successfully received a SMS.  We can now safely mark it as
         * transmitted */

+       if (trans->net->enable_sms_over_gsup)
+               goto sms_over_gsup;
+
        if (!sms) {
                LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in 
transaction?!?\n");
                return gsm411_send_rp_error(trans, rph->msg_ref,
@@ -816,6 +821,10 @@
        trans->sms.sms = NULL;

        return 0;
+
+sms_over_gsup:
+       /* Forward towards ESME via GSUP */
+       return gsm411_gsup_mt_fwd_sm_res(trans, rph->msg_ref);
 }

 static int gsm411_rx_rp_error(struct gsm_trans *trans,
@@ -834,6 +843,9 @@
             vlr_subscr_name(trans->conn->vsub), cause_len, cause,
             get_value_string(gsm411_rp_cause_strs, cause));

+       if (trans->net->enable_sms_over_gsup)
+               goto sms_over_gsup;
+
        if (!sms) {
                LOGP(DLSMS, LOGL_ERROR,
                        "RX RP-ERR, but no sms in transaction?!?\n");
@@ -859,6 +871,10 @@
        trans->sms.sms = NULL;

        return 0;
+
+sms_over_gsup:
+       /* Forward towards ESME via GSUP */
+       return gsm411_gsup_mt_fwd_sm_err(trans, rph->msg_ref, cause);
 }

 static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
@@ -1115,6 +1131,54 @@
                GSM411_SM_RL_DATA_REQ);
 }
 
+/* Low-level function to send raw RP-DATA to a given subscriber */
+int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
+                       size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,
+                       size_t sm_rp_ud_len, const uint8_t *sm_rp_ud)
+{
+       struct gsm_trans *trans;
+       struct msgb *msg;
+       uint8_t *ptr;
+
+       /* Allocate a new transaction for MT SMS */
+       trans = gsm411_alloc_mt_trans(net, vsub);
+       if (!trans)
+               return -ENOMEM;
+
+       /* Allocate a message buffer for to be encoded SMS */
+       msg = gsm411_msgb_alloc();
+       if (!msg) {
+               trans_free(trans);
+               return -ENOMEM;
+       }
+
+       /* Encode RP-DA length */
+       ptr = (uint8_t *) msgb_put(msg, 1);
+       ptr[0] = sm_rp_oa_len;
+
+       /* Encode RP-OA (SMSC address) */
+       ptr = (uint8_t *) msgb_put(msg, sm_rp_oa_len);
+       memcpy(ptr, sm_rp_oa, sm_rp_oa_len);
+
+       /* Encode RP-DA (shall be empty, len=0) */
+       ptr = (uint8_t *) msgb_put(msg, 1);
+       ptr[0] = 0x00;
+
+       /* Encode RP-UD length */
+       ptr = (uint8_t *) msgb_put(msg, 1);
+       ptr[0] = sm_rp_ud_len;
+
+       /* Encode RP-UD itself (SM TPDU) */
+       ptr = (uint8_t *) msgb_put(msg, sm_rp_ud_len);
+       memcpy(ptr, sm_rp_ud, sm_rp_ud_len);
+
+       rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVERED]);
+
+       return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
+               GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr,
+               GSM411_SM_RL_DATA_REQ);
+}
+
 /* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */
 int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn,
                    struct msgb *msg)
diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c
index ee06936..d94c384 100644
--- a/src/libmsc/gsm_04_11_gsup.c
+++ b/src/libmsc/gsm_04_11_gsup.c
@@ -239,3 +239,98 @@
                msg_name, msg_is_err ? "Err" : "Res");
        return -EINVAL;
 }
+
+int gsm411_gsup_mt_fwd_sm_res(struct gsm_trans *trans, uint8_t sm_rp_mr)
+{
+       struct osmo_gsup_message gsup_msg;
+
+       /* Associate logging messages with this subscriber */
+       log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+
+       LOGP(DLSMS, LOGL_DEBUG, "TX MT-forwardSM-Res\n");
+
+       /* Initialize a new GSUP message */
+       gsup_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,
+               trans->vsub->imsi, &sm_rp_mr);
+
+       return gsup_msg_send(trans->net, &gsup_msg);
+}
+
+int gsm411_gsup_mt_fwd_sm_err(struct gsm_trans *trans,
+       uint8_t sm_rp_mr, uint8_t cause)
+{
+       struct osmo_gsup_message gsup_msg;
+
+       /* Associate logging messages with this subscriber */
+       log_set_context(LOG_CTX_VLR_SUBSCR, trans->vsub);
+
+       LOGP(DLSMS, LOGL_DEBUG, "TX MT-forwardSM-Err\n");
+
+       /* Initialize a new GSUP message */
+       gsup_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR,
+               trans->vsub->imsi, &sm_rp_mr);
+
+       /* SM-RP-Cause value */
+       gsup_msg.sm_rp_cause = &cause;
+
+       /* TODO: include optional SM-RP-UI field if present */
+       return gsup_msg_send(trans->net, &gsup_msg);
+}
+
+/* Handles MT SMS (and triggers Paging Request if required) */
+int gsm411_gsup_mt_handler(struct vlr_subscr *vsub,
+       struct osmo_gsup_message *gsup_msg)
+{
+       struct vlr_instance *vlr;
+       struct gsm_network *net;
+       int rc;
+
+       /* Obtain required pointers */
+       vlr = vsub->vlr;
+       net = (struct gsm_network *) vlr->user_ctx;
+
+       /* Associate logging messages with this subscriber */
+       log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
+
+       LOGP(DLSMS, LOGL_DEBUG, "RX MT-forwardSM-Req\n");
+
+       /* Make sure that 'SMS over GSUP' is expected */
+       if (!net->enable_sms_over_gsup) {
+               LOGP(DLSMS, LOGL_NOTICE, "Unexpected MT SMS over GSUP, "
+                       "ignoring message...\n");
+               /* TODO: notify sender about that? */
+               return -EIO;
+       }
+
+       /* Verify GSUP message */
+       if (!gsup_msg->sm_rp_mr)
+               goto msg_error;
+       if (!gsup_msg->sm_rp_da_type)
+               goto msg_error;
+       if (!gsup_msg->sm_rp_oa_type)
+               goto msg_error;
+       if (!gsup_msg->sm_rp_ui)
+               goto msg_error;
+
+       /**
+        * FIXME: SM-RP-MR is not known yet
+        * TODO: SM-RP-DA is out of our interest
+        * TODO: SM-RP-OA should contain the SMSC address
+        */
+       rc = gsm411_send_rp_data(net, vsub,
+               gsup_msg->sm_rp_oa_len, gsup_msg->sm_rp_oa,
+               gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui);
+       if (rc) {
+               LOGP(DLSMS, LOGL_NOTICE, "Failed to send MT SMS, "
+                       "ignoring MT-forwardSM-Req message...\n");
+               /* TODO: notify sender about that? */
+               return rc;
+       }
+
+       return 0;
+
+msg_error:
+       /* TODO: notify sender about that? */
+       LOGP(DLSMS, LOGL_NOTICE, "RX malformed MT-forwardSM-Req\n");
+       return -EINVAL;
+}

--
To view, visit https://gerrit.osmocom.org/11920
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I57357982ca0e51f6722c24a4aa1d0fb3e6caef88
Gerrit-Change-Number: 11920
Gerrit-PatchSet: 1
Gerrit-Owner: Vadim Yanitskiy <[email protected]>

Reply via email to