aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2023-06-26 18:38:01 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2023-07-21 13:33:51 +0200
commit2d93d61fe3b9a36d76e446a49c11de522c5243cc (patch)
tree1558c81659c60963bef2115658a5410871ae7e46
parentb0712a9f228b2f6823be174ed2c88cf9e7c708ee (diff)
ASCI: Add assignment to a VGCS/VBS channel
The assignment is triggered by the MSC by sending an ASSIGNMENT REQUEST with a group call reference. The reference is used to find the VGCS/VBS channel that belogs to the referenced call. The existing VGCS/VBS channel is reactivated. This will put the channel into a state where the MS can establish the link on it, to complete the assignment. The old connection is released by the MSC and assignment completion is handled by the VGCS FSM. Change-Id: Idaa864cd5ce4df6c3193494ce12d91523c104d89 Related: OS#4852
-rw-r--r--include/osmocom/bsc/gsm_data.h1
-rw-r--r--src/osmo-bsc/abis_rsl.c4
-rw-r--r--src/osmo-bsc/assignment_fsm.c15
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c35
4 files changed, 51 insertions, 4 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 70be943c6..7d36baac4 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -142,6 +142,7 @@ struct assignment_request {
enum assign_for assign_for;
bool aoip;
+ bool vgcs;
uint16_t msc_assigned_cic;
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 24aee8add..125f0bab5 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1652,6 +1652,10 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
switch (rslh->c.msg_type) {
case RSL_MT_CHAN_ACTIV_ACK:
+ /* Ignore acknowlegement of channel reactivation, if a VGCS/VBS channel was reactivated to assign
+ * the calling subscriber to it. */
+ if (msg->lchan->conn && msg->lchan->conn->assignment.req.vgcs)
+ break;
if (msg_for_osmocom_dyn_ts(msg))
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_ACT_ACK, NULL);
else {
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index 037c256eb..3ae1367a4 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -261,9 +261,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
static void assignment_success(struct gsm_subscriber_connection *conn)
{
struct gsm_bts *bts;
- bool lchan_changed = (conn->assignment.new_lchan != NULL);
+ bool lchan_changed = (conn->assignment.new_lchan != NULL && !conn->assignment.req.vgcs);
- /* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on. */
+ /* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on.
+ * In case of VGCS/VBS channel, the assignment is handled by its state machine. This subscriber connection will
+ * be released by MSC. */
if (lchan_changed) {
gscon_change_primary_lchan(conn, conn->assignment.new_lchan);
@@ -569,7 +571,10 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
return;
}
- if (req->target_lchan) {
+ if (req->vgcs) {
+ /* When assigning to a VGCS/VBS, the target lchan is already defined. */
+ conn->assignment.new_lchan = req->target_lchan;
+ } else if (req->target_lchan) {
bool matching_mode;
/* The caller already picked a target lchan to assign to. No need to try re-using the current lchan or
@@ -643,7 +648,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
req->aoip ? "yes" : "no", req->msc_rtp_addr, req->msc_rtp_port,
req->use_osmux ? "yes" : "no");
- assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
+ /* Wait for lchan to become active before send assignment. In case of VGCS/VBS directly send assignment,
+ * because the channel is already active. */
+ assignment_fsm_state_chg(req->vgcs ? ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE : ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
}
static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index de059e312..2a9805444 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -1089,6 +1089,7 @@ static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn,
struct msgb *resp;
struct tlv_parsed tp;
struct gsm0808_channel_type ct;
+ struct gsm0808_group_callref gc;
uint8_t cause;
int rc;
struct assignment_request req = {};
@@ -1120,6 +1121,40 @@ static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn,
goto reject;
}
+ /* Check for assignment to VGCS channel. */
+ if (TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) {
+ struct gsm_bts *bts = conn_get_bts(conn);
+
+ OSMO_ASSERT(bts);
+ /* Decode Group Call Reference. */
+ rc = gsm0808_dec_group_callref(&gc, TLVP_VAL(&tp, GSM0808_IE_GROUP_CALL_REFERENCE),
+ TLVP_LEN(&tp, GSM0808_IE_GROUP_CALL_REFERENCE));
+ if (rc < 0) {
+ LOGP(DMSC, LOGL_ERROR, "Unable to decode Group Call Reference.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ req.target_lchan = vgcs_vbs_find_lchan(bts, &gc);
+ if (!req.target_lchan) {
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ req.assign_for = ASSIGN_FOR_BSSMAP_REQ;
+ req.vgcs = true;
+
+ /* Copy timing advance. */
+ if (conn->lchan) {
+ req.target_lchan->activate.info.ta_known = conn->lchan->activate.info.ta_known;
+ req.target_lchan->activate.info.ta = conn->lchan->activate.info.ta;
+ }
+
+ /* Send reactivation on target lchan to prepare VGCS channel for assignment.
+ * See patent EP 1 858 275 A1. */
+ rsl_tx_chan_activ(req.target_lchan, RSL_ACT_TYPE_REACT | RSL_ACT_INTRA_NORM_ASS, 0);
+
+ return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req);
+ }
+
bssmap_handle_ass_req_lcls(conn, &tp);
/* Currently we only support a limited subset of all