Change in osmo-bsc[master]: fix inter-BSC-HO-incoming for AoIP (1/2)

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Apr 26 19:25:01 UTC 2019


Neels Hofmeyr has uploaded this change for review. ( https://gerrit.osmocom.org/13797


Change subject: fix inter-BSC-HO-incoming for AoIP (1/2)
......................................................................

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

Move the HO_ST_WAIT_MGW_ENDPOINT_TO_MSC state up to right after the lchan is
done establishing. For AoIP, the local RTP address towards the MSC already
needs to be known before the Handover Request Acknowledge is sent, so the AoIP
Transport Layer Address IE can be included. This patch only modifies the
handover FSM, a subsequent patch adds the IE.

Change-Id: I00c18b78573386145af71c4b39f7f22aec24579b
---
M include/osmocom/bsc/handover_fsm.h
M src/osmo-bsc/handover_fsm.c
2 files changed, 105 insertions(+), 86 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/97/13797/1

diff --git a/include/osmocom/bsc/handover_fsm.h b/include/osmocom/bsc/handover_fsm.h
index 4db0890..7c2145e 100644
--- a/include/osmocom/bsc/handover_fsm.h
+++ b/include/osmocom/bsc/handover_fsm.h
@@ -28,10 +28,10 @@
 	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 @@
 	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 0d1449f..6a07fbe 100644
--- a/src/osmo-bsc/handover_fsm.c
+++ b/src/osmo-bsc/handover_fsm.c
@@ -162,10 +162,10 @@
 
 static const struct osmo_tdef_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 },
 };
@@ -877,10 +877,24 @@
 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:
-		ho_fsm_state_chg(HO_ST_WAIT_RR_HO_DETECT);
+		/* - 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);
 		return;
 
 	case HO_EV_LCHAN_ERROR:
@@ -893,6 +907,75 @@
 	}
 }
 
+/* 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 = osmo_mgcpc_ep_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;
@@ -1010,24 +1093,23 @@
 	}
 }
 
-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_fsm_post_lchan_established(fi);
+		ho_success();
 	}
 }
 
 static void ho_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
-	switch (event) {
+	struct gsm_subscriber_connection *conn = ho_fi_conn(fi);
 
+	switch (event) {
 	case HO_EV_LCHAN_ESTABLISHED:
-		ho_fsm_post_lchan_established(fi);
+		ho_success();
 		break;
 
 	default:
@@ -1035,69 +1117,6 @@
 	}
 }
 
-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 = osmo_mgcpc_ep_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,
@@ -1186,6 +1205,19 @@
 			,
 		.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)
 			,
 	},
@@ -1223,20 +1255,7 @@
 		.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,

-- 
To view, visit https://gerrit.osmocom.org/13797
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I00c18b78573386145af71c4b39f7f22aec24579b
Gerrit-Change-Number: 13797
Gerrit-PatchSet: 1
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190426/9afbf6d9/attachment.htm>


More information about the gerrit-log mailing list