summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-10-30 10:26:20 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2012-10-30 10:26:20 +0100
commit07f83456460a2cdb8d288ac647f04a5bc09dc1cf (patch)
treebb213ff0af638ac4439ae079eda12b094b34fbea
parenta4924a33b03a13ad78d69785b73d3d2dd09b18b2 (diff)
Fixed decoding of hexadecimal LAI components
libosmocore has changed its LAI decoding from hex to decimal. This caused wrong decoding of MCC and MNC. In order to provide required hex transcoding, special hex encoding and decoding function are added to mobile/sysinfo.c.
-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 5d3ed59..f843f27 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 b7280fb..38ac361 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 8f82c28..2816c26 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 a8f699d..331cfe3 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 b6083af..bc24469 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 8ebb173..cefc855 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;