implement support for 3-digit MNC with leading zeros
Add 3-digit flags and use the new RAI and LAI API from libosmocore throughout the code base to be able to handle an MNC < 100 that has three digits (leading zeros). Depends: Id2240f7f518494c9df6c8bda52c0d5092f90f221 (libosmocore), Ib7176b1d65a03b76f41f94bc9d3293a8a07d24c6 (libosmocore) Change-Id: I82f0016d9512ee8722a3489a3cb4b6c704a271fc
This commit is contained in:
parent
7f48420923
commit
379d5799f0
|
@ -223,11 +223,11 @@ struct gsm_network {
|
|||
* these have in common, like country and network code, put in yet
|
||||
* separate structs and placed as members in osmo_bsc and osmo_msc. */
|
||||
|
||||
/* global parameters */
|
||||
uint16_t country_code;
|
||||
uint16_t network_code;
|
||||
struct osmo_plmn_id plmn;
|
||||
|
||||
char *name_long;
|
||||
char *name_short;
|
||||
|
||||
/* bit-mask of permitted encryption algorithms. LSB=A5/0, MSB=A5/7 */
|
||||
uint8_t a5_encryption_mask;
|
||||
bool authentication_required;
|
||||
|
|
|
@ -45,8 +45,8 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
|
|||
if (!net)
|
||||
return NULL;
|
||||
|
||||
net->country_code = 1;
|
||||
net->network_code = 1;
|
||||
net->plmn = (struct osmo_plmn_id){ .mcc=1, .mnc=1 };
|
||||
|
||||
/* Permit a compile-time default of A5/3 and A5/1 */
|
||||
net->a5_encryption_mask = (1 << 3) | (1 << 1);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ DEFUN(cfg_net_ncc,
|
|||
{
|
||||
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||
|
||||
gsmnet->country_code = atoi(argv[0]);
|
||||
gsmnet->plmn.mcc = atoi(argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -75,8 +75,16 @@ DEFUN(cfg_net_mnc,
|
|||
"Mobile Network Code to use\n")
|
||||
{
|
||||
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
|
||||
uint16_t mnc;
|
||||
bool mnc_3_digits;
|
||||
|
||||
gsmnet->network_code = atoi(argv[0]);
|
||||
if (osmo_mnc_from_str(argv[0], &mnc, &mnc_3_digits)) {
|
||||
vty_out(vty, "%% Error decoding MNC: %s%s", argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
gsmnet->plmn.mnc = mnc;
|
||||
gsmnet->plmn.mnc_3_digits = mnc_3_digits;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -263,9 +263,7 @@ static int bssmap_rx_l3_compl(struct osmo_sccp_user *scu, const struct a_conn_in
|
|||
struct gsm48_loc_area_id lai;
|
||||
uint16_t ci;
|
||||
} __attribute__ ((packed)) lai_ci;
|
||||
uint16_t mcc;
|
||||
uint16_t mnc;
|
||||
uint16_t lac;
|
||||
struct osmo_location_area_id lai;
|
||||
uint8_t data_length;
|
||||
const uint8_t *data;
|
||||
int rc;
|
||||
|
@ -301,18 +299,15 @@ static int bssmap_rx_l3_compl(struct osmo_sccp_user *scu, const struct a_conn_in
|
|||
"Unable to parse element CELL IDENTIFIER (wrong cell identification discriminator) -- discarding message!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (gsm48_decode_lai(&lai_ci.lai, &mcc, &mnc, &lac) != 0) {
|
||||
LOGP(DBSSAP, LOGL_ERROR,
|
||||
"Unable to parse element CELL IDENTIFIER (lai decoding failed) -- discarding message!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
gsm48_decode_lai2(&lai_ci.lai, &lai);
|
||||
/* FIXME: Actually compare the MCC-MNC to the local network config?? */
|
||||
|
||||
/* Parse Layer 3 Information element */
|
||||
msg->l3h = (uint8_t*)TLVP_VAL(tp, GSM0808_IE_LAYER_3_INFORMATION);
|
||||
msgb_l3trim(msg, TLVP_LEN(tp, GSM0808_IE_LAYER_3_INFORMATION));
|
||||
|
||||
/* Create new subscriber context */
|
||||
conn = subscr_conn_allocate_a(a_conn_info, network, lac, scu, a_conn_info->conn_id);
|
||||
conn = subscr_conn_allocate_a(a_conn_info, network, lai.lac, scu, a_conn_info->conn_id);
|
||||
|
||||
/* Handover location update to the MSC code */
|
||||
rc = msc_compl_l3(conn, msg, 0);
|
||||
|
|
|
@ -222,15 +222,17 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
|
|||
struct gsm48_hdr *gh;
|
||||
struct gsm48_loc_area_id *lai;
|
||||
uint8_t *mid;
|
||||
struct osmo_location_area_id laid = {
|
||||
.plmn = conn->network->plmn,
|
||||
.lac = conn->lac,
|
||||
};
|
||||
|
||||
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||
gh->proto_discr = GSM48_PDISC_MM;
|
||||
gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
|
||||
|
||||
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
|
||||
gsm48_generate_lai(lai, conn->network->country_code,
|
||||
conn->network->network_code,
|
||||
conn->lac);
|
||||
gsm48_generate_lai2(lai, &laid);
|
||||
|
||||
if (send_tmsi == GSM_RESERVED_TMSI) {
|
||||
/* we did not allocate a TMSI to the MS, so we need to
|
||||
|
@ -381,10 +383,8 @@ int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb *msg)
|
|||
break;
|
||||
}
|
||||
|
||||
gsm48_decode_lai(&lu->lai, &old_lai.plmn.mcc,
|
||||
&old_lai.plmn.mnc, &old_lai.lac);
|
||||
new_lai.plmn.mcc = conn->network->country_code;
|
||||
new_lai.plmn.mnc = conn->network->network_code;
|
||||
gsm48_decode_lai2(&lu->lai, &old_lai);
|
||||
new_lai.plmn = conn->network->plmn;
|
||||
new_lai.lac = conn->lac;
|
||||
DEBUGP(DMM, "LU/new-LAC: %u/%u\n", old_lai.lac, new_lai.lac);
|
||||
|
||||
|
@ -701,8 +701,7 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms
|
|||
bool is_utran;
|
||||
int rc;
|
||||
|
||||
lai.plmn.mcc = conn->network->country_code;
|
||||
lai.plmn.mnc = conn->network->network_code;
|
||||
lai.plmn = conn->network->plmn;
|
||||
lai.lac = conn->lac;
|
||||
|
||||
DEBUGP(DMM, "<- CM SERVICE REQUEST ");
|
||||
|
@ -1152,8 +1151,7 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
|
|||
struct osmo_location_area_id lai;
|
||||
bool is_utran;
|
||||
|
||||
lai.plmn.mcc = conn->network->country_code;
|
||||
lai.plmn.mnc = conn->network->network_code;
|
||||
lai.plmn = conn->network->plmn;
|
||||
lai.lac = conn->lac;
|
||||
|
||||
resp = (struct gsm48_pag_resp *) &gh->data[0];
|
||||
|
|
|
@ -183,8 +183,9 @@ static int config_write_net(struct vty *vty)
|
|||
int i;
|
||||
|
||||
vty_out(vty, "network%s", VTY_NEWLINE);
|
||||
vty_out(vty, " network country code %u%s", gsmnet->country_code, VTY_NEWLINE);
|
||||
vty_out(vty, " mobile network code %u%s", gsmnet->network_code, VTY_NEWLINE);
|
||||
vty_out(vty, " network country code %s%s", osmo_mcc_name(gsmnet->plmn.mcc), VTY_NEWLINE);
|
||||
vty_out(vty, " mobile network code %s%s",
|
||||
osmo_mnc_name(gsmnet->plmn.mnc, gsmnet->plmn.mnc_3_digits), VTY_NEWLINE);
|
||||
vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE);
|
||||
vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE);
|
||||
vty_out(vty, " encryption a5");
|
||||
|
|
|
@ -911,14 +911,6 @@ static int assoc_lfp_with_sub(struct osmo_fsm_inst *fi, struct vlr_subscr *vsub)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *lai_name(struct osmo_location_area_id *lai)
|
||||
{
|
||||
static char buf[64];
|
||||
snprintf(buf, sizeof(buf),"MCC:%u, MNC:%u, LAC:%u",
|
||||
lai->plmn.mcc, lai->plmn.mnc, lai->lac);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int _lu_fsm_associate_vsub(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
struct lu_fsm_priv *lfp = fi->priv;
|
||||
|
@ -988,7 +980,7 @@ static void _start_lu_main(struct osmo_fsm_inst *fi)
|
|||
#endif
|
||||
LOGPFSML(fi, LOGL_NOTICE, "LAI change from %s,"
|
||||
" but checking previous VLR not implemented\n",
|
||||
lai_name(&lfp->old_lai));
|
||||
osmo_lai_name(&lfp->old_lai));
|
||||
}
|
||||
|
||||
/* If this is a TMSI based LU, we may not have the IMSI. Make sure that
|
||||
|
|
|
@ -281,9 +281,7 @@ static int rcvmsg_iu_cs(struct msgb *msg, struct gprs_ra_id *ra_id, uint16_t *sa
|
|||
{
|
||||
DEBUGP(DIUCS, "got IuCS message %d bytes: %s\n", msg->len, msgb_hexdump(msg));
|
||||
if (ra_id) {
|
||||
DEBUGP(DIUCS, "got IuCS message on"
|
||||
" MNC %d MCC %d LAC %d RAC %d\n",
|
||||
ra_id->mnc, ra_id->mcc, ra_id->lac, ra_id->rac);
|
||||
DEBUGP(DIUCS, "got IuCS message on %s\n", osmo_rai_name(ra_id));
|
||||
}
|
||||
|
||||
return gsm0408_rcvmsg_iucs(msc_network, msg, ra_id? &ra_id->lac : NULL);
|
||||
|
|
Loading…
Reference in New Issue