[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)

diff --git a/include/openbsc/gsm_data.h b/include/openbsc/gsm_data.h
index 621f116..75b3db5 100644
--- a/include/openbsc/gsm_data.h
+++ b/include/openbsc/gsm_data.h
@@ -176,6 +176,36 @@
 	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 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 884d163..44361f7 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 6e54b93..cadf41c 100644
--- a/src/bsc_hack.c
+++ b/src/bsc_hack.c
@@ -672,7 +672,6 @@
 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 @@
 
 	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 7f2b0e5..7ce7364 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 @@
 /*
  * 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 @@
 	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 @@
 	} 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 @@
 	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 @@
 	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;
 		}
 	}