From 255539c7422750c5e3643739538b8dcb1f106fcd Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 28 Dec 2008 02:26:27 +0000 Subject: [PATCH] working state up to location update and classmark inquiry --- include/openbsc/gsm_data.h | 4 +++ src/abis_rsl.c | 2 +- src/bsc_hack.c | 74 ++++++++++++++++++++++++++++++++++++++ src/db_test.c | 1 + src/gsm_04_08.c | 45 +++++++++++++++-------- tests/sms.txt | 2 ++ 6 files changed, 113 insertions(+), 15 deletions(-) diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h index 8a04b7b9e..2d0c3c53b 100644 --- a/include/openbsc/gsm_data.h +++ b/include/openbsc/gsm_data.h @@ -3,6 +3,8 @@ #include +#include + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define GSM_MAX_BTS 8 @@ -67,6 +69,8 @@ struct gsm_lchan { enum gsm_chan_t type; /* To whom we are allocated at the moment */ struct gsm_subscriber *subscr; + /* Universal timer, undefined use ;) */ + struct timer_list timer; /* local end of a call, if any */ struct gsm_call call; diff --git a/src/abis_rsl.c b/src/abis_rsl.c index 54b706936..9c1c2934a 100644 --- a/src/abis_rsl.c +++ b/src/abis_rsl.c @@ -374,7 +374,7 @@ int rsl_paging_cmd(struct gsm_bts *bts, u_int8_t paging_group, u_int8_t len, dh->chan_nr = RSL_CHAN_PCH_AGCH; msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group); - msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len, ms_ident); + msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2); msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed); msg->trx = bts->c0; diff --git a/src/bsc_hack.c b/src/bsc_hack.c index b9b9f8beb..2838ff8bc 100644 --- a/src/bsc_hack.c +++ b/src/bsc_hack.c @@ -30,7 +30,10 @@ #define _GNU_SOURCE #include +#include +#include #include +#include #include #include #include @@ -631,6 +634,74 @@ static void handle_options(int argc, char** argv) } } +static struct timer_list pag_timer; + +/* handles uppercase decimal and hexadecimal */ +static u_int8_t char2bcd(char c) +{ + if (c <= '9') + return c - '0'; + else + return c - 'A'; +} + +static int string_to_mi(u_int8_t *mi, const char *string, + u_int8_t type) +{ + u_int8_t *cur = mi+3; + + mi[0] = GSM48_IE_MOBILE_ID; + //mi[1] = TMSI_LEN; + mi[2] = type & GSM_MI_TYPE_MASK; + + if (strlen(string) & 0x01) + mi[2] |= char2bcd(*string++) << 4; + else + mi[2] |= 0xf0; + + while (*string && *(string+1)) + *cur++ = char2bcd(*string++) | (char2bcd(*string++) << 4); + + mi[1] = cur - mi; + + return cur - mi; +} + +static const char *nokia_imsi = "7240311131388"; +static const char *rokr_imsi = "4660198001300"; + +void pag_timer_cb(void *data) +{ + struct gsm_bts *bts = &gsmnet->bts[0]; + u_int8_t mi[128]; + struct gsm_subscriber _subscr, *subscr = &_subscr; + unsigned int paging_group, mi_len; + u_int64_t num_imsi; + const char *imsi = nokia_imsi; + + printf("FEUER\n"); + +#if 1 + memset(subscr, 0, sizeof(*subscr)); + strcpy(subscr->imsi, imsi); + db_get_subscriber(GSM_SUBSCRIBER_IMSI, subscr); + if (!subscr) + return; + + mi_len = generate_mid_from_tmsi(mi, strtoul(subscr->tmsi, NULL, 10)); +#else + mi_len = string_to_mi(mi, imsi, GSM_MI_TYPE_IMSI); +#endif + + num_imsi = strtoull(imsi, NULL, 10); + paging_group = get_paging_group(num_imsi, 1, 3); + + for (paging_group = 0; paging_group < 3; paging_group++) + rsl_paging_cmd(bts, paging_group, mi_len, mi, RSL_CHANNEED_TCH_F); + + schedule_timer(&pag_timer, 10, 0); +} + int main(int argc, char **argv) { /* parse options */ @@ -650,6 +721,9 @@ int main(int argc, char **argv) bootstrap_network(); + pag_timer.cb = pag_timer_cb; + schedule_timer(&pag_timer, 10, 0); + while (1) { bsc_select_main(); } diff --git a/src/db_test.c b/src/db_test.c index 27ddbab0b..0367ce227 100644 --- a/src/db_test.c +++ b/src/db_test.c @@ -21,6 +21,7 @@ #include #include +#include int main() { diff --git a/src/gsm_04_08.c b/src/gsm_04_08.c index 9a6212d67..3902d9406 100644 --- a/src/gsm_04_08.c +++ b/src/gsm_04_08.c @@ -97,15 +97,19 @@ static void generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, lai48->lac = htons(lac); } -#define TMSI_LEN 4 +#define TMSI_LEN 5 #define MID_TMSI_LEN (TMSI_LEN + 2) -static void generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) +int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) { + u_int32_t *tptr = &buf[3]; + buf[0] = GSM48_IE_MOBILE_ID; buf[1] = TMSI_LEN; buf[2] = 0xf0 | GSM_MI_TYPE_TMSI; - *((u_int32_t *) &buf[3]) = htonl(tmsi); + *tptr = htonl(tmsi); + + return 7; } static struct msgb *gsm48_msgb_alloc(void) @@ -256,11 +260,12 @@ static int mm_rx_id_resp(struct msgb *msg) if (lchan->subscr && lchan->subscr->authorized) { /* FIXME: check if we've recently received UPDATE REQUEST */ db_subscriber_alloc_tmsi(lchan->subscr); - tmsi = strtoul(lchan->subscr->tmsi, NULL, 16); + tmsi = strtoul(lchan->subscr->tmsi, NULL, 10); return gsm0408_loc_upd_acc(msg->lchan, tmsi); } break; case GSM_MI_TYPE_IMEI: + case GSM_MI_TYPE_IMEISV: /* update subscribe <-> IMEI mapping */ if (lchan->subscr) db_subscriber_assoc_imei(lchan->subscr, mi_string); @@ -269,6 +274,15 @@ static int mm_rx_id_resp(struct msgb *msg) return 0; } + +static void loc_upd_rej_cb(void *data) +{ + struct gsm_lchan *lchan = data; + + gsm0408_loc_upd_rej(lchan, 0x16); + rsl_chan_release(lchan); +} + #define MI_SIZE 32 /* Chapter 9.2.15 */ static int mm_rx_loc_upd_req(struct msgb *msg) @@ -277,6 +291,7 @@ static int mm_rx_loc_upd_req(struct msgb *msg) struct gsm_bts *bts = msg->trx->bts; struct gsm48_loc_upd_req *lu; struct gsm_subscriber *subscr; + struct gsm_lchan *lchan = msg->lchan; u_int8_t mi_type; u_int32_t tmsi; char mi_string[MI_SIZE]; @@ -292,18 +307,18 @@ static int mm_rx_loc_upd_req(struct msgb *msg) switch (mi_type) { case GSM_MI_TYPE_IMSI: /* we always want the IMEI, too */ - rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV); + rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEISV); /* look up subscriber based on IMSI */ subscr = db_create_subscriber(mi_string); break; case GSM_MI_TYPE_TMSI: /* we always want the IMEI, too */ - rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMEISV); + rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMEISV); /* look up the subscriber based on TMSI, request IMSI if it fails */ subscr = subscr_get_by_tmsi(lu->mi); if (!subscr) { /* send IDENTITY REQUEST message to get IMSI */ - rc = mm_tx_identity_req(msg->lchan, GSM_MI_TYPE_IMSI); + rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI); } break; case GSM_MI_TYPE_IMEI: @@ -316,20 +331,22 @@ static int mm_rx_loc_upd_req(struct msgb *msg) break; } + lchan->subscr = subscr; + if (!subscr || !subscr->authorized) { /* 0x16 is congestion */ - gsm0408_loc_upd_rej(msg->lchan, 0x16); - rsl_chan_release(msg->lchan); - return -EINVAL; + lchan->timer.cb = loc_upd_rej_cb; + lchan->timer.data = lchan; + schedule_timer(&lchan->timer, 1, 0); + return 0; } db_subscriber_alloc_tmsi(subscr); - - msg->lchan->subscr = subscr; subscr_update(subscr, bts); - tmsi = strtoul(subscr->tmsi, NULL, 16); - return gsm0408_loc_upd_acc(msg->lchan, tmsi); + tmsi = strtoul(subscr->tmsi, NULL, 10); + + return gsm0408_loc_upd_acc(lchan, tmsi); } static int gsm48_tx_mm_serv_ack(struct gsm_lchan *lchan) diff --git a/tests/sms.txt b/tests/sms.txt index 307cc4c21..ea6eab15f 100644 --- a/tests/sms.txt +++ b/tests/sms.txt @@ -1,5 +1,7 @@ 03 02 01 0a 02 43 0b 00 1d 39 01 1a 00 01 00 07 91 55 11 18 31 28 00 0e 31 20 04 81 21 43 00 00 ff 04 d4 f2 9c 0e +03 02 01 0a 02 43 0b 00 9f 09 01 9c 00 da 00 07 91 88 96 13 00 00 99 90 11 7b 04 81 22 22 00 08 ff 86 6c 38 8c 50 92 80 88 4c 00 4d 00 4d 00 41 6a 19 67 03 74 06 8c a1 7d b2 00 20 00 20 51 68 74 03 99 96 52 75 7d b2 8d ef 6a 19 67 03 ff 0c 6a 19 67 03 96 f6 98 a8 96 aa ff 01 8b 93 60 a8 80 70 66 0e 51 32 84 c4 ff 0c 97 48 6d 3b 62 95 8c c7 ff 01 73 fe 57 28 52 a0 51 65 90 01 96 50 91 cf 59 27 80 6f 76 df 6d 0b 57 fa 96 8a 91 77 5e 63 53 61 ff 0c 8a cb 4e 0a 7d b2 64 1c 5c 0b 30 0c 6a 19 67 03 30 0d + 03 - 02 - 01 -