aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2019-03-12 16:40:07 +0100
committerKeith Whyte <keith@rhizomatica.org>2020-12-23 07:21:14 +0100
commitba8fe4e43565896773a9ce2cd00084c6fdd924f3 (patch)
tree340a343a55f6fd08332b14b03c9370a1aa22d243
parent4dc5dcf4e0d238638c03cb1bc8f8401510099853 (diff)
Autofill LCLS parameters for A-interface transactionskeith/lcls2r1
That's experimental patch to facilitate testing of BSC implementation of LCLS. Change-Id: I35ae6b6ca04925c8d300bc1a0269af00eac727f3
-rw-r--r--include/osmocom/msc/debug.h1
-rw-r--r--include/osmocom/msc/mncc.h3
-rw-r--r--include/osmocom/msc/ran_msg.h1
-rw-r--r--include/osmocom/msc/transaction.h3
-rw-r--r--include/osmocom/msc/vlr.h1
-rw-r--r--src/libmsc/msc_a.c10
-rw-r--r--src/libmsc/ran_msg_a.c3
-rw-r--r--src/libmsc/transaction.c69
-rw-r--r--src/libvlr/vlr.c1
9 files changed, 91 insertions, 1 deletions
diff --git a/include/osmocom/msc/debug.h b/include/osmocom/msc/debug.h
index 3347e20d4..0d08ceb11 100644
--- a/include/osmocom/msc/debug.h
+++ b/include/osmocom/msc/debug.h
@@ -8,6 +8,7 @@ enum {
DCC,
DMM,
DRR,
+ DLCLS,
DMNCC,
DPAG,
DMSC,
diff --git a/include/osmocom/msc/mncc.h b/include/osmocom/msc/mncc.h
index 1c8aff0c9..076747547 100644
--- a/include/osmocom/msc/mncc.h
+++ b/include/osmocom/msc/mncc.h
@@ -26,6 +26,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/mncc.h>
+#include <osmocom/gsm/gsm29205.h>
#include <stdint.h>
#include <netinet/in.h>
@@ -161,6 +162,8 @@ struct gsm_mncc {
unsigned char lchan_type;
unsigned char lchan_mode;
+ struct osmo_gcr_parsed gcr;
+
/* A buffer to contain SDP ('\0' terminated) */
char sdp[1024];
};
diff --git a/include/osmocom/msc/ran_msg.h b/include/osmocom/msc/ran_msg.h
index 3b08b466c..5fdb90cda 100644
--- a/include/osmocom/msc/ran_msg.h
+++ b/include/osmocom/msc/ran_msg.h
@@ -88,6 +88,7 @@ struct ran_assignment_command {
uint8_t osmux_cid;
bool call_id_present;
uint32_t call_id;
+ struct osmo_lcls *lcls;
};
struct ran_cipher_mode_command {
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 928b137ae..494ad88db 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -132,6 +132,7 @@ struct gsm_trans {
struct gsm_trans *peer;
enum bridge_state state;
} bridge;
+ struct osmo_lcls *lcls;
};
@@ -145,6 +146,8 @@ struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
const struct vlr_subscr *vsub,
uint8_t sm_rp_mr);
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac);
+
struct gsm_trans *trans_alloc(struct gsm_network *net,
struct vlr_subscr *vsub,
enum trans_type type, uint8_t trans_id,
diff --git a/include/osmocom/msc/vlr.h b/include/osmocom/msc/vlr.h
index 3b9bbc41c..971db528b 100644
--- a/include/osmocom/msc/vlr.h
+++ b/include/osmocom/msc/vlr.h
@@ -271,6 +271,7 @@ struct vlr_instance {
bool is_ps;
uint8_t nri_bitlen;
struct osmo_nri_ranges *nri_ranges;
+ bool lcls_enable;
} cfg;
/* A free-form pointer for use by the caller */
void *user_ctx;
diff --git a/src/libmsc/msc_a.c b/src/libmsc/msc_a.c
index 0645c5434..765a2dc3f 100644
--- a/src/libmsc/msc_a.c
+++ b/src/libmsc/msc_a.c
@@ -517,6 +517,7 @@ static void msc_a_fsm_authenticated(struct osmo_fsm_inst *fi, uint32_t event, vo
}
}
+
/* The MGW has given us a local IP address for the RAN side. Ready to start the Assignment of a voice channel. */
static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
{
@@ -549,8 +550,10 @@ static void msc_a_call_leg_ran_local_addr_available(struct msc_a *msc_a)
.osmux_cid = msc_a->cc.call_leg->rtp[RTP_TO_RAN]->local_osmux_cid,
.call_id_present = true,
.call_id = cc_trans->callref,
+ .lcls = cc_trans->lcls,
},
};
+
if (msc_a_ran_down(msc_a, MSC_ROLE_I, &msg)) {
LOG_MSC_A(msc_a, LOGL_ERROR, "Cannot send Assignment\n");
trans_free(cc_trans);
@@ -1484,6 +1487,13 @@ int msc_a_ran_dec_from_msc_i(struct msc_a *msc_a, struct msc_a_ran_dec_data *d)
rc = msc_a_up_ho(msc_a, d, MSC_HO_EV_RX_FAILURE);
break;
+ case RAN_MSG_LCLS_STATUS:
+ /* The BSS sends us LCLS_STATUS. We do nothing for now, but it is not an error. */
+ LOG_MSC_A(msc_a, LOGL_DEBUG, "LCLS_STATUS (%s) received from MSC-I\n",
+ gsm0808_lcls_status_name(msg->lcls_status.status));
+ rc = 0;
+ break;
+
default:
LOG_MSC_A(msc_a, LOGL_ERROR, "Message from MSC-I not implemented: %s\n", ran_msg_type_name(msg->msg_type));
rc = -ENOTSUP;
diff --git a/src/libmsc/ran_msg_a.c b/src/libmsc/ran_msg_a.c
index 6a3370443..87e0a8b39 100644
--- a/src/libmsc/ran_msg_a.c
+++ b/src/libmsc/ran_msg_a.c
@@ -997,7 +997,8 @@ static struct msgb *ran_a_make_assignment_command(struct osmo_fsm_inst *log_fi,
if(ac->call_id_present == true)
call_id = &ac->call_id;
- msg = gsm0808_create_ass(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id);
+ msg = gsm0808_create_ass2(ac->channel_type, NULL, use_rtp_addr, use_scl, call_id,
+ NULL, ac->lcls);
if (ac->osmux_present)
_gsm0808_assignment_extend_osmux(msg, ac->osmux_cid);
return msg;
diff --git a/src/libmsc/transaction.c b/src/libmsc/transaction.c
index 94712cc89..64bef8609 100644
--- a/src/libmsc/transaction.c
+++ b/src/libmsc/transaction.c
@@ -110,6 +110,75 @@ struct gsm_trans *trans_find_by_sm_rp_mr(const struct gsm_network *net,
return NULL;
}
+struct osmo_lcls *trans_lcls_compose(const struct gsm_trans *trans, bool use_lac)
+{
+ /* FIXME: ensure that a interface is in use for this transaction
+ This fails test #13 because we have no sccp there Do we need this logging?
+ Can we get primary_pc elsewhere? */
+ if (!trans->net->a.sri->sccp) {
+ printf("but returning NULL\n");
+ return NULL;
+ }
+ struct osmo_ss7_instance *ss7 = osmo_sccp_get_ss7(trans->net->a.sri->sccp);
+ struct osmo_lcls *lcls;
+ uint8_t w = osmo_ss7_pc_width(&ss7->cfg.pc_fmt);
+
+ if (!trans) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for unallocated transaction\n");
+ return NULL;
+ }
+
+ if (!trans->net->vlr->cfg.lcls_enable) {
+ LOGP(DCC, LOGL_NOTICE, "LCLS disabled globally\n");
+ return NULL;
+ }
+
+ if (!trans->msc_a) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: unable to fill parameters for transaction without connection\n");
+ return NULL;
+ }
+
+ if (trans->msc_a->c.ran->type != OSMO_RAT_GERAN_A) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: only A interface is supported at the moment\n");
+ return NULL;
+ }
+
+ lcls = talloc_zero(trans, struct osmo_lcls);
+ if (!lcls) {
+ LOGP(DCC, LOGL_ERROR, "LCLS: failed to allocate osmo_lcls\n");
+ return NULL;
+ }
+
+ LOGP(DCC, LOGL_INFO, "LCLS: using %u bits (%u bytes) for node ID\n", w, w / 8);
+
+ lcls->gcr.net_len = 3;
+ lcls->gcr.node = ss7->cfg.primary_pc;
+
+ /* net id from Q.1902.3 3-5 bytes, this function gives 3 bytes exactly */
+ osmo_plmn_to_bcd(lcls->gcr.net, &trans->net->plmn);
+
+ osmo_store32be(trans->callref, lcls->gcr.cr);
+ osmo_store16be(use_lac ? trans->msc_a->via_cell.lai.lac : trans->msc_a->via_cell.cell_identity, lcls->gcr.cr + 3);
+
+ LOGP(DCC, LOGL_INFO, "LCLS: allocated %s-based CR-ID %s\n", use_lac ? "LAC" : "CI",
+ osmo_hexdump(lcls->gcr.cr, 5));
+
+ lcls->config = GSM0808_LCLS_CFG_BOTH_WAY;
+ lcls->control = GSM0808_LCLS_CSC_CONNECT;
+ lcls->corr_needed = true;
+ lcls->gcr_available = true;
+
+ LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_lcls_dump(lcls));
+ LOGP(DCC, LOGL_DEBUG, "Filled %s\n", osmo_gcr_dump(lcls));
+
+ printf("Filled %s\n", osmo_lcls_dump(lcls));
+ printf("Filled %s\n", osmo_gcr_dump(lcls));
+
+ printf("LCLS compose returning%p\n", lcls);
+
+ return lcls;
+}
+
static const char *trans_vsub_use(enum trans_type type)
{
return get_value_string_or_null(trans_type_names, type) ? : "trans-type-unknown";
diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c
index 33d6331c0..c6ec5ef53 100644
--- a/src/libvlr/vlr.c
+++ b/src/libvlr/vlr.c
@@ -1258,6 +1258,7 @@ struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops)
vlr->cfg.assign_tmsi = true;
vlr->cfg.nri_bitlen = OSMO_NRI_BITLEN_DEFAULT;
vlr->cfg.nri_ranges = osmo_nri_ranges_alloc(vlr);
+ vlr->cfg.lcls_enable = 1;
/* reset shared timer definitions */
osmo_tdefs_reset(msc_tdefs_vlr);