aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-11-15 01:05:53 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2019-01-11 21:42:43 +0000
commit82cc8a5cfa234068ded337e90596d3d1e45b3244 (patch)
tree702f60febc19116b8890dd4c962c7e3f6968ba5b /src/libmsc
parent4a5cfa559a674d3012e6e38a8d61d159ebef2ba1 (diff)
libmsc/gsm_04_11.c: accept MT SMS messages over GSUP
Diffstat (limited to 'src/libmsc')
-rw-r--r--src/libmsc/gsm_04_08.c5
-rw-r--r--src/libmsc/gsm_04_11.c57
-rw-r--r--src/libmsc/gsm_04_11_gsup.c96
3 files changed, 154 insertions, 4 deletions
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 7ff868140..686194fc8 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -1810,6 +1810,11 @@ static int msc_vlr_route_gsup_msg(struct vlr_subscr *vsub,
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 788a0a946..15a92d487 100644
--- a/src/libmsc/gsm_04_11.c
+++ b/src/libmsc/gsm_04_11.c
@@ -158,10 +158,13 @@ static int paging_cb_mmsms_est_req(unsigned int hooknum, unsigned int event,
gsm411_smc_recv(&trans->sms.smc_inst,
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);
+ /* gsm411_send_rp_data() doesn't set trans->sms.sms */
+ if (sms != NULL) {
+ /* Notify the SMSqueue and free stored SMS */
+ send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, event);
+ trans->sms.sms = NULL;
+ sms_free(sms);
+ }
/* Destroy this transaction */
trans_free(trans);
@@ -794,6 +797,11 @@ static int gsm411_rx_rp_ack(struct gsm_trans *trans,
* successfully received a SMS. We can now safely mark it as
* transmitted */
+ if (trans->net->sms_over_gsup) {
+ /* Forward towards SMSC via GSUP */
+ return gsm411_gsup_mt_fwd_sm_res(trans, rph->msg_ref);
+ }
+
if (!sms) {
LOGP(DLSMS, LOGL_ERROR, "RX RP-ACK but no sms in transaction?!?\n");
return gsm411_send_rp_error(trans, rph->msg_ref,
@@ -830,6 +838,11 @@ static int gsm411_rx_rp_error(struct gsm_trans *trans,
vlr_subscr_name(trans->conn->vsub), cause_len, cause,
get_value_string(gsm411_rp_cause_strs, cause));
+ if (trans->net->sms_over_gsup) {
+ /* Forward towards SMSC via GSUP */
+ return gsm411_gsup_mt_fwd_sm_err(trans, rph->msg_ref, cause);
+ }
+
if (!sms) {
LOGP(DLSMS, LOGL_ERROR,
"RX RP-ERR, but no sms in transaction?!?\n");
@@ -1112,6 +1125,42 @@ int gsm411_send_sms(struct gsm_network *net,
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;
+
+ /* 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 SM-RP-OA (SMSC address) */
+ msgb_lv_put(msg, sm_rp_oa_len, sm_rp_oa);
+
+ /* Encode SM-RP-DA (shall be empty, len=0) */
+ msgb_v_put(msg, 0x00);
+
+ /* Encode RP-UD itself (SM TPDU) */
+ msgb_lv_put(msg, sm_rp_ud_len, sm_rp_ud);
+
+ 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 ran_conn *conn,
struct msgb *msg)
diff --git a/src/libmsc/gsm_04_11_gsup.c b/src/libmsc/gsm_04_11_gsup.c
index 5c0107245..f2de95f70 100644
--- a/src/libmsc/gsm_04_11_gsup.c
+++ b/src/libmsc/gsm_04_11_gsup.c
@@ -201,3 +201,99 @@ msg_error:
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_sm_msg_init(&gsup_msg, OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT,
+ trans->vsub->imsi, &sm_rp_mr);
+
+ return osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &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_sm_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 osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &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->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
+ *
+ * FIXME: SM-RP-MR is not known yet (to be assigned by MSC)
+ * NOTE: SM-RP-DA is out of our interest
+ */
+ if (!gsup_msg->sm_rp_mr)
+ goto msg_error;
+ if (!gsup_msg->sm_rp_ui)
+ goto msg_error;
+
+ /* SM-RP-OA shall contain SMSC address */
+ if (gsup_msg->sm_rp_oa_type != OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR)
+ goto msg_error;
+
+ /* Send RP-DATA */
+ 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;
+}