From 3bb01d0ef690708d45043feff96514382b56214d Mon Sep 17 00:00:00 2001 From: "Mychaela N. Falconia" Date: Mon, 28 Aug 2023 18:46:41 +0000 Subject: [PATCH] SMS over GSUP: handle READY-FOR-SM.req from MSCs When an MS indicates that it is ready to receive MT SMS, the MSC will send us a READY-FOR-SM.req message. Handle it by sending copies of the same message to all connected SMSCs and returning OK result to the MS that indicates its ready status. Related: OS#6135 Change-Id: I731545a3a0d0804289e24a7769e13bfd3f645132 --- include/osmocom/hlr/hlr_sms.h | 1 + src/hlr.c | 3 ++ src/hlr_sms.c | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/include/osmocom/hlr/hlr_sms.h b/include/osmocom/hlr/hlr_sms.h index b3beea6f..0a75b051 100644 --- a/include/osmocom/hlr/hlr_sms.h +++ b/include/osmocom/hlr/hlr_sms.h @@ -30,3 +30,4 @@ void smsc_route_del(struct hlr_smsc_route *rt); void forward_mo_sms(struct osmo_gsup_req *req); void forward_mt_sms(struct osmo_gsup_req *req); +void rx_ready_for_sm_req(struct osmo_gsup_req *req); diff --git a/src/hlr.c b/src/hlr.c index eae9e843..8ad3dfcf 100644 --- a/src/hlr.c +++ b/src/hlr.c @@ -563,6 +563,9 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg) case OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST: forward_mt_sms(req); break; + case OSMO_GSUP_MSGT_READY_FOR_SM_REQUEST: + rx_ready_for_sm_req(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 ac4d50d6..918d0945 100644 --- a/src/hlr_sms.c +++ b/src/hlr_sms.c @@ -219,3 +219,59 @@ void forward_mt_sms(struct osmo_gsup_req *req) strlen(subscr.vlr_number) + 1); osmo_gsup_forward_to_local_peer(req->cb_data, &dest_peer, req, NULL); } + +/*********************************************************************** + * READY-FOR-SM handling + * + * An MSC indicates that an MS is ready to receive messages. If one + * or more SMSCs have previously tried to send MT SMS to this MS and + * failed, we should pass this READY-FOR-SM message to them so they + * can resend their queued SMS right away. But which SMSC do we + * forward the message to? 3GPP specs call for a complicated system + * where the HLR remembers which SMSCs have tried and failed to deliver + * MT SMS, and those SMSCs then get notified - but that design is too + * much complexity for the current state of Osmocom. So we keep it + * simple: we iterate over all configured SMSCs and forward a copy + * of the READY-FOR-SM.req message to each. + * + * Routing of responses is another problem: the MSC that sent + * READY-FOR-SM.req expects only one response, and one can even argue + * that the operation is a "success" from the perspective of the MS + * irrespective of whether each given SMSC handled the notification + * successfully or not. Hence our approach: we always return success + * to the MS, and when we forward copies of READY-FOR-SM.req to SMSCs, + * we list the HLR as the message source - this way SMSC responses + * will terminate at this HLR and won't be forwarded to the MSC. + ***********************************************************************/ + +static void forward_req_copy_to_smsc(const struct osmo_gsup_req *req, + const struct hlr_smsc *smsc) +{ + const char *my_ipa_name = g_hlr->gsup_unit_name.serno; + struct osmo_gsup_message forward = req->gsup; + struct osmo_ipa_name smsc_ipa_name; + + /* set the source to this HLR */ + forward.source_name = (const uint8_t *) my_ipa_name; + forward.source_name_len = strlen(my_ipa_name) + 1; + + /* send it off */ + LOG_GSUP_REQ(req, LOGL_INFO, "Forwarding source-reset copy to %s\n", + smsc->name); + osmo_ipa_name_set(&smsc_ipa_name, (const uint8_t *) smsc->name, + strlen(smsc->name) + 1); + osmo_gsup_enc_send_to_ipa_name(g_hlr->gs, &smsc_ipa_name, &forward); +} + +void rx_ready_for_sm_req(struct osmo_gsup_req *req) +{ + struct hlr_smsc *smsc; + + /* fan request msg out to all SMSCs */ + llist_for_each_entry(smsc, &g_hlr->smsc_list, list) + forward_req_copy_to_smsc(req, smsc); + + /* send OK response to the MSC and the MS */ + osmo_gsup_req_respond_msgt(req, OSMO_GSUP_MSGT_READY_FOR_SM_RESULT, + true); +}