aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-01-06 23:10:57 +0000
committerHarald Welte <laforge@gnumonks.org>2009-01-06 23:10:57 +0000
commit38c2f13098abb18ad58785bf473692ef4e0211fa (patch)
tree36cf196b9d2093c6aee458a619267692c18394e1
parentb68899d3e3f581cfa0b8d943cc90fddfe1596412 (diff)
Hook the paging code into bsc_hack.c and telnet_interface.c
Wrote and test code to add and remove paging requests... This will be using the fact that the linux list is building a circle on each tick we can send one/x paging requests and continue round robin...
-rw-r--r--include/openbsc/paging.h9
-rw-r--r--src/bsc_hack.c11
-rw-r--r--src/paging.c42
-rw-r--r--src/telnet_interface.c3
4 files changed, 62 insertions, 3 deletions
diff --git a/include/openbsc/paging.h b/include/openbsc/paging.h
index 93137fccd..72b0f11eb 100644
--- a/include/openbsc/paging.h
+++ b/include/openbsc/paging.h
@@ -27,6 +27,7 @@
#include "linuxlist.h"
#include "gsm_data.h"
#include "gsm_subscriber.h"
+#include "timer.h"
/**
* A pending paging request
@@ -35,6 +36,8 @@ struct paging_request {
struct llist_head entry;
struct gsm_subscriber *subscr;
struct gsm_bts *bts;
+
+ int chan_type;
};
/*
@@ -49,13 +52,17 @@ struct paging_bts {
/* pending requests */
struct llist_head pending_requests;
+ struct paging_request *last_request;
struct gsm_bts *bts;
+
+ /* tick timer */
+ struct timer_list page_timer;
};
/* call once for every gsm_bts... */
struct paging_bts* page_allocate(struct gsm_bts *bts);
/* schedule paging request */
-void page_request(struct gsm_bts *bts, struct gsm_subscriber *subscr);
+void page_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, int type);
#endif
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index 2c6d16491..1f48c8d48 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -44,6 +44,7 @@
#include <openbsc/debug.h>
#include <openbsc/misdn.h>
#include <openbsc/telnet_interface.h>
+#include <openbsc/paging.h>
/* global pointer to the gsm network data structure */
static struct gsm_network *gsmnet;
@@ -599,6 +600,12 @@ static int set_system_infos(struct gsm_bts *bts)
}
/*
+ * Inform anyone...
+ */
+static void bsc_hack_channel_allocated(struct gsm_lchan *lchan) {
+}
+
+/*
* Patch the various SYSTEM INFORMATION tables to update
* the LAI
*/
@@ -662,6 +669,7 @@ static void mi_cb(int event, struct gsm_bts *bts)
static int bootstrap_network(void)
{
struct gsm_bts *bts;
+ struct paging_bts *paging_bts;
/* initialize our data structures */
gsmnet = gsm_network_init(1, MCC, MNC);
@@ -675,6 +683,9 @@ static int bootstrap_network(void)
bts->trx[0].arfcn = ARFCN;
patch_tables(bts);
+ paging_bts = page_allocate(bts);
+ paging_bts->channel_allocated = bsc_hack_channel_allocated;
+
telnet_init(gsmnet, 4242);
if (mi_setup(bts, 0, mi_cb) < 0)
return -EIO;
diff --git a/src/paging.c b/src/paging.c
index 5578130de..c7782f9bd 100644
--- a/src/paging.c
+++ b/src/paging.c
@@ -38,8 +38,40 @@
#include <openbsc/paging.h>
#include <openbsc/debug.h>
+#define PAGING_TIMEOUT 0, 5000
+
static LLIST_HEAD(managed_bts);
+/*
+ * Kill one paging request update the internal list...
+ */
+static void page_remove_request(struct paging_bts *paging_bts) {
+ struct paging_request *to_be_deleted = paging_bts->last_request;
+ paging_bts->last_request =
+ (struct paging_request *)paging_bts->last_request->entry.next;
+ if (&to_be_deleted->entry == &paging_bts->pending_requests)
+ paging_bts->last_request = NULL;
+ llist_del(&to_be_deleted->entry);
+ free(to_be_deleted);
+}
+
+
+static void page_handle_pending_requests(void *data) {
+ struct paging_bts *paging_bts = (struct paging_bts *)data;
+
+ if (!paging_bts->last_request)
+ paging_bts->last_request =
+ (struct paging_request *)paging_bts->pending_requests.next;
+ if (&paging_bts->last_request->entry == &paging_bts->pending_requests) {
+ paging_bts->last_request = NULL;
+ return;
+ }
+
+ DEBUGP(DPAG, "Going to send paging commands: '%s'\n",
+ paging_bts->last_request->subscr->imsi);
+ schedule_timer(&paging_bts->page_timer, PAGING_TIMEOUT);
+}
+
static int page_pending_request(struct paging_bts *bts,
struct gsm_subscriber *subscr) {
struct paging_request *req;
@@ -57,22 +89,30 @@ struct paging_bts* page_allocate(struct gsm_bts *bts) {
page = (struct paging_bts *)malloc(sizeof(*page));
memset(page, 0, sizeof(*page));
+ page->bts = bts;
+ INIT_LLIST_HEAD(&page->pending_requests);
+ page->page_timer.cb = page_handle_pending_requests;
+ page->page_timer.data = page;
+
llist_add_tail(&page->bts_list, &managed_bts);
return page;
}
-void page_request(struct gsm_bts *bts, struct gsm_subscriber *subscr) {
+void page_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, int type) {
struct paging_bts *bts_entry;
struct paging_request *req;
req = (struct paging_request *)malloc(sizeof(*req));
req->subscr = subscr_get(subscr);
req->bts = bts;
+ req->chan_type = type;
llist_for_each_entry(bts_entry, &managed_bts, bts_list) {
if (bts == bts_entry->bts && !page_pending_request(bts_entry, subscr)) {
llist_add_tail(&req->entry, &bts_entry->pending_requests);
+ if (!timer_pending(&bts_entry->page_timer))
+ schedule_timer(&bts_entry->page_timer, PAGING_TIMEOUT);
return;
}
}
diff --git a/src/telnet_interface.c b/src/telnet_interface.c
index 7da53fda5..4eb9bcb4b 100644
--- a/src/telnet_interface.c
+++ b/src/telnet_interface.c
@@ -31,6 +31,7 @@
#include <openbsc/gsm_04_08.h>
#include <openbsc/msgb.h>
#include <openbsc/abis_rsl.h>
+#include <openbsc/paging.h>
extern void telnet_parse(struct telnet_connection *connection, char *line);
@@ -174,7 +175,7 @@ void telnet_page(struct telnet_connection *connection, const char *imsi, int typ
if (!subscr)
return;
- rsl_paging_cmd_subscr(bts, type, subscr);
+ page_request(bts, subscr, type);
}
void telnet_put_channel(struct telnet_connection *connection, const char *imsi) {