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:
parent
ba4d28a36e
commit
07cc8d8bee
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue