gerrit-log
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
July 2023
- 1 participants
- 3051 discussions
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33613 )
Change subject: ASCI: Forward RLL to VGCS FSM
......................................................................
ASCI: Forward RLL to VGCS FSM
RLL events are forwarded to VGCS FSM. Included L3 information are not
forwarded to gsm0408_rcvmsg(), but forwarded to VGCS FSM only.
Change-Id: I5e098a20225ba11206f43281f4da519a4086bae5
Related: OS#4852
---
M src/osmo-bsc/abis_rsl.c
1 file changed, 53 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/13/33613/1
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 1b02450..fcc6f51 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -58,6 +58,7 @@
#include <osmocom/bsc/power_control.h>
#include <osmocom/bsc/chan_counts.h>
#include <osmocom/bsc/lchan.h>
+#include <osmocom/bsc/vgcs_fsm.h>
static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
struct gsm_meas_rep *resp)
@@ -1303,6 +1304,15 @@
break;
}
+ /* Report to VGCS FSM */
+ if (lchan_is_asci(lchan)) {
+ if (lchan->conn && lchan->conn->vgcs_chan.fi) {
+ uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
+ return 0;
+ }
+ }
+
/* If the lchan is associated with a conn, we shall notify the MSC of the RSL Conn Failure, and
* the connection will presumably be torn down and lead to an lchan release. During initial
* Channel Request from the MS, an lchan has no conn yet, so in that case release now. */
@@ -2552,6 +2562,13 @@
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ERR_IND, &rlm_cause);
+ /* Report to VGCS FSM */
+ if (lchan_is_asci(msg->lchan)) {
+ if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
+ uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
+ }
+ }
return 0;
}
@@ -2579,9 +2596,17 @@
switch (rllh->c.msg_type) {
case RSL_MT_DATA_IND:
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "SAPI=%u DATA INDICATION\n", sapi);
+
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
rllh->data[0] == RSL_IE_L3_INFO) {
msg->l3h = &rllh->data[3];
+ /* Data message on a VGCS channel is handled by VGCS FSM only. */
+ if (lchan_is_asci(msg->lchan)) {
+ if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DATA,
+ msg);
+ return 0;
+ }
return gsm0408_rcvmsg(msg, rllh->link_id);
}
break;
@@ -2621,6 +2646,13 @@
msg->lchan->sapis[sapi] = LCHAN_SAPI_MS;
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ESTABLISH_IND, msg);
+ /* Establishment message on a VGCS channel is handled by VGCS FSM only. */
+ if (lchan_is_asci(msg->lchan)) {
+ if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_EST, msg);
+ break;
+ }
+
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
rllh->data[0] == RSL_IE_L3_INFO) {
msg->l3h = &rllh->data[3];
@@ -2636,6 +2668,14 @@
case RSL_MT_REL_IND:
/* BTS informs us of having received DISC from MS */
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_REL_IND, &rllh->link_id);
+
+ /* Report to VGCS FSM */
+ if (lchan_is_asci(msg->lchan)) {
+ if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
+ uint8_t cause = GSM0808_CAUSE_CALL_CONTROL;
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_REL, &cause);
+ }
+ }
break;
case RSL_MT_REL_CONF:
/* BTS informs us of having received UA from MS,
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33613
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I5e098a20225ba11206f43281f4da519a4086bae5
Gerrit-Change-Number: 33613
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[M] Change in osmo-bsc[master]: ASCI: Forward lchan activation states to VGCS FSM
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33614 )
Change subject: ASCI: Forward lchan activation states to VGCS FSM
......................................................................
ASCI: Forward lchan activation states to VGCS FSM
Change-Id: I757b562e02480c1a68446d91217910069f17d060
Related: OS#4852
---
M src/osmo-bsc/lchan_fsm.c
1 file changed, 67 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/14/33614/1
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 816d4b5..99bdaf2 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -43,6 +43,7 @@
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/bsc_stats.h>
#include <osmocom/bsc/lchan.h>
+#include <osmocom/bsc/vgcs_fsm.h>
static struct osmo_fsm lchan_fsm;
@@ -191,6 +192,23 @@
_osmo_fsm_inst_dispatch(for_conn->ho.fi, HO_EV_LCHAN_ERROR, lchan, file, line);
break;
+ case ACTIVATE_FOR_VGCS_CHANNEL:
+ LOG_LCHAN(lchan, LOGL_NOTICE, "Signalling VGCS Assignment FSM of error (%s)\n",
+ lchan->last_error ? : "unknown error");
+ if (!for_conn) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "lchan activation for VGCS Assignment failed, but activation request has no conn\n");
+ break;
+ }
+ if (!for_conn->vgcs_chan.fi) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "lchan activation for VGCS Assignment failed, but conn has no ongoing"
+ " assignment procedure\n");
+ break;
+ }
+ _osmo_fsm_inst_dispatch(for_conn->vgcs_chan.fi, VGCS_EV_LCHAN_ERROR, lchan, file, line);
+ break;
+
case ACTIVATE_FOR_VTY:
LOG_LCHAN(lchan, LOGL_ERROR, "VTY user invoked lchan activation failed (%s)\n",
lchan->last_error ? : "unknown error");
@@ -278,6 +296,22 @@
* we will try to roll back a modified RTP connection. */
break;
+ case ACTIVATE_FOR_VGCS_CHANNEL:
+ if (!lchan->conn) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "lchan activation for VGCS assignment succeeded, but lchan has no conn\n");
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
+ break;
+ }
+ if (!lchan->conn->vgcs_chan.fi) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "lchan Activation for VGCS assignment requested, but conn has no VGCS resource FSM.\n");
+ lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL);
+ break;
+ }
+ osmo_fsm_inst_dispatch(lchan->conn->vgcs_chan.fi, VGCS_EV_LCHAN_ACTIVE, lchan);
+ break;
+
case ACTIVATE_FOR_MODE_MODIFY_RTP:
lchan_on_mode_modify_success(lchan);
break;
@@ -412,6 +446,28 @@
}
break;
+ case ACTIVATE_FOR_VGCS_CHANNEL:
+ if (!info->for_conn
+ || !info->for_conn->fi) {
+ LOG_LCHAN(lchan, LOGL_ERROR, "Activation requested, but no conn\n");
+ goto abort;
+ }
+ if (!info->for_conn->vgcs_chan.fi) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "Activation for VGCS assignment requested, but conn has no VGCS resource FSM.\n");
+ goto abort;
+ }
+ if (info->for_conn->vgcs_chan.new_lchan != lchan) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "Activation for VGCS assignment requested, but conn's VGCS assignment state does"
+ " not reflect this lchan to be activated (instead: %s)\n",
+ info->for_conn->vgcs_chan.new_lchan?
+ gsm_lchan_name(info->for_conn->vgcs_chan.new_lchan)
+ : "NULL");
+ goto abort;
+ }
+ break;
+
default:
break;
}
@@ -856,6 +912,7 @@
ho_ref = lchan->conn->ho.ho_ref;
break;
case ACTIVATE_FOR_ASSIGNMENT:
+ case ACTIVATE_FOR_VGCS_CHANNEL:
default:
act_type = RSL_ACT_INTRA_NORM_ASS;
break;
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33614
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I757b562e02480c1a68446d91217910069f17d060
Gerrit-Change-Number: 33614
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[S] Change in osmo-bsc[master]: ASCI: Indicate release of subscriber connection to VGCS FSM
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33615 )
Change subject: ASCI: Indicate release of subscriber connection to VGCS FSM
......................................................................
ASCI: Indicate release of subscriber connection to VGCS FSM
If an SCCP connection or channel is released or fails, send indications
towards VGCS FSM, so that it can terminate the state machines belonging
to these connections.
Change-Id: Ia74db9ba47fea11b359ac01269f714482485d464
Related: OS#4852
---
M src/osmo-bsc/bsc_subscr_conn_fsm.c
1 file changed, 39 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/15/33615/1
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index b8c2e82..7235338 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -213,6 +213,12 @@
if (conn->lcs.loc_req)
osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);
+ if (conn->vgcs_call.fi)
+ osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
+
+ if (conn->vgcs_chan.fi)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
+
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);
@@ -247,6 +253,8 @@
conn->lchan = NULL;
if (conn->ho.fi && conn->ho.new_lchan == lchan)
conn->ho.new_lchan = NULL;
+ if (conn->vgcs_chan.new_lchan == lchan)
+ conn->vgcs_chan.new_lchan = NULL;
if (conn->assignment.new_lchan == lchan)
conn->assignment.new_lchan = NULL;
lchan_release(lchan, do_rr_release, err, cause_rr,
@@ -953,6 +961,10 @@
if (conn->ho.fi)
osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_LCHAN_ERROR, lchan);
}
+ if (conn->vgcs_chan.new_lchan == lchan) {
+ if (conn->vgcs_chan.fi)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_LCHAN_ERROR, lchan);
+ }
if (conn->lchan == lchan) {
lchan_forget_conn(conn->lchan);
conn->lchan = NULL;
@@ -989,6 +1001,10 @@
conn->ho.new_lchan = NULL;
detach_label = "ho.new_lchan";
}
+ if (conn->vgcs_chan.new_lchan == lchan) {
+ conn->vgcs_chan.new_lchan = NULL;
+ detach_label = "vgcs.new_lchan";
+ }
if (conn->lchan == lchan) {
conn->lchan = NULL;
detach_label = "primary lchan";
@@ -1007,6 +1023,7 @@
if (!conn->lchan
&& !conn->ho.new_lchan
&& !conn->assignment.new_lchan
+ && !conn->vgcs_chan.new_lchan
&& !conn->lcs.loc_req)
gscon_bssmap_clear(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
}
@@ -1028,6 +1045,7 @@
conn->ho.created_ci_for_msc = NULL;
lchan_forget_mgw_endpoint(conn->lchan);
lchan_forget_mgw_endpoint(conn->assignment.new_lchan);
+ lchan_forget_mgw_endpoint(conn->vgcs_chan.new_lchan);
lchan_forget_mgw_endpoint(conn->ho.new_lchan);
}
@@ -1117,6 +1135,7 @@
lchan_forget_conn(conn->lchan);
lchan_forget_conn(conn->assignment.new_lchan);
+ lchan_forget_conn(conn->vgcs_chan.new_lchan);
lchan_forget_conn(conn->ho.new_lchan);
lb_close_conn(conn);
@@ -1169,6 +1188,12 @@
conn->lcls.fi = NULL;
}
+ if (conn->vgcs_call.fi)
+ osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
+
+ if (conn->vgcs_chan.fi)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
+
LOGPFSML(fi, LOGL_DEBUG, "Releasing all lchans (if any) because this conn is terminating\n");
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33615
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ia74db9ba47fea11b359ac01269f714482485d464
Gerrit-Change-Number: 33615
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[M] Change in osmo-bsc[master]: ASCI: Add support for reception of TALKER/LISTENER DETECTION
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33616 )
Change subject: ASCI: Add support for reception of TALKER/LISTENER DETECTION
......................................................................
ASCI: Add support for reception of TALKER/LISTENER DETECTION
TALKER DETECTION and LISTENER DETECTION is used when the uplink is
accessed on the VGCS channel by a talker or listener.
Change-Id: I166d6d42c04337e669307943ecbb8eea6906b385
Related: OS#4852
---
M src/osmo-bsc/abis_rsl.c
1 file changed, 79 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/16/33616/1
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index fcc6f51..5edcd8b 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1544,6 +1544,66 @@
return 0;
}
+/* Chapter 8.4.21: TALKER DETECTION */
+static int rsl_rx_talker_det(struct msgb *msg)
+{
+ struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
+ struct tlv_parsed tp;
+ /* We use this struct, because it has same data. */
+ struct handover_rr_detect_data d = {
+ .msg = msg,
+ };
+
+ if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
+ LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
+ rsl_or_ipac_msg_name(dh->c.msg_type));
+ return -EINVAL;
+ }
+
+ if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
+ d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
+
+ if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
+ LOGP(DRSL, LOGL_ERROR, "%s TALKER DETECTION but no VGCS channel\n",
+ gsm_lchan_name(msg->lchan));
+ return 0;
+ }
+
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DET, &d);
+
+ return 0;
+}
+
+/* Chapter 8.4.22: LISTENER DETECTION */
+static int rsl_rx_listener_det(struct msgb *msg)
+{
+ struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
+ struct tlv_parsed tp;
+ /* We use this struct, because it has same data. */
+ struct handover_rr_detect_data d = {
+ .msg = msg,
+ };
+
+ if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
+ LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
+ rsl_or_ipac_msg_name(dh->c.msg_type));
+ return -EINVAL;
+ }
+
+ if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
+ d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
+
+ if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
+ LOGP(DRSL, LOGL_ERROR, "%s LISTENER DETECTION but no VGCS channel\n",
+ gsm_lchan_name(msg->lchan));
+ return 0;
+ }
+
+ osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_LISTENER_DET, &d);
+
+ return 0;
+}
+
static int rsl_rx_ipacc_pdch(struct msgb *msg, char *name, uint32_t ts_ev)
{
struct gsm_bts_trx_ts *ts = msg->lchan->ts;
@@ -1611,6 +1671,12 @@
case RSL_MT_HANDO_DET:
rc = rsl_rx_hando_det(msg);
break;
+ case RSL_MT_TALKER_DET:
+ rc = rsl_rx_talker_det(msg);
+ break;
+ case RSL_MT_LISTENER_DET:
+ rc = rsl_rx_listener_det(msg);
+ break;
case RSL_MT_RF_CHAN_REL_ACK:
if (msg_for_osmocom_dyn_ts(msg))
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_DEACT_ACK, NULL);
@@ -1641,8 +1707,6 @@
break;
case RSL_MT_PHY_CONTEXT_CONF:
case RSL_MT_PREPROC_MEAS_RES:
- case RSL_MT_TALKER_DET:
- case RSL_MT_LISTENER_DET:
case RSL_MT_REMOTE_CODEC_CONF_REP:
case RSL_MT_MR_CODEC_MOD_ACK:
case RSL_MT_MR_CODEC_MOD_NACK:
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33616
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I166d6d42c04337e669307943ecbb8eea6906b385
Gerrit-Change-Number: 33616
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[S] Change in osmo-bsc[master]: ASCI: Send release on VGCS/VBS channel via unit data
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33617 )
Change subject: ASCI: Send release on VGCS/VBS channel via unit data
......................................................................
ASCI: Send release on VGCS/VBS channel via unit data
Channel release is sent to MS that is in dedicated mode on the main
DCCH. Additionally it is sent as unit data on a VGCS/VBS to notify all
listeners that the channel has been released. All listeners return to
IDLE mode.
Change-Id: Ib777fe98c8ce2342082d88d227b796167d92cfe1
Related: OS#4852
---
M include/osmocom/bsc/gsm_04_08_rr.h
M src/osmo-bsc/gsm_04_08_rr.c
M src/osmo-bsc/lchan_fsm.c
3 files changed, 40 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/17/33617/1
diff --git a/include/osmocom/bsc/gsm_04_08_rr.h b/include/osmocom/bsc/gsm_04_08_rr.h
index 3106e77..9a9956b 100644
--- a/include/osmocom/bsc/gsm_04_08_rr.h
+++ b/include/osmocom/bsc/gsm_04_08_rr.h
@@ -18,7 +18,7 @@
void gsm_net_update_ctype(struct gsm_network *network);
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra);
int get_reason_by_chreq(uint8_t ra, int neci);
-int gsm48_send_rr_release(struct gsm_lchan *lchan);
+int gsm48_send_rr_release(struct gsm_lchan *lchan, bool ui);
int send_siemens_mrpci(struct gsm_lchan *lchan,
uint8_t *classmark2_lv);
int gsm48_send_rr_classmark_enquiry(struct gsm_lchan *lchan);
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index 78a4f45..60ccb5a 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -308,12 +308,15 @@
}
}
+#define REPEAT_RR_RELEASE_UI 3
+
/* 7.1.7 and 9.1.7: RR CHANnel RELease */
-int gsm48_send_rr_release(struct gsm_lchan *lchan)
+int gsm48_send_rr_release(struct gsm_lchan *lchan, bool ui)
{
- struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL");
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL"), *msgc;
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
uint8_t *cause;
+ int n;
msg->lchan = lchan;
gh->proto_discr = GSM48_PDISC_RR;
@@ -338,8 +341,17 @@
gsm_lchan_name(lchan), lchan->release.rr_cause,
rr_cause_name(lchan->release.rr_cause));
- /* Send actual release request to MS */
- return gsm48_sendmsg(msg);
+ /* Send actual release request to MS (dedicated channel) */
+ if (!ui)
+ return gsm48_sendmsg(msg);
+
+ /* Send actual release request to MS (VGCS channel) */
+ for (n = 1; n < REPEAT_RR_RELEASE_UI; n++) {
+ msgc = msgb_copy(msg, "CHAN RELEASE copy");
+ msgc->lchan = lchan;
+ gsm48_sendmsg_unit(msgc);
+ }
+ return gsm48_sendmsg_unit(msg);
}
int send_siemens_mrpci(struct gsm_lchan *lchan,
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 99bdaf2..cdeecd8 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -1417,8 +1417,14 @@
static void lchan_do_release(struct gsm_lchan *lchan)
{
- if (lchan->release.do_rr_release && lchan->sapis[0] != LCHAN_SAPI_UNUSED)
- gsm48_send_rr_release(lchan);
+ if (lchan->release.do_rr_release) {
+ /* To main DCCH in dedicated and group transmit mode */
+ if (lchan->sapis[0] != LCHAN_SAPI_UNUSED)
+ gsm48_send_rr_release(lchan, false);
+ /* As UI to all listeners in group receive mdoe */
+ if (lchan_is_asci(lchan))
+ gsm48_send_rr_release(lchan, true);
+ }
if (lchan->fi_rtp)
osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_RELEASE, 0);
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33617
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ib777fe98c8ce2342082d88d227b796167d92cfe1
Gerrit-Change-Number: 33617
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33611 )
Change subject: ASCI: Add FSM for VGCS/VBS
......................................................................
ASCI: Add FSM for VGCS/VBS
Change-Id: Id9e94fb4f27bb438b7093c031344a3400bfa34f1
Related: OS#4852
---
M include/osmocom/bsc/Makefile.am
M include/osmocom/bsc/gsm_data.h
A include/osmocom/bsc/vgcs_fsm.h
M src/osmo-bsc/Makefile.am
M src/osmo-bsc/bsc_subscr_conn_fsm.c
M src/osmo-bsc/osmo_bsc_bssap.c
A src/osmo-bsc/vgcs_fsm.c
7 files changed, 1,457 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/11/33611/1
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 8baff9c..2010d6b 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -67,4 +67,5 @@
osmo_bsc_lcls.h \
smscb.h \
power_control.h \
+ vgcs_fsm.h \
$(NULL)
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index c2bd7ad..a434df1 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -412,6 +412,54 @@
} fast_return;
enum gsm0808_cause clear_cause;
+
+ /* VGCS/VBS "call controling" connection */
+ struct {
+ /* Features supported by MSC/BSC */
+ bool ff_present;
+ struct gsm0808_vgcs_feature_flags ff;
+ /* Group Call Reference IE */
+ struct gsm0808_group_callref gc_ie;
+ enum gsm0808_service_flag sf;
+ uint32_t call_ref;
+ /* Call (BSC) FSM */
+ struct osmo_fsm_inst *fi;
+ /* Current talker */
+ struct gsm_subscriber_connection *talker;
+ /* L3 info of link establihment (Talker established) */
+ struct llist_head l3_queue;
+ /* Flag that states acknowledgement of the talker by MSC */
+ bool msc_ack;
+ /* List of VGCS/VBS "resource controling" connections */
+ struct llist_head chan_list;
+ } vgcs_call;
+
+ /* VGCS/VBS "resource controling" connection */
+ struct {
+ /* List entry of chan_list of "call controling" connection */
+ struct llist_head list;
+ /* Group Call Reference IE (required, to remove call from NCH) */
+ struct gsm0808_group_callref gc_ie;
+ /* Channel type IE */
+ struct gsm0808_channel_type ct;
+ /* Channel mode and rate */
+ struct channel_mode_and_rate ch_mode_rate;
+ /* Cell Identifier IE */
+ struct gsm0808_cell_id ci;
+ /* Assignment Requirements IE */
+ enum gsm0808_assignment_requirement ar;
+ /* Call Identifier IE */
+ uint32_t call_id;
+ /* Pointer to VGCS/VBS "call controling" gsconn */
+ struct gsm_subscriber_connection *call;
+ /* Cell (BTS) FSM */
+ struct osmo_fsm_inst *fi;
+ /* lchan to be assigned */
+ struct gsm_lchan *new_lchan;
+ /* MGW peer */
+ char msc_rtp_addr[INET6_ADDRSTRLEN];
+ uint16_t msc_rtp_port;
+ } vgcs_chan;
};
diff --git a/include/osmocom/bsc/vgcs_fsm.h b/include/osmocom/bsc/vgcs_fsm.h
new file mode 100644
index 0000000..39647d4
--- /dev/null
+++ b/include/osmocom/bsc/vgcs_fsm.h
@@ -0,0 +1,121 @@
+/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+/* Events for both VGCS/VBS state machines. */
+enum vgcs_fsm_event {
+ /* The BSC sets up a VGCS/VBS call. */
+ VGCS_EV_SETUP,
+ /* The BSC wants to assign a VGCS/VBS channel. */
+ VGCS_EV_ASSIGN_REQ,
+ /* The BTS detects a talker on a channel. */
+ VGCS_EV_TALKER_DET,
+ /* The BTS detects a listener on a channel. */
+ VGCS_EV_LISTENER_DET,
+ /* The MSC accepts a talker. */
+ VGCS_EV_MSC_ACK,
+ /* The MSC rejects a talker. */
+ VGCS_EV_MSC_REJECT,
+ /* The MSC seizes all channels. (blocking for calls) */
+ VGCS_EV_MSC_SEIZE,
+ /* The MSC releases all channels. (unblocking for calls) */
+ VGCS_EV_MSC_RELEASE,
+ /* The MSC sends message to talker. (E.g. CONNECT) */
+ VGCS_EV_MSC_DTAP,
+ /* Channel is now active. Waiting for Talker. */
+ VGCS_EV_LCHAN_ACTIVE,
+ /* Channel activation error. */
+ VGCS_EV_LCHAN_ERROR,
+ /* MGW connection is now active. Waiting for Talker. */
+ VGCS_EV_MGW_OK,
+ /* MGW connection error. */
+ VGCS_EV_MGW_FAIL,
+ /* Channel link established. (Talker establised.) */
+ VGCS_EV_TALKER_EST,
+ /* Channel link data. (Talker sends data.) */
+ VGCS_EV_TALKER_DATA,
+ /* Channel link released. (Talker released.) */
+ VGCS_EV_TALKER_REL,
+ /* Channel link failed. (Talker faild.) */
+ VGCS_EV_TALKER_FAIL,
+ /* Channel is blocked by BSC. */
+ VGCS_EV_BLOCK,
+ /* Channel is rejected by BSC. */
+ VGCS_EV_REJECT,
+ /* Channel is unblocked by BSC. */
+ VGCS_EV_UNBLOCK,
+ /* The connection will be destroyed. (free VGCS resources) */
+ VGCS_EV_CLEANUP,
+ /* The calling subscriber has been assigned to the group channel. */
+ VGCS_EV_CALLING_ASSIGNED,
+};
+
+
+/* States of the VGCS/VBS call state machine */
+enum vgcs_call_fsm_state {
+ /* Call is not setup. Initial state when instance is created. */
+ VGCS_CALL_ST_NULL = 0,
+ /* Call is idle. */
+ VGCS_CALL_ST_IDLE,
+ /* Call is busy, due to a talker in this BSC. */
+ VGCS_CALL_ST_BUSY,
+ /* Call is blocked, due to a talker in a different BSC. */
+ VGCS_CALL_ST_BLOCKED,
+};
+
+/* States of the VGCS/VBS channel state machine */
+enum vgcs_chan_fsm_state {
+ /* Channel not assigned. Initial state when instance is created. */
+ VGCS_CHAN_ST_NULL = 0,
+ /* Wait for establishment of VGCS/VBS channel at BTS. */
+ VGCS_CHAN_ST_WAIT_EST,
+ /* Channel active and idle. Channel is marked as uplink busy. */
+ VGCS_CHAN_ST_ACTIVE_BLOCKED,
+ /* Channel active and idle. Channel is marked as uplink free. */
+ VGCS_CHAN_ST_ACTIVE_FREE,
+ /* Channel active and talker was detected, L2 must be established. */
+ VGCS_CHAN_ST_ACTIVE_INIT,
+ /* Channel active and talker established L2. */
+ VGCS_CHAN_ST_ACTIVE_EST,
+ /* Channel active and wait for talker to release L2. */
+ VGCS_CHAN_ST_ACTIVE_REL,
+};
+
+int vgcs_vbs_chan_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
+int vgcs_vbs_call_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
+
+int bssmap_handle_ass_req_ct_speech(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
+ struct tlv_parsed *tp, struct gsm0808_channel_type *ct,
+ struct assignment_request *req, uint8_t *cause);
+void tx_setup_ack(struct gsm_subscriber_connection *conn, struct gsm0808_vgcs_feature_flags *ff);
+void tx_setup_refuse(struct gsm_subscriber_connection *conn, uint8_t cause);
+void tx_vgcs_vbs_assignment_result(struct gsm_subscriber_connection *conn, struct gsm0808_channel_type *ct,
+ struct gsm0808_cell_id *ci, uint32_t call_id);
+void tx_vgcs_vbs_assignment_fail(struct gsm_subscriber_connection *conn, uint8_t cause);
+void tx_uplink_req(struct gsm_subscriber_connection *conn);
+void tx_uplink_req_conf(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
+ uint8_t length);
+void tx_uplink_app_data(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
+ uint8_t length);
+void tx_uplink_release_ind(struct gsm_subscriber_connection *conn, uint8_t cause);
+struct gsm_lchan *vgcs_vbs_find_lchan(struct gsm_bts *bts, struct gsm0808_group_callref *gc);
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 53c0912..661188e 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -73,6 +73,7 @@
handover_fsm.c \
handover_logic.c \
handover_vty.c \
+ vgcs_fsm.c \
lb.c \
lchan.c \
lchan_fsm.c \
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index 6300ca6..b8c2e82 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -50,6 +50,7 @@
#include <osmocom/core/byteswap.h>
#include <osmocom/bsc/lb.h>
#include <osmocom/bsc/lcs_loc_req.h>
+#include <osmocom/bsc/vgcs_fsm.h>
#define S(x) (1 << (x))
@@ -303,6 +304,8 @@
switch (bssmap_type) {
case BSS_MAP_MSG_HANDOVER_RQST:
case BSS_MAP_MSG_PERFORM_LOCATION_RQST:
+ case BSS_MAP_MSG_VGCS_VBS_SETUP:
+ case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
return 0;
default:
@@ -343,6 +346,20 @@
lcs_loc_req_start(conn, msg);
return;
+ case BSS_MAP_MSG_VGCS_VBS_SETUP:
+ rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP]);
+ /* VGCS: MSC asks vor voice group/bcast call. */
+ conn_fsm_state_chg(ST_ACTIVE);
+ vgcs_vbs_call_start(conn, msg);
+ return;
+
+ case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
+ rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST]);
+ /* VGCS: MSC asks vor resource (channel) for voice group/bcast call. */
+ conn_fsm_state_chg(ST_ACTIVE);
+ vgcs_vbs_chan_start(conn, msg);
+ return;
+
default:
LOGPFSML(fi, LOGL_ERROR, "No support for initial BSSMAP: %s: %s\n",
gsm0808_bssap_name(bs->type), gsm0808_bssmap_name(bssmap_type));
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 8b4eff3..7e82534 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -50,6 +50,7 @@
#include <osmocom/bsc/lcs_loc_req.h>
#include <osmocom/bsc/bssmap_reset.h>
#include <osmocom/bsc/assignment_fsm.h>
+#include <osmocom/bsc/vgcs_fsm.h>
#define IP_V4_ADDR_LEN 4
@@ -1465,7 +1466,10 @@
/* convert DLCI to RSL link ID, store in msg->cb */
OBSC_LINKID_CB(gsm48) = DLCI2RSL_LINK_ID(header->link_id);
- dtap_rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, gsm48);
+ if (conn->vgcs_call.fi)
+ dtap_rc = osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_DTAP, gsm48);
+ else
+ dtap_rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, gsm48);
return dtap_rc;
}
diff --git a/src/osmo-bsc/vgcs_fsm.c b/src/osmo-bsc/vgcs_fsm.c
new file mode 100644
index 0000000..e06b491
--- /dev/null
+++ b/src/osmo-bsc/vgcs_fsm.c
@@ -0,0 +1,1254 @@
+/* Handle VGCS/VBCS calls. (Voice Group/Broadcast Call Service). */
+/*
+ * (C) 2023 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * All Rights Reserved
+ *
+ * SPDX-License-Identifier: AGPL-3.0+
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The process consists of two state machnes:
+ *
+ * The VGCS call state machine handles the voice group/broadcast call control.
+ * There is one instance for every call. It controls the uplink states of the
+ * call. They will be reported to the MSC or can be changed by the MSC.
+ * One SCCP connection for is associated with the state machine. This is used
+ * to talk to the MSC about state changes.
+ *
+ * The VGCS channel state machine handles the channel states in each cell.
+ * There is one instance for every cell and every call. The instances are
+ * linked to the call state process. It controls the uplink states of the
+ * channel. They will be reported to the call state machine or can be changed
+ * by the call state machine.
+ * One SCCP connection for every cell is associated with the state machine.
+ * It is used to perform VGCS channel assignment.
+ *
+ */
+
+#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h>
+#include <osmocom/bsc/osmo_bsc.h>
+#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/vgcs_fsm.h>
+#include <osmocom/bsc/handover_fsm.h>
+#include <osmocom/bsc/abis_rsl.h>
+#include <osmocom/bsc/lchan_fsm.h>
+#include <osmocom/bsc/lchan_select.h>
+#include <osmocom/bsc/bsc_subscr_conn_fsm.h>
+#include <osmocom/bsc/assignment_fsm.h>
+#include <osmocom/bsc/gsm_08_08.h>
+#include <osmocom/bsc/gsm_04_08_rr.h>
+#include <osmocom/bsc/bts_trx.h>
+#include <osmocom/bsc/bts.h>
+
+#define S(x) (1 << (x))
+
+#define LOG_CALL(conn, level, fmt, args...) \
+ LOGP(DASCI, level, \
+ (conn->vgcs_call.sf == GSM0808_SF_VGCS) ? ("VGCS callref %s: " fmt) : ("VBS callref %s: " fmt), \
+ gsm44068_group_id_string(conn->vgcs_call.call_ref), ##args)
+#define LOG_CHAN(conn, level, fmt, args...) \
+ LOGP(DASCI, level, \
+ ("VGCS/VBS channel: " fmt), \
+ ##args)
+
+const char *gsm44068_group_id_string(uint32_t callref)
+{
+ static char string[16];
+
+ sprintf(string, "%08u", callref);
+
+ return string;
+}
+
+static struct osmo_fsm vgcs_call_fsm;
+static struct osmo_fsm vgcs_chan_fsm;
+
+static __attribute__((constructor)) void vgcs_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_call_fsm) == 0);
+ OSMO_ASSERT(osmo_fsm_register(&vgcs_chan_fsm) == 0);
+}
+
+static const struct value_string vgcs_fsm_event_names[] = {
+ OSMO_VALUE_STRING(VGCS_EV_SETUP),
+ OSMO_VALUE_STRING(VGCS_EV_ASSIGN_REQ),
+ OSMO_VALUE_STRING(VGCS_EV_TALKER_DET),
+ OSMO_VALUE_STRING(VGCS_EV_LISTENER_DET),
+ OSMO_VALUE_STRING(VGCS_EV_MSC_ACK),
+ OSMO_VALUE_STRING(VGCS_EV_MSC_REJECT),
+ OSMO_VALUE_STRING(VGCS_EV_MSC_SEIZE),
+ OSMO_VALUE_STRING(VGCS_EV_MSC_RELEASE),
+ OSMO_VALUE_STRING(VGCS_EV_MSC_DTAP),
+ OSMO_VALUE_STRING(VGCS_EV_LCHAN_ACTIVE),
+ OSMO_VALUE_STRING(VGCS_EV_LCHAN_ERROR),
+ OSMO_VALUE_STRING(VGCS_EV_MGW_OK),
+ OSMO_VALUE_STRING(VGCS_EV_MGW_FAIL),
+ OSMO_VALUE_STRING(VGCS_EV_TALKER_EST),
+ OSMO_VALUE_STRING(VGCS_EV_TALKER_DATA),
+ OSMO_VALUE_STRING(VGCS_EV_TALKER_REL),
+ OSMO_VALUE_STRING(VGCS_EV_TALKER_FAIL),
+ OSMO_VALUE_STRING(VGCS_EV_BLOCK),
+ OSMO_VALUE_STRING(VGCS_EV_REJECT),
+ OSMO_VALUE_STRING(VGCS_EV_UNBLOCK),
+ OSMO_VALUE_STRING(VGCS_EV_CLEANUP),
+ OSMO_VALUE_STRING(VGCS_EV_CALLING_ASSIGNED),
+ { }
+};
+
+static struct gsm_subscriber_connection *find_calling_subscr_conn(struct gsm_subscriber_connection *conn)
+{
+ struct gsm_subscriber_connection *c;
+
+ llist_for_each_entry(c, &conn->network->subscr_conns, entry) {
+ if (!c->assignment.fi)
+ continue;
+ if (c->assignment.req.target_lchan != conn->lchan)
+ continue;
+ return c;
+ }
+
+ return NULL;
+}
+
+/*
+ * VGCS call FSM
+ */
+
+static void vgcs_call_detach_and_destroy(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
+{
+ struct gsm_subscriber_connection *conn = fi->priv, *c;
+ struct msgb *msg;
+
+ /* Flush message queue. */
+ while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue)))
+ msgb_free(msg);
+
+ /* Detach all cell instances. */
+ while (!llist_empty(&conn->vgcs_call.chan_list)) {
+ c = llist_entry(conn->vgcs_call.chan_list.next, struct gsm_subscriber_connection, vgcs_chan.list);
+ c->vgcs_chan.call = NULL;
+ llist_del(&c->vgcs_chan.list);
+ }
+
+ /* No Talker. */
+ conn->vgcs_call.talker = NULL;
+
+ /* Remove pointer of FSM. */
+ conn->vgcs_call.fi = NULL;
+}
+
+static void vgcs_call_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+
+ switch (event) {
+ case VGCS_EV_SETUP:
+ LOG_CALL(conn, LOGL_DEBUG, "VGCS/VBS SETUP from MSC.\n");
+ /* MSC sends VGCS/VBS SETUP for a new call. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0);
+ /* Remove unsupported features. */
+ conn->vgcs_call.ff.tp_ind = 0;
+ conn->vgcs_call.ff.as_ind_circuit = 0;
+ conn->vgcs_call.ff.as_ind_link = 0;
+ conn->vgcs_call.ff.bss_res = 0;
+ conn->vgcs_call.ff.tcp = 0;
+ /* Acknowlege the call. */
+ tx_setup_ack(conn, &conn->vgcs_call.ff);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_call_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv, *c;
+ struct handover_rr_detect_data *d = data;
+ struct msgb *msg;
+
+ switch (event) {
+ case VGCS_EV_TALKER_DET:
+ LOG_CALL(conn, LOGL_DEBUG, "Talker detected.\n");
+ /* Talker detected on a channel, call becomes busy. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BUSY, 0, 0);
+ conn->vgcs_call.talker = d->msg->lchan->conn;
+ /* Reset pending states. */
+ while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue)))
+ msgb_free(msg);
+ conn->vgcs_call.msc_ack = false;
+ /* Report busy uplink to the MSC. */
+ tx_uplink_req(conn);
+ /* Block all other channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) {
+ if (c == conn->vgcs_call.talker)
+ continue;
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL);
+ }
+ break;
+ case VGCS_EV_LISTENER_DET:
+ LOG_CALL(conn, LOGL_DEBUG, "Listener detected.\n");
+ // Listener detection not supported.
+ break;
+ case VGCS_EV_MSC_SEIZE:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC seizes all channels.\n");
+ /* MSC seizes call (talker on a different BSS), call becomes blocked. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BLOCKED, 0, 0);
+ /* Block all channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list)
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL);
+ break;
+ case VGCS_EV_MSC_RELEASE:
+ /* Ignore, because there is no blocked channel in this state. */
+ break;
+ case VGCS_EV_MSC_REJECT:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC rejects talker on uplink.\n");
+ /* Race condition: Talker released before the MSC rejects the talker. Ignore! */
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+/* Get L3 info from message, if exists. Return the length or otherwise return 0. */
+int l3_data_from_msg(struct msgb *msg, uint8_t **l3_info)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+
+ /* No space for L3 info */
+ if (msgb_l2len(msg) < sizeof(*rllh) + 3 || rllh->data[0] != RSL_IE_L3_INFO)
+ return 0;
+
+ *l3_info = msg->l3h = &rllh->data[3];
+ return msgb_l3len(msg);
+}
+
+static void vgcs_call_fsm_busy(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv, *c;
+ struct msgb *msg = data;
+ uint8_t cause = (data) ? *(uint8_t *)data : 0;
+ uint8_t *l3_info;
+ int l3_len;
+ int rc;
+
+ switch (event) {
+ case VGCS_EV_TALKER_EST:
+ LOG_CALL(conn, LOGL_DEBUG, "Talker established uplink.\n");
+ /* Talker established L2 connection. Sent L3 info to MSC, if MSC already acked, otherwise enqueue. */
+ if (conn->vgcs_call.msc_ack) {
+ LOG_CALL(conn, LOGL_DEBUG, "Sending establishment messages to MSC.\n");
+ l3_len = l3_data_from_msg(msg, &l3_info);
+ if (conn->vgcs_call.talker)
+ tx_uplink_req_conf(conn, &conn->vgcs_call.talker->vgcs_chan.ci, l3_info, l3_len);
+ else
+ LOG_CALL(conn, LOGL_ERROR, "Talker establishes, but talker not set, please fix!\n");
+ } else {
+ LOG_CALL(conn, LOGL_DEBUG, "No uplink request ack from MSC yet, queue message.\n");
+ msg = msgb_copy(msg, "Queued Talker establishment");
+ if (msg)
+ msgb_enqueue(&conn->vgcs_call.l3_queue, msg);
+ }
+ break;
+ case VGCS_EV_TALKER_DATA:
+ LOG_CALL(conn, LOGL_DEBUG, "Talker sent data on uplink.\n");
+ /* Talker sends data. Sent L3 info to MSC, if MSC already acked, otherwise enqueue. */
+ if (conn->vgcs_call.msc_ack) {
+ LOG_CALL(conn, LOGL_DEBUG, "Sending data messages to MSC.\n");
+ bsc_dtap(conn, 0, msg);
+ } else {
+ LOG_CALL(conn, LOGL_DEBUG, "No uplink request ack from MSC yet, queue message.\n");
+ msg = msgb_copy(msg, "Queued DTAP");
+ if (msg)
+ msgb_enqueue(&conn->vgcs_call.l3_queue, msg);
+ }
+ break;
+ case VGCS_EV_MSC_DTAP:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC sends DTAP message to talker.\n");
+ if (!conn->vgcs_call.talker)
+ msgb_free(data);
+ rc = osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_MSC_DTAP, data);
+ if (rc < 0)
+ msgb_free(data);
+ break;
+ case VGCS_EV_TALKER_REL:
+ LOG_CALL(conn, LOGL_DEBUG, "Talker released on uplink.\n");
+ /* Talker released channel, call becomes idle. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0);
+ conn->vgcs_call.talker = NULL;
+ /* Report free uplink to the MSC. */
+ tx_uplink_release_ind(conn, cause);
+ /* Unblock all other channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) {
+ if (c == conn->vgcs_call.talker)
+ continue;
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL);
+ }
+ break;
+ case VGCS_EV_MSC_SEIZE:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC seizes all channels. (channels are blocked)\n");
+ /* Race condition: MSC seizes call (talker on a different BSS), call becomes blocked. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BLOCKED, 0, 0);
+ /* Reject talker. (Forward to chan FSM.) */
+ if (conn->vgcs_call.talker) {
+ osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_REJECT, NULL);
+ conn->vgcs_call.talker = NULL;
+ }
+ /* Block all channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list)
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL);
+ break;
+ case VGCS_EV_MSC_ACK:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC acks talker on uplink.\n");
+ /* MSC acknowledges uplink. Send L3 info to MSC, if talker already established. */
+ conn->vgcs_call.msc_ack = true;
+ /* Send establish message via UPLINK REQUEST CONFIRM, if already received. */
+ msg = msgb_dequeue(&conn->vgcs_call.l3_queue);
+ if (msg) {
+ LOG_CALL(conn, LOGL_DEBUG, "Sending queued establishment messages to MSC.\n");
+ l3_len = l3_data_from_msg(msg, &l3_info);
+ if (conn->vgcs_call.talker)
+ tx_uplink_req_conf(conn, &conn->vgcs_call.talker->vgcs_chan.ci, l3_info, l3_len);
+ else
+ LOG_CALL(conn, LOGL_ERROR, "MSC acks taker, but talker not set, please fix!\n");
+ msgb_free(msg);
+ }
+ /* Send data messages via UPLINK APPLICATION DATA, if already received. */
+ while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue))) {
+ LOG_CALL(conn, LOGL_DEBUG, "Sending queued DTAP messages to MSC.\n");
+ bsc_dtap(conn, 0, msg);
+ msgb_free(msg);
+ }
+ break;
+ case VGCS_EV_MSC_REJECT:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC rejects talker on uplink.\n");
+ /* MSC rejects talker, call becomes idle. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0);
+ /* Reject talker. (Forward to chan FSM.) */
+ if (conn->vgcs_call.talker)
+ osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_REJECT, NULL);
+ else
+ LOG_CALL(conn, LOGL_ERROR, "MSC rejects, but talker not set, please fix!\n");
+ conn->vgcs_call.talker = NULL;
+ /* Unblock all other channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) {
+ if (c == conn->vgcs_call.talker)
+ continue;
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL);
+ }
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_call_fsm_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv, *c;
+ struct msgb *msg;
+
+ switch (event) {
+ case VGCS_EV_CALLING_ASSIGNED:
+ LOG_CALL(conn, LOGL_DEBUG, "Calling subscriber assiged and now on uplink.\n");
+ /* Talker detected on a channel, call becomes busy. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BUSY, 0, 0);
+ conn->vgcs_call.talker = data;
+ /* Reset pending states, but imply that MSC acked this uplink session. */
+ while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue)))
+ msgb_free(msg);
+ conn->vgcs_call.msc_ack = true;
+ break;
+ case VGCS_EV_TALKER_REL:
+ LOG_CALL(conn, LOGL_DEBUG, "Talker released on uplink.\n");
+ /* Talker release was complete. Ignore. */
+ break;
+ case VGCS_EV_MSC_RELEASE:
+ LOG_CALL(conn, LOGL_DEBUG, "MSC releases all channels. (channels are free)\n");
+ /* MSC releases call (no mor talker on a different BSS), call becomes idle */
+ osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0);
+ /* Unblock all channels. */
+ llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list)
+ osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_call_fsm_states[] = {
+ [VGCS_CALL_ST_NULL] = {
+ .name = "NULL",
+ .in_event_mask = S(VGCS_EV_SETUP),
+ .out_state_mask = S(VGCS_CALL_ST_IDLE),
+ .action = vgcs_call_fsm_null,
+ },
+ [VGCS_CALL_ST_IDLE] = {
+ .name = "IDLE",
+ .in_event_mask = S(VGCS_EV_TALKER_DET) |
+ S(VGCS_EV_MSC_SEIZE) |
+ S(VGCS_EV_MSC_RELEASE) |
+ S(VGCS_EV_MSC_REJECT) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CALL_ST_BUSY) |
+ S(VGCS_CALL_ST_BLOCKED) |
+ S(VGCS_CALL_ST_NULL),
+ .action = vgcs_call_fsm_idle,
+ },
+ [VGCS_CALL_ST_BUSY] = {
+ .name = "BUSY",
+ .in_event_mask = S(VGCS_EV_TALKER_EST) |
+ S(VGCS_EV_TALKER_DATA) |
+ S(VGCS_EV_MSC_DTAP) |
+ S(VGCS_EV_TALKER_REL) |
+ S(VGCS_EV_MSC_SEIZE) |
+ S(VGCS_EV_MSC_ACK) |
+ S(VGCS_EV_MSC_REJECT) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CALL_ST_IDLE) |
+ S(VGCS_CALL_ST_BLOCKED) |
+ S(VGCS_CALL_ST_NULL),
+ .action = vgcs_call_fsm_busy,
+ },
+ [VGCS_CALL_ST_BLOCKED] = {
+ .name = "BLOCKED",
+ .in_event_mask = S(VGCS_EV_CALLING_ASSIGNED) |
+ S(VGCS_EV_TALKER_REL) |
+ S(VGCS_EV_MSC_RELEASE) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CALL_ST_IDLE) |
+ S(VGCS_CALL_ST_BUSY) |
+ S(VGCS_CALL_ST_NULL),
+ .action = vgcs_call_fsm_blocked,
+ },
+};
+
+static struct osmo_fsm vgcs_call_fsm = {
+ .name = "vgcs_call_fsm",
+ .states = vgcs_call_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_call_fsm_states),
+ .log_subsys = DASCI,
+ .event_names = vgcs_fsm_event_names,
+ .cleanup = vgcs_call_detach_and_destroy,
+};
+
+/* Handle VGCS/VBS SETUP message.
+ *
+ * See 3GPP TS 48.008 §3.2.1.50
+ */
+int vgcs_vbs_call_start(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+ int payload_length = msg->tail - msg->l4h;
+ struct tlv_parsed tp;
+ struct gsm_subscriber_connection *c;
+ struct gsm0808_group_callref *gc = &conn->vgcs_call.gc_ie;
+ int rc;
+ uint8_t cause;
+
+ if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, payload_length - 1) < 0) {
+ LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__);
+ cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS;
+ goto reject;
+ }
+
+ /* Check for mandatory Group Call Reference. */
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) {
+ LOGP(DASCI, LOGL_ERROR, "Mandatory group call reference not present.\n");
+ cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
+ goto reject;
+ }
+
+ /* 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(DASCI, LOGL_ERROR, "Unable to decode group call reference.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ conn->vgcs_call.sf = gc->sf;
+ conn->vgcs_call.call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo;
+
+ /* Check for duplicated callref. */
+ llist_for_each_entry(c, &conn->network->subscr_conns, entry) {
+ if (!c->vgcs_call.fi)
+ continue;
+ if (c == conn)
+ continue;
+ if (conn->vgcs_call.sf == c->vgcs_call.sf
+ && conn->vgcs_call.call_ref == c->vgcs_call.call_ref) {
+ LOGP(DASCI, LOGL_ERROR, "A %s call with callref %s already exists.\n",
+ (conn->vgcs_call.sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS",
+ gsm44068_group_id_string(conn->vgcs_call.call_ref));
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ }
+
+ /* Decode VGCS Feature Flags */
+ if (TLVP_PRESENT(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS)) {
+ rc = gsm0808_dec_vgcs_feature_flags(&conn->vgcs_call.ff,
+ TLVP_VAL(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS),
+ TLVP_LEN(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS));
+ if (rc < 0) {
+ LOGP(DASCI, LOGL_ERROR, "Unable to decode feature flags.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ conn->vgcs_call.ff_present = true;
+ }
+
+ /* Create VGCS FSM. */
+ conn->vgcs_call.fi = osmo_fsm_inst_alloc(&vgcs_call_fsm, conn->network, conn, LOGL_DEBUG, NULL);
+ if (!conn->vgcs_call.fi)
+ goto reject;
+
+ /* Init list of cells that are used by the call. */
+ INIT_LLIST_HEAD(&conn->vgcs_call.chan_list);
+
+ /* Init L3 queue. */
+ INIT_LLIST_HEAD(&conn->vgcs_call.l3_queue);
+
+ osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_SETUP, NULL);
+ return 0;
+reject:
+ tx_setup_refuse(conn, cause);
+ return -EINVAL;
+}
+
+/*
+ * VGCS chan FSM
+ */
+
+static void vgcs_chan_detach_and_destroy(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+
+ if (conn->vgcs_chan.fi->state != VGCS_CHAN_ST_WAIT_EST) {
+ /* Remove call from notification channel. */
+ if (conn->lchan)
+ rsl_notification_cmd(conn->lchan->ts->trx->bts, NULL, &conn->vgcs_chan.gc_ie, NULL);
+ else
+ LOGP(DASCI, LOGL_ERROR, "Unable to remove notification, lchan is already gone.\n");
+ }
+
+ /* Detach from call, if not already. */
+ if (conn->vgcs_chan.call) {
+ llist_del(&conn->vgcs_chan.list);
+ conn->vgcs_chan.call = NULL;
+ }
+
+ /* Remove pointer of FSM. */
+ conn->vgcs_chan.fi = NULL;
+}
+
+static void uplink_released(struct gsm_subscriber_connection *conn)
+{
+ LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n");
+ /* Go into blocked or free state. */
+ if (conn->vgcs_chan.call && conn->vgcs_chan.call->vgcs_call.fi
+ && conn->vgcs_chan.call->vgcs_call.fi->state == VGCS_CALL_ST_IDLE)
+ osmo_fsm_inst_state_chg(conn->vgcs_chan.fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ else
+ osmo_fsm_inst_state_chg(conn->vgcs_chan.fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0);
+}
+
+static void vgcs_chan_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+ struct lchan_activate_info info;
+
+ switch (event) {
+ case VGCS_EV_ASSIGN_REQ:
+ LOG_CHAN(conn, LOGL_DEBUG, "MSC assigns channel.\n");
+ /* MSC requests channel assignment. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_WAIT_EST, 0, 0);
+ /* Requesting channel from BTS. */
+ info = (struct lchan_activate_info){
+ .activ_for = ACTIVATE_FOR_VGCS_CHANNEL,
+ .for_conn = conn,
+ .chreq_reason = GSM_CHREQ_REASON_OTHER,
+ .ch_mode_rate = conn->vgcs_chan.ch_mode_rate,
+ .ch_indctr = conn->vgcs_chan.ct.ch_indctr,
+ /* TSC is used from TS config. */
+ .encr = conn->vgcs_chan.new_lchan->encr,
+ /* Timing advance of 0 is used until channel is activated for uplink. */
+ .ta_known = true,
+ .ta = 0,
+ };
+ if (conn->vgcs_chan.call->vgcs_call.sf == GSM0808_SF_VGCS)
+ info.vgcs = 1;
+ else
+ info.vbs = 1;
+ /* Activate lchan. If an error occurs, this the function call may trigger VGCS_EV_LCHAN_ERROR event.
+ * This means that this must be the last action in this handler. */
+ lchan_activate(conn->vgcs_chan.new_lchan, &info);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_wait_est(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+ const struct mgcp_conn_peer *mgw_info;
+
+ switch (event) {
+ case VGCS_EV_LCHAN_ACTIVE:
+ LOG_CHAN(conn, LOGL_DEBUG, "lchan is active.\n");
+ /* If no MGW is used. */
+ if (!gscon_is_aoip(conn)) {
+ LOG_CHAN(conn, LOGL_DEBUG, "Not connecting MGW endpoint, no AoIP connection.\n");
+ goto no_aoip;
+ }
+ /* Send activation to MGW. */
+ LOG_CHAN(conn, LOGL_DEBUG, "Connecting MGW endpoint to the MSC's RTP port: %s:%u\n",
+ conn->vgcs_chan.msc_rtp_addr, conn->vgcs_chan.msc_rtp_port);
+ /* Connect MGW. The function call may trigger VGCS_EV_MGW_OK event.
+ * This means that this must be the last action in this handler.
+ * If this function fails, VGCS_EV_MGW_FAIL will not trigger. */
+ if (!gscon_connect_mgw_to_msc(conn,
+ conn->vgcs_chan.new_lchan,
+ conn->vgcs_chan.msc_rtp_addr,
+ conn->vgcs_chan.msc_rtp_port,
+ fi,
+ VGCS_EV_MGW_OK,
+ VGCS_EV_MGW_FAIL,
+ NULL,
+ NULL)) {
+ /* Report failure to MSC. */
+ tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
+ break;
+ }
+ break;
+ case VGCS_EV_LCHAN_ERROR:
+ LOG_CHAN(conn, LOGL_DEBUG, "lchan failed.\n");
+ /* BTS reports failure on channel request. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_NULL, 0, 0);
+ /* Report failure to MSC. */
+ tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
+ break;
+ case VGCS_EV_MGW_OK:
+ LOG_CHAN(conn, LOGL_DEBUG, "MGW endpoint connected.\n");
+ /* MGW reports success. */
+ mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc);
+ if (!mgw_info) {
+ LOG_CHAN(conn, LOGL_ERROR, "Unable to retrieve RTP port info allocated by MGW for"
+ " the MSC side.");
+ /* Report failure to MSC. */
+ tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
+ break;
+ }
+ LOG_CHAN(conn, LOGL_DEBUG, "MGW's MSC side CI: %s:%u\n", mgw_info->addr, mgw_info->port);
+ no_aoip:
+ /* Channel established from BTS. */
+ gscon_change_primary_lchan(conn, conn->vgcs_chan.new_lchan);
+ /* Change state according to call state. */
+ if (conn->vgcs_chan.call && conn->vgcs_chan.call->vgcs_call.fi
+ && conn->vgcs_chan.call->vgcs_call.fi->state == VGCS_CALL_ST_IDLE)
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ else
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0);
+ /* Add call to notification channel. */
+ if (conn->vgcs_chan.call)
+ rsl_notification_cmd(conn->lchan->ts->trx->bts, conn->lchan, &conn->vgcs_chan.gc_ie, NULL);
+ /* Report result to MSC. */
+ tx_vgcs_vbs_assignment_result(conn, &conn->vgcs_chan.ct, &conn->vgcs_chan.ci, conn->vgcs_chan.call_id);
+ break;
+ case VGCS_EV_MGW_FAIL:
+ LOG_CHAN(conn, LOGL_DEBUG, "MGW endpoint failed.\n");
+ /* MGW reports failure. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_NULL, 0, 0);
+ /* Report failure to MSC. */
+ tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ case VGCS_EV_BLOCK:
+ case VGCS_EV_UNBLOCK:
+ /* Ignore, because channel is not yet ready. */
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_active_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv, *cc;
+
+ switch (event) {
+ case VGCS_EV_UNBLOCK:
+ LOG_CHAN(conn, LOGL_DEBUG, "Unblocking channel.\n");
+ /* No uplink is used in other cell. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ break;
+ case VGCS_EV_TALKER_DET:
+ LOG_CHAN(conn, LOGL_DEBUG, "Talker detected on blocked channel.\n");
+ if (conn->vgcs_chan.call->vgcs_call.sf == GSM0808_SF_VBS)
+ LOG_CHAN(conn, LOGL_ERROR, "Talker detection not allowed on VBS channel.\n");
+ /* Race condition: BTS detected a talker. Waiting for talker to establish or fail. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0);
+ break;
+ case VGCS_EV_TALKER_EST:
+ cc = find_calling_subscr_conn(conn);
+ if (!cc) {
+ LOG_CHAN(conn, LOGL_ERROR, "No assignment requested from MSC!\n");
+ /* Uplink is used while blocked. Waiting for channel to be release. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0);
+ /* Send UPLINK RELEASE to MS. */
+ gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL);
+ /* Go into blocked or free state. */
+ uplink_released(conn);
+ break;
+ }
+ /* Talker is assigning to this channel. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_EST, 0, 0);
+ /* Report talker detection to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_CALLING_ASSIGNED, conn);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_enter_active_free(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+
+ /* Send UPLINK FREE message to BTS. This hits on every state change (and or timer start). */
+ LOG_CHAN(conn, LOGL_DEBUG, "Sending UPLINK FREE message to channel.\n");
+ gsm48_send_uplink_free(conn->lchan, 0, NULL);
+}
+
+static void vgcs_chan_fsm_active_free(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+
+ switch (event) {
+ case VGCS_EV_BLOCK:
+ LOG_CHAN(conn, LOGL_DEBUG, "Blocking channel.\n");
+ /* Uplink is used in other cell. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0);
+ /* Send UPLINK BUSY to MS. */
+ LOG_CHAN(conn, LOGL_DEBUG, "Sending UPLINK BUSY message to channel.\n");
+ gsm48_send_uplink_busy(conn->lchan);
+ break;
+ case VGCS_EV_TALKER_DET:
+ LOG_CHAN(conn, LOGL_DEBUG, "Talker detected on free channel.\n");
+ /* BTS detected a talker. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_INIT, 0, 0);
+ /* Report talker detection to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_DET, data);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_active_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+ uint8_t cause = (data) ? *(uint8_t *)data : 0;
+
+ switch (event) {
+ case VGCS_EV_BLOCK:
+ case VGCS_EV_REJECT:
+ LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n");
+ /* Uplink is used in other cell. Waiting for channel to be established and then released. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0);
+ break;
+ case VGCS_EV_TALKER_EST:
+ LOG_CHAN(conn, LOGL_DEBUG, "Talker established uplink.\n");
+ /* Uplink has been established */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_EST, 0, 0);
+ /* Send UPLINK BUSY to MS. */
+ LOG_CHAN(conn, LOGL_DEBUG, "Sending UPLINK BUSY message to channel.\n");
+ gsm48_send_uplink_busy(conn->lchan);
+ /* Report talker establishment to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_EST, data);
+ break;
+ case VGCS_EV_TALKER_FAIL:
+ LOG_CHAN(conn, LOGL_NOTICE, "Uplink failed, establishment timeout.\n");
+ /* Release datalink */
+ rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END);
+ /* fall thru */
+ case VGCS_EV_TALKER_REL:
+ LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n");
+ /* Uplink establishment failed. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ /* Report release indication to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL, &cause);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_active_est(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+ uint8_t cause = (data) ? *(uint8_t *)data : 0;
+ struct msgb *msg = data;
+
+ switch (event) {
+ case VGCS_EV_BLOCK:
+ case VGCS_EV_REJECT:
+ LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n");
+ /* Uplink is used in other cell. Waiting for channel to be release. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0);
+ /* Send UPLINK RELEASE to MS. */
+ gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL);
+ /* Go into blocked or free state. */
+ uplink_released(conn);
+ break;
+ case VGCS_EV_TALKER_DATA:
+ LOG_CHAN(conn, LOGL_DEBUG, "Talker sends data on uplink.\n");
+ if (msg) {
+ struct gsm48_hdr *gh;
+ uint8_t pdisc;
+ uint8_t msg_type;
+ if (msgb_l3len(msg) < sizeof(*gh)) {
+ LOG_LCHAN(msg->lchan, LOGL_ERROR,
+ "Message too short for a GSM48 header (%u)\n", msgb_l3len(msg));
+ break;
+ }
+ gh = msgb_l3(msg);
+ pdisc = gsm48_hdr_pdisc(gh);
+ msg_type = gsm48_hdr_msg_type(gh);
+ if (pdisc == GSM48_PDISC_RR && msg_type == GSM48_MT_RR_UPLINK_RELEASE) {
+ LOG_CHAN(conn, LOGL_DEBUG, "Uplink is released by UPLINK RELEASE message.\n");
+ /* Release datalink */
+ rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END);
+ /* Talker released the uplink. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ /* Report talker release to call state machine. */
+ if (conn->vgcs_chan.call) {
+ cause = GSM0808_CAUSE_CALL_CONTROL;
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL,
+ &cause);
+ }
+ break;
+ }
+ if (pdisc == GSM48_PDISC_RR && msg_type == GSM48_MT_RR_ASS_COMPL) {
+ LOG_CHAN(conn, LOGL_DEBUG, "Asssignment complete.\n");
+ struct gsm_subscriber_connection *cc;
+ cc = find_calling_subscr_conn(conn);
+ if (!cc) {
+ LOG_CHAN(conn, LOGL_ERROR, "No assignment requested from MSC!\n");
+ break;
+ }
+ LOG_CHAN(conn, LOGL_DEBUG, "Trigger State machine.\n");
+ osmo_fsm_inst_dispatch(cc->assignment.fi, ASSIGNMENT_EV_RR_ASSIGNMENT_COMPLETE, msg);
+ break;
+ }
+ }
+ /* Report talker data to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_DATA, data);
+ break;
+ case VGCS_EV_MSC_DTAP:
+ LOG_CHAN(conn, LOGL_DEBUG, "MSC sends DTAP message to talker.\n");
+ osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, data);
+ break;
+ case VGCS_EV_TALKER_FAIL:
+ LOG_CHAN(conn, LOGL_NOTICE, "Uplink failed after establishment.\n");
+ /* Release datalink */
+ rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END);
+ /* fall thru */
+ case VGCS_EV_TALKER_REL:
+ LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n");
+ /* Talker released the uplink. */
+ osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0);
+ /* Report talker release to call state machine. */
+ if (conn->vgcs_chan.call)
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL, &cause);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static void vgcs_chan_fsm_active_rel(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_subscriber_connection *conn = fi->priv;
+
+ switch (event) {
+ case VGCS_EV_BLOCK:
+ case VGCS_EV_REJECT:
+ LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n");
+ /* Race condition: Uplink is used in other cell, we are already releasing. */
+ break;
+ case VGCS_EV_TALKER_EST:
+ LOG_CHAN(conn, LOGL_DEBUG, "Talker established uplink, releasing.\n");
+ /* Finally the talker established the connection. Send UPLINK RELEASE to MS. */
+ gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL);
+ /* Release datalink */
+ rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END);
+ /* fall thru */
+ case VGCS_EV_TALKER_FAIL:
+ /* Release datalink */
+ rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END);
+ /* fall thru */
+ case VGCS_EV_TALKER_REL:
+ /* Go into blocked or free state. */
+ uplink_released(conn);
+ break;
+ case VGCS_EV_CLEANUP:
+ LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n");
+ /* MSC wants to terminate. */
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ break;
+ default:
+ OSMO_ASSERT(false);
+ }
+}
+
+static const struct osmo_fsm_state vgcs_chan_fsm_states[] = {
+ [VGCS_CHAN_ST_NULL] = {
+ .name = "NULL",
+ .in_event_mask = S(VGCS_EV_ASSIGN_REQ),
+ .out_state_mask = S(VGCS_CHAN_ST_WAIT_EST),
+ .action = vgcs_chan_fsm_null,
+ },
+ [VGCS_CHAN_ST_WAIT_EST] = {
+ .name = "WAIT_EST",
+ .in_event_mask = S(VGCS_EV_LCHAN_ACTIVE) |
+ S(VGCS_EV_LCHAN_ERROR) |
+ S(VGCS_EV_MGW_OK) |
+ S(VGCS_EV_MGW_FAIL) |
+ S(VGCS_EV_CLEANUP) |
+ S(VGCS_EV_BLOCK) |
+ S(VGCS_EV_UNBLOCK),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_BLOCKED) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE),
+ .action = vgcs_chan_fsm_wait_est,
+ },
+ [VGCS_CHAN_ST_ACTIVE_BLOCKED] = {
+ .name = "ACTIVE/BLOCKED",
+ .in_event_mask = S(VGCS_EV_UNBLOCK) |
+ S(VGCS_EV_TALKER_DET) |
+ S(VGCS_EV_TALKER_EST) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_EST) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE) |
+ S(VGCS_CHAN_ST_ACTIVE_REL),
+ .action = vgcs_chan_fsm_active_blocked,
+ },
+ [VGCS_CHAN_ST_ACTIVE_FREE] = {
+ .name = "ACTIVE/FREE",
+ .in_event_mask = S(VGCS_EV_BLOCK) |
+ S(VGCS_EV_TALKER_DET) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_BLOCKED) |
+ S(VGCS_CHAN_ST_ACTIVE_INIT) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE),
+ .action = vgcs_chan_fsm_active_free,
+ .onenter = vgcs_chan_fsm_enter_active_free,
+ },
+ [VGCS_CHAN_ST_ACTIVE_INIT] = {
+ .name = "ACTIVE/INIT",
+ .in_event_mask = S(VGCS_EV_BLOCK) |
+ S(VGCS_EV_REJECT) |
+ S(VGCS_EV_TALKER_EST) |
+ S(VGCS_EV_TALKER_FAIL) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_EST) |
+ S(VGCS_CHAN_ST_ACTIVE_REL) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE),
+ .action = vgcs_chan_fsm_active_init,
+ },
+ [VGCS_CHAN_ST_ACTIVE_EST] = {
+ .name = "ACTIVE/ESTABLISHED",
+ .in_event_mask = S(VGCS_EV_BLOCK) |
+ S(VGCS_EV_REJECT) |
+ S(VGCS_EV_TALKER_DATA) |
+ S(VGCS_EV_MSC_DTAP) |
+ S(VGCS_EV_TALKER_REL) |
+ S(VGCS_EV_TALKER_FAIL) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE) |
+ S(VGCS_CHAN_ST_ACTIVE_REL),
+ .action = vgcs_chan_fsm_active_est,
+ },
+ [VGCS_CHAN_ST_ACTIVE_REL] = {
+ .name = "ACTIVE/RELEASE",
+ .in_event_mask = S(VGCS_EV_BLOCK) |
+ S(VGCS_EV_REJECT) |
+ S(VGCS_EV_TALKER_EST) |
+ S(VGCS_EV_TALKER_REL) |
+ S(VGCS_EV_TALKER_FAIL) |
+ S(VGCS_EV_CLEANUP),
+ .out_state_mask = S(VGCS_CHAN_ST_NULL) |
+ S(VGCS_CHAN_ST_ACTIVE_BLOCKED) |
+ S(VGCS_CHAN_ST_ACTIVE_FREE),
+ .action = vgcs_chan_fsm_active_rel,
+ },
+};
+
+static struct osmo_fsm vgcs_chan_fsm = {
+ .name = "vgcs_chan_fsm",
+ .states = vgcs_chan_fsm_states,
+ .num_states = ARRAY_SIZE(vgcs_chan_fsm_states),
+ .log_subsys = DASCI,
+ .event_names = vgcs_fsm_event_names,
+ .cleanup = vgcs_chan_detach_and_destroy,
+};
+
+/* Handle VGCS/VBS ASSIGNMENT REQUEST message.
+ *
+ * See 3GPP TS 48.008 §3.2.1.53
+ */
+int vgcs_vbs_chan_start(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+ int payload_length = msg->tail - msg->l4h;
+ struct tlv_parsed tp;
+ struct gsm_subscriber_connection *c;
+ struct gsm0808_group_callref *gc = &conn->vgcs_chan.gc_ie;
+ enum gsm0808_service_flag sf;
+ uint32_t call_ref;
+ struct assignment_request req = {
+ .aoip = gscon_is_aoip(conn),
+ };
+ uint8_t cause;
+ struct gsm_bts *bts;
+ struct gsm_lchan *lchan;
+ int rc;
+ int i;
+
+ if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, payload_length - 1) < 0) {
+ LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__);
+ cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS;
+ goto reject;
+ }
+
+ /* Check for mandatory IEs. */
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE)
+ || !TLVP_PRESENT(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT)
+ || !TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER)
+ || !TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) {
+ LOGP(DASCI, LOGL_ERROR, "Mandatory IE not present.\n");
+ cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING;
+ goto reject;
+ }
+
+ /* Decode Channel Type element. */
+ rc = gsm0808_dec_channel_type(&conn->vgcs_chan.ct, TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE),
+ TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE));
+ if (rc < 0) {
+ LOGP(DASCI, LOGL_ERROR, "Unable to decode Channel Type.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+
+ /* Only speech is supported. */
+ if (conn->vgcs_chan.ct.ch_indctr != GSM0808_CHAN_SPEECH) {
+ cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS;
+ goto reject;
+ }
+
+ /* Decode Assignment Requirement element. */
+ rc = gsm0808_dec_assign_req(&conn->vgcs_chan.ar, TLVP_VAL(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT),
+ TLVP_LEN(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT));
+ if (rc < 0) {
+ LOGP(DASCI, LOGL_ERROR, "Unable to decode Assignment Requirement.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+
+ /* Decode Cell Identifier element. */
+ rc = gsm0808_dec_cell_id(&conn->vgcs_chan.ci, TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER),
+ TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER));
+ if (rc < 0) {
+ LOGP(DASCI, LOGL_ERROR, "Unable to decode Cell Identifier.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+
+ /* Decode Group Call Reference element. */
+ 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(DASCI, LOGL_ERROR, "Unable to decode Group Call Reference.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ sf = gc->sf;
+ call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo;
+
+ /* Find BTS from Cell Identity. */
+ bts = gsm_bts_by_cell_id(conn->network, &conn->vgcs_chan.ci, 0);
+ if (!bts) {
+ LOGP(DASCI, LOGL_ERROR, "No cell found that matches the given Cell Identifier.\n");
+ cause = GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE;
+ goto reject;
+ }
+
+ /* If Cell Identity is ambiguous. */
+ if (gsm_bts_by_cell_id(conn->network, &conn->vgcs_chan.ci, 1))
+ LOGP(DASCI, LOGL_NOTICE, "More thant one cell found that match the given Cell Identifier.\n");
+
+ /* Decode channel related elements.
+ * This must be done after selecting the BTS, because codec selection requires relation to BTS. */
+ rc = bssmap_handle_ass_req_ct_speech(conn, bts, &tp, &conn->vgcs_chan.ct, &req, &cause);
+ if (rc < 0)
+ goto reject;
+
+ /* Store AoIP elements. */
+ strcpy(conn->vgcs_chan.msc_rtp_addr, req.msc_rtp_addr);
+ conn->vgcs_chan.msc_rtp_port = req.msc_rtp_port;
+ if (TLVP_PRESENT(&tp, GSM0808_IE_CALL_ID)) {
+ /* Decode Call Identifier element. */
+ rc = gsm0808_dec_call_id(&conn->vgcs_chan.call_id, TLVP_VAL(&tp, GSM0808_IE_CALL_ID),
+ TLVP_LEN(&tp, GSM0808_IE_CALL_ID));
+ if (rc < 0) {
+ LOGP(DASCI, LOGL_ERROR, "Unable to decode Call Identifier.\n");
+ cause = GSM0808_CAUSE_INCORRECT_VALUE;
+ goto reject;
+ }
+ }
+
+ /* Try to allocate a new lchan in order of preference. */
+ for (i = 0; i < req.n_ch_mode_rate; i++) {
+ lchan = lchan_select_by_chan_mode(bts,
+ req.ch_mode_rate_list[i].chan_mode,
+ req.ch_mode_rate_list[i].chan_rate,
+ SELECT_FOR_VGCS, NULL);
+ if (!lchan)
+ continue;
+ LOGP(DASCI, LOGL_DEBUG, "Selected new lchan %s for mode[%d] = %s channel_rate=%d\n",
+ gsm_lchan_name(lchan), i, gsm48_chan_mode_name(req.ch_mode_rate_list[i].chan_mode),
+ req.ch_mode_rate_list[i].chan_rate);
+
+ conn->vgcs_chan.ch_mode_rate = req.ch_mode_rate_list[i];
+ break;
+ }
+ if (!lchan) {
+ LOGP(DASCI, LOGL_ERROR, "Requested lchan not available.\n");
+ cause = GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE;
+ goto reject;
+ }
+ conn->vgcs_chan.new_lchan = lchan;
+
+ /* Create VGCS FSM. */
+ conn->vgcs_chan.fi = osmo_fsm_inst_alloc(&vgcs_chan_fsm, conn->network, conn, LOGL_DEBUG, NULL);
+ if (!conn->vgcs_chan.fi)
+ goto reject;
+
+ /* Attach to call control instance, if a call with same callref exists. */
+ llist_for_each_entry(c, &conn->network->subscr_conns, entry) {
+ if (!c->vgcs_call.fi)
+ continue;
+ if (c->vgcs_call.sf == sf
+ && c->vgcs_call.call_ref == call_ref) {
+ llist_add_tail(&conn->vgcs_chan.list, &c->vgcs_call.chan_list);
+ conn->vgcs_chan.call = c;
+ break;
+ }
+ }
+ if (!conn->vgcs_chan.call) {
+ LOGP(DASCI, LOGL_ERROR, "A %s call with callref %s does not exist.\n",
+ (sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS", gsm44068_group_id_string(call_ref));
+ cause = GSM0808_CAUSE_VGCS_VBS_CALL_NON_EXISTENT;
+ osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL);
+ goto reject;
+ }
+
+ osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_ASSIGN_REQ, NULL);
+ return 0;
+reject:
+ tx_vgcs_vbs_assignment_fail(conn, cause);
+ return -EINVAL;
+}
+
+/* Return lchan of group call that exists in the same BTS. */
+struct gsm_lchan *vgcs_vbs_find_lchan(struct gsm_bts *bts, struct gsm0808_group_callref *gc)
+{
+ struct gsm_subscriber_connection *call = NULL, *c;
+ struct gsm_lchan *lchan = NULL;
+ uint32_t call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo;
+
+ /* Find group call. */
+ llist_for_each_entry(c, &bts->network->subscr_conns, entry) {
+ if (!c->vgcs_call.fi)
+ continue;
+ if (c->vgcs_call.sf == gc->sf
+ && c->vgcs_call.call_ref == call_ref) {
+ call = c;
+ break;
+ }
+ }
+ if (!call) {
+ LOGP(DASCI, LOGL_ERROR, "Cannot assign to VGCS channel, callref does not exist.\n");
+ return NULL;
+ }
+
+ /* Find channel in same BTS. */
+ llist_for_each_entry(c, &call->vgcs_call.chan_list, vgcs_chan.list) {
+ if (c->lchan && c->lchan->ts->trx->bts == bts)
+ lchan = c->lchan;
+ }
+ if (!call) {
+ LOGP(DASCI, LOGL_ERROR, "Cannot assign to VGCS channel, caller's BTS has no VGCS channel.\n");
+ return NULL;
+ }
+
+ return lchan;
+}
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33611
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Id9e94fb4f27bb438b7093c031344a3400bfa34f1
Gerrit-Change-Number: 33611
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33618 )
Change subject: ASCI: Add assignment to a VGCS/VBS channel
......................................................................
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
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/assignment_fsm.c
M src/osmo-bsc/osmo_bsc_bssap.c
4 files changed, 70 insertions(+), 4 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/18/33618/1
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index a434df1..056425c 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -142,6 +142,7 @@
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 5edcd8b..26b8f68 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1652,6 +1652,10 @@
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 27180ef..fbc5607 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -260,9 +260,11 @@
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);
@@ -568,7 +570,10 @@
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
@@ -642,7 +647,9 @@
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 c415ede..ad53f42 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -1091,6 +1091,7 @@
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 = {};
@@ -1122,6 +1123,40 @@
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
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33618
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Idaa864cd5ce4df6c3193494ce12d91523c104d89
Gerrit-Change-Number: 33618
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[M] Change in osmo-bsc[master]: ASCI: Add new rate counters to support VGCS/VBS messages
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33596 )
Change subject: ASCI: Add new rate counters to support VGCS/VBS messages
......................................................................
ASCI: Add new rate counters to support VGCS/VBS messages
Change-Id: I18e4ca3599e480de2d0f64cc1b6f4bb6ce8020d4
Related: OS#4852
---
M include/osmocom/bsc/bsc_msc_data.h
M src/osmo-bsc/osmo_bsc_msc.c
2 files changed, 110 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/96/33596/1
diff --git a/include/osmocom/bsc/bsc_msc_data.h b/include/osmocom/bsc/bsc_msc_data.h
index 47bdf12..8454cca 100644
--- a/include/osmocom/bsc/bsc_msc_data.h
+++ b/include/osmocom/bsc/bsc_msc_data.h
@@ -71,6 +71,15 @@
MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR,
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST,
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT,
+ MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP,
+ MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST,
+ MSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE,
+ MSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD,
+ MSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD,
+ MSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD,
+ MSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO,
+ MSC_CTR_BSSMAP_RX_DT1_VGCS_SMS,
+ MSC_CTR_BSSMAP_RX_DT1_NOTIFICATION_DATA,
/* Tx message counters (per connection type) */
MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT,
@@ -102,6 +111,17 @@
MSC_CTR_BSSMAP_TX_DT1_DTAP,
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS,
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_QUEUING_INDICATION,
+ MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGNMENT_STATUS,
+ MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_AREA_CELL_INFO,
+ MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION,
+ MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION,
+ MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA,
MSC_CTR_MSCPOOL_SUBSCR_NEW,
MSC_CTR_MSCPOOL_SUBSCR_REATTACH,
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index 08a2466..2aeb5ca 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -66,6 +66,42 @@
[MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR] = {"bssmap:rx:dt1:dtap:error", "Number of received BSSMAP DTAP messages with errors"},
[MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST] = {"bssmap:rx:dt1:location:request", "Number of received BSSMAP Perform Location Request messages"},
[MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT] = {"bssmap:tx:dt1:location:abort", "Number of received BSSMAP Perform Location Abort messages"},
+ [MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP] = {
+ "bssmap:rx:dt1:vgcs_vbs_setup",
+ "Number of received BSSMAP DT1 VGCS/VBS SETUP messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST] = {
+ "bssmap:rx:dt1:vgcs_vbs_assignment:req",
+ "Number of received BSSMAP DT1 VGCS/VBS ASSIGNMENT messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE] = {
+ "bssmap:rx:dt1:uplink_rqst:ack",
+ "Number of received BSSMAP DT1 UPLINK REQUEST ACKNOWLEDGE messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD] = {
+ "bssmap:rx:dt1:uplink_reject:cmd",
+ "Number of received BSSMAP DT1 UPLINK REJECT COMMAND messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD] = {
+ "bssmap:rx:dt1:uplink_release:cmd",
+ "Number of received BSSMAP DT1 UPLINK RELEASE COMMAND messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD] = {
+ "bssmap:rx:dt1:uplink_seized:cmd",
+ "Number of received BSSMAP DT1 UPLINK SEIZED COMMAND messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO] = {
+ "bssmap:rx:dt1:vgcs_addl_info",
+ "Number of received BSSMAP DT1 VGCS/VBS ASSITIONAL INFORMATION messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_VGCS_SMS] = {
+ "bssmap:rx:dt1:vgcs_sms",
+ "Number of received BSSMAP DT1 VGCS SMS messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_NOTIFICATION_DATA] = {
+ "bssmap:rx:dt1:notification_data",
+ "Number of received BSSMAP DT1 NOTIFICATION DATA messages"
+ },
/* Tx message counters (per message type)
*
@@ -110,6 +146,50 @@
"Number of transmitted BSSMAP Perform Location Response messages containing a location estimate"},
[MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE] = {"bssmap:tx:dt1:location:response_failure",
"Number of transmitted BSSMAP Perform Location Response messages containing a failure cause"},
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK] = {
+ "bssmap:tx:dt1:vgcs_vbs_setup:ack",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS SETUP ACK messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE] = {
+ "bssmap:tx:dt1:vgcs_vbs_setup:refuse",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS SETUP REFUSE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT] = {
+ "bssmap:tx:dt1:vgcs_vbs_assignment:res",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT RESULT messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL] = {
+ "bssmap:tx:dt1:vgcs_vbs_assignment:fail",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT FAILURE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_QUEUING_INDICATION] = {
+ "bssmap:tx:dt1:vgcs_vbs_queuing:ind",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS QUEUING INDICATION messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST] = {
+ "bssmap:tx:dt1:uplink_rqst",
+ "Number of transmitted BSSMAP DT1 UPLINK REQUEST messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGNMENT_STATUS] = {
+ "bssmap:tx:dt1:vgcs_vbs_assignment:status",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT STATUS messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_AREA_CELL_INFO] = {
+ "bssmap:tx:dt1:vgcs_vbs_area_cell:info",
+ "Number of transmitted BSSMAP DT1 VGCS/VBS AREA CELL INFO messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION] = {
+ "bssmap:tx:dt1:uplink_rqst:cnf",
+ "Number of transmitted BSSMAP DT1 UPLINK REQUEST CONFIRMATION messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION] = {
+ "bssmap:tx:dt1:uplink_release:ind",
+ "Number of transmitted BSSMAP DT1 UPLINK RELEASE INDICATION messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA] = {
+ "bssmap:tx:dt1:uplink_app_data",
+ "Number of transmitted BSSMAP DT1 UPLINK APPLICATION DATA messages"
+ },
/* Indicators for MSC pool usage */
[MSC_CTR_MSCPOOL_SUBSCR_NEW] = {
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33596
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I18e4ca3599e480de2d0f64cc1b6f4bb6ce8020d4
Gerrit-Change-Number: 33596
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[M] Change in osmo-bsc[master]: ASCI: Add support for NOTIFICATION COMMAND (RSL) message
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33598 )
Change subject: ASCI: Add support for NOTIFICATION COMMAND (RSL) message
......................................................................
ASCI: Add support for NOTIFICATION COMMAND (RSL) message
This message will be sent to each BTS with a VGCS/VBS channel to notify
the served MSs about ongoing group/broadcast calls. It is also used to
remove the notification, if the call is terminated.
Change-Id: I96ec0ee5d1a772a45f1ebfd64210718c8bf5aa58
Related: OS#4852
---
M include/osmocom/bsc/abis_rsl.h
M src/osmo-bsc/abis_rsl.c
2 files changed, 54 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/98/33598/1
diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h
index 06880bf..83e8f7d 100644
--- a/include/osmocom/bsc/abis_rsl.h
+++ b/include/osmocom/bsc/abis_rsl.h
@@ -55,6 +55,7 @@
int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group,
const struct osmo_mobile_identity *mi,
uint8_t chan_needed, bool is_gprs);
+int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx);
int rsl_imm_assign_cmd(const struct gsm_bts *bts, uint8_t len, const uint8_t *val);
int rsl_tx_imm_assignment(struct gsm_lchan *lchan);
int rsl_tx_imm_ass_rej(struct gsm_bts *bts, struct gsm48_req_ref *rqd_ref);
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 54357de..8abb675 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -870,6 +870,45 @@
return abis_rsl_sendmsg(msg);
}
+/* Chapter 8.5.10: NOTIFICATION COMMAND */
+int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx)
+{
+ struct abis_rsl_cchan_hdr *cch;
+ struct msgb *msg = rsl_msgb_alloc();
+ struct gsm48_chan_desc cd;
+ uint8_t sti = (lchan) ? RSL_CMD_INDICATOR_START : RSL_CMD_INDICATOR_STOP;
+ uint8_t *t;
+ int rc;
+
+ cch = (struct abis_rsl_cchan_hdr *) msgb_put(msg, sizeof(*cch));
+ rsl_init_cchan_hdr(cch, RSL_MT_NOT_CMD);
+ cch->chan_nr = RSL_CHAN_PCH_AGCH;
+
+ msgb_tlv_put(msg, RSL_IE_CMD_INDICATOR, 1, &sti);
+
+ /* Use TLV encoding from TS 08.08. Change different IE type. */
+ t = msg->tail;
+ gsm0808_enc_group_callref(msg, gc);
+ *t = RSL_IE_GROUP_CALL_REF;
+
+ if (lchan) {
+ memset(&cd, 0, sizeof(cd));
+ rc = gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc, true);
+ if (rc) {
+ LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
+ msgb_free(msg);
+ return rc;
+ }
+ msgb_tlv_put(msg, RSL_IE_CHAN_DESC, sizeof(cd), (const uint8_t *)&cd);
+
+ if (drx)
+ msgb_tlv_put(msg, RSL_IE_NCH_DRX_INFO, 1, drx);
+ }
+
+ msg->dst = bts->c0->rsl_link_primary;
+ return abis_rsl_sendmsg(msg);
+}
+
int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uint8_t l3_info_len)
{
struct msgb *msg;
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33598
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I96ec0ee5d1a772a45f1ebfd64210718c8bf5aa58
Gerrit-Change-Number: 33598
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0
[M] Change in osmo-bsc[master]: Cleanup code style of rate counters in osmo_bsc_msc.c
by jolly 06 Jul '23
by jolly 06 Jul '23
06 Jul '23
jolly has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/33597 )
Change subject: Cleanup code style of rate counters in osmo_bsc_msc.c
......................................................................
Cleanup code style of rate counters in osmo_bsc_msc.c
Change-Id: I7cfd4f20ebfee0c8df9305372977d6628d6337c5
---
M src/osmo-bsc/osmo_bsc_msc.c
1 file changed, 189 insertions(+), 47 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/97/33597/1
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index 2aeb5ca..c3faf86 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -48,24 +48,78 @@
static const struct rate_ctr_desc msc_ctr_description[] = {
/* Rx message counters (per specific message) */
- [MSC_CTR_BSSMAP_RX_UDT_RESET_ACKNOWLEDGE] = {"bssmap:rx:udt:reset:ack", "Number of received BSSMAP UDT RESET ACKNOWLEDGE messages"},
- [MSC_CTR_BSSMAP_RX_UDT_RESET] = {"bssmap:rx:udt:reset:request", "Number of received BSSMAP UDT RESET messages"},
- [MSC_CTR_BSSMAP_RX_UDT_PAGING] = {"bssmap:rx:udt:paging", "Number of received BSSMAP UDT PAGING messages"},
- [MSC_CTR_BSSMAP_RX_UDT_UNKNOWN] = {"bssmap:rx:udt:err_unknown", "Number of received BSSMAP unknown UDT messages"},
- [MSC_CTR_BSSMAP_RX_DT1_CLEAR_CMD] = {"bssmap:rx:dt1:clear:cmd", "Number of received BSSMAP DT1 CLEAR CMD messages"},
- [MSC_CTR_BSSMAP_RX_DT1_CIPHER_MODE_CMD] = {"bssmap:rx:dt1:cipher_mode:cmd", "Number of received BSSMAP DT1 CIPHER MODE CMD messages"},
- [MSC_CTR_BSSMAP_RX_DT1_ASSIGNMENT_RQST] = {"bssmap:rx:dt1:assignment:rqst", "Number of received BSSMAP DT1 ASSIGNMENT RQST messages"},
- [MSC_CTR_BSSMAP_RX_DT1_LCLS_CONNECT_CTRL] = {"bssmap:rx:dt1:lcls_connect_ctrl:cmd", "Number of received BSSMAP DT1 LCLS CONNECT CTRL messages"},
- [MSC_CTR_BSSMAP_RX_DT1_HANDOVER_RQST] = {"bssmap:rx:dt1:handover:rqst", "Number of received BSSMAP DT1 HANDOVER RQST messages"},
- [MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD] = {"bssmap:rx:dt1:handover:cmd", "Number of received BSSMAP DT1 HANDOVER CMD messages"},
- [MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST] = {"bssmap:rx:dt1:classmark:rqst", "Number of received BSSMAP DT1 CLASSMARK RQST messages"},
- [MSC_CTR_BSSMAP_RX_DT1_CONFUSION] = {"bssmap:rx:dt1:confusion", "Number of received BSSMAP DT1 CONFUSION messages"},
- [MSC_CTR_BSSMAP_RX_DT1_COMMON_ID] = {"bssmap:rx:dt1:common_id", "Number of received BSSMAP DT1 COMMON ID messages"},
- [MSC_CTR_BSSMAP_RX_DT1_UNKNOWN] = {"bssmap:rx:dt1:err_unknown", "Number of received BSSMAP unknown DT1 messages"},
- [MSC_CTR_BSSMAP_RX_DT1_DTAP] = {"bssmap:rx:dt1:dtap:good", "Number of received BSSMAP DTAP messages"},
- [MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR] = {"bssmap:rx:dt1:dtap:error", "Number of received BSSMAP DTAP messages with errors"},
- [MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST] = {"bssmap:rx:dt1:location:request", "Number of received BSSMAP Perform Location Request messages"},
- [MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT] = {"bssmap:tx:dt1:location:abort", "Number of received BSSMAP Perform Location Abort messages"},
+ [MSC_CTR_BSSMAP_RX_UDT_RESET_ACKNOWLEDGE] = {
+ "bssmap:rx:udt:reset:ack",
+ "Number of received BSSMAP UDT RESET ACKNOWLEDGE messages"
+ },
+ [MSC_CTR_BSSMAP_RX_UDT_RESET] = {
+ "bssmap:rx:udt:reset:request",
+ "Number of received BSSMAP UDT RESET messages"
+ },
+ [MSC_CTR_BSSMAP_RX_UDT_PAGING] = {
+ "bssmap:rx:udt:paging",
+ "Number of received BSSMAP UDT PAGING messages"
+ },
+ [MSC_CTR_BSSMAP_RX_UDT_UNKNOWN] = {
+ "bssmap:rx:udt:err_unknown",
+ "Number of received BSSMAP unknown UDT messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_CLEAR_CMD] = {
+ "bssmap:rx:dt1:clear:cmd",
+ "Number of received BSSMAP DT1 CLEAR CMD messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_CIPHER_MODE_CMD] = {
+ "bssmap:rx:dt1:cipher_mode:cmd",
+ "Number of received BSSMAP DT1 CIPHER MODE CMD messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_ASSIGNMENT_RQST] = {
+ "bssmap:rx:dt1:assignment:rqst",
+ "Number of received BSSMAP DT1 ASSIGNMENT RQST messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_LCLS_CONNECT_CTRL] = {
+ "bssmap:rx:dt1:lcls_connect_ctrl:cmd",
+ "Number of received BSSMAP DT1 LCLS CONNECT CTRL messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_HANDOVER_RQST] = {
+ "bssmap:rx:dt1:handover:rqst",
+ "Number of received BSSMAP DT1 HANDOVER RQST messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD] = {
+ "bssmap:rx:dt1:handover:cmd",
+ "Number of received BSSMAP DT1 HANDOVER CMD messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST] = {
+ "bssmap:rx:dt1:classmark:rqst",
+ "Number of received BSSMAP DT1 CLASSMARK RQST messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_CONFUSION] = {
+ "bssmap:rx:dt1:confusion",
+ "Number of received BSSMAP DT1 CONFUSION messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_COMMON_ID] = {
+ "bssmap:rx:dt1:common_id",
+ "Number of received BSSMAP DT1 COMMON ID messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_UNKNOWN] = {
+ "bssmap:rx:dt1:err_unknown",
+ "Number of received BSSMAP unknown DT1 messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_DTAP] = {
+ "bssmap:rx:dt1:dtap:good",
+ "Number of received BSSMAP DTAP messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR] = {
+ "bssmap:rx:dt1:dtap:error",
+ "Number of received BSSMAP DTAP messages with errors"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST] = {
+ "bssmap:rx:dt1:location:request",
+ "Number of received BSSMAP Perform Location Request messages"
+ },
+ [MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT] = {
+ "bssmap:tx:dt1:location:abort",
+ "Number of received BSSMAP Perform Location Abort messages"
+ },
[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP] = {
"bssmap:rx:dt1:vgcs_vbs_setup",
"Number of received BSSMAP DT1 VGCS/VBS SETUP messages"
@@ -108,44 +162,123 @@
* The counters here follow the logic of the osmo_bsc_sigtran_send() function
* which receives DT1 messages from the upper layers and actually sends them to the MSC.
* These counters cover all messages passed to the function by the upper layers: */
- [MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT] = {"bssmap:tx:type:bss_management", "Number of transmitted BSS MANAGEMENT messages"},
- [MSC_CTR_BSSMAP_TX_DTAP] = {"bssmap:tx:type:dtap", "Number of transmitted DTAP messages"},
- [MSC_CTR_BSSMAP_TX_UNKNOWN] = {"bssmap:tx:type:err_unknown", "Number of transmitted messages with unknown type (an error in our code?)"},
- [MSC_CTR_BSSMAP_TX_SHORT] = {"bssmap:tx:type:err_short", "Number of transmitted messages which are too short (an error in our code?)"},
+ [MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT] = {
+ "bssmap:tx:type:bss_management",
+ "Number of transmitted BSS MANAGEMENT messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DTAP] = {
+ "bssmap:tx:type:dtap",
+ "Number of transmitted DTAP messages"
+ },
+ [MSC_CTR_BSSMAP_TX_UNKNOWN] = {
+ "bssmap:tx:type:err_unknown",
+ "Number of transmitted messages with unknown type (an error in our code?)"
+ },
+ [MSC_CTR_BSSMAP_TX_SHORT] = {
+ "bssmap:tx:type:err_short",
+ "Number of transmitted messages which are too short (an error in our code?)"
+ },
/* The next counters are also counted in the osmo_bsc_sigtran_send() function and
* sum up to the exactly same number as the counters above but instead of message
* classes they split by the result of the sending attempt: */
- [MSC_CTR_BSSMAP_TX_ERR_CONN_NOT_READY] = {"bssmap:tx:result:err_conn_not_ready", "Number of BSSMAP messages we tried to send when the connection was not ready yet"},
- [MSC_CTR_BSSMAP_TX_ERR_SEND] = {"bssmap:tx:result:err_send", "Number of socket errors while sending BSSMAP messages"},
- [MSC_CTR_BSSMAP_TX_SUCCESS] = {"bssmap:tx:result:success", "Number of successfully sent BSSMAP messages"},
+ [MSC_CTR_BSSMAP_TX_ERR_CONN_NOT_READY] = {
+ "bssmap:tx:result:err_conn_not_ready",
+ "Number of BSSMAP messages we tried to send when the connection was not ready yet"
+ },
+ [MSC_CTR_BSSMAP_TX_ERR_SEND] = {
+ "bssmap:tx:result:err_send",
+ "Number of socket errors while sending BSSMAP messages"
+ },
+ [MSC_CTR_BSSMAP_TX_SUCCESS] = {
+ "bssmap:tx:result:success",
+ "Number of successfully sent BSSMAP messages"
+ },
/* Tx message counters (per specific message)
*
* Theoretically, the DT1 counters should sum up to the same number as the Tx counters
* above but since these counters are coming from the upper layers, there might be
* some difference if we forget some code path. */
- [MSC_CTR_BSSMAP_TX_UDT_RESET] = {"bssmap:tx:udt:reset:request", "Number of transmitted BSSMAP UDT RESET messages"},
- [MSC_CTR_BSSMAP_TX_UDT_RESET_ACK] = {"bssmap:tx:udt:reset:ack", "Number of transmitted BSSMAP UDT RESET ACK messages"},
- [MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST] = {"bssmap:tx:dt1:clear:rqst", "Number of transmitted BSSMAP DT1 CLEAR RQSTtx messages"},
- [MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE] = {"bssmap:tx:dt1:clear:complete", "Number of transmitted BSSMAP DT1 CLEAR COMPLETE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE] = {"bssmap:tx:dt1:assigment:failure", "Number of transmitted BSSMAP DT1 ASSIGMENT FAILURE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE] = {"bssmap:tx:dt1:assigment:complete", "Number of transmitted BSSMAP DT1 ASSIGMENT COMPLETE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT] = {"bssmap:tx:dt1:sapi_n:reject", "Number of transmitted BSSMAP DT1 SAPI N REJECT messages"},
- [MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE] = {"bssmap:tx:dt1:cipher_mode:complete", "Number of transmitted BSSMAP DT1 CIPHER COMPLETE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT] = {"bssmap:tx:dt1:cipher_mode:reject", "Number of transmitted BSSMAP DT1 CIPHER REJECT messages"},
- [MSC_CTR_BSSMAP_TX_DT1_CLASSMARK_UPDATE] = {"bssmap:tx:dt1:classmark:update", "Number of transmitted BSSMAP DT1 CLASSMARK UPDATE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_LCLS_CONNECT_CTRL_ACK] = {"bssmap:tx:dt1:lcls_connect_ctrl:ack", "Number of transmitted BSSMAP DT1 LCLS CONNECT CTRL ACK messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_REQUIRED] = {"bssmap:tx:dt1:handover:required", "Number of transmitted BSSMAP DT1 HANDOVER REQUIRED messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_PERFORMED] = {"bssmap:tx:dt1:handover:performed", "Number of transmitted BSSMAP DT1 HANDOVER PERFORMED messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_RQST_ACKNOWLEDGE] = {"bssmap:tx:dt1:handover:rqst_acknowledge", "Number of transmitted BSSMAP DT1 HANDOVER RQST ACKNOWLEDGE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_DETECT] = {"bssmap:tx:dt1:handover:detect", "Number of transmitted BSSMAP DT1 HANDOVER DETECT messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_COMPLETE] = {"bssmap:tx:dt1:handover:complete", "Number of transmitted BSSMAP DT1 HANDOVER COMPLETE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_FAILURE] = {"bssmap:tx:dt1:handover:failure", "Number of transmitted BSSMAP DT1 HANDOVER FAILURE messages"},
- [MSC_CTR_BSSMAP_TX_DT1_DTAP] = {"bssmap:tx:dt1:dtap", "Number of transmitted BSSMAP DT1 DTAP messages"},
- [MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS] = {"bssmap:tx:dt1:location:response_success",
- "Number of transmitted BSSMAP Perform Location Response messages containing a location estimate"},
- [MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE] = {"bssmap:tx:dt1:location:response_failure",
- "Number of transmitted BSSMAP Perform Location Response messages containing a failure cause"},
+ [MSC_CTR_BSSMAP_TX_UDT_RESET] = {
+ "bssmap:tx:udt:reset:request",
+ "Number of transmitted BSSMAP UDT RESET messages"
+ },
+ [MSC_CTR_BSSMAP_TX_UDT_RESET_ACK] = {
+ "bssmap:tx:udt:reset:ack",
+ "Number of transmitted BSSMAP UDT RESET ACK messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST] = {
+ "bssmap:tx:dt1:clear:rqst",
+ "Number of transmitted BSSMAP DT1 CLEAR RQSTtx messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE] = {
+ "bssmap:tx:dt1:clear:complete",
+ "Number of transmitted BSSMAP DT1 CLEAR COMPLETE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE] = {
+ "bssmap:tx:dt1:assigment:failure",
+ "Number of transmitted BSSMAP DT1 ASSIGMENT FAILURE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE] = {
+ "bssmap:tx:dt1:assigment:complete",
+ "Number of transmitted BSSMAP DT1 ASSIGMENT COMPLETE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT] = {
+ "bssmap:tx:dt1:sapi_n:reject",
+ "Number of transmitted BSSMAP DT1 SAPI N REJECT messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE] = {
+ "bssmap:tx:dt1:cipher_mode:complete",
+ "Number of transmitted BSSMAP DT1 CIPHER COMPLETE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT] = {
+ "bssmap:tx:dt1:cipher_mode:reject",
+ "Number of transmitted BSSMAP DT1 CIPHER REJECT messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_CLASSMARK_UPDATE] = {
+ "bssmap:tx:dt1:classmark:update",
+ "Number of transmitted BSSMAP DT1 CLASSMARK UPDATE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_LCLS_CONNECT_CTRL_ACK] = {
+ "bssmap:tx:dt1:lcls_connect_ctrl:ack",
+ "Number of transmitted BSSMAP DT1 LCLS CONNECT CTRL ACK messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_REQUIRED] = {
+ "bssmap:tx:dt1:handover:required",
+ "Number of transmitted BSSMAP DT1 HANDOVER REQUIRED messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_PERFORMED] = {
+ "bssmap:tx:dt1:handover:performed",
+ "Number of transmitted BSSMAP DT1 HANDOVER PERFORMED messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_RQST_ACKNOWLEDGE] = {
+ "bssmap:tx:dt1:handover:rqst_acknowledge",
+ "Number of transmitted BSSMAP DT1 HANDOVER RQST ACKNOWLEDGE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_DETECT] = {
+ "bssmap:tx:dt1:handover:detect",
+ "Number of transmitted BSSMAP DT1 HANDOVER DETECT messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_COMPLETE] = {
+ "bssmap:tx:dt1:handover:complete",
+ "Number of transmitted BSSMAP DT1 HANDOVER COMPLETE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_HANDOVER_FAILURE] = {
+ "bssmap:tx:dt1:handover:failure",
+ "Number of transmitted BSSMAP DT1 HANDOVER FAILURE messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_DTAP] = {
+ "bssmap:tx:dt1:dtap",
+ "Number of transmitted BSSMAP DT1 DTAP messages"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS] = {
+ "bssmap:tx:dt1:location:response_success",
+ "Number of transmitted BSSMAP Perform Location Response messages containing a location estimate"
+ },
+ [MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE] = {
+ "bssmap:tx:dt1:location:response_failure",
+ "Number of transmitted BSSMAP Perform Location Response messages containing a failure cause"
+ },
[MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK] = {
"bssmap:tx:dt1:vgcs_vbs_setup:ack",
"Number of transmitted BSSMAP DT1 VGCS/VBS SETUP ACK messages"
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/33597
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I7cfd4f20ebfee0c8df9305372977d6628d6337c5
Gerrit-Change-Number: 33597
Gerrit-PatchSet: 1
Gerrit-Owner: jolly <andreas(a)eversberg.eu>
Gerrit-MessageType: newchange
1
0