From f087c1ebd44f10d41a8f2b55d648ae34f6d92cd5 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 2 Sep 2020 18:40:43 +0200 Subject: lchan_rtp_fsm: Deferr IPACC MDCX after BTS side MGCP MDCX This is needed to be able to force MGW to provide an IPv4 address during MDCX, since IPACC protocol on the BTS side only supports IPv4, but one may need IPv6 side at the same time on the core side. By moving the IPACC MDCX request to a later step, the BSC gains knowledge of the local address on each side (BTS, MGW), and if they don't match (ie. BTS uses IPv4 and MGW uses IPv6), it can then get MGW to offer an IPv4 address during MGCP MDCX containing the BTS IPv4 address. At that point, the MGW can see the mismatch and provide an IPv4 address in the MGCP MDCX ACK, which can then finally be communicated to the BTS during IPACC MDCX phase. Previous order: BSC -> MGW: CRCX BSC <- MGW: CRCX ACK (get MGW local IP addr) BSC -> BTS: IPACC CRCX BSC <- BTS: IPACC CRCX ACK (get BTS local IP addr) BSC -> BTS: IPACC MDCX (set MGW IP addr) BSC <- BTS: IPACC MDCX ACK BSC -> MGW: MDCX (set BTS IP addr) BSC <- MGW: MDCX ACK New order: BSC -> MGW: CRCX BSC <- MGW: CRCX ACK (get MGCP local IPv6 addr) BSC -> BTS: IPACC CRCX BSC <- BTS: IPACC CRCX ACK (get BTS local IPv4 addr) BSC -> MGW: MDCX (set BTS IPv4 addr) BSC <- MGW: MDCX ACK (here MGW changes its local addr to IPv4) BSC -> BTS: IPACC MDCX (set MGW IPv4 addr) BSC <- BTS: IPACC MDCX ACK Change-Id: I4de5ea5c94c1482c9cb0b6386997a942edc60e32 --- doc/lchan-rtp-fsm.dot | 7 +++--- doc/lchan.msc | 10 ++++---- src/osmo-bsc/lchan_rtp_fsm.c | 54 +++++++++++++++++++++----------------------- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/doc/lchan-rtp-fsm.dot b/doc/lchan-rtp-fsm.dot index d5df643b5..4c2dd31bf 100644 --- a/doc/lchan-rtp-fsm.dot +++ b/doc/lchan-rtp-fsm.dot @@ -1,7 +1,7 @@ digraph G { rankdir=TB labelloc=t; label="lchan RTP FSM" - + lchan [label="lchan\nFSM",shape=box3d] lchan2 [label="lchan\nFSM",shape=box3d] ho_as [label="Handover or Assignment FSM",shape=box3d] @@ -23,14 +23,15 @@ labelloc=t; label="lchan RTP FSM" lchan -> WAIT_LCHAN_READY [label="LCHAN_RTP_EV_LCHAN_READY",style=dashed] WAIT_LCHAN_READY -> WAIT_IPACC_CRCX_ACK [label="IPACC BTS"] WAIT_LCHAN_READY -> WAIT_READY_TO_SWITCH_RTP - WAIT_IPACC_CRCX_ACK -> WAIT_IPACC_MDCX_ACK - WAIT_IPACC_MDCX_ACK -> WAIT_READY_TO_SWITCH_RTP + WAIT_IPACC_CRCX_ACK -> WAIT_READY_TO_SWITCH_RTP invisible -> ho [label="HO DETECT",style=dashed] ho -> WAIT_READY_TO_SWITCH_RTP [label="LCHAN_RTP_EV_READY_TO_SWITCH",style=dashed] WAIT_READY_TO_SWITCH_RTP -> WAIT_MGW_ENDPOINT_CONFIGURED WAIT_MGW_ENDPOINT_CONFIGURED -> mgwep [label="MDCX",style=dashed] mgwep -> WAIT_MGW_ENDPOINT_CONFIGURED [label="LCHAN_RTP_EV_\nMGW_ENDPOINT_\nCONFIGURED",style=dashed] + WAIT_MGW_ENDPOINT_CONFIGURED -> WAIT_IPACC_MDCX_ACK [label="IPACC BTS"] WAIT_MGW_ENDPOINT_CONFIGURED -> RTP_READY + WAIT_IPACC_MDCX_ACK -> RTP_READY RTP_READY -> lchan2 [label="LCHAN_EV_\nRTP_READY",style=dashed] RTP_READY -> RTP_ESTABLISHED lchan2 -> RTP_ESTABLISHED [label="LCHAN_RTP_EV_\nRELEASE",style=dashed] diff --git a/doc/lchan.msc b/doc/lchan.msc index b0e32d684..9962c77a7 100644 --- a/doc/lchan.msc +++ b/doc/lchan.msc @@ -68,10 +68,6 @@ msc { ms <= rtp [label="IPACC CRCX"]; ...; ms => rtp [label="IPACC CRCX ACK (BTS RTP port info)"]; - rtp abox rtp [label="LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK"]; - ms <= rtp [label="IPACC MDCX (MGW RTP port info)"]; - ...; - ms => rtp [label="IPACC MDCX ACK"]; --- [label="END ip.access style BTS"]; |||; rtp box rtp [label="lchan_rtp_fsm_switch_rtp()"]; @@ -91,6 +87,12 @@ msc { ...; mgwep rbox mgwep [label="MGCP: MDCX OK"]; rtp <- mgwep [label="LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED"]; + --- [label="IF ip.access style BTS"]; + rtp abox rtp [label="LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK"]; + ms <= rtp [label="IPACC MDCX (MGW RTP port info)"]; + ...; + ms => rtp [label="IPACC MDCX ACK"]; + --- [label="END ip.access style BTS"]; rtp abox rtp [label="LCHAN_RTP_ST_READY"]; lchan <- rtp [label="LCHAN_EV_RTP_READY"]; rtp note rtp [label="RTP FSM stays ready for Rollback until final establish event"]; diff --git a/src/osmo-bsc/lchan_rtp_fsm.c b/src/osmo-bsc/lchan_rtp_fsm.c index 1dd31b134..5de296707 100644 --- a/src/osmo-bsc/lchan_rtp_fsm.c +++ b/src/osmo-bsc/lchan_rtp_fsm.c @@ -301,10 +301,7 @@ static void lchan_rtp_fsm_wait_ipacc_crcx_ack(struct osmo_fsm_inst *fi, uint32_t switch (event) { case LCHAN_RTP_EV_IPACC_CRCX_ACK: - /* the CRCX ACK parsing has already noted the RTP port information at - * lchan->abis_ip.bound_*, see ipac_parse_rtp(). We'll use that in - * lchan_rtp_fsm_wait_mgw_endpoint_configured_onenter(). */ - lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK); + lchan_rtp_fsm_switch_rtp(fi); return; case LCHAN_RTP_EV_IPACC_CRCX_NACK: @@ -366,21 +363,16 @@ static void lchan_rtp_fsm_wait_ipacc_mdcx_ack_onenter(struct osmo_fsm_inst *fi, static void lchan_rtp_fsm_wait_ipacc_mdcx_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi); switch (event) { case LCHAN_RTP_EV_IPACC_MDCX_ACK: - lchan_rtp_fsm_switch_rtp(fi); + lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_READY); return; case LCHAN_RTP_EV_IPACC_MDCX_NACK: lchan_rtp_fail("Received NACK on IPACC MDCX"); return; - case LCHAN_RTP_EV_READY_TO_SWITCH_RTP: - lchan->activate.info.wait_before_switching_rtp = false; - return; - case LCHAN_RTP_EV_RELEASE: case LCHAN_RTP_EV_ROLLBACK: osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, 0); @@ -480,10 +472,15 @@ static void lchan_rtp_fsm_wait_mgw_endpoint_configured_onenter(struct osmo_fsm_i static void lchan_rtp_fsm_wait_mgw_endpoint_configured(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - switch (event) { + struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi); + switch (event) { case LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED: - lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_READY); + if (is_ipaccess_bts(lchan->ts->trx->bts)) + lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK); + else { + lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_READY); + } return; case LCHAN_RTP_EV_MGW_ENDPOINT_ERROR: @@ -651,24 +648,9 @@ static const struct osmo_fsm_state lchan_rtp_fsm_states[] = { | S(LCHAN_RTP_EV_RELEASE) | S(LCHAN_RTP_EV_ROLLBACK) , - .out_state_mask = 0 - | S(LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK) - , - }, - [LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK] = { - .name = "WAIT_IPACC_MDCX_ACK", - .onenter = lchan_rtp_fsm_wait_ipacc_mdcx_ack_onenter, - .action = lchan_rtp_fsm_wait_ipacc_mdcx_ack, - .in_event_mask = 0 - | S(LCHAN_RTP_EV_READY_TO_SWITCH_RTP) - | S(LCHAN_RTP_EV_IPACC_MDCX_ACK) - | S(LCHAN_RTP_EV_IPACC_MDCX_NACK) - | S(LCHAN_RTP_EV_RELEASE) - | S(LCHAN_RTP_EV_ROLLBACK) - , .out_state_mask = 0 | S(LCHAN_RTP_ST_WAIT_READY_TO_SWITCH_RTP) - | S(LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_CONFIGURED) + | S(LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_CONFIGURED) /*old: LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK*/ , }, [LCHAN_RTP_ST_WAIT_READY_TO_SWITCH_RTP] = { @@ -693,6 +675,22 @@ static const struct osmo_fsm_state lchan_rtp_fsm_states[] = { | S(LCHAN_RTP_EV_RELEASE) | S(LCHAN_RTP_EV_ROLLBACK) , + .out_state_mask = 0 + | S(LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK) + | S(LCHAN_RTP_ST_READY) + | S(LCHAN_RTP_ST_ROLLBACK) + , + }, + [LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK] = { + .name = "WAIT_IPACC_MDCX_ACK", + .onenter = lchan_rtp_fsm_wait_ipacc_mdcx_ack_onenter, + .action = lchan_rtp_fsm_wait_ipacc_mdcx_ack, + .in_event_mask = 0 + | S(LCHAN_RTP_EV_IPACC_MDCX_ACK) + | S(LCHAN_RTP_EV_IPACC_MDCX_NACK) + | S(LCHAN_RTP_EV_RELEASE) + | S(LCHAN_RTP_EV_ROLLBACK) + , .out_state_mask = 0 | S(LCHAN_RTP_ST_READY) | S(LCHAN_RTP_ST_ROLLBACK) -- cgit v1.2.3