aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/openbsc/gsm_data.h2
-rw-r--r--src/bsc_hack.c92
-rw-r--r--src/gsm_04_08.c11
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)