diff --git a/src/host/layer23/include/osmocom/bb/common/networks.h b/src/host/layer23/include/osmocom/bb/common/networks.h index d34f31628..408e17d0e 100644 --- a/src/host/layer23/include/osmocom/bb/common/networks.h +++ b/src/host/layer23/include/osmocom/bb/common/networks.h @@ -1,24 +1,27 @@ #ifndef _NETWORKS_H #define _NETWORKS_H +#include -#define GSM_INPUT_INVALID 0xffff - +/* Instead of handling numerical MCC and MNC, they stored and handled + * hexadecimal. This makes it possible + * to correctly handle 2 and 3 digits MNC. Internally 2 digit MNCs are stored + * as 0xXXf, and 3 digits MNC are stored as 0xXXX, where X is the digit 0..9. +*/ struct gsm_networks { - uint16_t mcc; - int16_t mnc; + uint16_t mcc_hex; + int16_t mnc_hex; const char *name; }; int gsm_match_mcc(uint16_t mcc, char *imsi); -int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi); -const char *gsm_print_mcc(uint16_t mcc); -const char *gsm_print_mnc(uint16_t mcc); +int gsm_match_mnc(uint16_t mcc, uint16_t mnc, bool mnc_3_digits, char *imsi); const char *gsm_get_mcc(uint16_t mcc); -const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc); +const char *gsm_get_mnc(const struct osmo_plmn_id *plmn); const char *gsm_imsi_mcc(char *imsi); const char *gsm_imsi_mnc(char *imsi); -const uint16_t gsm_input_mcc(char *string); -const uint16_t gsm_input_mnc(char *string); + +uint16_t gsm_mcc_to_hex(uint16_t mcc); +uint16_t gsm_mnc_to_hex(uint16_t mnc, bool mnc_3_digits); #endif /* _NETWORKS_H */ diff --git a/src/host/layer23/include/osmocom/bb/common/settings.h b/src/host/layer23/include/osmocom/bb/common/settings.h index e312a1c16..f66874c1c 100644 --- a/src/host/layer23/include/osmocom/bb/common/settings.h +++ b/src/host/layer23/include/osmocom/bb/common/settings.h @@ -4,6 +4,7 @@ #include #include #include +#include struct osmocom_ms; struct osmobb_apn; @@ -64,7 +65,7 @@ struct test_sim_settings { uint8_t ki[16]; /* 128 bit max */ uint8_t barr; uint8_t rplmn_valid; - uint16_t rplmn_mcc, rplmn_mnc; + struct osmo_plmn_id rplmn; uint16_t lac; uint8_t imsi_attached; uint8_t always; /* ...search hplmn... */ diff --git a/src/host/layer23/include/osmocom/bb/common/subscriber.h b/src/host/layer23/include/osmocom/bb/common/subscriber.h index 972f61332..e2a8dab4f 100644 --- a/src/host/layer23/include/osmocom/bb/common/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/common/subscriber.h @@ -5,6 +5,7 @@ #include #include +#include /* GSM 04.08 4.1.2.2 SIM update status */ enum gsm_sub_sim_ustate { @@ -22,12 +23,12 @@ static inline const char *gsm_sub_sim_ustate_name(enum gsm_sub_sim_ustate val) struct gsm_sub_plmn_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; }; struct gsm_sub_plmn_na { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t cause; }; @@ -58,7 +59,7 @@ struct gsm_subscriber { /* TMSI / LAI */ uint32_t tmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ - uint16_t mcc, mnc, lac; /* invalid lac: 0x0000 */ + struct osmo_location_area_id lai; /* invalid lac: 0x0000 */ /* key */ @@ -80,7 +81,7 @@ struct gsm_subscriber { /* PLMN last registered */ uint8_t plmn_valid; - uint16_t plmn_mcc, plmn_mnc; + struct osmo_plmn_id plmn; /* our access */ uint8_t acc_barr; /* if we may access, if cell barred */ @@ -111,12 +112,9 @@ int gsm_subscr_write_loci(struct osmocom_ms *ms); int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq, const uint8_t *rand, bool no_sim); void new_sim_ustate(struct gsm_subscriber *subscr, int state); -int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc); -int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc, uint8_t cause); -int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc); +int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn); +int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn, uint8_t cause); +int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn); int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms, void (*print)(void *, const char *, ...), void *priv); void gsm_subscr_dump(struct gsm_subscriber *subscr, diff --git a/src/host/layer23/include/osmocom/bb/common/sysinfo.h b/src/host/layer23/include/osmocom/bb/common/sysinfo.h index 75cbcd944..0368901f4 100644 --- a/src/host/layer23/include/osmocom/bb/common/sysinfo.h +++ b/src/host/layer23/include/osmocom/bb/common/sysinfo.h @@ -2,6 +2,7 @@ #define _SYSINFO_H #include +#include /* collection of system information of the current cell */ @@ -44,7 +45,7 @@ struct gsm48_sysinfo { /* serving cell */ uint8_t bsic; uint16_t cell_id; - uint16_t mcc, mnc, lac; /* LAI */ + struct osmo_location_area_id lai; uint8_t max_retrans; /* decoded */ uint8_t tx_integer; /* decoded */ uint8_t reest_denied; /* 1 = denied */ @@ -195,9 +196,5 @@ int gsm48_decode_sysinfo13(struct gsm48_sysinfo *s, int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq, const uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len, int si4); -int gsm48_encode_lai_hex(struct gsm48_loc_area_id *lai, - uint16_t mcc, uint16_t mnc, uint16_t lac); -int gsm48_decode_lai_hex(const struct gsm48_loc_area_id *lai, - uint16_t *mcc, uint16_t *mnc, uint16_t *lac); #endif /* _SYSINFO_H */ diff --git a/src/host/layer23/include/osmocom/bb/misc/log.h b/src/host/layer23/include/osmocom/bb/misc/log.h index 54d795bc9..3183f876c 100644 --- a/src/host/layer23/include/osmocom/bb/misc/log.h +++ b/src/host/layer23/include/osmocom/bb/misc/log.h @@ -29,6 +29,7 @@ struct node_mcc { struct node_mnc { struct node_mnc *next; uint16_t mnc; + bool mnc_3_digits; struct node_lac *lac; }; @@ -75,7 +76,7 @@ struct node_meas { }; struct node_mcc *get_node_mcc(uint16_t mcc); -struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc); +struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc, bool mnc_3_digits); struct node_lac *get_node_lac(struct node_mnc *mnc, uint16_t lac); struct node_cell *get_node_cell(struct node_lac *lac, uint16_t cellid); struct node_meas *add_node_meas(struct node_cell *cell); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h index 86b1ef174..4b20a1a1c 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm322.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm322.h @@ -1,10 +1,11 @@ #ifndef _GSM322_H #define _GSM322_H -#include - #include #include +#include + +#include /* 4.3.1.1 List of states for PLMN selection process (automatic mode) */ #define GSM322_A0_NULL 0 @@ -74,7 +75,7 @@ enum { /* node for each PLMN */ struct gsm322_plmn_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t rxlev; /* rx level in range format */ uint8_t cause; /* cause value, if PLMN is not allowed */ }; @@ -82,14 +83,14 @@ struct gsm322_plmn_list { /* node for each forbidden LA */ struct gsm322_la_list { struct llist_head entry; - uint16_t mcc, mnc, lac; + struct osmo_location_area_id lai; uint8_t cause; }; /* node for each BA-List */ struct gsm322_ba_list { struct llist_head entry; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; /* Band allocation for 1024+299 frequencies. * First bit of first index is frequency 0. */ @@ -124,7 +125,7 @@ struct gsm322_plmn { struct osmo_timer_list timer; int plmn_curr; /* current index in sorted_plmn */ - uint16_t mcc, mnc; /* current network selected */ + struct osmo_plmn_id plmn; /* current network selected */ }; /* state of CCCH activation */ @@ -171,7 +172,7 @@ struct gsm322_cellsel { /* cell selection list per frequency. */ /* scan and tune state */ struct osmo_timer_list timer; /* cell selection timer */ - uint16_t mcc, mnc; /* current network to search for */ + struct osmo_plmn_id plmn; /* current network to search for */ uint8_t powerscan; /* currently scanning for power */ uint8_t ccch_state; /* special state of current ccch */ uint32_t scan_state; /* special state of current scan */ @@ -188,7 +189,7 @@ struct gsm322_cellsel { uint8_t selected; /* if a cell is selected */ uint16_t sel_arfcn; /* current selected serving cell! */ struct gsm48_sysinfo sel_si; /* copy of selected cell, will update */ - uint16_t sel_mcc, sel_mnc, sel_lac, sel_id; + struct osmo_cell_global_id sel_cgi; /* cell re-selection */ struct llist_head nb_list; /* list of neighbour cells */ @@ -209,7 +210,7 @@ struct gsm322_cellsel { /* GSM 03.22 message */ struct gsm322_msg { int msg_type; - uint16_t mcc, mnc; + struct osmo_plmn_id plmn; uint8_t sysinfo; /* system information type */ uint8_t same_cell; /* select same cell when RET_IDLE */ uint8_t reject; /* location update reject cause */ @@ -229,18 +230,15 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg); int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg); int gsm322_plmn_dequeue(struct osmocom_ms *ms); int gsm322_cs_dequeue(struct osmocom_ms *ms); -int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac, uint8_t cause); -int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac); -int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc, - uint16_t lac); +int gsm322_add_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai, uint8_t cause); +int gsm322_del_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai); +int gsm322_is_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai); int gsm322_dump_sorted_plmn(struct osmocom_ms *ms); int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags, void (*print)(void *, const char *, ...), void *priv); int gsm322_dump_forbidden_la(struct osmocom_ms *ms, void (*print)(void *, const char *, ...), void *priv); -int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc, +int gsm322_dump_ba_list(struct gsm322_cellsel *cs, const struct osmo_plmn_id *plmn, void (*print)(void *, const char *, ...), void *priv); int gsm322_dump_nb_list(struct gsm322_cellsel *cs, void (*print)(void *, const char *, ...), void *priv); diff --git a/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h index ce8031746..b637a603b 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h +++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h @@ -186,7 +186,7 @@ struct gsm48_mmlayer { uint8_t lupd_rej_cause; /* cause of last reject */ uint8_t lupd_periodic; /* periodic update pending */ uint8_t lupd_retry; /* pending T3211/T3213 to */ - uint16_t lupd_mcc, lupd_mnc, lupd_lac; + struct osmo_location_area_id lupd_lai; /* imsi detach */ uint8_t delay_detach; /* do detach when possible */ diff --git a/src/host/layer23/src/common/networks.c b/src/host/layer23/src/common/networks.c index 5374bc084..e2429ef8b 100644 --- a/src/host/layer23/src/common/networks.c +++ b/src/host/layer23/src/common/networks.c @@ -2,6 +2,8 @@ #include #include +#include + #include /* list of networks */ @@ -1774,6 +1776,43 @@ static struct gsm_networks gsm_networks[] = { { 0, 0, NULL } }; +/* param: numerically stored mcc as per osmo_plmn_id. */ +uint16_t gsm_mcc_to_hex(uint16_t mcc) +{ + uint8_t buf[3]; + uint16_t in = mcc; + + buf[2] = in % 10; + in = in / 10; + buf[1] = in % 10; + in = in / 10; + buf[0] = in % 10; + + return ((buf[0] << 8) + + (buf[1] << 4) + + buf[2]); +} + +/* param: numerically stored mnc as per osmo_plmn_id. */ +uint16_t gsm_mnc_to_hex(uint16_t mnc, bool mnc_3_digits) +{ + uint8_t buf[3]; + uint16_t in = mnc; + if (mnc_3_digits) { + buf[2] = in % 10; + in = in / 10; + } else { + buf[2] = 0x0f; + } + buf[1] = in % 10; + in = in / 10; + buf[0] = in % 10; + + return ((buf[0] << 8) + + (buf[1] << 4) + + buf[2]); +} + /* GSM 03.22 Annex A */ int gsm_match_mcc(uint16_t mcc, char *imsi) { @@ -1783,30 +1822,33 @@ int gsm_match_mcc(uint16_t mcc, char *imsi) + ((imsi[1] - '0') << 4) + imsi[2] - '0'; - return (mcc == sim_mcc); + return (gsm_mcc_to_hex(mcc) == sim_mcc); } /* GSM 03.22 Annex A */ -int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi) +int gsm_match_mnc(uint16_t mcc, uint16_t mnc, bool mnc_3_digits, char *imsi) { uint16_t sim_mnc; + uint16_t mnc_hex; /* 1. SIM-MCC = BCCH-MCC */ if (!gsm_match_mcc(mcc, imsi)) return 0; + mnc_hex = gsm_mnc_to_hex(mnc, mnc_3_digits); + /* 2. 3rd digit of BCCH-MNC is not 0xf */ - if ((mnc & 0x00f) != 0x00f) { + if ((mnc_hex & 0x00f) != 0x00f) { /* 3. 3 digit SIM-MNC = BCCH-MNC */ sim_mnc = ((imsi[3] - '0') << 8) + ((imsi[4] - '0') << 4) + imsi[5] - '0'; - return (mnc == sim_mnc); + return (mnc_hex == sim_mnc); } /* 4. BCCH-MCC in the range 310-316 */ - if (mcc >= 310 && mcc <= 316) { + if (gsm_mcc_to_hex(mcc) >= 310 && mnc_hex <= 316) { /* 5. 3rd diit of SIM-MNC is 0 */ if (imsi[5] != 0) return 0; @@ -1817,123 +1859,47 @@ int gsm_match_mnc(uint16_t mcc, uint16_t mnc, char *imsi) + ((imsi[4] - '0') << 4) + 0x00f; - return (mnc == sim_mnc); -} - -const char *gsm_print_mcc(uint16_t mcc) -{ - static char string[6] = "000"; - - snprintf(string, 5, "%03x", mcc); - return string; -} - -const char *gsm_print_mnc(uint16_t mnc) -{ - static char string[8]; - - /* invalid format: return hex value */ - if ((mnc & 0xf000) - || (mnc & 0x0f00) > 0x0900 - || (mnc & 0x00f0) > 0x0090 - || ((mnc & 0x000f) > 0x0009 && (mnc & 0x000f) < 0x000f)) { - snprintf(string, 7, "0x%03x", mnc); - return string; - } - - /* two digits */ - if ((mnc & 0x000f) == 0x000f) { - snprintf(string, 7, "%02x", mnc >> 4); - return string; - } - - /* three digits */ - snprintf(string, 7, "%03x", mnc); - return string; -} - -const uint16_t gsm_input_mcc(char *string) -{ - uint16_t mcc; - - if (strlen(string) != 3) - return GSM_INPUT_INVALID; - if (string[0] < '0' || string [0] > '9' - || string[1] < '0' || string [1] > '9' - || string[2] < '0' || string [2] > '9') - return GSM_INPUT_INVALID; - - mcc = ((string[0] - '0') << 8) - | ((string[1] - '0') << 4) - | ((string[2] - '0')); - - if (mcc == 0x000) - return GSM_INPUT_INVALID; - - return mcc; -} - -const uint16_t gsm_input_mnc(char *string) -{ - uint16_t mnc = 0; - - if (strlen(string) == 2) { - if (string[0] < '0' || string [0] > '9' - || string[1] < '0' || string [1] > '9') - return GSM_INPUT_INVALID; - - mnc = ((string[0] - '0') << 8) - | ((string[1] - '0') << 4) - | 0x00f; - } else - if (strlen(string) == 3) { - if (string[0] < '0' || string [0] > '9' - || string[1] < '0' || string [1] > '9' - || string[2] < '0' || string [2] > '9') - return GSM_INPUT_INVALID; - - mnc = ((string[0] - '0') << 8) - | ((string[1] - '0') << 4) - | ((string[2] - '0')); - } - - return mnc; + return (mnc_hex == sim_mnc); } const char *gsm_get_mcc(uint16_t mcc) { int i; + uint16_t mcc_hex = gsm_mcc_to_hex(mcc); for (i = 0; gsm_networks[i].name; i++) - if (gsm_networks[i].mnc < 0 && gsm_networks[i].mcc == mcc) + if (gsm_networks[i].mnc_hex < 0 && gsm_networks[i].mcc_hex == mcc_hex) return gsm_networks[i].name; - return gsm_print_mcc(mcc); + return osmo_mcc_name(mcc); } -const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc) +const char *gsm_get_mnc(const struct osmo_plmn_id *plmn) { int i; + uint16_t mcc_hex = gsm_mcc_to_hex(plmn->mcc); + uint16_t mnc_hex = gsm_mnc_to_hex(plmn->mnc, plmn->mnc_3_digits); for (i = 0; gsm_networks[i].name; i++) - if (gsm_networks[i].mcc == mcc && gsm_networks[i].mnc == mnc) + if (gsm_networks[i].mcc_hex == mcc_hex && + gsm_networks[i].mnc_hex == mnc_hex) return gsm_networks[i].name; - return gsm_print_mnc(mnc); + return osmo_mnc_name(plmn->mnc, plmn->mnc_3_digits); } /* get MCC from IMSI */ const char *gsm_imsi_mcc(char *imsi) { int i, found = 0; - uint16_t mcc; + uint16_t mcc_hex; - mcc = ((imsi[0] - '0') << 8) + mcc_hex = ((imsi[0] - '0') << 8) | ((imsi[1] - '0') << 4) | ((imsi[2] - '0')); for (i = 0; gsm_networks[i].name; i++) { - if (gsm_networks[i].mcc == mcc) { + if (gsm_networks[i].mcc_hex == mcc_hex) { found = 1; break; } @@ -1961,15 +1927,15 @@ const char *gsm_imsi_mnc(char *imsi) + imsi[5] - '0'; for (i = 0; gsm_networks[i].name; i++) { - if (gsm_networks[i].mcc != mcc) + if (gsm_networks[i].mcc_hex != mcc) continue; - if ((gsm_networks[i].mnc & 0x00f) == 0x00f) { - if (mnc2 == gsm_networks[i].mnc) { + if ((gsm_networks[i].mnc_hex & 0x00f) == 0x00f) { + if (mnc2 == gsm_networks[i].mnc_hex) { found++; position = i; } } else { - if (mnc3 == gsm_networks[i].mnc) { + if (mnc3 == gsm_networks[i].mnc_hex) { found++; position = i; } diff --git a/src/host/layer23/src/common/settings.c b/src/host/layer23/src/common/settings.c index 6c58e65f1..288b03ed6 100644 --- a/src/host/layer23/src/common/settings.c +++ b/src/host/layer23/src/common/settings.c @@ -68,7 +68,9 @@ int gsm_settings_init(struct osmocom_ms *ms) /* test SIM */ OSMO_STRLCPY_ARRAY(set->test_sim.imsi, "001010000000000"); - set->test_sim.rplmn_mcc = set->test_sim.rplmn_mnc = 1; + set->test_sim.rplmn.mcc = 1; + set->test_sim.rplmn.mnc = 1; + set->test_sim.rplmn.mnc_3_digits = false; set->test_sim.lac = 0x0000; set->test_sim.tmsi = GSM_RESERVED_TMSI; diff --git a/src/host/layer23/src/common/subscriber.c b/src/host/layer23/src/common/subscriber.c index c1f980618..b0c5f1933 100644 --- a/src/host/layer23/src/common/subscriber.c +++ b/src/host/layer23/src/common/subscriber.c @@ -106,7 +106,7 @@ int gsm_subscr_init(struct osmocom_ms *ms) /* set TMSI / LAC invalid */ subscr->tmsi = GSM_RESERVED_TMSI; subscr->ptmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* set key invalid */ subscr->key_seq = 7; @@ -328,22 +328,20 @@ static int subscr_write_plmn_na(struct osmocom_ms *ms) } } -/* del forbidden PLMN. if MCC==0, flush complete list */ -int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc) +/* del forbidden PLMN. if PLMN is NULL, flush complete list */ +int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn) { struct gsm_sub_plmn_na *na, *na2; int deleted = 0; llist_for_each_entry_safe(na, na2, &subscr->plmn_na, entry) { - if (!mcc || (na->mcc == mcc && na->mnc == mnc)) { - LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden " - "PLMNs (mcc=%s, mnc=%s)\n", - gsm_print_mcc(mcc), gsm_print_mnc(mnc)); + if (!plmn || (osmo_plmn_cmp(&na->plmn, plmn) == 0)) { + LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden PLMNs (mcc-mnc=%s)\n", + osmo_plmn_name(&na->plmn)); llist_del(&na->entry); talloc_free(na); deleted = 1; - if (mcc) + if (plmn) break; } } @@ -357,26 +355,24 @@ int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, } /* add forbidden PLMN */ -int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc, uint8_t cause) +int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn, uint8_t cause) { struct gsm_sub_plmn_na *na; /* if already in the list, remove and add to tail */ - gsm_subscr_del_forbidden_plmn(subscr, mcc, mnc); + gsm_subscr_del_forbidden_plmn(subscr, plmn); LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden PLMNs " - "(mcc=%s, mnc=%s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc)); + "(mcc-mnc=%s)\n", osmo_plmn_name(plmn)); na = talloc_zero(subscr->ms, struct gsm_sub_plmn_na); if (!na) return -ENOMEM; - na->mcc = mcc; - na->mnc = mnc; + memcpy(&na->plmn, plmn, sizeof(struct osmo_plmn_id)); na->cause = cause ? : -1; /* cause 0 is not allowed */ llist_add_tail(&na->entry, &subscr->plmn_na); /* don't add Home PLMN to SIM */ - if (subscr->sim_valid && gsm_match_mnc(mcc, mnc, subscr->imsi)) + if (subscr->sim_valid && gsm_match_mnc(plmn->mcc, plmn->mnc, plmn->mnc_3_digits, subscr->imsi)) return -EINVAL; /* update plmn not allowed list on SIM */ @@ -386,13 +382,12 @@ int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, } /* search forbidden PLMN */ -int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc, - uint16_t mnc) +int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, const struct osmo_plmn_id *plmn) { struct gsm_sub_plmn_na *na; llist_for_each_entry(na, &subscr->plmn_na, entry) { - if (na->mcc == mcc && na->mnc == mnc) + if (osmo_plmn_cmp(&na->plmn, plmn) == 0) return 1; } @@ -416,9 +411,10 @@ int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms, print(priv, "MCC |MNC |cause\n"); print(priv, "-------+-------+-------\n"); llist_for_each_entry(temp, &subscr->plmn_na, entry) - print(priv, "%s |%s%s |#%d\n", - gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc), - ((temp->mnc & 0x00f) == 0x00f) ? " ":"", temp->cause); + print(priv, "%s |%-3s |#%d\n", + osmo_mcc_name(temp->plmn.mcc), + osmo_mnc_name(temp->plmn.mnc, temp->plmn.mnc_3_digits), + temp->cause); return 0; } @@ -454,13 +450,12 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr, print(priv, " TMSI 0x%08x", subscr->tmsi); if (subscr->ptmsi != GSM_RESERVED_TMSI) print(priv, " P-TMSI 0x%08x", subscr->ptmsi); - if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) { + if (subscr->lai.lac > 0x0000 && subscr->lai.lac < 0xfffe) { print(priv, "\n"); - print(priv, " LAI: MCC %s MNC %s LAC 0x%04x " - "(%s, %s)\n", gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac, - gsm_get_mcc(subscr->mcc), - gsm_get_mnc(subscr->mcc, subscr->mnc)); + print(priv, " LAI: %s (%s, %s)\n", + osmo_lai_name(&subscr->lai), + gsm_get_mcc(subscr->lai.plmn.mcc), + gsm_get_mnc(&subscr->lai.plmn)); } else print(priv, " LAI: invalid\n"); if (subscr->key_seq != 7) { @@ -470,11 +465,10 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr, print(priv, "\n"); } if (subscr->plmn_valid) - print(priv, " Registered PLMN: MCC %s MNC %s (%s, %s)\n", - gsm_print_mcc(subscr->plmn_mcc), - gsm_print_mnc(subscr->plmn_mnc), - gsm_get_mcc(subscr->plmn_mcc), - gsm_get_mnc(subscr->plmn_mcc, subscr->plmn_mnc)); + print(priv, " Registered PLMN: MCC-MNC %s (%s, %s)\n", + osmo_plmn_name(&subscr->plmn), + gsm_get_mcc(subscr->plmn.mcc), + gsm_get_mnc(&subscr->plmn)); print(priv, " Access barred cells: %s\n", (subscr->acc_barr) ? "yes" : "no"); print(priv, " Access classes:"); @@ -488,22 +482,21 @@ void gsm_subscr_dump(struct gsm_subscriber *subscr, print(priv, " -------+-------\n"); llist_for_each_entry(plmn_list, &subscr->plmn_list, entry) print(priv, " %s |%s (%s, %s)\n", - gsm_print_mcc(plmn_list->mcc), - gsm_print_mnc(plmn_list->mnc), - gsm_get_mcc(plmn_list->mcc), - gsm_get_mnc(plmn_list->mcc, plmn_list->mnc)); + osmo_mcc_name(plmn_list->plmn.mcc), + osmo_mnc_name(plmn_list->plmn.mnc, plmn_list->plmn.mnc_3_digits), + gsm_get_mcc(plmn_list->plmn.mcc), + gsm_get_mnc(&plmn_list->plmn)); } if (!llist_empty(&subscr->plmn_na)) { print(priv, " List of forbidden PLMNs:\n"); print(priv, " MCC |MNC |cause\n"); print(priv, " -------+-------+-------\n"); llist_for_each_entry(plmn_na, &subscr->plmn_na, entry) - print(priv, " %s |%s%s |#%d " - "(%s, %s)\n", gsm_print_mcc(plmn_na->mcc), - gsm_print_mnc(plmn_na->mnc), - ((plmn_na->mnc & 0x00f) == 0x00f) ? " ":"", - plmn_na->cause, gsm_get_mcc(plmn_na->mcc), - gsm_get_mnc(plmn_na->mcc, plmn_na->mnc)); + print(priv, " %s |%-3s |#%d (%s, %s)\n", + osmo_mcc_name(plmn_na->plmn.mcc), + osmo_mnc_name(plmn_na->plmn.mnc, plmn_na->plmn.mnc_3_digits), + plmn_na->cause, gsm_get_mcc(plmn_na->plmn.mcc), + gsm_get_mnc(&plmn_na->plmn)); } } @@ -528,11 +521,9 @@ int gsm_subscr_insert_testcard(struct osmocom_ms *ms) subscr->acc_barr = set->test_sim.barr; /* we may access barred cell */ subscr->acc_class = 0xffff; /* we have any access class */ subscr->plmn_valid = set->test_sim.rplmn_valid; - subscr->plmn_mcc = set->test_sim.rplmn_mcc; - subscr->plmn_mnc = set->test_sim.rplmn_mnc; - subscr->mcc = set->test_sim.rplmn_mcc; - subscr->mnc = set->test_sim.rplmn_mnc; - subscr->lac = set->test_sim.lac; + memcpy(&subscr->plmn, &set->test_sim.rplmn, sizeof(struct osmo_plmn_id)); + memcpy(&subscr->lai.plmn, &set->test_sim.rplmn, sizeof(struct osmo_plmn_id)); + subscr->lai.lac = set->test_sim.lac; subscr->tmsi = set->test_sim.tmsi; subscr->ptmsi = GSM_RESERVED_TMSI; subscr->always_search_hplmn = set->test_sim.always; @@ -549,10 +540,10 @@ int gsm_subscr_insert_testcard(struct osmocom_ms *ms) gsm_imsi_mnc(subscr->imsi)); if (subscr->plmn_valid) - LOGP(DMM, LOGL_INFO, "-> Test card registered to %s %s 0x%04x" - "(%s, %s)\n", gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac, gsm_get_mcc(subscr->mcc), - gsm_get_mnc(subscr->mcc, subscr->mnc)); + LOGP(DMM, LOGL_INFO, "-> Test card registered to %s" + "(%s, %s)\n", osmo_lai_name(&subscr->lai), + gsm_get_mcc(subscr->lai.plmn.mcc), + gsm_get_mnc(&subscr->lai.plmn)); else LOGP(DMM, LOGL_INFO, "-> Test card not registered\n"); if (subscr->imsi_attached) @@ -654,8 +645,7 @@ static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data, subscr->tmsi = ntohl(loci->tmsi); /* LAI */ - gsm48_decode_lai_hex(&loci->lai, &subscr->mcc, &subscr->mnc, - &subscr->lac); + gsm48_decode_lai2(&loci->lai, &subscr->lai); /* location update status */ switch (loci->lupd_status & 0x07) { @@ -670,9 +660,8 @@ static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data, subscr->ustate = GSM_SIM_U2_NOT_UPDATED; } - LOGP(DMM, LOGL_INFO, "received LOCI from SIM (mcc=%s mnc=%s lac=0x%04x " - "U%d)\n", gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac, subscr->ustate); + LOGP(DMM, LOGL_INFO, "received LOCI from SIM (lai=%s U%d)\n", + osmo_lai_name(&subscr->lai), subscr->ustate); return 0; } @@ -760,8 +749,6 @@ static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data, struct gsm_subscriber *subscr = &ms->subscr; struct gsm_sub_plmn_list *plmn; struct llist_head *lh, *lh2; - uint8_t lai[5]; - uint16_t dummy_lac; /* flush list */ llist_for_each_safe(lh, lh2, &subscr->plmn_list) { @@ -778,16 +765,11 @@ static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data, plmn = talloc_zero(ms, struct gsm_sub_plmn_list); if (!plmn) return -ENOMEM; - lai[0] = data[0]; - lai[1] = data[1]; - lai[2] = data[2]; - gsm48_decode_lai_hex((struct gsm48_loc_area_id *)lai, - &plmn->mcc, &plmn->mnc, &dummy_lac); + osmo_plmn_to_bcd(&data[0], &plmn->plmn); llist_add_tail(&plmn->entry, &subscr->plmn_list); - LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc=%s mnc=%s) " - "from SIM\n", - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc)); + LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc-mnc=%s) from SIM\n", + osmo_plmn_name(&plmn->plmn)); data += 3; length -= 3; @@ -860,8 +842,6 @@ static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data, struct gsm_subscriber *subscr = &ms->subscr; struct gsm_sub_plmn_na *na; struct llist_head *lh, *lh2; - uint8_t lai[5]; - uint16_t dummy_lac; #ifdef TEST_EMPTY_FPLMN return 0; @@ -882,13 +862,9 @@ static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data, na = talloc_zero(ms, struct gsm_sub_plmn_na); if (!na) return -ENOMEM; - lai[0] = data[0]; - lai[1] = data[1]; - lai[2] = data[2]; - gsm48_decode_lai_hex((struct gsm48_loc_area_id *)lai, &na->mcc, - &na->mnc, &dummy_lac); - LOGP(DMM, LOGL_INFO, "received Forbidden PLMN %s %s from SIM\n", - gsm_print_mcc(na->mcc), gsm_print_mnc(na->mnc)); + osmo_plmn_to_bcd(&data[0], &na->plmn); + LOGP(DMM, LOGL_INFO, "received Forbidden PLMN %s from SIM\n", + osmo_plmn_name(&na->plmn)); na->cause = -1; /* must have a value, but SIM stores no cause */ llist_add_tail(&na->entry, &subscr->plmn_na); @@ -936,16 +912,13 @@ static int subscr_sim_request(struct osmocom_ms *ms) gsm_imsi_mcc(subscr->imsi), gsm_imsi_mnc(subscr->imsi)); /* if LAI is valid, set RPLMN */ - if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) { + if (subscr->lai.lac > 0x0000 && subscr->lai.lac < 0xfffe) { subscr->plmn_valid = 1; - subscr->plmn_mcc = subscr->mcc; - subscr->plmn_mnc = subscr->mnc; - LOGP(DMM, LOGL_INFO, "-> SIM card registered to %s %s " - "(%s, %s)\n", gsm_print_mcc(subscr->plmn_mcc), - gsm_print_mnc(subscr->plmn_mnc), - gsm_get_mcc(subscr->plmn_mcc), - gsm_get_mnc(subscr->plmn_mcc, - subscr->plmn_mnc)); + memcpy(&subscr->plmn, &subscr->lai.plmn, sizeof(struct osmo_plmn_id)); + LOGP(DMM, LOGL_INFO, "-> SIM card registered to %s (%s, %s)\n", + osmo_plmn_name(&subscr->plmn), + gsm_get_mcc(subscr->plmn.mcc), + gsm_get_mnc(&subscr->plmn)); } else LOGP(DMM, LOGL_INFO, "-> SIM card not registered\n"); @@ -1138,7 +1111,6 @@ static int subscr_write_plmn_na_simcard(struct osmocom_ms *ms) struct gsm_sub_plmn_na *na, *nas[4] = { NULL, NULL, NULL, NULL }; int count = 0, i; uint8_t *data; - uint8_t lai[5]; #ifdef TEST_EMPTY_FPLMN return 0; @@ -1170,11 +1142,8 @@ static int subscr_write_plmn_na_simcard(struct osmocom_ms *ms) nsh->file = 0x6f7b; for (i = 0; i < 4; i++) { if (nas[i]) { - gsm48_encode_lai_hex((struct gsm48_loc_area_id *)lai, - nas[i]->mcc, nas[i]->mnc, 0); - *data++ = lai[0]; - *data++ = lai[1]; - *data++ = lai[2]; + osmo_plmn_to_bcd(data, &nas[i]->plmn); + data += 3; } else { *data++ = 0xff; *data++ = 0xff; @@ -1209,7 +1178,7 @@ static int gsm_subscr_write_loci_simcard(struct osmocom_ms *ms) loci->tmsi = htonl(subscr->tmsi); /* LAI */ - gsm48_encode_lai_hex(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac); + gsm48_generate_lai2(&loci->lai, &subscr->lai); /* TMSI time */ loci->tmsi_time = 0xff; diff --git a/src/host/layer23/src/common/sysinfo.c b/src/host/layer23/src/common/sysinfo.c index 42bc8abfa..700accd0c 100644 --- a/src/host/layer23/src/common/sysinfo.c +++ b/src/host/layer23/src/common/sysinfo.c @@ -22,6 +22,7 @@ #include #include +#include #include @@ -203,12 +204,10 @@ int gsm48_sysinfo_dump(const struct gsm48_sysinfo *s, uint16_t arfcn, /* serving cell */ print(priv, "Serving Cell:\n"); - print(priv, " BSIC = %d,%d MCC = %s MNC = %s LAC = 0x%04x Cell ID " - "= 0x%04x\n", s->bsic >> 3, s->bsic & 0x7, - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac, - s->cell_id); - print(priv, " Country = %s Network Name = %s\n", gsm_get_mcc(s->mcc), - gsm_get_mnc(s->mcc, s->mnc)); + print(priv, " BSIC = %d,%d LAI = %s Cell ID = 0x%04x\n", + s->bsic >> 3, s->bsic & 0x7, osmo_lai_name(&s->lai), s->cell_id); + print(priv, " Country = %s Network Name = %s\n", + gsm_get_mcc(s->lai.plmn.mcc), gsm_get_mnc(&s->lai.plmn)); print(priv, " MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n", s->max_retrans, s->tx_integer, (s->reest_denied) ? "denied" : "allowed"); @@ -685,7 +684,7 @@ int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s, /* Cell Identity */ s->cell_id = ntohs(si->cell_identity); /* LAI */ - gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac); + gsm48_decode_lai2(&si->lai, &s->lai); /* Control Channel Description */ gsm48_decode_ccd(s, &si->control_channel_desc); /* Cell Options (BCCH) */ @@ -699,8 +698,7 @@ int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s, gsm48_decode_si3_rest(s, si->rest_octets, payload_len); LOGP(DRR, LOGL_INFO, - "New SYSTEM INFORMATION 3 (mcc %s mnc %s lac 0x%04x)\n", - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac); + "New SYSTEM INFORMATION 3 (lai=%s)\n", osmo_lai_name(&s->lai)); s->si3 = 1; @@ -718,7 +716,7 @@ int gsm48_decode_sysinfo4(struct gsm48_sysinfo *s, memcpy(s->si4_msg, si, OSMO_MIN(len, sizeof(s->si4_msg))); /* LAI */ - gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac); + gsm48_decode_lai2(&si->lai, &s->lai); /* Cell Selection Parameters */ gsm48_decode_cell_sel_param(s, &si->cell_sel_par); /* RACH Control Parameter */ @@ -828,7 +826,7 @@ int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s, "read.\n"); s->cell_id = ntohs(si->cell_identity); /* LAI */ - gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac); + gsm48_decode_lai2(&si->lai, &s->lai); /* Cell Options (SACCH) */ gsm48_decode_cellopt_sacch(s, &si->cell_options); /* NCC Permitted */ @@ -923,29 +921,3 @@ int gsm48_decode_sysinfo13(struct gsm48_sysinfo *s, return 0; } - -int gsm48_encode_lai_hex(struct gsm48_loc_area_id *lai, - uint16_t mcc, uint16_t mnc, uint16_t lac) -{ - lai->digits[0] = (mcc >> 8) | (mcc & 0xf0); - lai->digits[1] = (mcc & 0x0f) | (mnc << 4); - lai->digits[2] = (mnc >> 8) | (mnc & 0xf0); - lai->lac = htons(lac); - - return 0; -} - -int gsm48_decode_lai_hex(const struct gsm48_loc_area_id *lai, - uint16_t *mcc, uint16_t *mnc, uint16_t *lac) -{ - *mcc = ((lai->digits[0] & 0x0f) << 8) - | (lai->digits[0] & 0xf0) - | (lai->digits[1] & 0x0f); - *mnc = ((lai->digits[2] & 0x0f) << 8) - | (lai->digits[2] & 0xf0) - | ((lai->digits[1] & 0xf0) >> 4); - *lac = ntohs(lai->lac); - - return 0; -} - diff --git a/src/host/layer23/src/common/vty.c b/src/host/layer23/src/common/vty.c index 427c8aa36..424efb22f 100644 --- a/src/host/layer23/src/common/vty.c +++ b/src/host/layer23/src/common/vty.c @@ -503,18 +503,16 @@ static int _sim_test_cmd(struct vty *vty, int argc, const char *argv[], return CMD_WARNING; } if (argc >= 3) { - uint16_t mcc = gsm_input_mcc((char *)argv[1]); - uint16_t mnc = gsm_input_mnc((char *)argv[2]); - if (mcc == GSM_INPUT_INVALID) { + struct osmo_plmn_id plmn; + if (osmo_mcc_from_str(argv[1], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[2], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - set->test_sim.rplmn_mcc = mcc; - set->test_sim.rplmn_mnc = mnc; + memcpy(&set->test_sim.rplmn, &plmn, sizeof(plmn)); set->test_sim.rplmn_valid = 1; } else { set->test_sim.rplmn_valid = 0; @@ -743,26 +741,26 @@ DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC", " (use 0000 to remove LAI)") { struct osmocom_ms *ms; - uint16_t mcc = gsm_input_mcc((char *)argv[1]), - mnc = gsm_input_mnc((char *)argv[2]), - lac = strtoul(argv[3], NULL, 16); + struct osmo_plmn_id plmn; + uint16_t lac; ms = l23_vty_get_ms(argv[0], vty); if (!ms) return CMD_WARNING; - if (mcc == GSM_INPUT_INVALID) { + if (osmo_mcc_from_str(argv[1], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[2], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - ms->subscr.mcc = mcc; - ms->subscr.mnc = mnc; - ms->subscr.lac = lac; + lac = strtoul(argv[3], NULL, 0); + + memcpy(&ms->subscr.lai.plmn, &plmn, sizeof(plmn)); + ms->subscr.lai.lac = lac; ms->subscr.tmsi = GSM_RESERVED_TMSI; gsm_subscr_write_loci(ms); @@ -1044,7 +1042,9 @@ DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn", struct gsm_settings *set = &ms->settings; set->test_sim.rplmn_valid = 0; - set->test_sim.rplmn_mcc = set->test_sim.rplmn_mnc = 1; + set->test_sim.rplmn.mcc = 1; + set->test_sim.rplmn.mnc = 1; + set->test_sim.rplmn.mnc_3_digits = false; set->test_sim.lac = 0x0000; set->test_sim.tmsi = GSM_RESERVED_TMSI; @@ -1058,20 +1058,18 @@ static int _test_rplmn_cmd(struct vty *vty, int argc, const char *argv[], { struct osmocom_ms *ms = vty->index; struct gsm_settings *set = &ms->settings; - uint16_t mcc = gsm_input_mcc((char *)argv[0]), - mnc = gsm_input_mnc((char *)argv[1]); + struct osmo_plmn_id plmn; - if (mcc == GSM_INPUT_INVALID) { + if (osmo_mcc_from_str(argv[0], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[1], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } set->test_sim.rplmn_valid = 1; - set->test_sim.rplmn_mcc = mcc; - set->test_sim.rplmn_mnc = mnc; + memcpy(&set->test_sim.rplmn, &plmn, sizeof(plmn)); if (argc >= 3) set->test_sim.lac = strtoul(argv[2], NULL, 16); @@ -1205,8 +1203,8 @@ static int l23_vty_config_write_testsim_node(struct vty *vty, const struct osmoc (set->test_sim.barr) ? "" : "no ", VTY_NEWLINE); if (set->test_sim.rplmn_valid) { vty_out(vty, "%s rplmn %s %s", prefix, - gsm_print_mcc(set->test_sim.rplmn_mcc), - gsm_print_mnc(set->test_sim.rplmn_mnc)); + osmo_mcc_name(set->test_sim.rplmn.mcc), + osmo_mnc_name(set->test_sim.rplmn.mnc, set->test_sim.rplmn.mnc_3_digits)); if (set->test_sim.lac > 0x0000 && set->test_sim.lac < 0xfffe) { vty_out(vty, " 0x%04x", set->test_sim.lac); if (set->test_sim.tmsi != GSM_RESERVED_TMSI) { diff --git a/src/host/layer23/src/misc/cell_log.c b/src/host/layer23/src/misc/cell_log.c index 7635f1f29..ed4d74d1f 100644 --- a/src/host/layer23/src/misc/cell_log.c +++ b/src/host/layer23/src/misc/cell_log.c @@ -98,7 +98,7 @@ static struct log_si { uint16_t flags; uint8_t bsic; int8_t rxlev_dbm; - uint16_t mcc, mnc, lac, cellid; + struct osmo_cell_global_id cgi; uint8_t ta; double latitude, longitude; } log_si; @@ -187,9 +187,10 @@ static void log_sysinfo(void) if (log_si.ta != 0xff) sprintf(ta_str, " TA=%d", log_si.ta); - LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n", - arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), - gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str); + LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC-MNC=%s (%s, %s)%s\n", + arfcn, osmo_plmn_name(&s->lai.plmn), + gsm_get_mcc(s->lai.plmn.mcc), + gsm_get_mnc(&s->lai.plmn), ta_str); LOGFILE("[sysinfo]\n"); LOGFILE("arfcn %d\n", s->arfcn); diff --git a/src/host/layer23/src/misc/gsmmap.c b/src/host/layer23/src/misc/gsmmap.c index d98f23020..378b358ba 100644 --- a/src/host/layer23/src/misc/gsmmap.c +++ b/src/host/layer23/src/misc/gsmmap.c @@ -121,13 +121,13 @@ static void add_sysinfo(void) 23); printf("--------------------------------------------------------------------------\n"); gsm48_sysinfo_dump(&s, sysinfo.arfcn, print_si, stdout, NULL); - mcc = get_node_mcc(s.mcc); + mcc = get_node_mcc(s.lai.plmn.mcc); if (!mcc) nomem(); - mnc = get_node_mnc(mcc, s.mnc); + mnc = get_node_mnc(mcc, s.lai.plmn.mnc, s.lai.plmn.mnc_3_digits); if (!mnc) nomem(); - lac = get_node_lac(mnc, s.lac); + lac = get_node_lac(mnc, s.lai.lac); if (!lac) nomem(); cell = get_node_cell(lac, s.cell_id); @@ -296,8 +296,7 @@ void kml_footer(FILE *outfp) } -void kml_meas(FILE *outfp, struct node_meas *meas, int n, uint16_t mcc, - uint16_t mnc, uint16_t lac, uint16_t cellid) +static void kml_meas(FILE *outfp, struct node_meas *meas, int n, const struct osmo_cell_global_id *cgi) { struct tm *tm = localtime(&meas->gmt); @@ -305,8 +304,11 @@ void kml_meas(FILE *outfp, struct node_meas *meas, int n, uint16_t mcc, fprintf(outfp, "\t\t\t\t\t\t%d: %d\n", n, meas->rxlev); fprintf(outfp, "\t\t\t\t\t\t\n"); fprintf(outfp, "MCC=%s MNC=%s\nLAC=%04x CELL-ID=%04x\n(%s %s)\n", - gsm_print_mcc(mcc), gsm_print_mnc(mnc), lac, cellid, - gsm_get_mcc(mcc), gsm_get_mnc(mcc, mnc)); + osmo_mcc_name(cgi->lai.plmn.mcc), + osmo_mnc_name(cgi->lai.plmn.mnc, cgi->lai.plmn.mnc_3_digits), + cgi->lai.lac, cgi->cell_identity, + gsm_get_mcc(cgi->lai.plmn.mcc), + gsm_get_mnc(&cgi->lai.plmn)); fprintf(outfp, "\n%s", asctime(tm)); fprintf(outfp, "RX-LEV %d dBm\n", meas->rxlev); if (meas->ta_valid) @@ -423,11 +425,11 @@ void kml_cell(FILE *outfp, struct node_cell *cell) return; fprintf(outfp, "\t\t\t\t\t\n"); - fprintf(outfp, "\t\t\t\t\t\tMCC=%s MNC=%s\nLAC=%04x " - "CELL-ID=%04x\n(%s %s)\n", gsm_print_mcc(cell->s.mcc), - gsm_print_mnc(cell->s.mnc), cell->s.lac, cell->s.cell_id, - gsm_get_mcc(cell->s.mcc), - gsm_get_mnc(cell->s.mcc, cell->s.mnc)); + fprintf(outfp, "\t\t\t\t\t\tLAI=%s " + "CELL-ID=%04x\n(%s %s)\n", + osmo_lai_name(&cell->s.lai), cell->s.cell_id, + gsm_get_mcc(cell->s.lai.plmn.mcc), + gsm_get_mnc(&cell->s.lai.plmn)); fprintf(outfp, "\t\t\t\t\t\t\n"); gsm48_sysinfo_dump(&cell->s, cell->sysinfo.arfcn, print_si, outfp, NULL); @@ -576,15 +578,20 @@ usage: /* folder open */ fprintf(outfp, "\t\n"); fprintf(outfp, "\t\tMCC %s (%s)\n", - gsm_print_mcc(mcc->mcc), gsm_get_mcc(mcc->mcc)); + osmo_mcc_name(mcc->mcc), gsm_get_mcc(mcc->mcc)); fprintf(outfp, "\t\t0\n"); mnc = mcc->mnc; while (mnc) { + struct osmo_plmn_id plmn = { + .mcc = mcc->mcc, + .mnc = mnc->mnc, + .mnc_3_digits = mnc->mnc_3_digits, + }; printf(" MNC: %02x\n", mnc->mnc); /* folder open */ fprintf(outfp, "\t\t\n"); fprintf(outfp, "\t\t\tMNC %s (%s)\n", - gsm_print_mnc(mnc->mnc), gsm_get_mnc(mcc->mcc, mnc->mnc)); + osmo_mnc_name(mnc->mnc, mnc->mnc_3_digits), gsm_get_mnc(&plmn)); fprintf(outfp, "\t\t\t0\n"); lac = mnc->lac; while (lac) { @@ -604,9 +611,20 @@ usage: while (meas) { if (meas->ta_valid) printf(" TA: %d\n", meas->ta); - if (meas->gps_valid) - kml_meas(outfp, meas, ++n, mcc->mcc, mnc->mnc, - lac->lac, cell->cellid); + if (meas->gps_valid) { + struct osmo_cell_global_id cgi = { + .lai = { + .plmn = { + .mcc = mcc->mcc, + .mnc = mnc->mnc, + .mnc_3_digits = mnc->mnc_3_digits, + }, + .lac = lac->lac, + }, + .cell_identity = cell->cellid, + }; + kml_meas(outfp, meas, ++n, &cgi); + } meas = meas->next; } kml_cell(outfp, cell); diff --git a/src/host/layer23/src/misc/log.c b/src/host/layer23/src/misc/log.c index bd8de7f8a..577e12689 100644 --- a/src/host/layer23/src/misc/log.c +++ b/src/host/layer23/src/misc/log.c @@ -55,18 +55,22 @@ struct node_mcc *get_node_mcc(uint16_t mcc) return node_mcc; } -struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc) +struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc, bool mnc_3_digits) { struct node_mnc *node_mnc; struct node_mnc **node_mnc_p = &mcc->mnc; while (*node_mnc_p) { /* found in list */ - if ((*node_mnc_p)->mnc == mnc) + if ((*node_mnc_p)->mnc == mnc && + (*node_mnc_p)->mnc_3_digits == mnc_3_digits) return *node_mnc_p; /* insert into list */ - if ((*node_mnc_p)->mnc > mnc) + if (((*node_mnc_p)->mnc > mnc) || + ((*node_mnc_p)->mnc == mnc && + (*node_mnc_p)->mnc_3_digits > mnc_3_digits)) { break; + } node_mnc_p = &((*node_mnc_p)->next); } @@ -75,6 +79,7 @@ struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc) if (!node_mnc) return NULL; node_mnc->mnc = mnc; + node_mnc->mnc_3_digits = mnc_3_digits; node_mnc->next = *node_mnc_p; *node_mnc_p = node_mnc; return node_mnc; diff --git a/src/host/layer23/src/mobile/gsm322.c b/src/host/layer23/src/mobile/gsm322.c index d7b415408..f21cb5969 100644 --- a/src/host/layer23/src/mobile/gsm322.c +++ b/src/host/layer23/src/mobile/gsm322.c @@ -46,8 +46,7 @@ const char *ba_version = "osmocom BA V1\n"; static void gsm322_cs_timeout(void *arg); -static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc, - uint16_t mnc, int any); +static int gsm322_cs_select(struct osmocom_ms *ms, int index, const struct osmo_plmn_id *plmn, int any); static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg); static void gsm322_any_timeout(void *arg); static int gsm322_nb_scan(struct osmocom_ms *ms); @@ -513,7 +512,7 @@ static void gsm322_unselect_cell(struct gsm322_cellsel *cs) cs->si->si5 = 0; /* unset SI5* */ cs->si = NULL; memset(&cs->sel_si, 0, sizeof(cs->sel_si)); - cs->sel_mcc = cs->sel_mnc = cs->sel_lac = cs->sel_id = 0; + memset(&cs->sel_cgi, 0, sizeof(cs->sel_cgi)); } /* print to DCS logging */ @@ -535,17 +534,15 @@ static void print_dcs(void *priv, const char *fmt, ...) } /* del forbidden LA */ -int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac) +int gsm322_del_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai) { struct gsm322_plmn *plmn = &ms->plmn; struct gsm322_la_list *la; llist_for_each_entry(la, &plmn->forbidden_la, entry) { - if (la->mcc == mcc && la->mnc == mnc && la->lac == lac) { - LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden " - "LAs (mcc=%s, mnc=%s, lac=%04x)\n", - gsm_print_mcc(mcc), gsm_print_mnc(mnc), lac); + if (osmo_lai_cmp(&la->lai, lai) == 0) { + LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden LAs (LAI=%s)\n", + osmo_lai_name(lai)); llist_del(&la->entry); talloc_free(la); return 0; @@ -556,21 +553,16 @@ int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, } /* add forbidden LA */ -int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, uint16_t lac, uint8_t cause) +int gsm322_add_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai, uint8_t cause) { struct gsm322_plmn *plmn = &ms->plmn; struct gsm322_la_list *la; - LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden LAs " - "(mcc=%s, mnc=%s, lac=%04x)\n", gsm_print_mcc(mcc), - gsm_print_mnc(mnc), lac); + LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden LAs (LAI=%s)\n", osmo_lai_name(lai)); la = talloc_zero(ms, struct gsm322_la_list); if (!la) return -ENOMEM; - la->mcc = mcc; - la->mnc = mnc; - la->lac = lac; + la->lai = *lai; la->cause = cause; llist_add_tail(&la->entry, &plmn->forbidden_la); @@ -578,14 +570,13 @@ int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, } /* search forbidden LA */ -int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc, - uint16_t lac) +int gsm322_is_forbidden_la(struct osmocom_ms *ms, const struct osmo_location_area_id *lai) { struct gsm322_plmn *plmn = &ms->plmn; struct gsm322_la_list *la; llist_for_each_entry(la, &plmn->forbidden_la, entry) { - if (la->mcc == mcc && la->mnc == mnc && la->lac == lac) + if (osmo_lai_cmp(&la->lai, lai) == 0) return 1; } @@ -593,15 +584,13 @@ int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc, } /* search for PLMN in all BA lists */ -static struct gsm322_ba_list *gsm322_find_ba_list(struct gsm322_cellsel *cs, - uint16_t mcc, uint16_t mnc) +static struct gsm322_ba_list *gsm322_find_ba_list(struct gsm322_cellsel *cs, const struct osmo_plmn_id *plmn) { struct gsm322_ba_list *ba, *ba_found = NULL; /* search for BA list */ llist_for_each_entry(ba, &cs->ba_list, entry) { - if (ba->mcc == mcc - && ba->mnc == mnc) { + if (osmo_plmn_cmp(&ba->plmn, plmn) == 0) { ba_found = ba; break; } @@ -611,16 +600,14 @@ static struct gsm322_ba_list *gsm322_find_ba_list(struct gsm322_cellsel *cs, } /* search available PLMN */ -int gsm322_is_plmn_avail_and_allow(struct gsm322_cellsel *cs, uint16_t mcc, - uint16_t mnc) +int gsm322_is_plmn_avail_and_allow(struct gsm322_cellsel *cs, const struct osmo_plmn_id *plmn) { int i; for (i = 0; i <= 1023+299; i++) { if ((cs->list[i].flags & GSM322_CS_FLAG_TEMP_AA) && cs->list[i].sysinfo - && cs->list[i].sysinfo->mcc == mcc - && cs->list[i].sysinfo->mnc == mnc) + && (osmo_plmn_cmp(&cs->list[i].sysinfo->lai.plmn, plmn) == 0)) return 1; } @@ -635,9 +622,12 @@ int gsm322_is_hplmn_avail(struct gsm322_cellsel *cs, char *imsi) for (i = 0; i <= 1023+299; i++) { if ((cs->list[i].flags & GSM322_CS_FLAG_SYSINFO) && cs->list[i].sysinfo - && gsm_match_mnc(cs->list[i].sysinfo->mcc, - cs->list[i].sysinfo->mnc, imsi)) + && gsm_match_mnc(cs->list[i].sysinfo->lai.plmn.mcc, + cs->list[i].sysinfo->lai.plmn.mnc, + cs->list[i].sysinfo->lai.plmn.mnc_3_digits, + imsi)) return 1; + /* TODO: take into account mnc_3_digits, probably use osmo_mnc_cmp()*/ } return 0; @@ -899,8 +889,7 @@ static int gsm322_sort_list(struct osmocom_ms *ms) /* search if network has multiple cells */ found = NULL; llist_for_each_entry(temp, &temp_list, entry) { - if (temp->mcc == cs->list[i].sysinfo->mcc - && temp->mnc == cs->list[i].sysinfo->mnc) { + if (osmo_plmn_cmp(&temp->plmn, &cs->list[i].sysinfo->lai.plmn) == 0) { found = temp; break; } @@ -913,8 +902,7 @@ static int gsm322_sort_list(struct osmocom_ms *ms) temp = talloc_zero(ms, struct gsm322_plmn_list); if (!temp) return -ENOMEM; - temp->mcc = cs->list[i].sysinfo->mcc; - temp->mnc = cs->list[i].sysinfo->mnc; + memcpy(&temp->plmn, &cs->list[i].sysinfo->lai.plmn, sizeof(temp->plmn)); temp->rxlev = cs->list[i].rxlev; llist_add_tail(&temp->entry, &temp_list); } @@ -924,7 +912,7 @@ static int gsm322_sort_list(struct osmocom_ms *ms) if (subscr->sim_valid) { found = NULL; llist_for_each_entry(temp, &temp_list, entry) { - if (gsm_match_mnc(temp->mcc, temp->mnc, subscr->imsi)) { + if (gsm_match_mnc(temp->plmn.mcc, temp->plmn.mnc, temp->plmn.mnc_3_digits, subscr->imsi)) { found = temp; break; } @@ -940,8 +928,7 @@ static int gsm322_sort_list(struct osmocom_ms *ms) llist_for_each_entry(sim_entry, &subscr->plmn_list, entry) { found = NULL; llist_for_each_entry(temp, &temp_list, entry) { - if (temp->mcc == sim_entry->mcc - && temp->mnc == sim_entry->mnc) { + if (osmo_plmn_cmp(&temp->plmn, &sim_entry->plmn) == 0) { found = temp; break; } @@ -995,16 +982,15 @@ static int gsm322_sort_list(struct osmocom_ms *ms) i = 0; llist_for_each_entry(temp, &plmn->sorted_plmn, entry) { llist_for_each_entry(na_entry, &subscr->plmn_na, entry) { - if (temp->mcc == na_entry->mcc - && temp->mnc == na_entry->mnc) { + if (osmo_plmn_cmp(&temp->plmn, &na_entry->plmn) == 0) { temp->cause = na_entry->cause; break; } } LOGP(DPLMN, LOGL_INFO, "Creating Sorted PLMN list. " - "(%02d: mcc %s mnc %s allowed %s rx-lev %s)\n", - i, gsm_print_mcc(temp->mcc), - gsm_print_mnc(temp->mnc), (temp->cause) ? "no ":"yes", + "(%02d: mcc-mnc %s allowed %s rx-lev %s)\n", + i, osmo_plmn_name(&temp->plmn), + (temp->cause) ? "no ":"yes", gsm_print_rxlev(temp->rxlev)); i++; } @@ -1027,9 +1013,9 @@ static int gsm322_a_go_on_plmn(struct osmocom_ms *ms, struct msgb *msg) new_a_state(plmn, GSM322_A2_ON_PLMN); /* start timer, if on VPLMN of home country OR special case */ - if (!gsm_match_mnc(plmn->mcc, plmn->mnc, subscr->imsi) + if (!gsm_match_mnc(plmn->plmn.mcc, plmn->plmn.mnc, plmn->plmn.mnc_3_digits, subscr->imsi) && (subscr->always_search_hplmn - || gsm_match_mcc(plmn->mcc, subscr->imsi)) + || gsm_match_mcc(plmn->plmn.mcc, subscr->imsi)) && subscr->sim_valid && subscr->t6m_hplmn) start_plmn_timer(plmn, subscr->t6m_hplmn * 360); else @@ -1070,7 +1056,7 @@ static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg) int found; /* any allowable PLMN available? */ - found = gsm322_cs_select(ms, -1, 0, 0, 0); + found = gsm322_cs_select(ms, -1, NULL, 0); /* if no PLMN in list: * this means that we are at a point where we camp on any cell or @@ -1079,32 +1065,28 @@ static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg) if (subscr->plmn_valid) { LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. " "Do limited search with RPLMN.\n"); - plmn->mcc = subscr->plmn_mcc; - plmn->mnc = subscr->plmn_mnc; + memcpy(&plmn->plmn, &subscr->plmn, sizeof(struct osmo_plmn_id)); } else if (subscr->sim_valid) { LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. " "Do limited search with HPLMN.\n"); - plmn->mcc = subscr->mcc; - plmn->mnc = subscr->mnc; + memcpy(&plmn->plmn, &subscr->plmn, sizeof(struct osmo_plmn_id)); } else { LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. " "Do limited search with no PLMN.\n"); - plmn->mcc = 0; - plmn->mnc = 0; + memset(&plmn->plmn, 0, sizeof(struct osmo_plmn_id)); } return gsm322_a_go_wait_for_plmns(ms, msg); } /* select first PLMN in list */ - plmn->mcc = cs->list[found].sysinfo->mcc; - plmn->mnc = cs->list[found].sysinfo->mnc; + memcpy(&plmn->plmn, &cs->list[found].sysinfo->lai.plmn, sizeof(struct osmo_plmn_id)); LOGP(DPLMN, LOGL_INFO, "PLMN available after searching PLMN list " - "(mcc=%s mnc=%s %s, %s)\n", - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc)); + "(mcc=-mnc=%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), gsm_get_mnc(&plmn->plmn)); /* indicate New PLMN */ nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN); @@ -1133,10 +1115,9 @@ static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg) i = 0; llist_for_each_entry(plmn_entry, &plmn->sorted_plmn, entry) { /* if last selected PLMN was HPLMN, we skip that */ - if (gsm_match_mnc(plmn_entry->mcc, plmn_entry->mnc, - subscr->imsi) - && plmn_entry->mcc == plmn->mcc - && plmn_entry->mnc == plmn->mnc) { + if (gsm_match_mnc(plmn_entry->plmn.mcc, plmn_entry->plmn.mnc, + plmn_entry->plmn.mnc_3_digits, subscr->imsi) + && (osmo_plmn_cmp(&plmn_entry->plmn, &plmn->plmn) == 0)) { LOGP(DPLMN, LOGL_INFO, "Skip HPLMN, because it was " "previously selected.\n"); i++; @@ -1147,10 +1128,9 @@ static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg) plmn_first = plmn_entry; break; } - LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), " + LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc-mnc=%s), " "because it is not allowed (cause %d).\n", i, - gsm_print_mcc(plmn_entry->mcc), - gsm_print_mnc(plmn_entry->mnc), + osmo_plmn_name(&plmn_entry->plmn), plmn_entry->cause); i++; } @@ -1164,15 +1144,14 @@ static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg) return 0; } - LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%s " - "mnc=%s %s, %s)\n", plmn->plmn_curr, - gsm_print_mcc(plmn_first->mcc), gsm_print_mnc(plmn_first->mnc), - gsm_get_mcc(plmn_first->mcc), - gsm_get_mnc(plmn_first->mcc, plmn_first->mnc)); + LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc-mnc=%s %s, %s)\n", + plmn->plmn_curr, + osmo_plmn_name(&plmn_first->plmn), + gsm_get_mcc(plmn_first->plmn.mcc), + gsm_get_mnc(&plmn_first->plmn)); /* set current network */ - plmn->mcc = plmn_first->mcc; - plmn->mnc = plmn_first->mnc; + memcpy(&plmn->plmn, &plmn_first->plmn, sizeof(struct osmo_plmn_id)); new_a_state(plmn, GSM322_A3_TRYING_PLMN); @@ -1208,10 +1187,9 @@ static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg) plmn_next = plmn_entry; break; } - LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), " + LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc-mnc=%s), " "because it is not allowed (cause %d).\n", i, - gsm_print_mcc(plmn_entry->mcc), - gsm_print_mnc(plmn_entry->mnc), + osmo_plmn_name(&plmn_entry->plmn), plmn_entry->cause); i++; } @@ -1225,13 +1203,13 @@ static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg) } /* set next network */ - plmn->mcc = plmn_next->mcc; - plmn->mnc = plmn_next->mnc; + memcpy(&plmn->plmn, &plmn_next->plmn, sizeof(struct osmo_plmn_id)); - LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%s " - "mnc=%s %s, %s)\n", plmn->plmn_curr, - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc)); + LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc-mnc=%s %s, %s)\n", + plmn->plmn_curr, + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); new_a_state(plmn, GSM322_A3_TRYING_PLMN); @@ -1268,8 +1246,7 @@ static int gsm322_a_user_resel(struct osmocom_ms *ms, struct msgb *msg) /* search current PLMN in list */ llist_for_each_entry(plmn_entry, &plmn->sorted_plmn, entry) { - if (plmn_entry->mcc == plmn->mcc - && plmn_entry->mnc == plmn->mnc) { + if (osmo_plmn_cmp(&plmn_entry->plmn, &plmn->plmn) == 0) { plmn_found = plmn_entry; break; } @@ -1305,8 +1282,8 @@ static int gsm322_a_plmn_avail(struct osmocom_ms *ms, struct msgb *msg) struct gsm_subscriber *subscr = &ms->subscr; struct gsm322_msg *gm = (struct gsm322_msg *) msg->data; - if (subscr->plmn_valid && plmn->mcc == gm->mcc - && plmn->mnc == gm->mnc) { + if (subscr->plmn_valid && + (osmo_plmn_cmp(&plmn->plmn, &gm->plmn) == 0)) { struct msgb *nmsg; new_m_state(plmn, GSM322_A1_TRYING_RPLMN); @@ -1337,17 +1314,14 @@ static int gsm322_a_loss_of_radio(struct osmocom_ms *ms, struct msgb *msg) int found; /* any allowable PLMN available */ - found = gsm322_cs_select(ms, -1, 0, 0, 0); + found = gsm322_cs_select(ms, -1, NULL, 0); /* if PLMN in list */ if (found >= 0) { - LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%s mnc=%s " - "%s, %s)\n", gsm_print_mcc( - cs->list[found].sysinfo->mcc), - gsm_print_mnc(cs->list[found].sysinfo->mnc), - gsm_get_mcc(cs->list[found].sysinfo->mcc), - gsm_get_mnc(cs->list[found].sysinfo->mcc, - cs->list[found].sysinfo->mnc)); + LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&cs->list[found].sysinfo->lai.plmn), + gsm_get_mcc(cs->list[found].sysinfo->lai.plmn.mcc), + gsm_get_mnc(&cs->list[found].sysinfo->lai.plmn)); return gsm322_a_sel_first_plmn(ms, msg); } @@ -1374,17 +1348,17 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg) /* if there is a registered PLMN */ if (subscr->plmn_valid) { /* select the registered PLMN */ - plmn->mcc = subscr->plmn_mcc; - plmn->mnc = subscr->plmn_mnc; + memcpy(&plmn->plmn, &subscr->plmn, sizeof(struct osmo_plmn_id)); LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN " - "(mcc=%s mnc=%s %s, %s)\n", gsm_print_mcc(plmn->mcc), - gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); - LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%s mnc=%s " - "%s, %s)\n", gsm_print_mcc(plmn->mcc), - gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + "(mcc-%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); + LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); new_a_state(plmn, GSM322_A1_TRYING_RPLMN); @@ -1397,7 +1371,7 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg) return 0; } - plmn->mcc = plmn->mnc = 0; + memset(&plmn->plmn, 0, sizeof(plmn->plmn)); /* initiate search at cell selection */ LOGP(DSUM, LOGL_INFO, "Search for network\n"); @@ -1440,7 +1414,7 @@ static int gsm322_a_sim_removed(struct osmocom_ms *ms, struct msgb *msg) gsm322_cs_sendmsg(ms, nmsg); /* flush list of PLMNs */ - gsm_subscr_del_forbidden_plmn(&ms->subscr, 0, 0); + gsm_subscr_del_forbidden_plmn(&ms->subscr, NULL); return gsm322_a_switch_on(ms, msg); } @@ -1518,25 +1492,22 @@ static int gsm322_m_display_plmns(struct osmocom_ms *ms, struct msgb *msg) l23_vty_ms_notify(ms, NULL); switch (msg_type) { case GSM322_EVENT_REG_FAILED: - l23_vty_ms_notify(ms, "Failed to register to network %s, %s " - "(%s, %s)\n", - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + l23_vty_ms_notify(ms, "Failed to register to network %s (%s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); break; case GSM322_EVENT_NO_CELL_FOUND: - l23_vty_ms_notify(ms, "No cell found for network %s, %s " - "(%s, %s)\n", - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + l23_vty_ms_notify(ms, "No cell found for network %s (%s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); break; case GSM322_EVENT_ROAMING_NA: - l23_vty_ms_notify(ms, "Roaming not allowed to network %s, %s " - "(%s, %s)\n", - gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + l23_vty_ms_notify(ms, "Roaming not allowed to network %s (%s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); break; } @@ -1545,11 +1516,10 @@ static int gsm322_m_display_plmns(struct osmocom_ms *ms, struct msgb *msg) else { l23_vty_ms_notify(ms, "Search or select from network:\n"); llist_for_each_entry(temp, &plmn->sorted_plmn, entry) - l23_vty_ms_notify(ms, " Network %s, %s (%s, %s)\n", - gsm_print_mcc(temp->mcc), - gsm_print_mnc(temp->mnc), - gsm_get_mcc(temp->mcc), - gsm_get_mnc(temp->mcc, temp->mnc)); + l23_vty_ms_notify(ms, " Network mcc-mnc=%s (%s, %s)\n", + osmo_plmn_name(&temp->plmn), + gsm_get_mcc(temp->plmn.mcc), + gsm_get_mnc(&temp->plmn)); } /* go Not on PLMN state */ @@ -1582,7 +1552,7 @@ static int gsm322_m_user_resel(struct osmocom_ms *ms, struct msgb *msg) * selected by the user. this prevents from switching back to the * last selected PLMN and destroying the list of scanned networks. */ - plmn->mcc = plmn->mnc = 0; + memset(&plmn->plmn, 0, sizeof(plmn->plmn)); if (!subscr->sim_valid) { return 0; @@ -1634,17 +1604,16 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg) struct msgb *nmsg; /* select the registered PLMN */ - plmn->mcc = subscr->plmn_mcc; - plmn->mnc = subscr->plmn_mnc; + memcpy(&plmn->plmn, &subscr->plmn, sizeof(struct osmo_plmn_id)); - LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN " - "(mcc=%s mnc=%s %s, %s)\n", gsm_print_mcc(plmn->mcc), - gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); - LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%s mnc=%s " - "%s, %s)\n", gsm_print_mcc(plmn->mcc), - gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); + LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); new_m_state(plmn, GSM322_M1_TRYING_RPLMN); @@ -1657,7 +1626,7 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg) return 0; } - plmn->mcc = plmn->mnc = 0; + memset(&plmn->plmn, 0, sizeof(plmn->plmn)); /* initiate search at cell selection */ LOGP(DSUM, LOGL_INFO, "Search for network\n"); @@ -1704,7 +1673,7 @@ static int gsm322_m_sim_removed(struct osmocom_ms *ms, struct msgb *msg) gsm322_cs_sendmsg(ms, nmsg); /* flush list of PLMNs */ - gsm_subscr_del_forbidden_plmn(&ms->subscr, 0, 0); + gsm_subscr_del_forbidden_plmn(&ms->subscr, NULL); return gsm322_m_switch_on(ms, msg); } @@ -1717,8 +1686,7 @@ static int gsm322_m_go_on_plmn(struct osmocom_ms *ms, struct msgb *msg) /* set last registered PLMN */ subscr->plmn_valid = 1; - subscr->plmn_mcc = plmn->mcc; - subscr->plmn_mnc = plmn->mnc; + memcpy(&subscr->plmn, &plmn->plmn, sizeof(struct osmo_plmn_id)); new_m_state(plmn, GSM322_M2_ON_PLMN); @@ -1753,15 +1721,15 @@ static int gsm322_m_choose_plmn(struct osmocom_ms *ms, struct msgb *msg) struct msgb *nmsg; /* use user selection */ - plmn->mcc = gm->mcc; - plmn->mnc = gm->mnc; + memcpy(&plmn->plmn, &gm->plmn, sizeof(struct osmo_plmn_id)); - LOGP(DPLMN, LOGL_INFO, "User selects PLMN. (mcc=%s mnc=%s " - "%s, %s)\n", gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc), - gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc)); + LOGP(DPLMN, LOGL_INFO, "User selects PLMN. (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&plmn->plmn), + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); /* if selected PLMN is in list of forbidden PLMNs */ - gsm_subscr_del_forbidden_plmn(subscr, plmn->mcc, plmn->mnc); + gsm_subscr_del_forbidden_plmn(subscr, &plmn->plmn); new_m_state(plmn, GSM322_M4_TRYING_PLMN); @@ -1817,8 +1785,7 @@ static int gsm322_am_no_cell_found(struct osmocom_ms *ms, struct msgb *msg) */ /* select a suitable and allowable cell */ -static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc, - uint16_t mnc, int any) +static int gsm322_cs_select(struct osmocom_ms *ms, int index, const struct osmo_plmn_id *plmn, int any) { struct gsm322_cellsel *cs = &ms->cellsel; struct gsm_settings *set = &ms->settings; @@ -1906,58 +1873,51 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc, if ((cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) { if (!any) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is " - "in list of forbidden LAs. (mcc=%s " - "mnc=%s lai=%04x)\n", + "in list of forbidden LAs. (lai=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), s->lac); + osmo_lai_name(&s->lai)); continue; } LOGP(DCS, LOGL_INFO, "Accept ARFCN %s: Cell is in " "list of forbidden LAs, but we search for any " - "cell. (mcc=%s mnc=%s lai=%04x)\n", + "cell. (lai=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), s->lac); + osmo_lai_name(&s->lai)); cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA; } /* if cell is in list of forbidden PLMNs */ - if (gsm_subscr_is_forbidden_plmn(subscr, s->mcc, s->mnc)) { + if (gsm_subscr_is_forbidden_plmn(subscr, &s->lai.plmn)) { if (!any) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is " - "in list of forbidden PLMNs. (mcc=%s " - "mnc=%s)\n", + "in list of forbidden PLMNs. (mcc-mnc=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc)); + osmo_plmn_name(&s->lai.plmn)); continue; } LOGP(DCS, LOGL_INFO, "Accept ARFCN %s: Cell is in list " "of forbidden PLMNs, but we search for any " - "cell. (mcc=%s mnc=%s)\n", + "cell. (mcc-mnc=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc)); + osmo_plmn_name(&s->lai.plmn)); cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA; } /* if we search a specific PLMN, but it does not match */ - if (!any && mcc && (mcc != s->mcc - || mnc != s->mnc)) { + if (!any && plmn && (osmo_plmn_cmp(&s->lai.plmn, plmn) != 0)) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: PLMN of cell " - "does not match target PLMN. (mcc=%s " - "mnc=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc)); + "does not match target PLMN. (mcc-mnc=%s)\n", + gsm_print_arfcn(index2arfcn(i)), + osmo_plmn_name(&s->lai.plmn)); continue; } LOGP(DCS, LOGL_INFO, "Cell ARFCN %s: Cell found, (rxlev=%s " - "mcc=%s mnc=%s lac=%04x %s, %s)\n", - gsm_print_arfcn(index2arfcn(i)), + "lai=%s %s, %s)\n", + gsm_print_arfcn(index2arfcn(i)), gsm_print_rxlev(cs->list[i].rxlev), - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac, - gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc)); + osmo_lai_name(&s->lai), + gsm_get_mcc(s->lai.plmn.mcc), gsm_get_mnc(&s->lai.plmn)); /* find highest power cell */ if (found < 0 || cs->list[i].rxlev > power) { @@ -1974,8 +1934,7 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc, } /* re-select a suitable and allowable cell */ -static int gsm322_cs_reselect(struct osmocom_ms *ms, uint16_t mcc, - uint16_t mnc, int any) +static int gsm322_cs_reselect(struct osmocom_ms *ms, const struct osmo_plmn_id *plmn, int any) { struct gsm322_cellsel *cs = &ms->cellsel; struct gsm_subscriber *subscr = &ms->subscr; @@ -2004,18 +1963,18 @@ static int gsm322_cs_reselect(struct osmocom_ms *ms, uint16_t mcc, /* if cell is in list of forbidden LAs */ if (!any && (cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is in list of " - "forbidden LAs. (mcc=%s mnc=%s lai=%04x)\n", - gsm_print_arfcn(index2arfcn(i)), gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), s->lac); + "forbidden LAs. (lai=%s)\n", + gsm_print_arfcn(index2arfcn(i)), + osmo_lai_name(&s->lai)); return -1; } /* if cell is in list of forbidden PLMNs */ - if (!any && gsm_subscr_is_forbidden_plmn(subscr, s->mcc, s->mnc)) { + if (!any && gsm_subscr_is_forbidden_plmn(subscr, &s->lai.plmn)) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is in " - "list of forbidden PLMNs. (mcc=%s mnc=%s)\n", + "list of forbidden PLMNs. (mcc-mnc=%s)\n", gsm_print_arfcn(index2arfcn(i)), - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc)); + osmo_plmn_name(&s->lai.plmn)); return -1; } @@ -2030,21 +1989,21 @@ static int gsm322_cs_reselect(struct osmocom_ms *ms, uint16_t mcc, } /* if we search a specific PLMN, but it does not match */ - if (!any && mcc && (mcc != s->mcc - || mnc != s->mnc)) { + if (!any && plmn && (osmo_plmn_cmp(plmn, &s->lai.plmn) != 0)) { LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: PLMN of cell " - "does not match target PLMN. (mcc=%s mnc=%s)\n", - gsm_print_arfcn(index2arfcn(i)), gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc)); + "does not match target PLMN. (mcc-mnc=%s)\n", + gsm_print_arfcn(index2arfcn(i)), + osmo_plmn_name(&s->lai.plmn)); return -1; } LOGP(DCS, LOGL_INFO, "Cell ARFCN %s: Neighbour cell accepted, " - "(rxlev=%s mcc=%s mnc=%s lac=%04x %s, %s)\n", + "(rxlev=%s lai=%s %s, %s)\n", gsm_print_arfcn(index2arfcn(i)), gsm_print_rxlev(cs->list[i].rxlev), - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac, - gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc)); + osmo_lai_name(&s->lai), + gsm_get_mcc(s->lai.plmn.mcc), + gsm_get_mnc(&s->lai.plmn)); return i; } @@ -2053,12 +2012,13 @@ static int gsm322_cs_reselect(struct osmocom_ms *ms, uint16_t mcc, static int gsm322_search_end(struct osmocom_ms *ms) { struct gsm322_cellsel *cs = &ms->cellsel; - struct gsm322_plmn *plmn = &ms->plmn; + struct gsm322_plmn *plmn322 = &ms->plmn; struct msgb *nmsg; struct gsm322_msg *ngm; int msg_type = -1; /* no message to be sent */ - int tune_back = 0, mcc = 0, mnc = 0; + int tune_back = 0; int found; + struct osmo_plmn_id plmn = {}; switch (cs->state) { case GSM322_ANY_SEARCH: @@ -2066,12 +2026,12 @@ static int gsm322_search_end(struct osmocom_ms *ms) LOGP(DCS, LOGL_INFO, "Any cell search finished.\n"); /* create AA flag */ - found = gsm322_cs_select(ms, -1, 0, 0, 0); + found = gsm322_cs_select(ms, -1, NULL, 0); /* if no cell is found, or if we don't wait for any available * and allowable PLMN to appear, we just continue to camp */ if (ms->settings.plmn_mode != PLMN_MODE_AUTO - || plmn->state != GSM322_A4_WAIT_FOR_PLMN + || plmn322->state != GSM322_A4_WAIT_FOR_PLMN || found < 0) { tune_back = 1; gsm322_c_camp_any_cell(ms, NULL); @@ -2080,10 +2040,9 @@ static int gsm322_search_end(struct osmocom_ms *ms) /* indicate available PLMN, include selected PLMN, if found */ msg_type = GSM322_EVENT_PLMN_AVAIL; - if (gsm322_is_plmn_avail_and_allow(cs, plmn->mcc, plmn->mnc)) { + if (gsm322_is_plmn_avail_and_allow(cs, &plmn322->plmn)) { /* set what PLMN becomes available */ - mcc = plmn->mcc; - mnc = plmn->mnc; + memcpy(&plmn, &plmn322->plmn, sizeof(struct osmo_plmn_id)); } new_c_state(cs, GSM322_C0_NULL); @@ -2096,7 +2055,7 @@ static int gsm322_search_end(struct osmocom_ms *ms) LOGP(DCS, LOGL_INFO, "PLMN search finished.\n"); /* create AA flag */ - gsm322_cs_select(ms, -1, 0, 0, 0); + gsm322_cs_select(ms, -1, NULL, 0); new_c_state(cs, GSM322_C0_NULL); @@ -2148,8 +2107,7 @@ static int gsm322_search_end(struct osmocom_ms *ms) if (!nmsg) return -ENOMEM; ngm = (struct gsm322_msg *) nmsg->data; - ngm->mcc = mcc; - ngm->mnc = mnc; + memcpy(&ngm->plmn, &plmn, sizeof(struct osmo_plmn_id)); gsm322_plmn_sendmsg(ms, nmsg); } @@ -2166,10 +2124,8 @@ static int gsm322_search_end(struct osmocom_ms *ms) memcpy(cs->list[cs->arfci].sysinfo, &cs->sel_si, sizeof(struct gsm48_sysinfo)); cs->si = cs->list[cs->arfci].sysinfo; - cs->sel_mcc = cs->si->mcc; - cs->sel_mnc = cs->si->mnc; - cs->sel_lac = cs->si->lac; - cs->sel_id = cs->si->cell_id; + cs->sel_cgi.lai = cs->si->lai; + cs->sel_cgi.cell_identity = cs->si->cell_id; LOGP(DCS, LOGL_INFO, "Tuning back to frequency %s after full " "search.\n", gsm_print_arfcn(cs->arfcn)); cs->sync_retries = SYNC_RETRIES; @@ -2317,17 +2273,17 @@ static int gsm322_cs_store(struct osmocom_ms *ms) cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_BARRED; /* store selected network */ - if (s->mcc) { - if (gsm322_is_forbidden_la(ms, s->mcc, s->mnc, s->lac)) + if (s->lai.plmn.mcc) { + if (gsm322_is_forbidden_la(ms, &s->lai)) cs->list[cs->arfci].flags |= GSM322_CS_FLAG_FORBIDD; else cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_FORBIDD; } - LOGP(DCS, LOGL_DEBUG, "Scan frequency %s: Cell found. (rxlev %s " - "mcc %s mnc %s lac %04x)\n", gsm_print_arfcn(cs->arfcn), + LOGP(DCS, LOGL_DEBUG, "Scan frequency %s: Cell found. (rxlev %s lai %s)\n", + gsm_print_arfcn(cs->arfcn), gsm_print_rxlev(cs->list[cs->arfci].rxlev), - gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac); + osmo_lai_name(&s->lai)); /* selected PLMN (auto) becomes available during "any search" */ if (ms->settings.plmn_mode == PLMN_MODE_AUTO @@ -2336,10 +2292,10 @@ static int gsm322_cs_store(struct osmocom_ms *ms) || cs->state == GSM322_C8_ANY_CELL_RESEL || cs->state == GSM322_C9_CHOOSE_ANY_CELL) && plmn->state == GSM322_A4_WAIT_FOR_PLMN - && s->mcc == plmn->mcc && s->mnc == plmn->mnc) { + && (osmo_plmn_cmp(&s->lai.plmn, &plmn->plmn) == 0)) { LOGP(DCS, LOGL_INFO, "Candidate network to become available " "again\n"); - found = gsm322_cs_select(ms, cs->arfci, s->mcc, s->mnc, 0); + found = gsm322_cs_select(ms, cs->arfci, &s->lai.plmn, 0); if (found >= 0) { LOGP(DCS, LOGL_INFO, "Selected PLMN in \"A4_WAIT_F" "OR_PLMN\" state becomes available.\n"); @@ -2350,8 +2306,7 @@ indicate_plmn_avail: return -ENOMEM; /* set what PLMN becomes available */ ngm = (struct gsm322_msg *) nmsg->data; - ngm->mcc = plmn->mcc; - ngm->mnc = plmn->mcc; + memcpy(&ngm->plmn, &plmn->plmn, sizeof(struct osmo_plmn_id)); gsm322_plmn_sendmsg(ms, nmsg); new_c_state(cs, GSM322_C0_NULL); @@ -2367,10 +2322,10 @@ indicate_plmn_avail: || cs->state == GSM322_C8_ANY_CELL_RESEL || cs->state == GSM322_C9_CHOOSE_ANY_CELL) && plmn->state == GSM322_M3_NOT_ON_PLMN - && s->mcc == plmn->mcc && s->mnc == plmn->mnc) { + && (osmo_plmn_cmp(&s->lai.plmn, &plmn->plmn) == 0)) { LOGP(DCS, LOGL_INFO, "Candidate network to become available " "again\n"); - found = gsm322_cs_select(ms, cs->arfci, s->mcc, s->mnc, 0); + found = gsm322_cs_select(ms, cs->arfci, &s->lai.plmn, 0); if (found >= 0) { LOGP(DCS, LOGL_INFO, "Current selected PLMN in \"M3_N" "OT_ON_PLMN\" state becomes available.\n"); @@ -2410,9 +2365,9 @@ indicate_plmn_avail: if (cs->state == GSM322_C4_NORMAL_CELL_RESEL || cs->state == GSM322_C8_ANY_CELL_RESEL) - found = gsm322_cs_reselect(ms, cs->mcc, cs->mnc, any); + found = gsm322_cs_reselect(ms, &cs->plmn, any); else - found = gsm322_cs_select(ms, -1, cs->mcc, cs->mnc, any); + found = gsm322_cs_select(ms, -1, &cs->plmn, any); /* if not found */ if (found < 0) { @@ -2437,18 +2392,14 @@ indicate_plmn_avail: cs->selected = 1; cs->sel_arfcn = cs->arfcn; memcpy(&cs->sel_si, cs->si, sizeof(cs->sel_si)); - cs->sel_mcc = cs->si->mcc; - cs->sel_mnc = cs->si->mnc; - cs->sel_lac = cs->si->lac; - cs->sel_id = cs->si->cell_id; + cs->sel_cgi.lai = cs->si->lai; + cs->sel_cgi.cell_identity = cs->si->cell_id; if (ms->rrlayer.monitor) { - l23_vty_ms_notify(ms, "MON: %scell selected ARFCN=%s MCC=%s MNC=%s " - "LAC=0x%04x cellid=0x%04x (%s %s)\n", + l23_vty_ms_notify(ms, "MON: %scell selected ARFCN=%s CGI=%s (%s %s)\n", (any) ? "any " : "", gsm_print_arfcn(cs->sel_arfcn), - gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc), - cs->sel_lac, cs->sel_id, - gsm_get_mcc(cs->sel_mcc), - gsm_get_mnc(cs->sel_mcc, cs->sel_mnc)); + osmo_cgi_name(&cs->sel_cgi), + gsm_get_mcc(cs->sel_cgi.lai.plmn.mcc), + gsm_get_mnc(&cs->sel_cgi.lai.plmn)); } /* tell CS process about available cell */ @@ -2484,13 +2435,12 @@ struct gsm322_ba_list *gsm322_cs_sysinfo_sacch(struct osmocom_ms *ms) /* collect system information received during dedicated mode */ if (s->si5 && (!s->nb_ext_ind_si5 || s->si5bis)) { /* find or create ba list */ - ba = gsm322_find_ba_list(cs, s->mcc, s->mnc); + ba = gsm322_find_ba_list(cs, &s->lai.plmn); if (!ba) { ba = talloc_zero(ms, struct gsm322_ba_list); if (!ba) return NULL; - ba->mcc = s->mcc; - ba->mnc = s->mnc; + memcpy(&ba->plmn, &s->lai.plmn, sizeof(struct osmo_plmn_id)); llist_add_tail(&ba->entry, &cs->ba_list); } /* update (add) ba list */ @@ -2506,10 +2456,10 @@ struct gsm322_ba_list *gsm322_cs_sysinfo_sacch(struct osmocom_ms *ms) } } if (!!memcmp(freq, ba->freq, sizeof(freq))) { - LOGP(DCS, LOGL_INFO, "New BA list (mcc=%s mnc=%s " - "%s, %s).\n", gsm_print_mcc(ba->mcc), - gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc), - gsm_get_mnc(ba->mcc, ba->mnc)); + LOGP(DCS, LOGL_INFO, "New BA list (mcc-mnc=%s %s, %s).\n", + osmo_plmn_name(&ba->plmn), + gsm_get_mcc(ba->plmn.mcc), + gsm_get_mnc(&ba->plmn)); memcpy(ba->freq, freq, sizeof(freq)); } } @@ -2526,13 +2476,12 @@ static int gsm322_store_ba_list(struct gsm322_cellsel *cs, uint8_t freq[128+38]; /* find or create ba list */ - ba = gsm322_find_ba_list(cs, s->mcc, s->mnc); + ba = gsm322_find_ba_list(cs, &s->lai.plmn); if (!ba) { ba = talloc_zero(cs->ms, struct gsm322_ba_list); if (!ba) return -ENOMEM; - ba->mcc = s->mcc; - ba->mnc = s->mnc; + memcpy(&ba->plmn, &s->lai.plmn, sizeof(struct osmo_plmn_id)); llist_add_tail(&ba->entry, &cs->ba_list); } /* update ba list */ @@ -2549,10 +2498,10 @@ static int gsm322_store_ba_list(struct gsm322_cellsel *cs, } } if (!!memcmp(freq, ba->freq, sizeof(freq))) { - LOGP(DCS, LOGL_INFO, "New BA list (mcc=%s mnc=%s " - "%s, %s).\n", gsm_print_mcc(ba->mcc), - gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc), - gsm_get_mnc(ba->mcc, ba->mnc)); + LOGP(DCS, LOGL_INFO, "New BA list (mcc-mnc=%s %s, %s).\n", + osmo_plmn_name(&ba->plmn), + gsm_get_mcc(ba->plmn.mcc), + gsm_get_mnc(&ba->plmn)); memcpy(ba->freq, freq, sizeof(freq)); } @@ -2586,8 +2535,8 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg) * Depending on the extended bit in the channel description, * we require more or less system information about neighbor cells */ - if (s->mcc - && s->mnc + if (s->lai.plmn.mcc + && s->lai.plmn.mnc && (gm->sysinfo == GSM48_MT_RR_SYSINFO_1 || gm->sysinfo == GSM48_MT_RR_SYSINFO_2 || gm->sysinfo == GSM48_MT_RR_SYSINFO_2bis @@ -2664,8 +2613,7 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg) } /* check if MCC, MNC, LAC, cell ID changes */ - if (cs->sel_mcc != s->mcc || cs->sel_mnc != s->mnc - || cs->sel_lac != s->lac) { + if (osmo_lai_cmp(&cs->sel_cgi.lai, &s->lai) != 0) { LOGP(DCS, LOGL_NOTICE, "Cell changes location area. " "This is not good!\n"); if (ms->rrlayer.monitor) @@ -2673,7 +2621,7 @@ static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg) "cell changes LAI\n"); goto trigger_resel; } - if (cs->sel_id != s->cell_id) { + if (cs->sel_cgi.cell_identity != s->cell_id) { LOGP(DCS, LOGL_NOTICE, "Cell changes cell ID. " "This is not good!\n"); if (ms->rrlayer.monitor) @@ -2702,8 +2650,8 @@ static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg) * Depending on the extended bit in the channel description, * we require more or less system information about neighbor cells */ - if (s->mcc - && s->mnc + if (s->lai.plmn.mcc + && s->lai.plmn.mnc && (gm->sysinfo == GSM48_MT_RR_SYSINFO_1 || gm->sysinfo == GSM48_MT_RR_SYSINFO_2 || gm->sysinfo == GSM48_MT_RR_SYSINFO_2bis @@ -3287,7 +3235,7 @@ static int gsm322_c_any_cell_sel(struct osmocom_ms *ms, struct msgb *msg) new_c_state(cs, GSM322_C6_ANY_CELL_SEL); - cs->mcc = cs->mnc = 0; + memset(&cs->plmn, 0, sizeof(cs->plmn)); /* unset selected cell */ gsm322_unselect_cell(cs); @@ -3389,11 +3337,10 @@ static int gsm322_c_camp_normally(struct osmocom_ms *ms, struct msgb *msg) struct gsm322_cellsel *cs = &ms->cellsel; struct msgb *nmsg; - LOGP(DSUM, LOGL_INFO, "Camping normally on cell (ARFCN=%s mcc=%s " - "mnc=%s %s, %s)\n", gsm_print_arfcn(cs->sel_arfcn), - gsm_print_mcc(cs->sel_mcc), - gsm_print_mnc(cs->sel_mnc), gsm_get_mcc(cs->sel_mcc), - gsm_get_mnc(cs->sel_mcc, cs->sel_mnc)); + LOGP(DSUM, LOGL_INFO, "Camping normally on cell (ARFCN=%s mcc-mnc=%s %s, %s)\n", gsm_print_arfcn(cs->sel_arfcn), + osmo_plmn_name(&cs->sel_cgi.lai.plmn), + gsm_get_mcc(cs->sel_cgi.lai.plmn.mcc), + gsm_get_mnc(&cs->sel_cgi.lai.plmn)); /* if we did cell reselection, we have a valid last serving cell */ if (cs->state != GSM322_C4_NORMAL_CELL_RESEL) @@ -3416,11 +3363,11 @@ static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg) struct gsm322_cellsel *cs = &ms->cellsel; struct msgb *nmsg; - LOGP(DSUM, LOGL_INFO, "Camping on any cell (ARFCN=%s mcc=%s " - "mnc=%s %s, %s)\n", gsm_print_arfcn(cs->sel_arfcn), - gsm_print_mcc(cs->sel_mcc), - gsm_print_mnc(cs->sel_mnc), gsm_get_mcc(cs->sel_mcc), - gsm_get_mnc(cs->sel_mcc, cs->sel_mnc)); + LOGP(DSUM, LOGL_INFO, "Camping on any cell (ARFCN=%s mcc-mnc=%s %s, %s)\n", + gsm_print_arfcn(cs->sel_arfcn), + osmo_plmn_name(&cs->sel_cgi.lai.plmn), + gsm_get_mcc(cs->sel_cgi.lai.plmn.mcc), + gsm_get_mnc(&cs->sel_cgi.lai.plmn)); /* (re-)starting 'any cell selection' timer to look for coverage of * allowed PLMNs. @@ -3429,13 +3376,12 @@ static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg) if (ms->subscr.sim_valid && (cs->state != GSM322_C8_ANY_CELL_RESEL || !osmo_timer_pending(&cs->any_timer))) { - struct gsm322_plmn *plmn = &ms->plmn; + struct gsm322_plmn *plmn322 = &ms->plmn; stop_any_timer(cs); if (ms->settings.plmn_mode == PLMN_MODE_MANUAL - && (!plmn->mcc - || gsm_subscr_is_forbidden_plmn(&ms->subscr, plmn->mcc, - plmn->mnc))) { + && (!plmn322->plmn.mcc + || gsm_subscr_is_forbidden_plmn(&ms->subscr, &plmn322->plmn))) { LOGP(DCS, LOGL_INFO, "Not starting 'any search' timer, " "because no selected PLMN or forbidden\n"); } else @@ -3526,8 +3472,7 @@ static int gsm322_cs_choose(struct osmocom_ms *ms) if (!ba) { LOGP(DCS, LOGL_INFO, "No BA on sysinfo, try stored " "BA list.\n"); - ba = gsm322_find_ba_list(cs, cs->sel_si.mcc, - cs->sel_si.mnc); + ba = gsm322_find_ba_list(cs, &cs->sel_si.lai.plmn); } } @@ -3628,23 +3573,22 @@ static int gsm322_c_new_plmn(struct osmocom_ms *ms, struct msgb *msg) { struct gsm322_msg *gm = (struct gsm322_msg *) msg->data; struct gsm322_cellsel *cs = &ms->cellsel; - struct gsm322_plmn *plmn = &ms->plmn; + struct gsm322_plmn *plmn322 = &ms->plmn; struct gsm322_ba_list *ba; - cs->mcc = plmn->mcc; - cs->mnc = plmn->mnc; + memcpy(&cs->plmn, &plmn322->plmn, sizeof(struct osmo_plmn_id)); if (gm->limited) { LOGP(DCS, LOGL_INFO, "Selected PLMN with limited service.\n"); return gsm322_c_any_cell_sel(ms, msg); } - LOGP(DSUM, LOGL_INFO, "Selecting PLMN (mcc=%s mnc=%s %s, %s)\n", - gsm_print_mcc(cs->mcc), gsm_print_mnc(cs->mnc), - gsm_get_mcc(cs->mcc), gsm_get_mnc(cs->mcc, cs->mnc)); + LOGP(DSUM, LOGL_INFO, "Selecting PLMN (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&cs->plmn), + gsm_get_mcc(cs->plmn.mcc), gsm_get_mnc(&cs->plmn)); /* search for BA list */ - ba = gsm322_find_ba_list(cs, plmn->mcc, plmn->mnc); + ba = gsm322_find_ba_list(cs, &plmn322->plmn); if (ba) { LOGP(DCS, LOGL_INFO, "Start stored cell selection.\n"); @@ -4161,7 +4105,7 @@ static int gsm322_nb_check(struct osmocom_ms *ms, int any) gsm_print_arfcn(cs->sel_arfcn)); arfcn_text[9] = '\0'; l23_vty_ms_notify(ms, "MON: serving %s 0x%04x %3d %3d %4d " - "%s\n", arfcn_text, cs->sel_lac, cs->c1, cs->c2, + "%s\n", arfcn_text, cs->sel_cgi.lai.lac, cs->c1, cs->c2, cs->rla_c_dbm, bargraph(cs->rla_c_dbm / 2, -55, -24)); } @@ -4224,8 +4168,7 @@ static int gsm322_nb_check(struct osmocom_ms *ms, int any) nb->c12_valid = 1; /* calculate CRH depending on LAI */ - if (cs->sel_mcc == s->mcc && cs->sel_mnc == s->mnc - && cs->sel_lac == s->lac) { + if (osmo_lai_cmp(&cs->sel_cgi.lai, &s->lai) == 0) { LOGP(DNB, LOGL_INFO, "-> Cell of is in the same LA, " "so CRH = 0\n"); nb->crh = 0; @@ -4245,7 +4188,7 @@ static int gsm322_nb_check(struct osmocom_ms *ms, int any) gsm_print_arfcn(nb->arfcn)); arfcn_text[9] = '\0'; l23_vty_ms_notify(ms, "MON: nb %2d %s 0x%04x %3d %3d %2d" - " %4d %s\n", i + 1, arfcn_text, s->lac, + " %4d %s\n", i + 1, arfcn_text, s->lai.lac, nb->c1, nb->c2, nb->crh, nb->rla_c_dbm, bargraph(nb->rla_c_dbm / 2, -55, -24)); } @@ -4266,18 +4209,17 @@ static int gsm322_nb_check(struct osmocom_ms *ms, int any) } /* check if LA is forbidden */ - if (any && gsm322_is_forbidden_la(ms, s->mcc, s->mnc, s->lac)) { + if (any && gsm322_is_forbidden_la(ms, &s->lai)) { LOGP(DNB, LOGL_INFO, "Skip cell: Cell has " "forbidden LA.\n"); goto cont; } /* check if we have same PLMN */ - if (!any && (cs->sel_mcc != s->mcc || cs->sel_mnc != s->mnc)) { + if (!any && (osmo_plmn_cmp(&cs->sel_cgi.lai.plmn, &s->lai.plmn) != 0)) { LOGP(DNB, LOGL_INFO, "Skip cell: PLMN of cell " - "does not match target PLMN. (cell: mcc=%s " - "mnc=%s)\n", gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc)); + "does not match target PLMN. (cell: mcc-mnc=%s)\n", + osmo_plmn_name(&s->lai.plmn)); goto cont; } @@ -4861,9 +4803,9 @@ int gsm322_dump_sorted_plmn(struct osmocom_ms *ms) LOGP(DPLMN, LOGL_INFO, "MCC |MNC |allowed|rx-lev\n"); LOGP(DPLMN, LOGL_INFO, "-------+-------+-------+-------\n"); llist_for_each_entry(temp, &plmn->sorted_plmn, entry) { - LOGP(DPLMN, LOGL_INFO, "%s |%s%s |%s |%s\n", - gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc), - ((temp->mnc & 0x00f) == 0x00f) ? " ":"", + LOGP(DPLMN, LOGL_INFO, "%s |%-3s |%s |%s\n", + osmo_mcc_name(temp->plmn.mcc), + osmo_mnc_name(temp->plmn.mnc, temp->plmn.mnc_3_digits), (temp->cause) ? "no ":"yes", gsm_print_rxlev(temp->rxlev)); } @@ -4891,11 +4833,11 @@ int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags, print(priv, "%4dDCS|", i); else print(priv, "%4d |", i); - if (s->mcc) { - print(priv, "%s |%s%s |", gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), - ((s->mnc & 0x00f) == 0x00f) ? " ":""); - print(priv, "0x%04x |0x%04x |", s->lac, s->cell_id); + if (s->lai.plmn.mcc) { + print(priv, "%s |%-3s |", + osmo_mcc_name(s->lai.plmn.mcc), + osmo_mnc_name(s->lai.plmn.mnc, s->lai.plmn.mnc_3_digits)); + print(priv, "0x%04x |0x%04x |", s->lai.lac, s->cell_id); } else print(priv, "n/a |n/a |n/a |n/a |"); if ((cs->list[i].flags & GSM322_CS_FLAG_SYSINFO)) { @@ -4934,27 +4876,27 @@ int gsm322_dump_forbidden_la(struct osmocom_ms *ms, print(priv, "MCC |MNC |LAC |cause\n"); print(priv, "-------+-------+-------+-------\n"); llist_for_each_entry(temp, &plmn->forbidden_la, entry) - print(priv, "%s |%s%s |0x%04x |#%d\n", - gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc), - ((temp->mnc & 0x00f) == 0x00f) ? " ":"", - temp->lac, temp->cause); + print(priv, "%s |%-3s |0x%04x |#%d\n", + osmo_mcc_name(temp->lai.plmn.mcc), + osmo_mnc_name(temp->lai.plmn.mnc, temp->lai.plmn.mnc_3_digits), + temp->lai.lac, temp->cause); return 0; } -int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc, +int gsm322_dump_ba_list(struct gsm322_cellsel *cs, const struct osmo_plmn_id *plmn, void (*print)(void *, const char *, ...), void *priv) { struct gsm322_ba_list *ba; int i; llist_for_each_entry(ba, &cs->ba_list, entry) { - if (mcc && mnc && (mcc != ba->mcc || mnc != ba->mnc)) + if (plmn && (osmo_plmn_cmp(&ba->plmn, plmn) != 0)) continue; - print(priv, "Band Allocation of network: MCC %s MNC %s " - "(%s, %s)\n", gsm_print_mcc(ba->mcc), - gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc), - gsm_get_mnc(ba->mcc, ba->mnc)); + print(priv, "Band Allocation of network: MCC-MNC %s (%s, %s)\n", + osmo_plmn_name(&ba->plmn), + gsm_get_mcc(ba->plmn.mcc), + gsm_get_mnc(&ba->plmn)); for (i = 0; i <= 1023+299; i++) { if ((ba->freq[i >> 3] & (1 << (i & 7)))) print(priv, " %s", @@ -4984,7 +4926,7 @@ int gsm322_dump_nb_list(struct gsm322_cellsel *cs, print(priv, "C1=%d C2=%d ", cs->c1, cs->c1); else print(priv, "C1 - C2 - "); - print(priv, "LAC=0x%04x\n\n", (cs->selected) ? cs->sel_si.lac : 0); + print(priv, "LAC=0x%04x\n\n", (cs->selected) ? cs->sel_si.lai.lac : 0); print(priv, "Neighbour cells:\n\n"); llist_for_each_entry(nb, &cs->nb_list, entry) { @@ -5027,7 +4969,7 @@ int gsm322_dump_nb_list(struct gsm322_cellsel *cs, s = cs->list[arfcn2index(nb->arfcn)].sysinfo; if (nb->state == GSM322_NB_SYSINFO && s) { print(priv, "%s |0x%04x |0x%04x |", - (nb->prio_low) ? "low ":"normal", s->lac, + (nb->prio_low) ? "low ":"normal", s->lai.lac, s->cell_id); } else print(priv, "- |- |- |"); @@ -5098,6 +5040,7 @@ int gsm322_init(struct osmocom_ms *ms) "stored BA list becomes obsolete.\n"); } else while(!feof(fp)) { + uint16_t mcc_hex, mnc_hex; ba = talloc_zero(ms, struct gsm322_ba_list); if (!ba) { fclose(fp); @@ -5108,18 +5051,30 @@ int gsm322_init(struct osmocom_ms *ms) talloc_free(ba); break; } - ba->mcc = (buf[0] << 8) | buf[1]; - ba->mnc = (buf[2] << 8) | buf[3]; + mcc_hex = (buf[0] << 8) | buf[1]; + mnc_hex = (buf[2] << 8) | buf[3]; + ba->plmn.mcc = (((mcc_hex & 0x0f00) >> 8) * 100) + + (((mcc_hex & 0x00f0) >> 4) * 10) + + (mcc_hex & 0x000f); + ba->plmn.mnc_3_digits = ((mnc_hex & 0x00f) != 0x00f); + if (ba->plmn.mnc_3_digits) + ba->plmn.mnc = (((mnc_hex & 0x0f00) >> 8) * 100) + + (((mnc_hex & 0x00f0) >> 4) * 10) + + (mnc_hex & 0x000f); + else + ba->plmn.mnc = (((mnc_hex & 0x0f00) >> 8) * 10) + + (((mnc_hex & 0x00f0) >> 4)); + rc = fread(ba->freq, sizeof(ba->freq), 1, fp); if (!rc) { talloc_free(ba); break; } llist_add_tail(&ba->entry, &cs->ba_list); - LOGP(DCS, LOGL_INFO, "Read stored BA list (mcc=%s " - "mnc=%s %s, %s)\n", gsm_print_mcc(ba->mcc), - gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc), - gsm_get_mnc(ba->mcc, ba->mnc)); + LOGP(DCS, LOGL_INFO, "Read stored BA list (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&ba->plmn), + gsm_get_mcc(ba->plmn.mcc), + gsm_get_mnc(&ba->plmn)); } fclose(fp); } else @@ -5152,15 +5107,18 @@ static void gsm322_write_ba(struct osmocom_ms *ms) llist_for_each_entry(ba, &ms->cellsel.ba_list, entry) { size_t rc = 0; + uint16_t mcc_hex = gsm_mcc_to_hex(ba->plmn.mcc); + uint16_t mnc_hex = gsm_mnc_to_hex(ba->plmn.mnc, ba->plmn.mnc_3_digits); uint8_t buf[] = { - ba->mcc >> 8, ba->mcc & 0xff, - ba->mnc >> 8, ba->mnc & 0xff, + mcc_hex >> 8, mcc_hex & 0xff, + mnc_hex >> 8, mnc_hex & 0xff, }; LOGP(DCS, LOGL_INFO, - "Writing stored BA list entry (mcc=%s mnc=%s %s, %s)\n", - gsm_print_mcc(ba->mcc), gsm_print_mnc(ba->mnc), - gsm_get_mcc(ba->mcc), gsm_get_mnc(ba->mcc, ba->mnc)); + "Writing stored BA list entry (mcc-mnc=%s %s, %s)\n", + osmo_plmn_name(&ba->plmn), + gsm_get_mcc(ba->plmn.mcc), + gsm_get_mnc(&ba->plmn)); rc += fwrite(buf, sizeof(buf), 1, fp); rc += fwrite(ba->freq, sizeof(ba->freq), 1, fp); diff --git a/src/host/layer23/src/mobile/gsm48_mm.c b/src/host/layer23/src/mobile/gsm48_mm.c index e72c3e0fd..95808ee52 100644 --- a/src/host/layer23/src/mobile/gsm48_mm.c +++ b/src/host/layer23/src/mobile/gsm48_mm.c @@ -928,8 +928,8 @@ static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate) case GSM48_MM_SST_NORMAL_SERVICE: l23_vty_ms_notify(ms, NULL); l23_vty_ms_notify(ms, "On Network, normal service: %s, %s\n", - gsm_get_mcc(plmn->mcc), - gsm_get_mnc(plmn->mcc, plmn->mnc)); + gsm_get_mcc(plmn->plmn.mcc), + gsm_get_mnc(&plmn->plmn)); break; case GSM48_MM_SST_LIMITED_SERVICE: l23_vty_ms_notify(ms, NULL); @@ -953,7 +953,7 @@ static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate) case GSM48_MM_SST_ATTEMPT_UPDATE: l23_vty_ms_notify(ms, NULL); l23_vty_ms_notify(ms, "Trying to register with network %s, %s...\n", - gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc)); + gsm_get_mcc(plmn->plmn.mcc), gsm_get_mnc(&plmn->plmn)); break; } } @@ -1043,7 +1043,7 @@ static int gsm48_mm_set_plmn_search(struct osmocom_ms *ms) "SIM not updated.\n"); return GSM48_MM_SST_PLMN_SEARCH; } - if (subscr->lac == 0x0000 || subscr->lac >= 0xfffe) { + if (subscr->lai.lac == 0x0000 || subscr->lai.lac >= 0xfffe) { LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because " "LAI in SIM not valid.\n"); return GSM48_MM_SST_PLMN_SEARCH; @@ -1057,15 +1057,12 @@ static int gsm48_mm_set_plmn_search(struct osmocom_ms *ms) } /* selected cell's LAI not equal to LAI stored on the sim */ - if (cs->sel_mcc != subscr->mcc - || cs->sel_mnc != subscr->mnc - || cs->sel_lac != subscr->lac) { + if (osmo_lai_cmp(&cs->sel_cgi.lai, &subscr->lai) != 0) { LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because " - "LAI of selected cell (MCC %s MNC %s LAC 0x%04x) " - "!= LAI in SIM (MCC %s MNC %s LAC 0x%04x).\n", - gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc), - cs->sel_lac, gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac); + "LAI of selected cell (MCC-MNC %s LAC 0x%04x) " + "!= LAI in SIM (MCC-MNC %s LAC 0x%04x).\n", + osmo_plmn_name(&cs->sel_cgi.lai.plmn), cs->sel_cgi.lai.lac, + osmo_plmn_name2(&subscr->lai.plmn), subscr->lai.lac); return GSM48_MM_SST_PLMN_SEARCH; } @@ -1121,10 +1118,8 @@ static int gsm48_mm_return_idle(struct osmocom_ms *ms, struct msgb *msg) /* if we are attached and selected cell equals the registered LAI */ if (subscr->imsi_attached - && subscr->lac /* valid */ - && cs->sel_mcc == subscr->mcc - && cs->sel_mnc == subscr->mnc - && cs->sel_lac == subscr->lac) { + && subscr->lai.lac /* valid */ + && (osmo_lai_cmp(&cs->sel_cgi.lai, &subscr->lai) == 0)) { LOGP(DMM, LOGL_INFO, "We are in registered LAI as returning " "to MM IDLE\n"); /* if SIM not updated (abnormal case as described in 4.4.4.9) */ @@ -1141,15 +1136,13 @@ static int gsm48_mm_return_idle(struct osmocom_ms *ms, struct msgb *msg) if (cs->state == GSM322_C3_CAMPED_NORMALLY) { LOGP(DMM, LOGL_INFO, "We are camping normally as returning to " "MM IDLE\n"); - if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, - cs->sel_mnc)) { + if (gsm_subscr_is_forbidden_plmn(subscr, &cs->sel_cgi.lai.plmn)) { /* location update not allowed */ LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LIMITED_SERVICE); } else - if (gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc, - cs->sel_lac)) { + if (gsm322_is_forbidden_la(ms, &cs->sel_cgi.lai)) { /* location update not allowed */ LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n"); new_mm_state(mm, GSM48_MM_ST_MM_IDLE, @@ -1211,10 +1204,8 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) /* SIM not updated in this LA */ if (subscr->ustate == GSM_SIM_U1_UPDATED - && subscr->lac /* valid */ - && cs->sel_mcc == subscr->mcc - && cs->sel_mnc == subscr->mnc - && cs->sel_lac == subscr->lac + && subscr->lai.lac /* valid */ + && (osmo_lai_cmp(&cs->sel_cgi.lai, &subscr->lai) == 0) && !mm->lupd_periodic) { if (subscr->imsi_attached) { struct msgb *nmsg; @@ -1252,9 +1243,8 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) /* PLMN mode auto and selected cell is forbidden */ if (set->plmn_mode == PLMN_MODE_AUTO && (!cs->selected - || gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc) - || gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc, - cs->sel_lac))) { + || gsm_subscr_is_forbidden_plmn(subscr, &cs->sel_cgi.lai.plmn) + || gsm322_is_forbidden_la(ms, &cs->sel_cgi.lai))) { struct msgb *nmsg; LOGP(DMM, LOGL_INFO, "Selected cell is forbidden.\n"); @@ -1274,8 +1264,7 @@ static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg) * in M3 state the PLMN is not selected for registration. */ if (set->plmn_mode == PLMN_MODE_MANUAL && (!cs->selected - || plmn->mcc != cs->sel_mcc - || plmn->mnc != cs->sel_mnc + || (osmo_plmn_cmp(&plmn->plmn, &cs->sel_cgi.lai.plmn) != 0) || plmn->state == GSM322_M3_NOT_ON_PLMN)) { struct msgb *nmsg; @@ -1585,7 +1574,7 @@ static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg) return -EINVAL; } /* LAI */ - gsm48_decode_lai_hex(lai, &subscr->mcc, &subscr->mnc, &subscr->lac); + gsm48_decode_lai2(lai, &subscr->lai); /* MI */ mi = gh->data + sizeof(struct gsm48_loc_area_id); mi_type = mi[1] & GSM_MI_TYPE_MASK; @@ -1699,7 +1688,7 @@ static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg) /* TMSI and LAI invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* key is invalid */ subscr->key_seq = 7; @@ -2018,7 +2007,7 @@ static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg) /* TMSI and LAI invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* key is invalid */ subscr->key_seq = 7; @@ -2170,20 +2159,18 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg) "forbidden PLMN.\n"); LOGP(DSUM, LOGL_INFO, "Location updating is disabled by " "configuration\n"); - gsm_subscr_add_forbidden_plmn(subscr, cs->sel_mcc, - cs->sel_mnc, GSM48_REJECT_PLMN_NOT_ALLOWED); + gsm_subscr_add_forbidden_plmn(subscr, &cs->sel_cgi.lai.plmn, GSM48_REJECT_PLMN_NOT_ALLOWED); msg_type = GSM322_EVENT_REG_FAILED; goto _stop; } /* if LAI is forbidden, don't start */ - if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) { + if (gsm_subscr_is_forbidden_plmn(subscr, &cs->sel_cgi.lai.plmn)) { LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n"); msg_type = GSM322_EVENT_REG_FAILED; goto stop; } - if (gsm322_is_forbidden_la(ms, cs->sel_mcc, - cs->sel_mnc, cs->sel_lac)) { + if (gsm322_is_forbidden_la(ms, &cs->sel_cgi.lai)) { LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n"); msg_type = GSM322_EVENT_REG_FAILED; goto stop; @@ -2198,13 +2185,9 @@ static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg) goto stop; } - mm->lupd_mcc = cs->sel_mcc; - mm->lupd_mnc = cs->sel_mnc; - mm->lupd_lac = cs->sel_lac; + memcpy(&mm->lupd_lai, &cs->sel_cgi.lai, sizeof(mm->lupd_lai)); - LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %s, MNC %s " - "LAC 0x%04x)\n", gsm_print_mcc(mm->lupd_mcc), - gsm_print_mnc(mm->lupd_mnc), mm->lupd_lac); + LOGP(DSUM, LOGL_INFO, "Perform location update (LAI=%s)\n", osmo_lai_name(&mm->lupd_lai)); return gsm48_mm_tx_loc_upd_req(ms); } @@ -2247,9 +2230,7 @@ static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg) /* if location update is not required */ if (subscr->ustate == GSM_SIM_U1_UPDATED && cs->selected - && cs->sel_mcc == subscr->mcc - && cs->sel_mnc == subscr->mnc - && cs->sel_lac == subscr->lac + && (osmo_lai_cmp(&cs->sel_cgi.lai, &subscr->lai) == 0) && (subscr->imsi_attached || !s->att_allowed)) { LOGP(DMM, LOGL_INFO, "Loc. upd. not required.\n"); @@ -2277,9 +2258,7 @@ static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg) /* 4.4.3 is attachment required? */ if (subscr->ustate == GSM_SIM_U1_UPDATED && cs->selected - && cs->sel_mcc == subscr->mcc - && cs->sel_mnc == subscr->mnc - && cs->sel_lac == subscr->lac + && (osmo_lai_cmp(&cs->sel_cgi.lai, &subscr->lai) == 0) && !subscr->imsi_attached && s->att_allowed) { /* do location update for IMSI attach */ @@ -2357,10 +2336,8 @@ static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms) * * NOTE: The TMSI is only valid within a LAI! */ - gsm48_encode_lai_hex(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac); - LOGP(DMM, LOGL_INFO, " using LAI (mcc %s mnc %s " "lac 0x%04x)\n", - gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac); + gsm48_generate_lai2(&nlu->lai, &subscr->lai); + LOGP(DMM, LOGL_INFO, " using LAI=%s\n", osmo_lai_name(&subscr->lai)); /* classmark 1 */ pwr_lev = gsm48_current_pwr_lev(set, cs->sel_arfcn); gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind, @@ -2427,7 +2404,7 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg) stop_mm_t3212(mm); /* 4.4.2 */ /* LAI */ - gsm48_decode_lai_hex(lai, &subscr->mcc, &subscr->mnc, &subscr->lac); + gsm48_decode_lai2(lai, &subscr->lai); /* stop location update timer */ stop_mm_t3210(mm); @@ -2445,19 +2422,17 @@ static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg) gsm_subscr_write_loci(ms); /* set last registered PLMN */ - if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) { + if (subscr->lai.lac > 0x0000 && subscr->lai.lac < 0xfffe) { subscr->plmn_valid = 1; - subscr->plmn_mcc = subscr->mcc; - subscr->plmn_mnc = subscr->mnc; + memcpy(&subscr->plmn, &subscr->lai.plmn, sizeof(struct osmo_plmn_id)); } LOGP(DSUM, LOGL_INFO, "Location update accepted\n"); - LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %s mnc %s " - "lac 0x%04x)\n", gsm_print_mcc(subscr->mcc), - gsm_print_mnc(subscr->mnc), subscr->lac); + LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (lai=%s)\n", + osmo_lai_name(&subscr->lai)); /* remove LA from forbidden list */ - gsm322_del_forbidden_la(ms, subscr->mcc, subscr->mnc, subscr->lac); + gsm322_del_forbidden_la(ms, &subscr->lai); /* MI */ if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) { @@ -2583,7 +2558,7 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg) case GSM48_REJECT_ROAMING_NOT_ALLOWED: /* TMSI and LAI invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* key is invalid */ subscr->key_seq = 7; @@ -2632,15 +2607,13 @@ static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg) LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n"); break; case GSM48_REJECT_PLMN_NOT_ALLOWED: - gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc, - mm->lupd_mnc, mm->lupd_rej_cause); + gsm_subscr_add_forbidden_plmn(subscr, &mm->lupd_lai.plmn, mm->lupd_rej_cause); LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not " "allowed)\n"); break; case GSM48_REJECT_LOC_NOT_ALLOWED: case GSM48_REJECT_ROAMING_NOT_ALLOWED: - gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc, - mm->lupd_lac, mm->lupd_rej_cause); + gsm322_add_forbidden_la(ms, &mm->lupd_lai, mm->lupd_rej_cause); LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not " "allowed)\n"); break; @@ -2687,9 +2660,7 @@ static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg) stop_mm_t3210(mm); if (subscr->ustate == GSM_SIM_U1_UPDATED - && mm->lupd_mcc == subscr->mcc - && mm->lupd_mnc == subscr->mnc - && mm->lupd_lac == subscr->lac) { + && (osmo_lai_cmp(&mm->lupd_lai, &subscr->lai) == 0)) { if (mm->lupd_attempt < 4) { LOGP(DSUM, LOGL_INFO, "Try location update later\n"); LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n", @@ -2706,7 +2677,7 @@ static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg) /* TMSI and LAI invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* key is invalid */ subscr->key_seq = 7; @@ -2914,7 +2885,7 @@ static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg) /* TMSI and LAI invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->lac = 0x0000; + subscr->lai.lac = 0x0000; /* key is invalid */ subscr->key_seq = 7; diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 5690746d3..a0aad3c11 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -658,10 +658,9 @@ static void timeout_rr_meas(void *arg) berr = (meas->berr + meas->frames / 2) / meas->frames; snr = (meas->snr + meas->frames / 2) / meas->frames; OSMO_STRBUF_PRINTF(sb, "MON: f=%d lev=%s snr=%2d ber=%3d " - "LAI=%s %s %04x ID=%04x", cs->sel_arfcn, + "CGI=%s", cs->sel_arfcn, gsm_print_rxlev(rxlev), snr, berr, - gsm_print_mcc(cs->sel_mcc), - gsm_print_mnc(cs->sel_mnc), cs->sel_lac, cs->sel_id); + osmo_cgi_name(&cs->sel_cgi)); if (rr->state == GSM48_RR_ST_DEDICATED) { OSMO_STRBUF_PRINTF(sb, " TA=%d pwr=%d", rr->cd_now.ind_ta - set->alter_delay, @@ -1952,9 +1951,7 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg) gsm48_decode_sysinfo4(s, si, msgb_l3len(msg)); - LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4 (mcc %s mnc %s " - "lac 0x%04x)\n", gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), s->lac); + LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4 (lai=%s)\n", osmo_lai_name(&s->lai)); return gsm48_new_sysinfo(ms, si->header.system_information); } @@ -2077,9 +2074,8 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg) gsm48_decode_sysinfo6(s, si, msgb_l3len(msg)); - LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 6 (mcc %s mnc %s " - "lac 0x%04x SACCH-timeout %d)\n", gsm_print_mcc(s->mcc), - gsm_print_mnc(s->mnc), s->lac, s->sacch_radio_link_timeout); + LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 6 (lai=%s SACCH-timeout %d)\n", + osmo_lai_name(&s->lai), s->sacch_radio_link_timeout); meas->rl_fail = meas->s = s->sacch_radio_link_timeout; LOGP(DRR, LOGL_INFO, "using (new) SACCH timeout %d\n", meas->rl_fail); @@ -2148,9 +2144,7 @@ static uint8_t gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi) return 0; memcpy(&tmsi, mi+2, 4); if (ms->subscr.tmsi == ntohl(tmsi) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(tmsi)); @@ -2269,9 +2263,7 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg) chan_2 = pa->cneed2; /* first MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi1) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1, GSM_MI_TYPE_TMSI); @@ -2280,9 +2272,7 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg) ntohl(pa->tmsi1)); /* second MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi2) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1, GSM_MI_TYPE_TMSI); @@ -2339,9 +2329,7 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg) chan_4 = pa->cneed4; /* first MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi1) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1, GSM_MI_TYPE_TMSI); @@ -2350,9 +2338,7 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg) ntohl(pa->tmsi1)); /* second MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi2) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1, GSM_MI_TYPE_TMSI); @@ -2361,9 +2347,7 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg) ntohl(pa->tmsi2)); /* third MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi3) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi3)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1, GSM_MI_TYPE_TMSI); @@ -2372,9 +2356,7 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg) ntohl(pa->tmsi3)); /* fourth MI */ if (ms->subscr.tmsi == ntohl(pa->tmsi4) - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac) { + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0)) { LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi4)); return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1, GSM_MI_TYPE_TMSI); @@ -3310,9 +3292,7 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms) gsm48_rr_enc_cm2(ms, &pr->cm2, rr->cd_now.arfcn); /* mobile identity */ if (ms->subscr.tmsi != GSM_RESERVED_TMSI - && ms->subscr.mcc == cs->sel_mcc - && ms->subscr.mnc == cs->sel_mnc - && ms->subscr.lac == cs->sel_lac + && (osmo_lai_cmp(&ms->subscr.lai, &cs->sel_cgi.lai) == 0) && rr->paging_mi_type == GSM_MI_TYPE_TMSI) { gsm48_generate_mid_from_tmsi(mi, subscr->tmsi); LOGP(DRR, LOGL_INFO, "sending paging response with " diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 0761419ce..9b9ba951d 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -151,23 +151,21 @@ static void gsm_ms_dump(struct osmocom_ms *ms, struct vty *vty) else vty_out(vty, " manual network selection state : %s%s", get_m_state_name(ms->plmn.state), VTY_NEWLINE); - if (ms->plmn.mcc) + if (ms->plmn.plmn.mcc) vty_out(vty, " MCC=%s " - "MNC=%s (%s, %s)%s", gsm_print_mcc(ms->plmn.mcc), - gsm_print_mnc(ms->plmn.mnc), gsm_get_mcc(ms->plmn.mcc), - gsm_get_mnc(ms->plmn.mcc, ms->plmn.mnc), VTY_NEWLINE); + "MNC=%s (%s, %s)%s", osmo_mcc_name(ms->plmn.plmn.mcc), + osmo_mnc_name(ms->plmn.plmn.mnc, ms->plmn.plmn.mnc_3_digits), + gsm_get_mcc(ms->plmn.plmn.mcc), + gsm_get_mnc(&ms->plmn.plmn), VTY_NEWLINE); vty_out(vty, " cell selection state: %s%s", get_cs_state_name(ms->cellsel.state), VTY_NEWLINE); - if (ms->cellsel.sel_mcc) { - vty_out(vty, " ARFCN=%s MCC=%s MNC=%s " - "LAC=0x%04x CELLID=0x%04x%s", + if (ms->cellsel.sel_cgi.lai.plmn.mcc) { + vty_out(vty, " ARFCN=%s CGI=%s%s", gsm_print_arfcn(ms->cellsel.sel_arfcn), - gsm_print_mcc(ms->cellsel.sel_mcc), - gsm_print_mnc(ms->cellsel.sel_mnc), - ms->cellsel.sel_lac, ms->cellsel.sel_id, VTY_NEWLINE); + osmo_cgi_name(&ms->cellsel.sel_cgi), VTY_NEWLINE); vty_out(vty, " (%s, %s)%s", - gsm_get_mcc(ms->cellsel.sel_mcc), - gsm_get_mnc(ms->cellsel.sel_mcc, ms->cellsel.sel_mnc), + gsm_get_mcc(ms->cellsel.sel_cgi.lai.plmn.mcc), + gsm_get_mnc(&ms->cellsel.sel_cgi.lai.plmn), VTY_NEWLINE); } vty_out(vty, " radio resource layer state: %s%s", @@ -282,26 +280,26 @@ DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]", "Mobile Network Code") { struct osmocom_ms *ms; - uint16_t mcc = 0, mnc = 0; + struct osmo_plmn_id plmn; + struct osmo_plmn_id *plmn_ptr = NULL; ms = l23_vty_get_ms(argv[0], vty); if (!ms) return CMD_WARNING; if (argc >= 3) { - mcc = gsm_input_mcc((char *)argv[1]); - mnc = gsm_input_mnc((char *)argv[2]); - if (mcc == GSM_INPUT_INVALID) { + if (osmo_mcc_from_str(argv[1], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[2], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } + plmn_ptr = &plmn; } - gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, l23_vty_printf, vty); + gsm322_dump_ba_list(&ms->cellsel, plmn_ptr, l23_vty_printf, vty); return CMD_SUCCESS; } @@ -372,18 +370,17 @@ DEFUN(network_select, network_select_cmd, "Force selecting a network that is not in the list") { struct osmocom_ms *ms; - struct gsm322_plmn *plmn; + struct gsm322_plmn *plmn322; struct msgb *nmsg; struct gsm322_msg *ngm; struct gsm322_plmn_list *temp; - uint16_t mcc = gsm_input_mcc((char *)argv[1]), - mnc = gsm_input_mnc((char *)argv[2]); + struct osmo_plmn_id plmn; int found = 0; ms = l23_vty_get_ms(argv[0], vty); if (!ms) return CMD_WARNING; - plmn = &ms->plmn; + plmn322 = &ms->plmn; if (ms->settings.plmn_mode != PLMN_MODE_MANUAL) { vty_out(vty, "Not in manual network selection mode%s", @@ -391,18 +388,18 @@ DEFUN(network_select, network_select_cmd, return CMD_WARNING; } - if (mcc == GSM_INPUT_INVALID) { + if (osmo_mcc_from_str(argv[1], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[2], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } if (argc < 4) { - llist_for_each_entry(temp, &plmn->sorted_plmn, entry) - if (temp->mcc == mcc && temp->mnc == mnc) + llist_for_each_entry(temp, &plmn322->sorted_plmn, entry) + if (osmo_plmn_cmp(&temp->plmn, &plmn) == 0) found = 1; if (!found) { vty_out(vty, "Network not in list!%s", VTY_NEWLINE); @@ -416,8 +413,7 @@ DEFUN(network_select, network_select_cmd, if (!nmsg) return CMD_WARNING; ngm = (struct gsm322_msg *) nmsg->data; - ngm->mcc = mcc; - ngm->mnc = mnc; + memcpy(&ngm->plmn, &plmn, sizeof(struct osmo_plmn_id)); gsm322_plmn_sendmsg(ms, nmsg); return CMD_SUCCESS; @@ -623,23 +619,22 @@ DEFUN(delete_forbidden_plmn, delete_forbidden_plmn_cmd, "Mobile Country Code\nMobile Network Code") { struct osmocom_ms *ms; - uint16_t mcc = gsm_input_mcc((char *)argv[1]), - mnc = gsm_input_mnc((char *)argv[2]); + struct osmo_plmn_id plmn; ms = l23_vty_get_ms(argv[0], vty); if (!ms) return CMD_WARNING; - if (mcc == GSM_INPUT_INVALID) { + if (osmo_mcc_from_str(argv[1], &plmn.mcc) < 0) { vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - if (mnc == GSM_INPUT_INVALID) { + if (osmo_mnc_from_str(argv[2], &plmn.mnc, &plmn.mnc_3_digits) < 0) { vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); return CMD_WARNING; } - gsm_subscr_del_forbidden_plmn(&ms->subscr, mcc, mnc); + gsm_subscr_del_forbidden_plmn(&ms->subscr, &plmn); return CMD_SUCCESS; } @@ -667,9 +662,10 @@ DEFUN(network_show, network_show_cmd, "network show MS_NAME", llist_for_each_entry(temp, &plmn->sorted_plmn, entry) vty_out(vty, " Network %s, %s (%s, %s)%s", - gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc), - gsm_get_mcc(temp->mcc), - gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE); + osmo_mcc_name(temp->plmn.mcc), + osmo_mnc_name(temp->plmn.mnc, temp->plmn.mnc_3_digits), + gsm_get_mcc(temp->plmn.mcc), + gsm_get_mnc(&temp->plmn), VTY_NEWLINE); return CMD_SUCCESS; }