Change in osmo-bsc[master]: assignment_fsm: allow assignment to a specific lchan

neels gerrit-no-reply at lists.osmocom.org
Tue Jun 1 17:29:42 UTC 2021


neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24362 )

Change subject: assignment_fsm: allow assignment to a specific lchan
......................................................................

assignment_fsm: allow assignment to a specific lchan

So far the assignment FSM always tried to satisfy the channel mode and
rate by either re-using the current lchan or finding a new, unused
lchan. For VAMOS however, we want to pick one specific lchan.

Add target_lchan to struct assignment_request and skip all mode matching
and lchan selection when a specific target_lchan is set.

Related: SYS#5315 OS#4940
Change-Id: I71e0d4ff4746706e0be5266e4574d70ca432e3d7
---
M include/osmocom/bsc/assignment_fsm.h
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/assignment_fsm.c
3 files changed, 97 insertions(+), 19 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  fixeria: Looks good to me, but someone else must approve



diff --git a/include/osmocom/bsc/assignment_fsm.h b/include/osmocom/bsc/assignment_fsm.h
index b4af335..d4ed846 100644
--- a/include/osmocom/bsc/assignment_fsm.h
+++ b/include/osmocom/bsc/assignment_fsm.h
@@ -41,6 +41,10 @@
 
 void assignment_fsm_init();
 
+int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan);
+int reassignment_request_to_chan_type(enum assign_for assign_for, struct gsm_lchan *lchan,
+				      enum gsm_chan_t new_lchan_type);
+
 void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
 			  struct assignment_request *req);
 void assignment_reset(struct gsm_subscriber_connection *conn);
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 3ed624f..58ec124 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -154,6 +154,14 @@
 	/* Rate/codec setting in preference order (need at least 1 !) */
 	int n_ch_mode_rate;
 	struct channel_mode_and_rate ch_mode_rate_list[3];
