Autofill LCLS parameters for A-interface transactions
That's experimental patch to facilitate testing of BSC implementation of LCLS. Change-Id: I35ae6b6ca04925c8d300bc1a0269af00eac727f3
This commit is contained in:
parent
4dc5dcf4e0
commit
ba8fe4e435
|
@ -8,6 +8,7 @@ enum {
|
|||
DCC,
|
||||
DMM,
|
||||
DRR,
|
||||
DLCLS,
|
||||
DMNCC,
|
||||
DPAG,
|
||||
DMSC,
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue