diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2019-03-04 22:32:42 +0100 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2019-03-08 05:10:48 +0100 |
commit | e22027ae2a8b610a3a492246b88c744484b31b99 (patch) | |
tree | 7b976cab457699fb42b8ec03fa725eee8cbf3893 | |
parent | 39d7b5c646652d6ad075debf02f8a91a68a158be (diff) |
osmo-hnbgw: reply with RESET ACK when receiving a RESET
Rationale: current osmo-msc refactoring introduces RESET handling on IuCS.
In particular, it makes osmo-hnbgw be able to operate with an (upcoming)
osmo-msc that has strict RESET handling: it will send a RESET and require a
RESET ACK if it sees a new IuCS peer sending messages without prior RESET.
Even though a workaround to ignore missing RESET messages on IuCS will also be
in place in the new osmo-msc, this is a first small step towards more sane
RESET handling in osmo-hnbgw.
Related: OS#3820
Change-Id: I02bc74ef9fef61f4490b4d4dc3ce6c0a6d965909
-rw-r--r-- | src/hnbgw_cn.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/src/hnbgw_cn.c b/src/hnbgw_cn.c index 875a0d0..0623561 100644 --- a/src/hnbgw_cn.c +++ b/src/hnbgw_cn.c @@ -63,6 +63,23 @@ static int transmit_rst(struct hnb_gw *gw, RANAP_CN_DomainIndicator_t domain, msg); } +static int transmit_reset_ack(struct hnb_gw *gw, RANAP_CN_DomainIndicator_t domain, + const struct osmo_sccp_addr *remote_addr) +{ + struct msgb *msg; + + LOGP(DRANAP, LOGL_NOTICE, "Tx RESET ACK to %s %s\n", + domain == CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(gw->sccp.cnlink->sccp, remote_addr)); + + msg = ranap_new_msg_reset_ack(domain, NULL); + + return osmo_sccp_tx_unitdata_msg(gw->sccp.cnlink->sccp_user, + &gw->sccp.local_addr, + remote_addr, + msg); +} + /* Timer callback once T_RafC expires */ static void cnlink_trafc_cb(void *data) { @@ -99,15 +116,28 @@ void hnbgw_cnlink_change_state(struct hnbgw_cnlink *cnlink, enum hnbgw_cnlink_st ***********************************************************************/ static int cn_ranap_rx_reset_cmd(struct hnbgw_cnlink *cnlink, + const struct osmo_scu_unitdata_param *unitdata, RANAP_InitiatingMessage_t *imsg) { + CN_DomainIndicator_t domain; RANAP_ResetIEs_t ies; int rc; rc = ranap_decode_reseties(&ies, &imsg->value); - /* FIXME: reset resources and return reset ack */ - + domain = ies.cN_DomainIndicator; ranap_free_reseties(&ies); + + LOGP(DRANAP, LOGL_NOTICE, "Rx RESET from %s %s, returning ACK\n", + domain == CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + + /* FIXME: actually reset connections, if any */ + + if (transmit_reset_ack(cnlink->gw, domain, &unitdata->calling_addr)) + LOGP(DRANAP, LOGL_ERROR, "Error: cannot send RESET ACK to %s %s\n", + domain == CN_DomainIndicator_cs_domain ? "IuCS" : "IuPS", + osmo_sccp_inst_addr_name(cnlink->sccp, &unitdata->calling_addr)); + return rc; } @@ -149,12 +179,13 @@ static int cn_ranap_rx_paging_cmd(struct hnbgw_cnlink *cnlink, } static int cn_ranap_rx_initiating_msg(struct hnbgw_cnlink *cnlink, + const struct osmo_scu_unitdata_param *unitdata, RANAP_InitiatingMessage_t *imsg, const uint8_t *data, unsigned int len) { switch (imsg->procedureCode) { case RANAP_ProcedureCode_id_Reset: - return cn_ranap_rx_reset_cmd(cnlink, imsg); + return cn_ranap_rx_reset_cmd(cnlink, unitdata, imsg); case RANAP_ProcedureCode_id_Paging: return cn_ranap_rx_paging_cmd(cnlink, imsg, data, len); case RANAP_ProcedureCode_id_OverloadControl: /* Overload ind */ @@ -198,14 +229,15 @@ static int cn_ranap_rx_successful_msg(struct hnbgw_cnlink *cnlink, } -static int _cn_ranap_rx(struct hnbgw_cnlink *cnlink, RANAP_RANAP_PDU_t *pdu, - const uint8_t *data, unsigned int len) +static int _cn_ranap_rx(struct hnbgw_cnlink *cnlink, + const struct osmo_scu_unitdata_param *unitdata, + RANAP_RANAP_PDU_t *pdu, const uint8_t *data, unsigned int len) { int rc; switch (pdu->present) { case RANAP_RANAP_PDU_PR_initiatingMessage: - rc = cn_ranap_rx_initiating_msg(cnlink, &pdu->choice.initiatingMessage, + rc = cn_ranap_rx_initiating_msg(cnlink, unitdata, &pdu->choice.initiatingMessage, data, len); break; case RANAP_RANAP_PDU_PR_successfulOutcome: @@ -227,8 +259,8 @@ static int _cn_ranap_rx(struct hnbgw_cnlink *cnlink, RANAP_RANAP_PDU_t *pdu, return rc; } -static int handle_cn_ranap(struct hnbgw_cnlink *cnlink, const uint8_t *data, - unsigned int len) +static int handle_cn_ranap(struct hnbgw_cnlink *cnlink, const struct osmo_scu_unitdata_param *unitdata, + const uint8_t *data, unsigned int len) { RANAP_RANAP_PDU_t _pdu, *pdu = &_pdu; asn_dec_rval_t dec_ret; @@ -242,7 +274,7 @@ static int handle_cn_ranap(struct hnbgw_cnlink *cnlink, const uint8_t *data, return -1; } - rc = _cn_ranap_rx(cnlink, pdu, data, len); + rc = _cn_ranap_rx(cnlink, unitdata, pdu, data, len); return rc; } @@ -286,7 +318,7 @@ static int handle_cn_unitdata(struct hnbgw_cnlink *cnlink, if (classify_cn_remote_addr(cnlink->gw, ¶m->calling_addr, NULL) < 0) return -1; - return handle_cn_ranap(cnlink, msgb_l2(oph->msg), msgb_l2len(oph->msg)); + return handle_cn_ranap(cnlink, param, msgb_l2(oph->msg), msgb_l2len(oph->msg)); } static int handle_cn_conn_conf(struct hnbgw_cnlink *cnlink, |