summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2023-05-18 18:51:03 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2023-05-22 16:12:04 +0200
commit3348f491792788974c6bb3ee75f3a4f1d159aef9 (patch)
tree815af8fd65748bb4792edf2a6cebeec52a2a428c
parent554e7cfb56ff61e83c7321b7737baf4476bf8280 (diff)
Migrate network identifier fields to modern osmocom structures
This allows using well tested standarized API to print, compare, etc. usual identifiers like PLMN, LAI, etc. It also simplifies code by avoiding passing lots of parameters and making it easier to identify which fields go packed together. This is specially important since in the future more of those identifiers will be added for GPRS. Change-Id: I07a9289825c09ed748e53d36a746ea164c8a5d7f
-rw-r--r--src/host/layer23/include/osmocom/bb/common/networks.h23
-rw-r--r--src/host/layer23/include/osmocom/bb/common/settings.h3
-rw-r--r--src/host/layer23/include/osmocom/bb/common/subscriber.h18
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sysinfo.h7
-rw-r--r--src/host/layer23/include/osmocom/bb/misc/log.h3
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm322.h30
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h2
-rw-r--r--src/host/layer23/src/common/networks.c162
-rw-r--r--src/host/layer23/src/common/settings.c4
-rw-r--r--src/host/layer23/src/common/subscriber.c153
-rw-r--r--src/host/layer23/src/common/sysinfo.c46
-rw-r--r--src/host/layer23/src/common/vty.c44
-rw-r--r--src/host/layer23/src/misc/cell_log.c9
-rw-r--r--src/host/layer23/src/misc/gsmmap.c52
-rw-r--r--src/host/layer23/src/misc/log.c11
-rw-r--r--src/host/layer23/src/mobile/gsm322.c572
-rw-r--r--src/host/layer23/src/mobile/gsm48_mm.c113
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c46
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c68
19 files changed, 600 insertions, 766 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/networks.h b/src/host/layer23/include/osmocom/bb/common/networks.h
index d34f3162..408e17d0 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 <osmocom/gsm/gsm23003.h>
-#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 e312a1c1..f66874c1 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 <osmocom/core/utils.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/gsm/gsm23003.h>
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 972f6133..e2a8dab4 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 <osmocom/core/utils.h>
#include <osmocom/gsm/protocol/gsm_23_003.h>
+#include <osmocom/gsm/gsm23003.h>
/* 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 75cbcd94..0368901f 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 <osmocom/gsm/gsm48_ie.h>
+#include <osmocom/gsm/gsm23003.h>
/* 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 54d795bc..3183f876 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 86b1ef17..4b20a1a1 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 <osmocom/bb/common/sysinfo.h>
-
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
+#include <osmocom/gsm/gsm23003.h>
+
+#include <osmocom/bb/common/sysinfo.h>
/* 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 ce803174..b637a603 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 5374bc08..e2429ef8 100644
--- a/src/host/layer23/src/common/networks.c
+++ b/src/host/layer23/src/common/networks.c
@@ -2,6 +2,8 @@
#include <stdint.h>
#include <stdio.h>
+#include <osmocom/gsm/gsm23003.h>
+
#include <osmocom/bb/common/networks.h>
/* 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 6c58e65f..288b03ed 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 c1f98061..b0c5f193 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 42bc8abf..700accd0 100644
--- a/src/host/layer23/src/common/sysinfo.c
+++ b/src/host/layer23/src/common/sysinfo.c
@@ -22,6 +22,7 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/bitvec.h>
+#include <osmocom/gsm/gsm48.h>
#include <osmocom/gprs/rlcmac/csn1_defs.h>
@@ -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 427c8aa3..424efb22 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 7635f1f2..ed4d74d1 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 d98f2302..378b358b 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<name>%d: %d</name>\n", n, meas->rxlev);
fprintf(outfp, "\t\t\t\t\t\t<description>\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<Placemark>\n");
- fprintf(outfp, "\t\t\t\t\t\t<name>MCC=%s MNC=%s\nLAC=%04x "
- "CELL-ID=%04x\n(%s %s)</name>\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\t<name>LAI=%s "
+ "CELL-ID=%04x\n(%s %s)</name>\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<description>\n");
gsm48_sysinfo_dump(&cell->s, cell->sysinfo.arfcn, print_si, outfp,
NULL);
@@ -576,15 +578,20 @@ usage:
/* folder open */
fprintf(outfp, "\t<Folder>\n");
fprintf(outfp, "\t\t<name>MCC %s (%s)</name>\n",
- gsm_print_mcc(mcc->mcc), gsm_get_mcc(mcc->mcc));
+ osmo_mcc_name(mcc->mcc), gsm_get_mcc(mcc->mcc));
fprintf(outfp, "\t\t<open>0</open>\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<Folder>\n");
fprintf(outfp, "\t\t\t<name>MNC %s (%s)</name>\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\t<open>0</open>\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 bd8de7f8..577e1268 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 d7b41540..f21cb596 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 e72c3e0f..95808ee5 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 5690746d..a0aad3c1 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 0761419c..9b9ba951 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;
}