From d3ae3a536a0e78f96aff5c9f1683098c253a3a1b Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Thu, 18 Apr 2019 19:42:36 +0200 Subject: Revert "fix inter-BSC-HO-incoming for AoIP (1/2)" This reverts commit 94c9324fe07cd0ba1277278270c8979d949e49ec. --- include/osmocom/bsc/handover_fsm.h | 6 +- src/osmo-bsc/handover_fsm.c | 183 ++++++++++++++++--------------------- 2 files changed, 84 insertions(+), 105 deletions(-) diff --git a/include/osmocom/bsc/handover_fsm.h b/include/osmocom/bsc/handover_fsm.h index 7c2145e84..4db08901d 100644 --- a/include/osmocom/bsc/handover_fsm.h +++ b/include/osmocom/bsc/handover_fsm.h @@ -28,10 +28,10 @@ enum handover_fsm_state { HO_ST_NOT_STARTED, HO_ST_WAIT_LCHAN_ACTIVE, - HO_ST_WAIT_MGW_ENDPOINT_TO_MSC, HO_ST_WAIT_RR_HO_DETECT, HO_ST_WAIT_RR_HO_COMPLETE, HO_ST_WAIT_LCHAN_ESTABLISHED, + HO_ST_WAIT_MGW_ENDPOINT_TO_MSC, /* The inter-BSC Outgoing Handover FSM has completely separate states, but since it makes sense for it * to also live in conn->ho.fi, it should share the same event enum. From there it is merely @@ -46,11 +46,11 @@ enum handover_fsm_event { HO_EV_LCHAN_ACTIVE, HO_EV_LCHAN_ESTABLISHED, HO_EV_LCHAN_ERROR, - HO_EV_MSC_MGW_OK, - HO_EV_MSC_MGW_FAIL, HO_EV_RR_HO_DETECT, HO_EV_RR_HO_COMPLETE, HO_EV_RR_HO_FAIL, + HO_EV_MSC_MGW_OK, + HO_EV_MSC_MGW_FAIL, HO_EV_CONN_RELEASING, HO_OUT_EV_BSSMAP_HO_COMMAND, diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c index 3b5a66094..421c32efb 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -161,10 +161,10 @@ struct gsm_subscriber_connection *ho_fi_conn(struct osmo_fsm_inst *fi) static const struct state_timeout ho_fsm_timeouts[32] = { [HO_ST_WAIT_LCHAN_ACTIVE] = { .T = 23042 }, - [HO_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = 23042 }, [HO_ST_WAIT_RR_HO_DETECT] = { .T = 23042 }, [HO_ST_WAIT_RR_HO_COMPLETE] = { .T = 23042 }, [HO_ST_WAIT_LCHAN_ESTABLISHED] = { .T = 23042 }, + [HO_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = 23042 }, [HO_OUT_ST_WAIT_HO_COMMAND] = { .T = 7 }, [HO_OUT_ST_WAIT_CLEAR] = { .T = 8 }, }; @@ -876,24 +876,10 @@ void handover_end(struct gsm_subscriber_connection *conn, enum handover_result r static void ho_fsm_wait_lchan_active(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_subscriber_connection *conn = ho_fi_conn(fi); - struct handover *ho = &conn->ho; switch (event) { case HO_EV_LCHAN_ACTIVE: - /* - If the lchan is voiceless, no need to even think about the MGW. - * - If this is an intra-BSC Handover, we already have an RTP stream towards the MSC and aren't - * touching it. - * - If we're on SCCPlite, the MSC manages the MGW endpoint, all we do is the BTS side CI, so we can - * skip the part that would CRCX towards the MSC. - * So create an MSC side endpoint CI only if a voice lchan is established for an incoming inter-BSC - * handover on AoIP. Otherwise go on to send a Handover Command and wait for the Detect. - */ - if (ho->new_lchan->activate.info.requires_voice_stream - && (ho->scope & HO_INTER_BSC_IN) - && gscon_is_aoip(conn)) - ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC); - else - ho_fsm_state_chg(HO_ST_WAIT_RR_HO_DETECT); + ho_fsm_state_chg(HO_ST_WAIT_RR_HO_DETECT); return; case HO_EV_LCHAN_ERROR: @@ -906,76 +892,6 @@ static void ho_fsm_wait_lchan_active(struct osmo_fsm_inst *fi, uint32_t event, v } } -/* Only for voice, only for inter-BSC Handover into this BSC, and only for AoIP: - * - * Establish the MGW endpoint CI that points towards the MSC. This needs to happen after the lchan (lchan_rtp_fsm) has - * created an MGW endpoint with the first CRCX, so that an endpoint is available, and before sending the Handover - * Request Acknowledge, so that the RTP address and port established towards the MSC can be included in the Handover - * Request Acknowledge message. - * (For SCCPlite, the MSC manages the CN side endpoint CI itself, and we don't need to send any RTP address in the - * Handover Request Acknowledge.) - * - * Actually, it should be possible to kick this off even above in handover_start_inter_bsc_in(), to do the CRCX towards - * the MSC at the same time as establishing the lchan. The gscon_ensure_mgw_endpoint() doesn't care which one of - * lchan_rtp_fsm or handover_start_inter_bsc_in() calls it first. The benefit would be that we'd send out the Handover - * Command ever so slightly sooner -- which isn't critical really, because a) how long does a CRCX take, milliseconds? - * and b) the time critical part is *after* the Handover Command was kicked off to keep the transition between cells as - * short as possible. The drawback of doing this earlier is code complexity: receiving the HO_EV_MSC_MGW_OK / - * HO_EV_MSC_MGW_FAIL events would need to be juggled in between the HO_EV_LCHAN_ACTIVE / HO_EV_LCHAN_ERROR. So the - * decision for now is to leave it here. - */ -static void ho_fsm_wait_mgw_endpoint_to_msc_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) -{ - struct gsm_subscriber_connection *conn = ho_fi_conn(fi); - struct handover *ho = &conn->ho; - - if (!gscon_connect_mgw_to_msc(conn, - ho->new_lchan, - ho->inter_bsc_in.msc_assigned_rtp_addr, - ho->inter_bsc_in.msc_assigned_rtp_port, - fi, - HO_EV_MSC_MGW_OK, - HO_EV_MSC_MGW_FAIL, - NULL, - &ho->created_ci_for_msc)) { - ho_fail(HO_RESULT_ERROR, - "Unable to connect MGW endpoint to the MSC side"); - } -} - -static void ho_fsm_wait_mgw_endpoint_to_msc(struct osmo_fsm_inst *fi, uint32_t event, void *data) -{ - struct gsm_subscriber_connection *conn = ho_fi_conn(fi); - const struct mgcp_conn_peer *mgw_info; - - switch (event) { - - case HO_EV_MSC_MGW_OK: - /* Ensure the endpoint is really there, and log it. This state is only entered for AoIP connections, see - * ho_fsm_wait_lchan_active() above. */ - mgw_info = mgwep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc); - if (!mgw_info) { - ho_fail(HO_RESULT_ERROR, - "Unable to retrieve RTP port info allocated by MGW for" - " the MSC side."); - return; - } - LOG_HO(conn, LOGL_DEBUG, "MGW's MSC side CI: %s:%u\n", - mgw_info->addr, mgw_info->port); - ho_fsm_state_chg(HO_ST_WAIT_RR_HO_DETECT); - return; - - case HO_EV_MSC_MGW_FAIL: - ho_fail(HO_RESULT_ERROR, - "Unable to connect MGW endpoint to the MSC side"); - return; - - default: - OSMO_ASSERT(false); - } -} - - static void ho_fsm_wait_rr_ho_detect_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { int rc; @@ -1093,25 +1009,88 @@ static void ho_fsm_wait_rr_ho_complete(struct osmo_fsm_inst *fi, uint32_t event, } } +static void ho_fsm_post_lchan_established(struct osmo_fsm_inst *fi); + static void ho_fsm_wait_lchan_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_subscriber_connection *conn = ho_fi_conn(fi); if (conn->ho.fi && lchan_state_is(conn->ho.new_lchan, LCHAN_ST_ESTABLISHED)) { LOG_HO(conn, LOGL_DEBUG, "lchan already established earlier\n"); - ho_success(); + ho_fsm_post_lchan_established(fi); } } static void ho_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + switch (event) { + + case HO_EV_LCHAN_ESTABLISHED: + ho_fsm_post_lchan_established(fi); + break; + + default: + OSMO_ASSERT(false); + } +} + +static void ho_fsm_post_lchan_established(struct osmo_fsm_inst *fi) { struct gsm_subscriber_connection *conn = ho_fi_conn(fi); + struct handover *ho = &conn->ho; + if (ho->new_lchan->activate.info.requires_voice_stream + && (ho->scope & HO_INTER_BSC_IN)) + ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC); + else + ho_success(); +} + +static void ho_fsm_wait_mgw_endpoint_to_msc_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_subscriber_connection *conn = ho_fi_conn(fi); + struct handover *ho = &conn->ho; + + if (!gscon_connect_mgw_to_msc(conn, + ho->new_lchan, + ho->inter_bsc_in.msc_assigned_rtp_addr, + ho->inter_bsc_in.msc_assigned_rtp_port, + fi, + HO_EV_MSC_MGW_OK, + HO_EV_MSC_MGW_FAIL, + NULL, + &ho->created_ci_for_msc)) { + ho_fail(HO_RESULT_ERROR, + "Unable to connect MGW endpoint to the MSC side"); + } +} + +static void ho_fsm_wait_mgw_endpoint_to_msc(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = ho_fi_conn(fi); switch (event) { - case HO_EV_LCHAN_ESTABLISHED: + case HO_EV_MSC_MGW_OK: + /* For AoIP, we created the MGW endpoint. Ensure it is really there, and log it. */ + if (gscon_is_aoip(conn)) { + const struct mgcp_conn_peer *mgw_info; + mgw_info = mgwep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc); + if (!mgw_info) { + ho_fail(HO_RESULT_ERROR, + "Unable to retrieve RTP port info allocated by MGW for" + " the MSC side."); + return; + } + LOG_HO(conn, LOGL_DEBUG, "MGW's MSC side CI: %s:%u\n", + mgw_info->addr, mgw_info->port); + } ho_success(); - break; + return; + + case HO_EV_MSC_MGW_FAIL: + ho_fail(HO_RESULT_ERROR, + "Unable to connect MGW endpoint to the MSC side"); + return; default: OSMO_ASSERT(false); @@ -1206,19 +1185,6 @@ static const struct osmo_fsm_state ho_fsm_states[] = { , .out_state_mask = 0 | S(HO_ST_WAIT_LCHAN_ACTIVE) - | S(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC) - | S(HO_ST_WAIT_RR_HO_DETECT) - , - }, - [HO_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { - .name = "WAIT_MGW_ENDPOINT_TO_MSC", - .onenter = ho_fsm_wait_mgw_endpoint_to_msc_onenter, - .action = ho_fsm_wait_mgw_endpoint_to_msc, - .in_event_mask = 0 - | S(HO_EV_MSC_MGW_OK) - | S(HO_EV_MSC_MGW_FAIL) - , - .out_state_mask = 0 | S(HO_ST_WAIT_RR_HO_DETECT) , }, @@ -1256,7 +1222,20 @@ static const struct osmo_fsm_state ho_fsm_states[] = { .in_event_mask = 0 | S(HO_EV_LCHAN_ESTABLISHED) , + .out_state_mask = 0 + | S(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC) + , + }, + [HO_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { + .name = "WAIT_MGW_ENDPOINT_TO_MSC", + .onenter = ho_fsm_wait_mgw_endpoint_to_msc_onenter, + .action = ho_fsm_wait_mgw_endpoint_to_msc, + .in_event_mask = 0 + | S(HO_EV_MSC_MGW_OK) + | S(HO_EV_MSC_MGW_FAIL) + , }, + [HO_OUT_ST_WAIT_HO_COMMAND] = { .name = "inter-BSC-OUT:WAIT_HO_COMMAND", .action = ho_out_fsm_wait_ho_command, -- cgit v1.2.3