diff options
-rw-r--r-- | include/openbsc/gsm_data.h | 2 | ||||
-rw-r--r-- | src/bsc_hack.c | 92 | ||||
-rw-r--r-- | src/gsm_04_08.c | 11 |
3 files changed, 75 insertions, 30 deletions
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h index 9c0ac556a..8f21524eb 100644 --- a/include/openbsc/gsm_data.h +++ b/include/openbsc/gsm_data.h @@ -144,6 +144,8 @@ struct gsm_network { struct gsm_bts bts[GSM_MAX_BTS+1]; struct gsm_ms *ms; struct gsm_subscriber *subscriber; + + void (*update_request_accepted)(struct gsm_bts *, u_int32_t); }; struct gsm_network *gsm_network_init(unsigned int num_bts, u_int16_t country_code, diff --git a/src/bsc_hack.c b/src/bsc_hack.c index 3d5d6dff3..e409c7290 100644 --- a/src/bsc_hack.c +++ b/src/bsc_hack.c @@ -48,6 +48,9 @@ static int MCC = 1; static int MNC = 1; static const char *database_name = "hlr.sqlite3"; +/* forward declarations */ +static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t assigned_tmi); + /* The following definitions are for OM and NM packets that we cannot yet * generate by code but we just pass on */ @@ -636,6 +639,7 @@ static int bootstrap_network(void) bts = &gsmnet->bts[0]; bts->location_area_code = 1; bts->trx[0].arfcn = HARDCODED_ARFCN; + gsmnet->update_request_accepted = bsc_hack_update_request_accepted; if (mi_setup(bts, 0, mi_cb) < 0) return -EIO; @@ -738,41 +742,74 @@ static int string_to_mi(u_int8_t *mi, const char *string, return cur - mi; } -static const char *nokia_imsi = "7240311131388"; -static const char *rokr_imsi = "4660198001300"; +/* + * Stations that registered and that we need to page + */ +struct pending_registered_station { + struct llist_head entry; + + /* the tmsi of the subscriber */ + u_int32_t tmsi; + int last_page_group; +}; + +static LLIST_HEAD(pending_stations); -void pag_timer_cb(void *data) +static void pag_timer_cb(void *data); +static struct timer_list pag_timer = { + .cb = pag_timer_cb, +}; + +/* page the tmsi and wait for the channel request */ +static void pag_timer_cb(void *data) { struct gsm_bts *bts = &gsmnet->bts[0]; + struct pending_registered_station *pending_station; 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) + unsigned int mi_len; + + if (llist_empty(&pending_stations)) { + DEBUGP(DPAG, "pag_timer_cb but no pending mobile stations\n"); 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 + /* get the station to page */ + pending_station = (struct pending_registered_station*) pending_stations.next; + mi_len = generate_mid_from_tmsi(mi, pending_station->tmsi); + rsl_paging_cmd(bts, pending_station->last_page_group, mi_len, mi, RSL_CHANNEED_TCH_F); + + /* which group to page next */ + pending_station->last_page_group = (pending_station->last_page_group+1) % 12; + schedule_timer(&pag_timer, 1, 0); +} - num_imsi = strtoull(imsi, NULL, 10); - paging_group = get_paging_group(num_imsi, 1, 3); +/* + * initiate the a page command for the given + * station and retry until we get a channel request + */ +static void station_timer_cb(void *data) +{ + DEBUGP(DPAG, "Initiating paging of a channel\n"); + pag_timer_cb(0); +} -#if 0 - for (paging_group = 0; paging_group < 3; paging_group++) - rsl_paging_cmd(bts, paging_group, mi_len, mi, RSL_CHANNEED_TCH_F); +static struct timer_list station_timer = { + .cb = station_timer_cb, +}; - schedule_timer(&pag_timer, 10, 0); -#endif +/* + * schedule work + */ +static void bsc_hack_update_request_accepted(struct gsm_bts *bts, u_int32_t tmsi) +{ + struct pending_registered_station *station = + (struct pending_registered_station*)malloc(sizeof(*station)); + station->tmsi = tmsi; + station->last_page_group = 0; + llist_add_tail(&station->entry, &pending_stations); + + if (!timer_pending(&station_timer)) + schedule_timer(&station_timer, 1, 0); } int main(int argc, char **argv) @@ -794,9 +831,6 @@ 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/gsm_04_08.c b/src/gsm_04_08.c index 5c30a17e6..918116db1 100644 --- a/src/gsm_04_08.c +++ b/src/gsm_04_08.c @@ -50,6 +50,8 @@ struct gsm_lai { u_int16_t lac; }; + + static void parse_lai(struct gsm_lai *lai, const struct gsm48_loc_area_id *lai48) { u_int8_t dig[4]; @@ -176,6 +178,7 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) struct gsm48_hdr *gh; struct gsm48_loc_area_id *lai; u_int8_t *mid; + int ret; msg->lchan = lchan; @@ -195,7 +198,13 @@ int gsm0408_loc_upd_acc(struct gsm_lchan *lchan, u_int32_t tmsi) gsm48_sendmsg(msg); /* free the channel afterwards */ - return rsl_chan_release(lchan); + ret = rsl_chan_release(lchan); + + /* inform the upper layer on the progress */ + if (bts->network->update_request_accepted) + (*bts->network->update_request_accepted)(bts, tmsi); + + return ret; } static char bcd2char(u_int8_t bcd) |