aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-04-20 17:17:50 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-04-20 18:45:15 +0200
commiteb5cbcc02dc75aed3a7d338a30c656ef8a0d3eb8 (patch)
treeea2ce4a4526a9e8bca8539e33ed36d899e3430bf
parent5d0bc330a0cffd891453fc155b3b44a4eedb0826 (diff)
code markers to indicate RAN connection setupneels/vgcs
-rw-r--r--doc/examples/osmo-msc/osmo-msc.cfg4
-rw-r--r--include/osmocom/msc/msc_a.h4
-rw-r--r--include/osmocom/msc/ran_conn.h9
-rw-r--r--include/osmocom/msc/ran_msg.h3
-rw-r--r--src/libmsc/msc_a.c32
-rw-r--r--src/libmsc/msc_bcc.c43
-rw-r--r--src/libmsc/ran_msg_a.c33
-rw-r--r--src/libmsc/ran_peer.c17
8 files changed, 138 insertions, 7 deletions
diff --git a/doc/examples/osmo-msc/osmo-msc.cfg b/doc/examples/osmo-msc/osmo-msc.cfg
index b08623787..776a3f376 100644
--- a/doc/examples/osmo-msc/osmo-msc.cfg
+++ b/doc/examples/osmo-msc/osmo-msc.cfg
@@ -20,3 +20,7 @@ msc
assign-tmsi
auth-tuple-max-reuse-count 3
auth-tuple-reuse-on-error 1
+
+ # 123: LAC der BSS
+ # 1.23.3: SCCP point-code der BSS
+ neighbor a lac 123 ran-pc 1.23.3
diff --git a/include/osmocom/msc/msc_a.h b/include/osmocom/msc/msc_a.h
index 3b1115500..4460b5194 100644
--- a/include/osmocom/msc/msc_a.h
+++ b/include/osmocom/msc/msc_a.h
@@ -138,6 +138,10 @@ struct msc_a {
struct osmo_use_count use_count;
struct osmo_use_count_entry use_count_buf[8];
int32_t max_total_use_count;
+
+ struct {
+ struct ran_conn *ran_conn;
+ } vgcs;
};
osmo_static_assert(offsetof(struct msc_a, c) == 0, msc_role_common_first_member_of_msc_a);
diff --git a/include/osmocom/msc/ran_conn.h b/include/osmocom/msc/ran_conn.h
index 7aa50df07..77de0e1e9 100644
--- a/include/osmocom/msc/ran_conn.h
+++ b/include/osmocom/msc/ran_conn.h
@@ -18,9 +18,16 @@ struct ran_conn {
uint32_t sccp_conn_id;
/* MSC role that this RAN connection belongs to. This will be either an msc_i (currently active
- * connection) or an msc_t (transitory new connection during Handover). */
+ * connection) or an msc_t (transitory new connection during Handover).
+ * Used for usual L3 ran_conn to a subscriber. */
struct osmo_fsm_inst *msc_role;
+ /* For BCC, we have N connections to BSS. When receiving messages for a group call peer, dispatch to the VGCS
+ * management. */
+ struct {
+ struct msc_a *calling_subscriber;
+ } vgcs;
+
bool closing;
};
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 3e0ac6071..0df504b85 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -69,6 +69,9 @@ enum ran_msg_type {
RAN_MSG_HANDOVER_SUCCEEDED,
RAN_MSG_HANDOVER_COMPLETE,
RAN_MSG_HANDOVER_FAILURE,
+ RAN_MSG_VGCS_SETUP,
+ RAN_MSG_VGCS_SETUP_ACK,
+ ...
};
extern const struct value_string ran_msg_type_names[];
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index e8dc58b8a..961fcf8bb 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -1373,6 +1373,9 @@ int msc_a_up_l3(struct msc_a *msc_a, struct msgb *msg)
case GSM48_PDISC_TEST:
rc = gsm0414_rcv_test(msc_a, msg);
break;
+ case GSM48_PDISC_BCC:
+ rc = rcv_bcc(msc_a, msg);
+ break;
default:
LOG_MSC_A_CAT(msc_a, DRLL, LOGL_NOTICE, "Unknown "
"GSM 04.08 discriminator 0x%02x\n", pdisc);
@@ -1682,6 +1685,35 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
return rc;
}
+int msc_a_rx_vgcs_decoded(struct osmo_fsm_inst *caller_fi, void *caller_data, const struct ran_msg *msg)
+{
+ struct msc_a *msc_a = caller_fi;
+ struct ran_conn *from_ran_conn = caller_data;
+
+ switch (msg->msg_type) {
+ case RAN_MSG_VGCS_SETUP_ACK:
+ handle setup ack from peer from_ran_conn->ran_peer
+ }
+}
+
+int msc_a_rx_vgcs(struct msc_a *msc_a, struct ran_conn *from_conn, struct msgb *msg)
+{
+ /* Feed through the decoding mechanism ran_msg. The decoded message arrives in msc_a_rx_vgcs_decoded() */
+ ran_dec = (struct ran_dec) {
+ .caller_fi = fi,
+ .caller_data = from_conn,
+ .decode_cb = msc_a_rx_vgcs_decoded,
+ };
+ struct ran_peer *ran_peer = from_conn->ran_peer;
+ struct ran_inra *ran = ran_peer->sri->ran;
+ if (!ran->ran_dec_l2) {
+ LOGPFSML(fi, LOGL_ERROR, "No ran_dec_l2() defined for RAN type %s\n",
+ osmo_rat_type_name(ran->type));
+ return -ENOTSUP;
+ }
+ return ran->ran_dec_l2(&ran_dec, msg);
+}
+
static int msc_a_ran_dec_from_msc_t(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
{
struct msc_t *msc_t = msc_a_msc_t(msc_a);
diff --git a/src/libmsc/msc_bcc.c b/src/libmsc/msc_bcc.c
new file mode 100644
index 000000000..ded6e0744
--- /dev/null
+++ b/src/libmsc/msc_bcc.c
@@ -0,0 +1,43 @@
+
+int rcv_bcc(msc_a, msg)
+{
+ trans_alloc wie in gsm0408_rcv_cc()
+
+
+ struct gsm0808_cell_id cid = {
+ .lac = my_lac,
+ };
+
+ struct ran_peer *rp_from_neighbor_ident = NULL;
+ struct ran_peer *rp_from_cell_id = NULL;
+ struct ran_peer *rp;
+
+ switch (msc_ho_find_target_cell(msc_a, cid, &e, &rp_from_neighbor_ident, &rp_from_cell_id)) {
+ case MSC_NEIGHBOR_TYPE_REMOTE_MSC:
+ ERROR
+
+ case MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER:
+ rp = rp_from_neighbor_ident ? : rp_from_cell_id;
+ OSMO_ASSERT(rp);
+ msc_a->ho.new_cell.type = MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER;
+ msc_a->ho.new_cell.ran_peer = rp;
+ return true;
+
+ default:
+ break;
+ }
+
+ /* Now rp points at the ran_peer for my_lac */
+
+ /* new conn */
+ msc_a->vgcs.conn = ran_conn_create_outgoing(rp);
+ msc_a->vgcs.conn->vgcs.calling_subscriber = msc_a;
+
+ /* send first message */
+ ran_conn_down_l2_co(msc_a->vgcs.conn, l3_msg, true);
+
+ /* later */
+ ran_conn_down_l2_co(msc_a->vgcs.conn, l3_msg, false);
+
+ ...
+}
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 19402bc11..0241a349e 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -742,6 +742,33 @@ static int ran_a_decode_handover_failure(struct ran_dec *ran_dec, const struct m
return ran_decoded(ran_dec, &ran_dec_msg);
}
+/* es braucht decode nur für die empfangenen msgs; encode nur für die gesendeten msgs. */
+static int ran_a_decode_vgcs_setup_ack(struct ran_dec *ran_dec, const struct msgb *msg, const struct tlv_parsed *tp)
+{
+ // lese die TLV von tp und fülle die struct, wie z.b. in ran_a_decode_handover_request()
+
+ struct ran_msg ran_dec_msg = {
+ .msg_type = RAN_MSG_VGCS_SETUP_ACK,
+ .msg_name = "BSSMAP VGCS SETUP ACK",
+
+ .vgcs_setup = {
+ .members = from TLV in tp
+ },
+ };
+
+ // return decoded struct to caller
+ return ran_decoded(ran_dec, &ran_dec_msg);
+}
+
+struct msgb *ran_a_make_vgcs_setup(struct osmo_fsm_inst *log_fi, const struct ran_msg *msg)
+{
+ // lies das dekodierte struct 'msg' und schreibe es encoded in einen neuen msgb
+
+ // implement gsm0808_create_vgcs_setup in libosmocore/src/gsm/gsm0808.c
+ struct msgb *new_msg = gsm0808_create_vgcs_setup(msg->vgcs_setup.foo, msg->vgcs_setup.bar);
+ return new_msg;
+}
+
static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
{
struct tlv_parsed tp[2];
@@ -836,6 +863,9 @@ static int ran_a_decode_bssmap(struct ran_dec *ran_dec, struct msgb *bssmap)
case BSS_MAP_MSG_HANDOVER_FAILURE:
return ran_a_decode_handover_failure(ran_dec, bssmap, tp);
+ case BSS_MAP_MSG_VGCS_SETUP_ACK: <-- add in osmocom/gsm/protocol/gsm_08_08.h
+ return ran_a_decode_vgcs_setup_ack(...); <-- to be implemented here
+
default:
LOG_RAN_A_DEC(ran_dec, LOGL_ERROR, "Unimplemented msg type: %s\n", gsm0808_bssmap_name(msg_type));
return -EINVAL;
@@ -1281,6 +1311,9 @@ static struct msgb *_ran_a_encode(struct osmo_fsm_inst *caller_fi, const struct
case RAN_MSG_HANDOVER_FAILURE:
return ran_a_make_handover_failure(caller_fi, ran_enc_msg);
+ case RAN_MSG_VGCS_SETUP:
+ return ran_a_make_vgcs_setup(caller_fi, ran_enc_msg); <-- to be implemented
+
default:
LOG_RAN_A_ENC(caller_fi, LOGL_ERROR, "Unimplemented RAN-encode message type: %s\n",
ran_msg_type_name(ran_enc_msg->msg_type));
diff --git a/src/libmsc/ran_peer.c b/src/libmsc/ran_peer.c
index fcb5f5ad2..ab19c200d 100644
--- a/src/libmsc/ran_peer.c
+++ b/src/libmsc/ran_peer.c
@@ -399,12 +399,17 @@ void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
return;
}
- an_apdu = (struct an_apdu){
- .an_proto = rp->sri->ran->an_proto,
- .msg = ctx->msg,
- };
-
- osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
+ if (ctx->conn->msc_role) {
+ /* "normal" A connection, dispatch to MSC-I or MSC-T */
+ an_apdu = (struct an_apdu){
+ .an_proto = rp->sri->ran->an_proto,
+ .msg = ctx->msg,
+ };
+ osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
+ } else if (ctx->conn->vgcs->calling_subscriber) {
+ /* VGCS related */
+ msc_a_rx_vgcs(ctx->conn->vgcs->calling_subscriber, ctx->conn, ctx->msg);
+ }
return;
case RAN_PEER_EV_MSG_DOWN_CO_INITIAL: