diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2016-08-17 18:25:48 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2016-08-20 09:57:05 +0200 |
commit | 8cecf13b1a10cc72dd5a937178ebe17c43b60ee0 (patch) | |
tree | b643527b90aa9ef562000b0cc6e7cdf9a74cc01e /src/nmt/transaction.c | |
parent | 82901985af3f49ecd830b26b3f6265ec2ca9333a (diff) |
NMT: Add transaction handling
Diffstat (limited to 'src/nmt/transaction.c')
-rw-r--r-- | src/nmt/transaction.c | 144 |
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; +} + |