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
This commit is contained in:
Andreas Eversberg 2023-06-26 18:38:01 +02:00
parent b0712a9f22
commit 2d93d61fe3
4 changed files with 51 additions and 4 deletions

View File

@ -142,6 +142,7 @@ struct assignment_request {
enum assign_for assign_for;
bool aoip;
bool vgcs;
uint16_t msc_assigned_cic;

View File

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

View File

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

View File

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