aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gsm_04_08_utils.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-08-19 07:54:59 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-08-20 13:57:12 +0200
commitd1862d7cf98b984407d8533ac68b0ae85cfbf9c7 (patch)
tree5b83437ee68e41b0d831b3b2c45fc1f2449525a3 /openbsc/src/gsm_04_08_utils.c
parent081c00d885c9c929f2430f48eb11c2a96afea116 (diff)
[gsm48] Move parsing of the MI from to gsm_04_08_utils.c
The parsing of the IMSI is needed for the MSC part as well. Move it to the gsm_04_08_utils.c so it can be used.
Diffstat (limited to 'openbsc/src/gsm_04_08_utils.c')
-rw-r--r--openbsc/src/gsm_04_08_utils.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index 50deb2bcb..e771ea3b2 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -156,6 +156,15 @@ static void to_bcd(u_int8_t *bcd, u_int16_t val)
val = val / 10;
}
+static char bcd2char(u_int8_t bcd)
+{
+ if (bcd < 0xa)
+ return '0' + bcd;
+ else
+ return 'A' + (bcd - 0xa);
+}
+
+
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
u_int16_t mnc, u_int16_t lac)
{
@@ -308,3 +317,46 @@ int gsm48_send_rr_release(struct gsm_lchan *lchan)
return rsl_deact_sacch(lchan);
}
+/* Convert Mobile Identity (10.5.1.4) to string */
+int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len)
+{
+ int i;
+ u_int8_t mi_type;
+ char *str_cur = string;
+ u_int32_t tmsi;
+
+ mi_type = mi[0] & GSM_MI_TYPE_MASK;
+
+ switch (mi_type) {
+ case GSM_MI_TYPE_NONE:
+ break;
+ case GSM_MI_TYPE_TMSI:
+ /* Table 10.5.4.3, reverse generate_mid_from_tmsi */
+ if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
+ memcpy(&tmsi, &mi[1], 4);
+ tmsi = ntohl(tmsi);
+ return snprintf(string, str_len, "%u", tmsi);
+ }
+ break;
+ case GSM_MI_TYPE_IMSI:
+ case GSM_MI_TYPE_IMEI:
+ case GSM_MI_TYPE_IMEISV:
+ *str_cur++ = bcd2char(mi[0] >> 4);
+
+ for (i = 1; i < mi_len; i++) {
+ if (str_cur + 2 >= string + str_len)
+ return str_cur - string;
+ *str_cur++ = bcd2char(mi[i] & 0xf);
+ /* skip last nibble in last input byte when GSM_EVEN */
+ if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
+ *str_cur++ = bcd2char(mi[i] >> 4);
+ }
+ break;
+ default:
+ break;
+ }
+ *str_cur++ = '\0';
+
+ return str_cur - string;
+}
+