aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmsc/transaction.c')
-rw-r--r--openbsc/src/libmsc/transaction.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/openbsc/src/libmsc/transaction.c b/openbsc/src/libmsc/transaction.c
index 41fb5a914..73c509c2c 100644
--- a/openbsc/src/libmsc/transaction.c
+++ b/openbsc/src/libmsc/transaction.c
@@ -180,23 +180,35 @@ int trans_assign_trans_id(struct gsm_network *net, struct vlr_subscr *vsub,
* \param[in] conn Connection to check
* \returns 1 in case there is a transaction, 0 otherwise
*/
-int trans_has_conn(const struct gsm_subscriber_connection *conn)
+struct gsm_trans *trans_has_conn(const struct gsm_subscriber_connection *conn)
{
struct gsm_trans *trans;
llist_for_each_entry(trans, &conn->network->trans_list, entry)
if (trans->conn == conn)
- return 1;
+ return trans;
- return 0;
+ return NULL;
}
+/*
+ * Free all transactions that are associated with the released
+ * connection. The transaction code will inform the CC or SMS
+ * facilities that will send the release indications.
+ */
void trans_conn_closed(struct gsm_subscriber_connection *conn)
{
- struct gsm_trans *trans, *t2;
+ struct gsm_trans *trans;
- llist_for_each_entry_safe(trans, t2, &conn->network->trans_list, entry) {
- if (trans->conn == conn)
+ /* As part of the CC REL_IND the remote leg might be released and this
+ * will trigger the call to trans_free. This is something the llist
+ * macro can not handle and we will need to re-iterate the list.
+ */
+restart:
+ llist_for_each_entry(trans, &conn->network->trans_list, entry) {
+ if (trans->conn == conn) {
trans_free(trans);
+ goto restart;
+ }
}
}