diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2009-08-20 14:02:31 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2009-08-20 14:02:31 +0200 |
commit | 9fe11d8c07773689812cccf00c1325458b09ae41 (patch) | |
tree | 51a3767c861603d1e317053ec5687cced1c86e21 | |
parent | 878daf069cb10f930a270ff6cbe9787b8923694f (diff) | |
parent | 5d0e56f722ce77ed29226c85e93dd09c9184f97e (diff) |
Merge branch 'holger/merge-msc-bsc-split'
-rw-r--r-- | openbsc/.gitignore | 39 | ||||
-rw-r--r-- | openbsc/include/openbsc/debug.h | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 5 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_subscriber.h | 3 | ||||
-rw-r--r-- | openbsc/src/debug.c | 2 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08.c | 75 | ||||
-rw-r--r-- | openbsc/src/gsm_04_08_utils.c | 89 | ||||
-rw-r--r-- | openbsc/src/gsm_subscriber_base.c | 9 | ||||
-rw-r--r-- | openbsc/src/paging.c | 8 | ||||
-rw-r--r-- | openbsc/src/telnet_interface.c | 47 | ||||
-rw-r--r-- | openbsc/tests/channel/channel_test.c | 3 | ||||
-rw-r--r-- | openbsc/tests/gsm0408/gsm0408_test.c | 40 |
12 files changed, 191 insertions, 131 deletions
diff --git a/openbsc/.gitignore b/openbsc/.gitignore new file mode 100644 index 000000000..7b7b11a1e --- /dev/null +++ b/openbsc/.gitignore @@ -0,0 +1,39 @@ +*.o +*.a +.deps +Makefile +Makefile.in +bsc_hack +bsc_msc_ip +*.*~ +*.sw? + +#configure +aclocal.m4 +autom4te.cache/ +config.log +config.status +configure +depcomp +install-sh +missing +stamp-h1 + + + +# apps and app data +hlr.sqlite3 +bs11_config +ipaccess-config +ipaccess-find +isdnsync + +#tests +tests/channel/channel_test +tests/db/db_test +tests/debug/debug_test +tests/gsm0408/gsm0408_test +tests/sccp/sccp_test +tests/sms/sms_test +tests/timer/timer_test + diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index f99ce6081..089132ea9 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -30,7 +30,7 @@ #define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1]; -char *hexdump(unsigned char *buf, int len); +char *hexdump(const unsigned char *buf, int len); void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...); void debug_parse_category_mask(const char* mask); void debug_use_color(int use_color); diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 2518dfd6c..6f367864f 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -684,6 +684,7 @@ enum gsm48_bcap_rrq { #define GSM48_TMSI_LEN 5 #define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2) +#define GSM48_MI_SIZE 32 struct msgb; @@ -707,7 +708,9 @@ int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand); int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan); struct msgb *gsm48_msgb_alloc(void); int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans); -int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi); +int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi); +int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char* imsi); +int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len); int gsm48_send_rr_release(struct gsm_lchan *lchan); int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id, diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index f01a47ff0..aaf261eda 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -80,8 +80,7 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net, int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason); void subscr_put_channel(struct gsm_lchan *lchan); void subscr_get_channel(struct gsm_subscriber *subscr, - struct gsm_network *network, int type, - gsm_cbfn *cbfn, void *param); + int type, gsm_cbfn *cbfn, void *param); /* internal */ struct gsm_subscriber *subscr_alloc(void); diff --git a/openbsc/src/debug.c b/openbsc/src/debug.c index 6483710af..fa903af98 100644 --- a/openbsc/src/debug.c +++ b/openbsc/src/debug.c @@ -143,7 +143,7 @@ void debugp(unsigned int subsys, char *file, int line, int cont, const char *for static char hexd_buff[4096]; -char *hexdump(unsigned char *buf, int len) +char *hexdump(const unsigned char *buf, int len) { int i; char *cur = hexd_buff; diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index 94f9ef4d4..eeabc0fce 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -899,7 +899,7 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) bts->network->network_code, bts->location_area_code); mid = msgb_put(msg, GSM48_MID_TMSI_LEN); - generate_mid_from_tmsi(mid, tmsi); + gsm48_generate_mid_from_tmsi(mid, tmsi); DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n"); @@ -911,57 +911,6 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) return ret; } -static char bcd2char(u_int8_t bcd) -{ - if (bcd < 0xa) - return '0' + bcd; - else - return 'A' + (bcd - 0xa); -} - -/* Convert Mobile Identity (10.5.1.4) to string */ -static int mi_to_string(char *string, int str_len, u_int8_t *mi, 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; -} - /* Transmit Chapter 9.2.10 Identity Request */ static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type) { @@ -978,7 +927,6 @@ static int mm_tx_identity_req(struct gsm_lchan *lchan, u_int8_t id_type) return gsm48_sendmsg(msg, NULL); } -#define MI_SIZE 32 /* Parse Chapter 9.2.11 Identity Response */ static int mm_rx_id_resp(struct msgb *msg) @@ -988,9 +936,9 @@ static int mm_rx_id_resp(struct msgb *msg) struct gsm_bts *bts = lchan->ts->trx->bts; struct gsm_network *net = bts->network; u_int8_t mi_type = gh->data[1] & GSM_MI_TYPE_MASK; - char mi_string[MI_SIZE]; + char mi_string[GSM48_MI_SIZE]; - mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]); + gsm48_mi_to_string(mi_string, sizeof(mi_string), &gh->data[1], gh->data[0]); DEBUGP(DMM, "IDENTITY RESPONSE: mi_type=0x%02x MI(%s)\n", mi_type, mi_string); @@ -1052,7 +1000,6 @@ static const char *lupd_name(u_int8_t type) } } -#define MI_SIZE 32 /* Chapter 9.2.15: Receive Location Updating Request */ static int mm_rx_loc_upd_req(struct msgb *msg) { @@ -1062,14 +1009,14 @@ static int mm_rx_loc_upd_req(struct msgb *msg) struct gsm_lchan *lchan = msg->lchan; struct gsm_bts *bts = lchan->ts->trx->bts; u_int8_t mi_type; - char mi_string[MI_SIZE]; + char mi_string[GSM48_MI_SIZE]; int rc; lu = (struct gsm48_loc_upd_req *) gh->data; mi_type = lu->mi[0] & GSM_MI_TYPE_MASK; - mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len); + gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len); DEBUGPC(DMM, "mi_type=0x%02x MI(%s) type=%s ", mi_type, mi_string, lupd_name(lu->type)); @@ -1363,7 +1310,7 @@ static int send_siemens_mrpci(struct gsm_lchan *lchan, static int gsm48_rx_mm_serv_req(struct msgb *msg) { u_int8_t mi_type; - char mi_string[MI_SIZE]; + char mi_string[GSM48_MI_SIZE]; struct gsm_bts *bts = msg->lchan->ts->trx->bts; struct gsm_subscriber *subscr; @@ -1396,7 +1343,7 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg) GSM48_REJECT_INCORRECT_MESSAGE); } - mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len); DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n", req->cm_service_type, mi_type, mi_string); @@ -1431,10 +1378,10 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg) struct gsm48_imsi_detach_ind *idi = (struct gsm48_imsi_detach_ind *) gh->data; u_int8_t mi_type = idi->mi[0] & GSM_MI_TYPE_MASK; - char mi_string[MI_SIZE]; + char mi_string[GSM48_MI_SIZE]; struct gsm_subscriber *subscr = NULL; - mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len); + gsm48_mi_to_string(mi_string, sizeof(mi_string), idi->mi, idi->mi_len); DEBUGP(DMM, "IMSI DETACH INDICATION: mi_type=0x%02x MI(%s): ", mi_type, mi_string); @@ -1532,12 +1479,12 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg) u_int8_t *classmark2_lv = gh->data + 1; u_int8_t *mi_lv = gh->data + 2 + *classmark2_lv; u_int8_t mi_type = mi_lv[1] & GSM_MI_TYPE_MASK; - char mi_string[MI_SIZE]; + char mi_string[GSM48_MI_SIZE]; struct gsm_subscriber *subscr = NULL; struct paging_signal_data sig_data; int rc = 0; - mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv); + gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, *mi_lv); DEBUGP(DRR, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n", mi_type, mi_string); diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c index 50deb2bcb..c62f04d57 100644 --- a/openbsc/src/gsm_04_08_utils.c +++ b/openbsc/src/gsm_04_08_utils.c @@ -156,6 +156,21 @@ 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); +} + +/* only works for numbers in ascci */ +static u_int8_t char2bcd(char c) +{ + return c - 0x30; +} + + void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, u_int16_t mnc, u_int16_t lac) { @@ -178,7 +193,7 @@ void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc, lai48->lac = htons(lac); } -int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) +int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) { u_int32_t *tptr = (u_int32_t *) &buf[3]; @@ -190,6 +205,35 @@ int generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi) return 7; } +int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char *imsi) +{ + unsigned int length = strlen(imsi), i, off = 0; + u_int8_t odd = (length & 0x1) == 1; + + buf[0] = GSM48_IE_MOBILE_ID; + buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3); + + /* if the length is even we will fill half of the last octet */ + if (odd) + buf[1] = (length + 1) >> 1; + else + buf[1] = (length + 2) >> 1; + + for (i = 1; i < buf[1]; ++i) { + u_int8_t lower, upper; + + lower = char2bcd(imsi[++off]); + if (!odd && off + 1 == length) + upper = 0x0f; + else + upper = char2bcd(imsi[++off]) & 0x0f; + + buf[2 + i] = (upper << 4) | lower; + } + + return 2 + buf[1]; +} + /* Section 9.1.8 / Table 9.9 */ struct chreq { u_int8_t val; @@ -308,3 +352,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; +} + diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c index 83addd0a8..d6a179b5c 100644 --- a/openbsc/src/gsm_subscriber_base.c +++ b/openbsc/src/gsm_subscriber_base.c @@ -58,9 +58,6 @@ struct subscr_request { /* the requested channel type */ int channel_type; - /* the bts we have decided to use */ - struct gsm_network *network; - /* the callback data */ gsm_cbfn *cbfn; void *param; @@ -100,7 +97,7 @@ static void subscr_send_paging_request(struct gsm_subscriber *subscr) assert(!llist_empty(&subscr->requests)); request = (struct subscr_request *)subscr->requests.next; - paging_request(request->network, subscr, request->channel_type, + paging_request(subscr->net, subscr, request->channel_type, subscr_paging_cb, subscr); } @@ -146,8 +143,7 @@ struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr) } void subscr_get_channel(struct gsm_subscriber *subscr, - struct gsm_network *network, int type, - gsm_cbfn *cbfn, void *param) + int type, gsm_cbfn *cbfn, void *param) { struct subscr_request *request; @@ -160,7 +156,6 @@ void subscr_get_channel(struct gsm_subscriber *subscr, } memset(request, 0, sizeof(*request)); - request->network = network; request->subscr = subscr; request->channel_type = type; request->cbfn = cbfn; diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index 87c5a5407..fd0611a14 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -99,7 +99,7 @@ static void page_ms(struct gsm_paging_request *request) page_group = calculate_group(request->bts, request->subscr); tmsi = strtoul(request->subscr->tmsi, NULL, 10); - mi_len = generate_mid_from_tmsi(mi, tmsi); + mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi); rsl_paging_cmd(request->bts, page_group, mi_len, mi, request->chan_type); } @@ -202,9 +202,9 @@ static void paging_T3113_expired(void *data) DEBUGP(DPAG, "T3113 expired for request %p (%s)\n", req, req->subscr->imsi); - sig_data.subscr = req->subscr, - sig_data.bts = req->bts, - sig_data.lchan = NULL, + sig_data.subscr = req->subscr; + sig_data.bts = req->bts; + sig_data.lchan = NULL; dispatch_signal(SS_PAGING, S_PAGING_COMPLETED, &sig_data); if (req->cbfn) diff --git a/openbsc/src/telnet_interface.c b/openbsc/src/telnet_interface.c index ba574704e..d7c905518 100644 --- a/openbsc/src/telnet_interface.c +++ b/openbsc/src/telnet_interface.c @@ -52,12 +52,6 @@ static void *tall_telnet_ctx; /* per network data */ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what); -#if 0 -static int telnet_paging_callback(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data); -static int telnet_sms_callback(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data); -#endif static struct bsc_fd server_socket = { .when = BSC_FD_READ, @@ -101,12 +95,6 @@ void telnet_init(struct gsm_network *network, int port) { server_socket.data = network; server_socket.fd = fd; bsc_register_fd(&server_socket); - - /* register callbacks */ -#if 0 - register_signal_handler(SS_PAGING, telnet_paging_callback, network); - register_signal_handler(SS_SMS, telnet_sms_callback, network); -#endif } static void print_welcome(int fd) { @@ -216,38 +204,3 @@ void vty_event(enum event event, int sock, struct vty *vty) } } -#if 0 -static int telnet_paging_callback(unsigned int subsys, unsigned int singal, - void *handler_data, void *signal_data) -{ - struct paging_signal_data *paging = signal_data; - struct telnet_connection *con; - - llist_for_each_entry(con, &active_connections, entry) { - if (paging->lchan) { - WRITE_CONNECTION(con->fd.fd, "Paging succeeded\n"); - show_lchan(con->fd.fd, paging->lchan); - } else { - WRITE_CONNECTION(con->fd.fd, "Paging failed for subscriber: %s/%s/%s\n", - paging->subscr->imsi, - paging->subscr->tmsi, - paging->subscr->name); - } - } - - return 0; -} - -static int telnet_sms_callback(unsigned int subsys, unsigned int signal, - void *handler_data, void *signal_data) -{ - struct sms_submit *sms = signal_data; - struct telnet_connection *con; - - llist_for_each_entry(con, &active_connections, entry) { - WRITE_CONNECTION(con->fd.fd, "Incoming SMS: %s\n", sms->user_data); - } - - return 0; -} -#endif diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c index 4dcf69ae2..1b01878b5 100644 --- a/openbsc/tests/channel/channel_test.c +++ b/openbsc/tests/channel/channel_test.c @@ -63,9 +63,10 @@ int main(int argc, char** argv) /* Create a dummy subscriber */ struct gsm_subscriber *subscr = subscr_alloc(); subscr->lac = 23; + subscr->net = network; /* Ask for a channel... */ - subscr_get_channel(subscr, network, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L); + subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, subscr_cb, (void*)0x2342L); while (1) { bsc_select_main(0); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index c99766a72..bbf812965 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -24,13 +24,20 @@ #include <stdlib.h> #include <openbsc/gsm_04_08.h> +#include <openbsc/gsm_subscriber.h> +#include <openbsc/debug.h> #define COMPARE(result, op, value) \ if (!((result) op (value))) {\ fprintf(stderr, "Compare failed. Was %x should be %x in %s:%d\n",result, value, __FILE__, __LINE__); \ exit(-1); \ } - + +#define COMPARE_STR(result, value) \ + if (strcmp(result, value) != 0) { \ + fprintf(stderr, "Compare failed. Was %s should be %s in %s:%d\n",result, value, __FILE__, __LINE__); \ + exit(-1); \ + } /* * Test Location Area Identifier formatting. Table 10.5.3 of 04.08 @@ -58,9 +65,38 @@ static void test_location_area_identifier(void) COMPARE(lai48.lac, ==, htons(0x000f)); } +static void test_mi_functionality(void) +{ + const char *imsi_odd = "987654321098763"; + const char *imsi_even = "9876543210987654"; + const u_int32_t tmsi = 0xfabeacd0; + u_int8_t mi[128]; + unsigned int mi_len; + char mi_parsed[GSM48_MI_SIZE]; + + printf("Testing parsing and generating TMSI/IMSI\n"); + + /* tmsi code */ + mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi); + gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len - 2); + COMPARE((u_int32_t)strtoul(mi_parsed, NULL, 10), ==, tmsi); + + /* imsi code */ + mi_len = gsm48_generate_mid_from_imsi(mi, imsi_odd); + gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len -2); + printf("hex: %s\n", hexdump(mi, mi_len)); + COMPARE_STR(mi_parsed, imsi_odd); + + mi_len = gsm48_generate_mid_from_imsi(mi, imsi_even); + gsm48_mi_to_string(mi_parsed, sizeof(mi_parsed), mi + 2, mi_len -2); + printf("hex: %s\n", hexdump(mi, mi_len)); + COMPARE_STR(mi_parsed, imsi_even); +} + int main(int argc, char** argv) { - test_location_area_identifier(); + test_location_area_identifier(); + test_mi_functionality(); } |