mirror of https://github.com/asterisk/asterisk
commit
8435a0cdff
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 directly 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, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MAX_FORWARDS_H
|
||||
|
||||
struct ast_channel;
|
||||
|
||||
/*!
|
||||
* \brief Set the starting max forwards for a particular channel.
|
||||
*
|
||||
* \pre chan is locked
|
||||
*
|
||||
* \param starting_count The value to set the max forwards to.
|
||||
* \param chan The channel on which to set the max forwards.
|
||||
* \retval 0 Success
|
||||
* \retval 1 Failure
|
||||
*/
|
||||
int ast_max_forwards_set(struct ast_channel *chan, int starting_count);
|
||||
|
||||
/*!
|
||||
* \brief Get the current max forwards for a particular channel.
|
||||
*
|
||||
* If the channel has not had max forwards set on it, then the channel
|
||||
* will have the default max forwards set on it and that value will
|
||||
* be returned.
|
||||
*
|
||||
* \pre chan is locked
|
||||
*
|
||||
* \param chan The channel to get the max forwards for.
|
||||
* \return The current max forwards count on the channel
|
||||
*/
|
||||
int ast_max_forwards_get(struct ast_channel *chan);
|
||||
|
||||
/*!
|
||||
* \brief Decrement the max forwards count for a particular channel.
|
||||
*
|
||||
* If the channel has not had max forwards set on it, then the channel
|
||||
* will have the default max forwards set on it and that value will
|
||||
* not be decremented.
|
||||
*
|
||||
* \pre chan is locked
|
||||
*
|
||||
* \chan The channel for which the max forwards value should be decremented
|
||||
* \retval 0 Success
|
||||
* \retval -1 Failure
|
||||
*/
|
||||
int ast_max_forwards_decrement(struct ast_channel *chan);
|
||||
|
||||
/*!
|
||||
* \brief Reset the max forwards on a channel to its starting value.
|
||||
*
|
||||
* If the channel has not had max forwards set on it, then the channel
|
||||
* will have the default max forwards set on it.
|
||||
*
|
||||
* \pre chan is locked.
|
||||
*
|
||||
* \param chan The channel on which to reset the max forwards count.
|
||||
* \retval 0 Success
|
||||
* \retval -1 Failure
|
||||
*/
|
||||
int ast_max_forwards_reset(struct ast_channel *chan);
|
||||
|
||||
#endif /* MAX_FORWARDS_H */
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
Loading…
Reference in new issue