diff options
author | Holger Freyther <zecke@selfish.org> | 2009-02-06 18:54:00 +0000 |
---|---|---|
committer | Holger Freyther <zecke@selfish.org> | 2009-02-06 18:54:00 +0000 |
commit | ceb59b72c23f9af90538704d4ce29aaee80c11e4 (patch) | |
tree | ca4a5164583fdc0a253b4258a009e417c09de1cb | |
parent | 3d949240fe9a81643bef5a854e52f58e7b33bf04 (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.h | 33 | ||||
-rw-r--r-- | include/openbsc/paging.h | 33 | ||||
-rw-r--r-- | src/bsc_hack.c | 5 | ||||
-rw-r--r-- | src/paging.c | 87 |
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; } } |