From a1c4f765eca695bf3d9c41d741bcab81989c8d48 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 1 May 2010 11:59:42 +0200 Subject: [PATCH] import gsm48_parse_ra() and gprs_tlli_type() from openbsc --- include/osmocore/gsm48.h | 11 +++++++++++ include/osmocore/gsm_utils.h | 12 ++++++++++++ include/osmocore/protocol/gsm_04_08.h | 9 ++++++++- src/gsm48.c | 21 +++++++++++++++++++++ src/gsm_utils.c | 15 +++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/include/osmocore/gsm48.h b/include/osmocore/gsm48.h index e3a1defa7..9015c25b9 100644 --- a/include/osmocore/gsm48.h +++ b/include/osmocore/gsm48.h @@ -4,6 +4,14 @@ #include #include +/* A parsed GPRS routing area */ +struct gprs_ra_id { + uint16_t mnc; + uint16_t mcc; + uint16_t lac; + uint8_t rac; +}; + extern const struct tlv_definition gsm48_att_tlvdef; const char *gsm48_cc_state_name(uint8_t state); const char *gsm48_cc_msg_name(uint8_t msgtype); @@ -18,4 +26,7 @@ int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi); int gsm48_mi_to_string(char *string, const int str_len, const uint8_t *mi, const int mi_len); +/* Parse Routeing Area Identifier */ +void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf); + #endif diff --git a/include/osmocore/gsm_utils.h b/include/osmocore/gsm_utils.h index 195e865ca..51e9f2e6a 100644 --- a/include/osmocore/gsm_utils.h +++ b/include/osmocore/gsm_utils.h @@ -87,5 +87,17 @@ void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn); /* Convert from GSM time to frame number */ uint32_t gsm_gsmtime2fn(struct gsm_time *time); +/* GSM TS 03.03 Chapter 2.6 */ +enum gprs_tlli_tyoe { + TLLI_LOCAL, + TLLI_FOREIGN, + TLLI_RANDOM, + TLLI_AUXILIARY, + TLLI_RESERVED, +}; + +/* TS 03.03 Chapter 2.6 */ +int gprs_tlli_type(uint32_t tlli); + void generate_backtrace(); #endif diff --git a/include/osmocore/protocol/gsm_04_08.h b/include/osmocore/protocol/gsm_04_08.h index 47b98b292..1a112a085 100644 --- a/include/osmocore/protocol/gsm_04_08.h +++ b/include/osmocore/protocol/gsm_04_08.h @@ -735,10 +735,17 @@ enum gsm48_bcap_rrq { GSM48_BCAP_RRQ_DUAL_FR = 3, }; - #define GSM48_TMSI_LEN 5 #define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2) #define GSM48_MI_SIZE 32 +/* Chapter 10.4.4.15 */ +struct gsm48_ra_id { + uint8_t digits[3]; /* MCC + MNC BCD digits */ + uint16_t lac; /* Location Area Code */ + uint8_t rac; /* Routing Area Code */ +} __attribute__ ((packed)); + + #endif /* PROTO_GSM_04_08_H */ diff --git a/src/gsm48.c b/src/gsm48.c index 783ff6a5d..7e510664b 100644 --- a/src/gsm48.c +++ b/src/gsm48.c @@ -305,3 +305,24 @@ int gsm48_mi_to_string(char *string, const int str_len, const uint8_t *mi, return str_cur - string; } + +void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf) +{ + raid->mcc = (buf[0] & 0xf) * 100; + raid->mcc += (buf[0] >> 4) * 10; + raid->mcc += (buf[1] & 0xf) * 1; + + /* I wonder who came up with the stupidity of encoding the MNC + * differently depending on how many digits its decimal number has! */ + if ((buf[1] >> 4) == 0xf) { + raid->mnc = (buf[2] & 0xf) * 10; + raid->mnc += (buf[2] >> 4) * 1; + } else { + raid->mnc = (buf[2] & 0xf) * 100; + raid->mnc += (buf[2] >> 4) * 10; + raid->mnc += (buf[1] >> 4) * 1; + } + + raid->lac = ntohs(*(uint16_t *)(buf + 3)); + raid->rac = buf[5]; +} diff --git a/src/gsm_utils.c b/src/gsm_utils.c index 593dd5c94..b392fd37c 100644 --- a/src/gsm_utils.c +++ b/src/gsm_utils.c @@ -359,3 +359,18 @@ uint32_t gsm_gsmtime2fn(struct gsm_time *time) /* TS 05.02 Chapter 4.3.3 TDMA frame number */ return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1)); } + +/* TS 03.03 Chapter 2.6 */ +int gprs_tlli_type(uint32_t tlli) +{ + if ((tlli & 0xc0000000) == 0xc0000000) + return TLLI_LOCAL; + else if ((tlli & 0xc0000000) == 0x80000000) + return TLLI_FOREIGN; + else if ((tlli & 0xf8000000) == 0x78000000) + return TLLI_RANDOM; + else if ((tlli & 0xf8000000) == 0x70000000) + return TLLI_AUXILIARY; + + return TLLI_RESERVED; +}