pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/40176?usp=email )
Change subject: context_map_sccp: Queue RUA->SCCP RANAP msgs while in SCCP WAIT_CC state ......................................................................
context_map_sccp: Queue RUA->SCCP RANAP msgs while in SCCP WAIT_CC state
HNB transmits the first RANAP PDU over a RUA Connect msg, which creates the session without need for any confirmation from HNBGW. As a result, HNB is allowed to transmit more RANAP PDUs after that. On the other side HNBGW, SCCP conn establishment towards CN consists of a CREQ msg and then wait until CC (or CREF) is received. HNBGW is unable to transmit any more data during that time, only the one appended to the CREQ SCCP msg. If the RAN transmits any more RANAP PDU over RUA while SCCP side is still waiting for CC, we were discarding the message. Instead, queue it and transmit it once finally the CC is received from the peer.
Related: SYS#7453 Change-Id: I307ded905901421f8228fab720b3989a2f94412b --- M include/osmocom/hnbgw/context_map.h M src/osmo-hnbgw/context_map_sccp.c 2 files changed, 32 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/76/40176/1
diff --git a/include/osmocom/hnbgw/context_map.h b/include/osmocom/hnbgw/context_map.h index 469323a..7dd9a1a 100644 --- a/include/osmocom/hnbgw/context_map.h +++ b/include/osmocom/hnbgw/context_map.h @@ -164,6 +164,12 @@ uint32_t scu_conn_id; /* FSM handling the SCCP state for scu_conn_id. */ struct osmo_fsm_inst *sccp_fi; + /* State context related to field sccp_fi above: */ + struct { + /* List of cached packets received from RUA and to be forwarded + once SCCP CReq is CC'ed and move to CONNECTED state. */ + struct llist_head wait_cc_tx_msg_list; + } sccp_fi_ctx;
/* False for CS, true for PS */ bool is_ps; diff --git a/src/osmo-hnbgw/context_map_sccp.c b/src/osmo-hnbgw/context_map_sccp.c index cf57c82..d317e0f 100644 --- a/src/osmo-hnbgw/context_map_sccp.c +++ b/src/osmo-hnbgw/context_map_sccp.c @@ -79,7 +79,7 @@
OSMO_ASSERT(map->sccp_fi == NULL); map->sccp_fi = fi; - + INIT_LLIST_HEAD(&map->sccp_fi_ctx.wait_cc_tx_msg_list); /* trigger the timeout */ map_sccp_fsm_state_chg(MAP_SCCP_ST_INIT); } @@ -193,6 +193,19 @@ return hnbgw_ranap_rx_data_dl(map, ranap_msg); }
+static void wait_cc_tx_msg_list_enqueue(struct hnbgw_context_map *map, struct msgb *ranap_msg) +{ + talloc_steal(map, ranap_msg); + msgb_enqueue(&map->sccp_fi_ctx.wait_cc_tx_msg_list, ranap_msg); +} +static struct msgb *wait_cc_tx_msg_list_dequeue(struct hnbgw_context_map *map) +{ + struct msgb *ranap_msg = msgb_dequeue(&map->sccp_fi_ctx.wait_cc_tx_msg_list); + if (ranap_msg) + talloc_steal(OTC_SELECT, ranap_msg); + return ranap_msg; +} + static void map_sccp_init_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct msgb *ranap_msg = NULL; @@ -245,8 +258,9 @@ return;
case MAP_SCCP_EV_TX_DATA_REQUEST: - /* ranap_msg = data; */ - LOGPFSML(fi, LOGL_ERROR, "Connection not yet confirmed, cannot forward RANAP to CN\n"); + ranap_msg = data; + LOGPFSML(fi, LOGL_INFO, "Caching RANAP msg from RUA while waiting for SCCP CC\n"); + wait_cc_tx_msg_list_enqueue(map, ranap_msg); return;
case MAP_SCCP_EV_RAN_LINK_LOST: @@ -277,9 +291,15 @@ static void map_sccp_connected_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct hnbgw_context_map *map = fi->priv; + struct msgb *ranap_msg; + + /* Now that SCCP conn is confirmed, forward pending msgs received from RUA side: */ + while ((ranap_msg = wait_cc_tx_msg_list_dequeue(map))) + tx_sccp_df1(fi, ranap_msg); + if (map->please_disconnect) { - /* SCCP has already been asked to disconnect, so disconnect now that the CC has been received. Send RLSD - * to SCCP (without RANAP data) */ + /* SCCP has already been asked to disconnect, so disconnect now that the + * CC has been received. Send RLSD to SCCP (without RANAP data) */ tx_sccp_rlsd(fi); map_sccp_fsm_state_chg(MAP_SCCP_ST_DISCONNECTED); } @@ -465,6 +485,7 @@ { struct hnbgw_context_map *map = fi->priv; map->sccp_fi = NULL; + msgb_queue_free(&map->sccp_fi_ctx.wait_cc_tx_msg_list); }
#define S(x) (1 << (x))