summaryrefslogtreecommitdiffstats
path: root/src/host/layer23
diff options
context:
space:
mode:
Diffstat (limited to 'src/host/layer23')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/sysinfo.h4
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h4
-rw-r--r--src/host/layer23/src/common/sysinfo.c31
-rw-r--r--src/host/layer23/src/mobile/gsm48_mm.c6
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c11
-rw-r--r--src/host/layer23/src/mobile/subscriber.c15
6 files changed, 44 insertions, 27 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/sysinfo.h b/src/host/layer23/include/osmocom/bb/common/sysinfo.h
index 5d3ed596..f843f271 100644
--- a/src/host/layer23/include/osmocom/bb/common/sysinfo.h
+++ b/src/host/layer23/include/osmocom/bb/common/sysinfo.h
@@ -154,5 +154,9 @@ int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s,
int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq,
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(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/mobile/gsm48_rr.h b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
index b7280fb4..38ac3611 100644
--- a/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
+++ b/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
@@ -195,10 +195,6 @@ int gsm48_rsl_dequeue(struct osmocom_ms *ms);
int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
struct msgb *gsm48_l3_msgb_alloc(void);
struct msgb *gsm48_rr_msgb_alloc(int msg_type);
-int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
- uint16_t *mnc, uint16_t *lac);
-int gsm48_encode_lai(struct gsm48_loc_area_id *lai, uint16_t mcc,
- uint16_t mnc, uint16_t lac);
int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm,
uint16_t arfcn);
int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg);
diff --git a/src/host/layer23/src/common/sysinfo.c b/src/host/layer23/src/common/sysinfo.c
index 8f82c289..2816c266 100644
--- a/src/host/layer23/src/common/sysinfo.c
+++ b/src/host/layer23/src/common/sysinfo.c
@@ -687,7 +687,7 @@ int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s,
/* Cell Identity */
s->cell_id = ntohs(si->cell_identity);
/* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
+ gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac);
/* Control Channel Description */
gsm48_decode_ccd(s, &si->control_channel_desc);
/* Cell Options (BCCH) */
@@ -720,7 +720,7 @@ int gsm48_decode_sysinfo4(struct gsm48_sysinfo *s,
memcpy(s->si4_msg, si, MIN(len, sizeof(s->si4_msg)));
/* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
+ gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac);
/* Cell Selection Parameters */
gsm48_decode_cell_sel_param(s, &si->cell_sel_par);
/* RACH Control Parameter */
@@ -829,7 +829,7 @@ int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s,
"read.\n");
s->cell_id = ntohs(si->cell_identity);
/* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
+ gsm48_decode_lai_hex(&si->lai, &s->mcc, &s->mnc, &s->lac);
/* Cell Options (SACCH) */
gsm48_decode_cellopt_sacch(s, &si->cell_options);
/* NCC Permitted */
@@ -843,3 +843,28 @@ int gsm48_decode_sysinfo6(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(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/mobile/gsm48_mm.c b/src/host/layer23/src/mobile/gsm48_mm.c
index a8f699d2..331cfe3b 100644
--- a/src/host/layer23/src/mobile/gsm48_mm.c
+++ b/src/host/layer23/src/mobile/gsm48_mm.c
@@ -1577,7 +1577,7 @@ static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
/* LAI */
- gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
+ gsm48_decode_lai_hex(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
/* MI */
mi = gh->data + sizeof(struct gsm48_loc_area_id);
mi_type = mi[1] & GSM_MI_TYPE_MASK;
@@ -2349,7 +2349,7 @@ static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
*
* NOTE: The TMSI is only valid within a LAI!
*/
- gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
+ 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);
@@ -2419,7 +2419,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(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
+ gsm48_decode_lai_hex(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
/* stop location update timer */
stop_mm_t3210(mm);
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index b6083afe..bc244699 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -98,17 +98,6 @@ static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg);
#define MIN(a, b) ((a < b) ? a : b)
-int gsm48_encode_lai(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;
-}
-
/* decode "Power Command" (10.5.2.28) and (10.5.2.28a) */
static int gsm48_decode_power_cmd_acc(struct gsm48_power_cmd *pc,
uint8_t *power_level, uint8_t *atc)
diff --git a/src/host/layer23/src/mobile/subscriber.c b/src/host/layer23/src/mobile/subscriber.c
index 8ebb1738..cefc8556 100644
--- a/src/host/layer23/src/mobile/subscriber.c
+++ b/src/host/layer23/src/mobile/subscriber.c
@@ -282,7 +282,8 @@ static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data,
subscr->tmsi = ntohl(loci->tmsi);
/* LAI */
- gsm48_decode_lai(&loci->lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
+ gsm48_decode_lai_hex(&loci->lai, &subscr->mcc, &subscr->mnc,
+ &subscr->lac);
/* location update status */
switch (loci->lupd_status & 0x07) {
@@ -408,8 +409,8 @@ static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data,
lai[0] = data[0];
lai[1] = data[1];
lai[2] = data[2];
- gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &plmn->mcc,
- &plmn->mnc, &dummy_lac);
+ gsm48_decode_lai_hex((struct gsm48_loc_area_id *)lai,
+ &plmn->mcc, &plmn->mnc, &dummy_lac);
llist_add_tail(&plmn->entry, &subscr->plmn_list);
LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc=%s mnc=%s) "
@@ -512,8 +513,10 @@ static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data,
lai[0] = data[0];
lai[1] = data[1];
lai[2] = data[2];
- gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &na->mcc,
+ 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));
na->cause = -1; /* must have a value, but SIM stores no cause */
llist_add_tail(&na->entry, &subscr->plmn_na);
@@ -821,7 +824,7 @@ static int subscr_write_plmn_na(struct osmocom_ms *ms)
nsh->file = 0x6f7b;
for (i = 0; i < 4; i++) {
if (nas[i]) {
- gsm48_encode_lai((struct gsm48_loc_area_id *)lai,
+ gsm48_encode_lai_hex((struct gsm48_loc_area_id *)lai,
nas[i]->mcc, nas[i]->mnc, 0);
*data++ = lai[0];
*data++ = lai[1];
@@ -866,7 +869,7 @@ int gsm_subscr_write_loci(struct osmocom_ms *ms)
loci->tmsi = htonl(subscr->tmsi);
/* LAI */
- gsm48_encode_lai(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac);
+ gsm48_encode_lai_hex(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac);
/* TMSI time */
loci->tmsi_time = 0xff;