aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/transaction.h3
-rw-r--r--openbsc/src/gsm_04_08.c39
-rw-r--r--openbsc/src/transaction.c9
3 files changed, 39 insertions, 12 deletions
diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h
index 0ad7504e7..e41d8ef91 100644
--- a/openbsc/include/openbsc/transaction.h
+++ b/openbsc/include/openbsc/transaction.h
@@ -29,6 +29,9 @@ struct gsm_trans {
/* if traffic channel receive was requested */
int tch_recv;
+ /* is thats one paging? */
+ struct gsm_network **paging_request;
+
union {
struct {
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index ea11a7109..160f9672c 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1407,17 +1407,15 @@ static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
struct msgb *msg, void *_conn, void *param)
{
+ int found = 0;
struct gsm_subscriber_connection *conn = _conn;
- struct gsm_subscriber *subscr = param;
+ struct gsm_network **paging_request = param, *net;
struct gsm_trans *transt, *tmp;
- struct gsm_network *net;
if (hooknum != GSM_HOOK_RR_PAGING)
return -EINVAL;
- if (!subscr)
- return -EINVAL;
- net = subscr->net;
+ net = *paging_request;
if (!net) {
DEBUGP(DCC, "Error Network not set!\n");
return -EINVAL;
@@ -1425,16 +1423,18 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
/* check all tranactions (without lchan) for subscriber */
llist_for_each_entry_safe(transt, tmp, &net->trans_list, entry) {
- if (transt->subscr != subscr || transt->conn)
+ 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",
- subscr->extension);
+ transt->subscr->extension);
+ found = 1;
/* Assign lchan */
if (!transt->conn) {
+ transt->paging_request = NULL;
transt->conn = conn;
conn->put_channel = 1;
}
@@ -1444,17 +1444,29 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
case GSM_PAGING_EXPIRED:
case GSM_PAGING_BUSY:
DEBUGP(DCC, "Paging subscr %s expired!\n",
- subscr->extension);
+ transt->subscr->extension);
/* Temporarily out of order */
+ found = 1;
mncc_release_ind(transt->subscr->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;
}
}
+
+ 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;
return 0;
}
@@ -3070,7 +3082,16 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
/* Get a channel */
- subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, subscr);
+ trans->paging_request = talloc_zero(subscr->net, struct gsm_network*);
+ 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->net;
+ subscr_get_channel(subscr, RSL_CHANNEED_TCH_F, setup_trig_pag_evt, trans->paging_request);
subscr_put(subscr);
return 0;
diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c
index 09b6ad4a5..9b4af1aac 100644
--- a/openbsc/src/transaction.c
+++ b/openbsc/src/transaction.c
@@ -95,9 +95,12 @@ void trans_free(struct gsm_trans *trans)
break;
}
- if (!trans->conn && trans->subscr && trans->subscr->net) {
- /* Stop paging on all bts' */
- paging_request_stop(NULL, trans->subscr, NULL, NULL);
+ /* FIXME: implement a sane way to stop this. */
+ if (!trans->conn && trans->paging_request) {
+ LOGP(DNM, LOGL_ERROR,
+ "Transaction freed while paging for sub: %llu\n",
+ trans->subscr->id);
+ trans->paging_request = NULL;
}
if (trans->subscr)