aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Freyther <zecke@selfish.org>2009-02-06 18:54:00 +0000
committerHolger Freyther <zecke@selfish.org>2009-02-06 18:54:00 +0000
commitceb59b72c23f9af90538704d4ce29aaee80c11e4 (patch)
treeca4a5164583fdc0a253b4258a009e417c09de1cb
parent3d949240fe9a81643bef5a854e52f58e7b33bf04 (diff)
[paging] Move the paging state into struct gsm_bts
There is a 1:1 relationship between gsm_bts and the paging operation. Move the paging state into the gsm_bts which is simplfying the code a lot. This was hinted by LaF0rge. (I'm not happy with the names of the structs)
-rw-r--r--include/openbsc/gsm_data.h33
-rw-r--r--include/openbsc/paging.h33
-rw-r--r--src/bsc_hack.c5
-rw-r--r--src/paging.c87
4 files changed, 67 insertions, 91 deletions
diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 621f11604..75b3db516 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -176,6 +176,36 @@ enum gsm_bts_type {
GSM_BTS_TYPE_BS11,
};
+/**
+ * A pending paging request
+ */
+struct gsm_paging_request {
+ struct llist_head entry;
+ struct gsm_subscriber *subscr;
+ struct gsm_bts *bts;
+ int requests;
+
+ int chan_type;
+};
+
+/*
+ * This keeps track of the paging status of one BTS. It
+ * includes a number of pending requests, a back pointer
+ * to the gsm_bts, a timer and some more state.
+ */
+struct gsm_bts_paging_state {
+ /* public callbacks */
+ void (*channel_allocated)(struct gsm_lchan *lchan);
+
+ /* pending requests */
+ struct llist_head pending_requests;
+ struct gsm_paging_request *last_request;
+ struct gsm_bts *bts;
+
+ /* tick timer */
+ struct timer_list page_timer;
+};
+
/* One BTS */
struct gsm_bts {
struct gsm_network *network;
@@ -194,6 +224,9 @@ struct gsm_bts {
struct gsm48_control_channel_descr chan_desc;
+ /* paging state and control */
+ struct gsm_bts_paging_state paging;
+
/* CCCH is on C0 */
struct gsm_bts_trx *c0;
/* transceivers */
diff --git a/include/openbsc/paging.h b/include/openbsc/paging.h
index 884d16396..44361f7c7 100644
--- a/include/openbsc/paging.h
+++ b/include/openbsc/paging.h
@@ -29,39 +29,8 @@
#include "gsm_subscriber.h"
#include "timer.h"
-/**
- * A pending paging request
- */
-struct paging_request {
- struct llist_head entry;
- struct gsm_subscriber *subscr;
- struct gsm_bts *bts;
- int requests;
-
- int chan_type;
-};
-
-/*
- * struct for each bts we serve...
- */
-struct paging_bts {
- /* public callbacks */
- void (*channel_allocated)(struct gsm_lchan *lchan);
-
- /* list for each bts */
- struct llist_head bts_list;
-
- /* 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);
+void page_init(struct gsm_bts *bts);
/* schedule paging request */
void page_request(struct gsm_bts *bts, struct gsm_subscriber *subscr, int type);
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index 6e54b930f..cadf41cf6 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -672,7 +672,6 @@ 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);
@@ -694,8 +693,8 @@ static int bootstrap_network(void)
patch_tables(bts);
- paging_bts = page_allocate(bts);
- paging_bts->channel_allocated = bsc_hack_channel_allocated;
+ page_init(bts);
+ bts->paging.channel_allocated = bsc_hack_channel_allocated;
telnet_init(gsmnet, 4242);
if (mi_setup(bts, 0, mi_cb) < 0)
diff --git a/src/paging.c b/src/paging.c
index 7f2b0e5b5..7ce7364e1 100644
--- a/src/paging.c
+++ b/src/paging.c
@@ -41,13 +41,11 @@
#include <openbsc/paging.h>
#include <openbsc/debug.h>
#include <openbsc/abis_rsl.h>
-#include <openbsc/gsm_04_08.h>
+#include <openbsc/gsm_data.h>
#define PAGING_TIMEOUT 1, 75000
#define MAX_PAGING_REQUEST 750
-static LLIST_HEAD(managed_bts);
-
static unsigned int calculate_group(struct gsm_bts *bts, struct gsm_subscriber *subscr)
{
int ccch_conf;
@@ -67,13 +65,13 @@ static unsigned int calculate_group(struct gsm_bts *bts, struct gsm_subscriber *
/*
* Kill one paging request update the internal list...
*/
-static void page_remove_request(struct paging_bts *paging_bts,
- struct paging_request *to_be_deleted)
+static void page_remove_request(struct gsm_bts_paging_state *paging_bts,
+ struct gsm_paging_request *to_be_deleted)
{
/* Update the last_request if that is necessary */
if (to_be_deleted == paging_bts->last_request) {
paging_bts->last_request =
- (struct paging_request *)paging_bts->last_request->entry.next;
+ (struct gsm_paging_request *)paging_bts->last_request->entry.next;
if (&to_be_deleted->entry == &paging_bts->pending_requests)
paging_bts->last_request = NULL;
}
@@ -88,12 +86,13 @@ static void page_handle_pending_requests(void *data) {
unsigned long int tmsi;
unsigned int mi_len;
unsigned int pag_group;
- struct paging_bts *paging_bts = (struct paging_bts *)data;
- struct paging_request *request = NULL;
+ struct gsm_bts_paging_state *paging_bts =
+ (struct gsm_bts_paging_state *)data;
+ struct gsm_paging_request *request = NULL;
if (!paging_bts->last_request)
paging_bts->last_request =
- (struct paging_request *)paging_bts->pending_requests.next;
+ (struct gsm_paging_request *)paging_bts->pending_requests.next;
if (&paging_bts->last_request->entry == &paging_bts->pending_requests) {
paging_bts->last_request = NULL;
return;
@@ -116,7 +115,7 @@ static void page_handle_pending_requests(void *data) {
} else {
/* move to the next item */
paging_bts->last_request =
- (struct paging_request *)paging_bts->last_request->entry.next;
+ (struct gsm_paging_request *)paging_bts->last_request->entry.next;
if (&paging_bts->last_request->entry == &paging_bts->pending_requests)
paging_bts->last_request = NULL;
}
@@ -124,9 +123,17 @@ static void page_handle_pending_requests(void *data) {
schedule_timer(&paging_bts->page_timer, PAGING_TIMEOUT);
}
-static int page_pending_request(struct paging_bts *bts,
+void page_init(struct gsm_bts *bts)
+{
+ bts->paging.bts = bts;
+ INIT_LLIST_HEAD(&bts->paging.pending_requests);
+ bts->paging.page_timer.cb = page_handle_pending_requests;
+ bts->paging.page_timer.data = &bts->paging;
+}
+
+static int page_pending_request(struct gsm_bts_paging_state *bts,
struct gsm_subscriber *subscr) {
- struct paging_request *req;
+ struct gsm_paging_request *req;
llist_for_each_entry(req, &bts->pending_requests, entry) {
if (subscr == req->subscr)
@@ -136,67 +143,35 @@ static int page_pending_request(struct paging_bts *bts,
return 0;
}
-struct paging_bts* page_allocate(struct gsm_bts *bts) {
- struct paging_bts *page;
-
- 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, int type) {
- struct paging_bts *bts_entry;
- struct paging_request *req;
+ struct gsm_bts_paging_state *bts_entry = &bts->paging;
+ struct gsm_paging_request *req;
- req = (struct paging_request *)malloc(sizeof(*req));
+ req = (struct gsm_paging_request *)malloc(sizeof(*req));
memset(req, 0, 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) {
- if (!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);
- } else {
- DEBUGP(DPAG, "Paging request already pending\n");
- }
-
- return;
- }
+ if (!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);
+ } else {
+ DEBUGP(DPAG, "Paging request already pending\n");
}
-
- DEBUGP(DPAG, "Paging request for not managed BTS\n");
- free(req);
- return;
}
/* we consciously ignore the type of the request here */
void page_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr)
{
- struct paging_bts *bts_entry;
- struct paging_request *req, *req2;
-
- llist_for_each_entry(bts_entry, &managed_bts, bts_list) {
- if (bts == bts_entry->bts)
- break;
- }
- if (!bts_entry)
- return;
+ struct gsm_bts_paging_state *bts_entry = &bts->paging;
+ struct gsm_paging_request *req, *req2;
llist_for_each_entry_safe(req, req2, &bts_entry->pending_requests,
entry) {
if (req->subscr == subscr) {
- page_remove_request(bts_entry, req);
+ page_remove_request(&bts->paging, req);
break;
}
}