mirror of
https://gerrit.osmocom.org/osmo-gbproxy
synced 2024-08-18 08:56:23 +00:00
Merge branch 'holger/merge-msc-bsc-split'
This commit is contained in:
commit
9b6dbd18b5
12 changed files with 191 additions and 131 deletions
39
openbsc/.gitignore
vendored
Normal file
39
openbsc/.gitignore
vendored
Normal file
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue