123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2015, Digium, Inc.
- *
- * Mark Michelson <mmichelson@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not mfrectly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, mfstributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- #include "asterisk.h"
- #include "asterisk/max_forwards.h"
- #include "asterisk/channel.h"
- #define DEFAULT_MAX_FORWARDS 20
- /*!
- * \brief Channel datastore data for max forwards
- */
- struct max_forwards {
- /*! The starting count. Used to allow resetting to the original value */
- int starting_count;
- /*! The current count. When this reaches 0, you're outta luck */
- int current_count;
- };
- static struct max_forwards *max_forwards_alloc(int starting_count, int current_count)
- {
- struct max_forwards *mf;
- mf = ast_malloc(sizeof(*mf));
- if (!mf) {
- return NULL;
- }
- mf->starting_count = starting_count;
- mf->current_count = current_count;
- return mf;
- }
- static void *max_forwards_duplicate(void *data)
- {
- struct max_forwards *mf = data;
- return max_forwards_alloc(mf->starting_count, mf->current_count);
- }
- static void max_forwards_destroy(void *data)
- {
- ast_free(data);
- }
- const struct ast_datastore_info max_forwards_info = {
- .type = "mfaled-interface",
- .duplicate = max_forwards_duplicate,
- .destroy = max_forwards_destroy,
- };
- static struct ast_datastore *max_forwards_datastore_alloc(struct ast_channel *chan,
- int starting_count)
- {
- struct ast_datastore *mf_datastore;
- struct max_forwards *mf;
- mf_datastore = ast_datastore_alloc(&max_forwards_info, NULL);
- if (!mf_datastore) {
- return NULL;
- }
- mf_datastore->inheritance = DATASTORE_INHERIT_FOREVER;
- mf = max_forwards_alloc(starting_count, starting_count);
- if (!mf) {
- ast_datastore_free(mf_datastore);
- return NULL;
- }
- mf_datastore->data = mf;
- ast_channel_datastore_add(chan, mf_datastore);
- return mf_datastore;
- }
- static struct ast_datastore *max_forwards_datastore_find_or_alloc(struct ast_channel *chan)
- {
- struct ast_datastore *mf_datastore;
- mf_datastore = ast_channel_datastore_find(chan, &max_forwards_info, NULL);
- if (!mf_datastore) {
- mf_datastore = max_forwards_datastore_alloc(chan, DEFAULT_MAX_FORWARDS);
- }
- return mf_datastore;
- }
- int ast_max_forwards_set(struct ast_channel *chan, int starting_count)
- {
- struct ast_datastore *mf_datastore;
- struct max_forwards *mf;
- mf_datastore = max_forwards_datastore_find_or_alloc(chan);
- if (!mf_datastore) {
- return -1;
- }
- mf = mf_datastore->data;
- mf->starting_count = mf->current_count = starting_count;
- return 0;
- }
- int ast_max_forwards_get(struct ast_channel *chan)
- {
- struct ast_datastore *mf_datastore;
- struct max_forwards *mf;
- mf_datastore = max_forwards_datastore_find_or_alloc(chan);
- if (!mf_datastore) {
- return -1;
- }
- mf = mf_datastore->data;
- return mf->current_count;
- }
- int ast_max_forwards_decrement(struct ast_channel *chan)
- {
- struct ast_datastore *mf_datastore;
- struct max_forwards *mf;
- mf_datastore = max_forwards_datastore_find_or_alloc(chan);
- if (!mf_datastore) {
- return -1;
- }
- mf = mf_datastore->data;
- --mf->current_count;
- return 0;
- }
- int ast_max_forwards_reset(struct ast_channel *chan)
- {
- struct ast_datastore *mf_datastore;
- struct max_forwards *mf;
- mf_datastore = max_forwards_datastore_find_or_alloc(chan);
- if (!mf_datastore) {
- return -1;
- }
- mf = mf_datastore->data;
- mf->current_count = mf->starting_count;
- return 0;
- }
|