aboutsummaryrefslogtreecommitdiffstats
path: root/src/nmt/transaction.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2016-08-17 18:25:48 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2016-08-20 09:57:05 +0200
commit8cecf13b1a10cc72dd5a937178ebe17c43b60ee0 (patch)
treeb643527b90aa9ef562000b0cc6e7cdf9a74cc01e /src/nmt/transaction.c
parent82901985af3f49ecd830b26b3f6265ec2ca9333a (diff)
NMT: Add transaction handling
Diffstat (limited to 'src/nmt/transaction.c')
-rw-r--r--src/nmt/transaction.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/nmt/transaction.c b/src/nmt/transaction.c
new file mode 100644
index 0000000..26a1ccd
--- /dev/null
+++ b/src/nmt/transaction.c
@@ -0,0 +1,144 @@
+/* NMT transaction handling
+ *
+ * (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
+ * All Rights Reserved
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../common/debug.h"
+#include "../common/timer.h"
+#include "nmt.h"
+#include "transaction.h"
+
+static transaction_t *trans_list = NULL;
+static void transaction_timeout(struct timer *timer);
+
+/* link transaction to list */
+static void link_transaction(transaction_t *trans)
+{
+ transaction_t **transp;
+
+ /* attach to end of list, so first transaction is served first */
+ PDEBUG(DTRANS, DEBUG_DEBUG, "Linking transaction %p to list\n", trans);
+ trans->next = NULL;
+ transp = &trans_list;
+ while (*transp)
+ transp = &((*transp)->next);
+ *transp = trans;
+}
+
+/* unlink transaction from list */
+static void unlink_transaction(transaction_t *trans)
+{
+ transaction_t **transp;
+ sender_t *sender;
+ nmt_t *nmt;
+
+ /* unlink */
+ PDEBUG(DTRANS, DEBUG_DEBUG, "Unlinking transaction %p from list\n", trans);
+ transp = &trans_list;
+ while (*transp && *transp != trans)
+ transp = &((*transp)->next);
+ if (!(*transp)) {
+ PDEBUG(DTRANS, DEBUG_ERROR, "Transaction not in list, please fix!!\n");
+ abort();
+ }
+ *transp = trans->next;
+ trans->next = NULL;
+
+ /* unbind from channel */
+ trans->nmt = NULL;
+ for (sender = sender_head; sender; sender = sender->next) {
+ nmt = (nmt_t *)sender;
+ if (nmt->trans == trans)
+ nmt_go_idle(nmt);
+ }
+}
+
+/* create transaction */
+transaction_t *create_transaction(struct nmt_subscriber *subscr)
+{
+ transaction_t *trans;
+
+ trans = calloc(1, sizeof(*trans));
+ if (!trans) {
+ PDEBUG(DTRANS, DEBUG_ERROR, "No memory!\n");
+ return NULL;
+ }
+
+ timer_init(&trans->timer, transaction_timeout, trans);
+
+ memcpy(&trans->subscriber, subscr, sizeof(struct nmt_subscriber));
+
+ PDEBUG(DTRANS, DEBUG_INFO, "Created transaction for subscriber '%c,%s'\n", subscr->country, subscr->number);
+
+ link_transaction(trans);
+
+ return trans;
+}
+
+/* destroy transaction */
+void destroy_transaction(transaction_t *trans)
+{
+ unlink_transaction(trans);
+
+ PDEBUG(DTRANS, DEBUG_INFO, "Destroying transaction for subscriber '%c,%s'\n", trans->subscriber.country, trans->subscriber.number);
+
+ timer_exit(&trans->timer);
+
+ free(trans);
+}
+
+/* Timeout handling */
+static void transaction_timeout(struct timer *timer)
+{
+ transaction_t *trans = (transaction_t *)timer->priv;
+
+ timeout_mt_paging(trans);
+}
+
+transaction_t *get_transaction_by_callref(int callref)
+{
+ transaction_t *trans;
+
+ trans = trans_list;
+ while (trans) {
+ if (trans->callref == callref)
+ break;
+ trans = trans->next;
+ }
+
+ return trans;
+}
+
+transaction_t *get_transaction_by_number(struct nmt_subscriber *subscr)
+{
+ transaction_t *trans;
+
+ trans = trans_list;
+ while (trans) {
+ if (trans->subscriber.country == subscr->country
+ && !strcmp(trans->subscriber.number, subscr->number))
+ break;
+ trans = trans->next;
+ }
+
+ return trans;
+}
+