sub: Remove the queue from the subscriber code

The idea of "subscriber_get_channel" was that different
requests would be coordinated. At the same time we have
seen that the "queue" can get stuck at both 31C3 and the
rhizomatica installations.

Voice calls and SMS do not need coordination. We should
be able to send SMS on a voice channel and switch the MS
from a SDCCH to a TCH in case we establish a voice call.
The SMS code itself needs to coordinate to obey the limit
of one SMS per direction but this should be enforced in
the sms layer and not on the subscriber.

Modify the code to have a simple paging coordination. The
subscriber code will schedule the paging and register who
would like to know about success/failure.

This allowed to greatly simplify the paging response
handling for the transaction code (and in fact we could
move the transaction list into the subscriber structure
now). The code gained to support to cancel the notification
of a request (but not the paging itself yet).

TODO: Cancel paging request in case no one cares about it
anymore.
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 941090c..5609602 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1384,68 +1384,42 @@
 
 /* call-back from paging the B-end of the connection */
 static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
-			      struct msgb *msg, void *_conn, void *param)
+			      struct msgb *msg, void *_conn, void *_transt)
 {
-	int found = 0;
 	struct gsm_subscriber_connection *conn = _conn;
-	struct gsm_network **paging_request = param, *net;
-	struct gsm_trans *transt, *tmp;
+	struct gsm_trans *transt = _transt;
 
-	if (hooknum != GSM_HOOK_RR_PAGING)
-		return -EINVAL;
-
-	net = *paging_request;
-	if (!net) {
-		DEBUGP(DCC, "Error Network not set!\n");
-		return -EINVAL;
-	}
+	OSMO_ASSERT(!transt->conn);
+	OSMO_ASSERT(conn);
 
 	/* check all tranactions (without lchan) for subscriber */
-	llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
-		if (transt->paging_request != paging_request || transt->conn)
-			continue;
-		switch (event) {
-		case GSM_PAGING_SUCCEEDED:
-			if (!conn) // paranoid
-				break;
-			DEBUGP(DCC, "Paging subscr %s succeeded!\n",
-				transt->subscr->extension);
-			found = 1;
-			/* Assign lchan */
-			if (!transt->conn) {
-				transt->paging_request = NULL;
-				transt->conn = conn;
-				conn->put_channel = 1;
-			}
-			/* send SETUP request to called party */
-			gsm48_cc_tx_setup(transt, &transt->cc.msg);
-			break;
-		case GSM_PAGING_EXPIRED:
-		case GSM_PAGING_BUSY:
-			DEBUGP(DCC, "Paging subscr %s expired!\n",
-				transt->subscr->extension);
-			/* Temporarily out of order */
-			found = 1;
-			mncc_release_ind(transt->net, transt,
-					 transt->callref,
-					 GSM48_CAUSE_LOC_PRN_S_LU,
-					 GSM48_CC_CAUSE_DEST_OOO);
-			transt->callref = 0;
-			transt->paging_request = NULL;
-			trans_free(transt);
-			break;
-		}
+	switch (event) {
+	case GSM_PAGING_SUCCEEDED:
+		DEBUGP(DCC, "Paging subscr %s succeeded!\n", transt->subscr->extension);
+		/* Assign lchan */
+		transt->conn = conn;
+		/* send SETUP request to called party */
+		gsm48_cc_tx_setup(transt, &transt->cc.msg);
+		break;
+	case GSM_PAGING_EXPIRED:
+	case GSM_PAGING_BUSY:
+		DEBUGP(DCC, "Paging subscr %s expired!\n",
+			transt->subscr->extension);
+		/* Temporarily out of order */
+		mncc_release_ind(transt->net, transt,
+				 transt->callref,
+				 GSM48_CAUSE_LOC_PRN_S_LU,
+				 GSM48_CC_CAUSE_DEST_OOO);
+		transt->callref = 0;
+		transt->paging_request = NULL;
+		trans_free(transt);
+		break;
+	default:
+		LOGP(DCC, LOGL_ERROR, "Unknown paging event %d\n", event);
+		break;
 	}
 
-	talloc_free(paging_request);
-
-	/*
-	 * FIXME: The queue needs to be kicked. This is likely to go through a RF
-	 * failure and then the subscr will be poke again. This needs a lot of fixing
-	 * in the subscriber queue code.
-	 */
-	if (!found && conn)
-		conn->put_channel = 1;
+	transt->paging_request = NULL;
 	return 0;
 }
 
@@ -3124,19 +3098,16 @@
 			/* store setup informations until paging was successfull */
 			memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
 
-			/* Get a channel */
-			trans->paging_request = talloc_zero(subscr->group->net,
-							    struct gsm_network*);
+			/* Request a channel */
+			trans->paging_request = subscr_request_channel(subscr,
+							RSL_CHANNEED_TCH_F, setup_trig_pag_evt,
+							trans);
 			if (!trans->paging_request) {
 				LOGP(DCC, LOGL_ERROR, "Failed to allocate paging token.\n");
 				subscr_put(subscr);
 				trans_free(trans);
 				return 0;
 			}
-
-			*trans->paging_request = subscr->group->net;
-			subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, trans->paging_request);
-
 			subscr_put(subscr);
 			return 0;
 		}