Improve page command handling in the bsc_hack

Add a callback to the gsm_network. When updating the location and
assigning a new tmsi callback into the bsc_hack.c and have a queue
of mobile stations to page, allocate a channel for and ultimately
dial.
This commit is contained in:
Holger Freyther 2008-12-29 06:23:46 +00:00
parent ba4d28a36e
commit 07cc8d8bee
3 changed files with 74 additions and 29 deletions

View File

@ -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,

View File

@ -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;
void pag_timer_cb(void *data)
/* the tmsi of the subscriber */
u_int32_t tmsi;
int last_page_group;
};
static LLIST_HEAD(pending_stations);
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;
unsigned int mi_len;
printf("FEUER\n");
#if 1
memset(subscr, 0, sizeof(*subscr));
strcpy(subscr->imsi, imsi);
db_get_subscriber(GSM_SUBSCRIBER_IMSI, subscr);
if (!subscr)
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);
num_imsi = strtoull(imsi, NULL, 10);
paging_group = get_paging_group(num_imsi, 1, 3);
/* which group to page next */
pending_station->last_page_group = (pending_station->last_page_group+1) % 12;
schedule_timer(&pag_timer, 1, 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);
/*
* 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);
}
schedule_timer(&pag_timer, 10, 0);
#endif
static struct timer_list station_timer = {
.cb = station_timer_cb,
};
/*
* 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();
}

View File

@ -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)