Revert "fix inter-BSC-HO-incoming for AoIP (1/2)"

This reverts commit 94c9324fe0.
Multiple ttcn3 handover tests were broken due to this commit. Let's
merge this once all the other commits pertaining to that fix can be
merged as well.

Fixes: OS#3942
Change-Id: I01d93778fb19c601c21f99ec4d2a3ab8a4a48f67
This commit is contained in:
Daniel Willmann 2019-04-18 19:42:36 +02:00
parent 1d5eda4b4c
commit 62f3b302b0
2 changed files with 85 additions and 106 deletions

View File

@ -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,

View File

@ -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,24 +1009,24 @@ 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)
{
struct gsm_subscriber_connection *conn = ho_fi_conn(fi);
switch (event) {
case HO_EV_LCHAN_ESTABLISHED:
ho_success();
ho_fsm_post_lchan_established(fi);
break;
default:
@ -1118,6 +1034,69 @@ static void ho_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint32_t eve
}
}
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_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();
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);
}
}
/* Inter-BSC OUT */
static void handover_start_inter_bsc_out(struct gsm_subscriber_connection *conn,
@ -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,