+
+	/* An assignment request usually requests to assign any available lchan, to match above requirements. This may
+	 * also choose to just keep the current lchan and merely modify it as appropriate. In these cases, keep
+	 * target_lchan == NULL.
+	 * In some situations, an assignment to a specific target lchan is requested (congestion resolution, VAMOS
+	 * multiplexing, user request via VTY). In these situations, select a target lchan beforehand and point
+	 * target_lchan to it. */
+	struct gsm_lchan *target_lchan;
 };
 
 /* State of an ongoing Assignment, while the assignment_fsm is still busy. This serves as state separation to keep the
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index 83d2917..b96dbb3 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -438,6 +438,48 @@
 	return false;
 }
 
+static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan,
+				 enum gsm_chan_t new_lchan_type)
+{
+	struct gsm_subscriber_connection *conn = lchan->conn;
+	struct assignment_request req = {
+		.assign_for = assign_for,
+		.aoip = gscon_is_aoip(conn),
+		.msc_assigned_cic = conn->user_plane.msc_assigned_cic,
+		.msc_rtp_port = conn->user_plane.msc_assigned_rtp_port,
+		.n_ch_mode_rate = 1,
+		.ch_mode_rate_list = { lchan->current_ch_mode_rate },
+		.target_lchan = to_lchan,
+	};
+
+	if (to_lchan)
+		new_lchan_type = to_lchan->type;
+	req.ch_mode_rate_list[0].chan_rate = chan_t_to_chan_rate(new_lchan_type);
+	/* lchan activation will automatically convert chan_mode to a VAMOS equivalent if required.
+	 * So rather always pass the plain non-VAMOS mode. */
+	req.ch_mode_rate_list[0].chan_mode = gsm48_chan_mode_to_non_vamos(lchan->current_ch_mode_rate.chan_mode);
+
+	OSMO_STRLCPY_ARRAY(req.msc_rtp_addr, conn->user_plane.msc_assigned_rtp_addr);
+
+	if (conn->user_plane.mgw_endpoint_ci_msc) {
+		req.use_osmux = osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(conn->user_plane.mgw_endpoint_ci_msc,
+									    &req.osmux_cid);
+	}
+
+	return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req);
+}
+
+int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan)
+{
+	return _reassignment_request(assign_for, lchan, to_lchan, 0);
+}
+
+int reassignment_request_to_chan_type(enum assign_for assign_for, struct gsm_lchan *lchan,
+				      enum gsm_chan_t new_lchan_type)
+{
+	return _reassignment_request(assign_for, lchan, NULL, new_lchan_type);
+}
+
 void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
 			  struct assignment_request *req)
 {
@@ -470,13 +512,8 @@
 	if (check_requires_voice_stream(conn) < 0)
 		return;
 
-	/* There may be an already existing lchan, if yes, try to work with
-	 * the existing lchan.
-	 * If an RTP FSM is already set up for the lchan, Mode Modify is not yet supported -- see handling of
-	 * LCHAN_EV_REQUEST_MODE_MODIFY in lchan_fsm.c. To not break the lchan, do not even attempt to re-use an lchan
-	 * that already has an RTP stream set up, rather establish a new lchan (that transition is well implemented). */
-	if (reuse_existing_lchan(conn) && !conn->lchan->fi_rtp) {
-		/* The new lchan is the old lchan, keep new_lchan == NULL. */
+	if (!req->target_lchan && reuse_existing_lchan(conn)) {
+		/* The already existing lchan is suitable for this mode */
 		conn->assignment.new_lchan = NULL;
 
 		/* If the requested mode and the current TCH mode matches up, just send the
@@ -512,19 +549,48 @@
 		return;
 	}
 
-	/* Try to allocate a new lchan in order of preference */
-	for (i = 0; i < req->n_ch_mode_rate; i++) {
-		conn->assignment.new_lchan = lchan_select_by_chan_mode(bts,
-		    req->ch_mode_rate_list[i].chan_mode, req->ch_mode_rate_list[i].chan_rate);
-		if (!conn->assignment.new_lchan)
-			continue;
-		LOG_ASSIGNMENT(conn, LOGL_DEBUG, "selected new lchan %s for mode[%d] = %s channel_rate=%d\n",
-			       gsm_lchan_name(conn->assignment.new_lchan),
-			       i, gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode),
-			       req->ch_mode_rate_list[i].chan_rate);
+	if (req->target_lchan) {
+		bool matching_mode;
 
-		conn->assignment.selected_ch_mode_rate = req->ch_mode_rate_list[i];
-		break;
+		/* The caller already picked a target lchan to assign to. No need to try re-using the current lchan or
+		 * picking a new one. */
+		if (!lchan_state_is(req->target_lchan, LCHAN_ST_UNUSED)) {
+			assignment_fail(GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
+					"Assignment to lchan %s requested, but lchan is already in use (state=%s)\n",
+					gsm_lchan_name(req->target_lchan),
+					osmo_fsm_inst_state_name(req->target_lchan->fi));
+			return;
+		}
+
+		conn->assignment.new_lchan = req->target_lchan;
+		matching_mode = false;
+		for (i = 0; i < req->n_ch_mode_rate; i++) {
+			if (!lchan_type_compat_with_mode(conn->assignment.new_lchan->type, &req->ch_mode_rate_list[i]))
+				continue;
+			conn->assignment.selected_ch_mode_rate = req->ch_mode_rate_list[i];
+			matching_mode = true;
+		}
+		if (!matching_mode) {
+			assignment_fail(GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
+					"Assignment to lchan %s requested, but lchan is not compatible\n",
+					gsm_lchan_name(req->target_lchan));
+			return;
+		}
+	} else {
+		/* Try to allocate a new lchan in order of preference */
+		for (i = 0; i < req->n_ch_mode_rate; i++) {
+			conn->assignment.new_lchan = lchan_select_by_chan_mode(bts,
+			    req->ch_mode_rate_list[i].chan_mode, req->ch_mode_rate_list[i].chan_rate);
+			if (!conn->assignment.new_lchan)
+				continue;
+			LOG_ASSIGNMENT(conn, LOGL_DEBUG, "selected new lchan %s for mode[%d] = %s channel_rate=%d\n",
+				       gsm_lchan_name(conn->assignment.new_lchan),
+				       i, gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode),
+				       req->ch_mode_rate_list[i].chan_rate);
+
+			conn->assignment.selected_ch_mode_rate = req->ch_mode_rate_list[i];
+			break;
+		}
 	}
 
 	/* Check whether the lchan allocation was successful or not and tear

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/24362
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I71e0d4ff4746706e0be5266e4574d70ca432e3d7
Gerrit-Change-Number: 24362
Gerrit-PatchSet: 5
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210601/9ac3f128/attachment.htm>


More information about the gerrit-log mailing list