Directed Call Pickup Support. More...
#include "asterisk.h"#include "asterisk/file.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/module.h"#include "asterisk/lock.h"#include "asterisk/app.h"#include "asterisk/features.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/cel.h"
Go to the source code of this file.
Data Structures | |
| struct | pickup_by_name_args |
Defines | |
| #define | PICKUPMARK "PICKUPMARK" |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | find_by_mark (void *obj, void *arg, void *data, int flags) |
| static int | find_by_part (void *obj, void *arg, void *data, int flags) |
| static int | find_channel_by_group (void *obj, void *arg, void *data, int flags) |
| static int | load_module (void) |
| static struct ast_channel * | my_ast_get_channel_by_name_locked (const char *channame) |
| Helper Function to walk through ALL channels checking NAME and STATE. | |
| static int | pickup_by_channel (struct ast_channel *chan, char *pickup) |
| Attempt to pick up named channel, does not use context. | |
| static int | pickup_by_exten (struct ast_channel *chan, const char *exten, const char *context) |
| static int | pickup_by_group (struct ast_channel *chan) |
| static int | pickup_by_mark (struct ast_channel *chan, const char *mark) |
| static int | pickup_by_name_cb (void *obj, void *arg, void *data, int flags) |
| static int | pickup_by_part (struct ast_channel *chan, const char *part) |
| static int | pickup_exec (struct ast_channel *chan, const char *data) |
| static int | pickupchan_exec (struct ast_channel *chan, const char *data) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Directed Call Pickup Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "7a1b8b48c852d7a7061c7e499b9bd0d2" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
| static const char | app [] = "Pickup" |
| static const char | app2 [] = "PickupChan" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
Directed Call Pickup Support.
Definition in file app_directed_pickup.c.
| #define PICKUPMARK "PICKUPMARK" |
Definition at line 51 of file app_directed_pickup.c.
Referenced by find_by_mark(), and pickup_exec().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 403 of file app_directed_pickup.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 403 of file app_directed_pickup.c.
| static int find_by_mark | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
< Potential pickup target
Definition at line 205 of file app_directed_pickup.c.
References ast_channel::data, ast_channel_lock, pbx_builtin_getvar_helper(), PICKUPMARK, ast_can_pickup(), CMP_MATCH, CMP_STOP, and ast_channel_unlock.
Referenced by pickup_by_mark().
{
struct ast_channel *target = obj;/*!< Potential pickup target */
const char *mark = data;
const char *tmp;
ast_channel_lock(target);
tmp = pbx_builtin_getvar_helper(target, PICKUPMARK);
if (tmp && !strcasecmp(tmp, mark) && ast_can_pickup(target)) {
/* Return with the channel still locked on purpose */
return CMP_MATCH | CMP_STOP;
}
ast_channel_unlock(target);
return 0;
}
| static int find_by_part | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
< Potential pickup target
Definition at line 305 of file app_directed_pickup.c.
References ast_channel::data, len(), ast_channel_lock, ast_channel::name, ast_can_pickup(), CMP_MATCH, CMP_STOP, and ast_channel_unlock.
Referenced by pickup_by_part().
{
struct ast_channel *target = obj;/*!< Potential pickup target */
const char *part = data;
int len = strlen(part);
ast_channel_lock(target);
if (len <= strlen(target->name) && !strncmp(target->name, part, len)
&& ast_can_pickup(target)) {
/* Return with the channel still locked on purpose */
return CMP_MATCH | CMP_STOP;
}
ast_channel_unlock(target);
return 0;
}
| static int find_channel_by_group | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
< Potential pickup target
< Channel wanting to pickup call
Definition at line 239 of file app_directed_pickup.c.
References ast_channel::data, ast_channel_lock, ast_channel::pickupgroup, ast_channel::callgroup, ast_can_pickup(), CMP_MATCH, CMP_STOP, and ast_channel_unlock.
Referenced by pickup_by_group().
{
struct ast_channel *target = obj;/*!< Potential pickup target */
struct ast_channel *chan = data;/*!< Channel wanting to pickup call */
ast_channel_lock(target);
if (chan != target && (chan->pickupgroup & target->callgroup)
&& ast_can_pickup(target)) {
/* Return with the channel still locked on purpose */
return CMP_MATCH | CMP_STOP;
}
ast_channel_unlock(target);
return 0;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 393 of file app_directed_pickup.c.
References ast_register_application_xml, pickup_exec(), and pickupchan_exec().
{
int res;
res = ast_register_application_xml(app, pickup_exec);
res |= ast_register_application_xml(app2, pickupchan_exec);
return res;
}
| static struct ast_channel* my_ast_get_channel_by_name_locked | ( | const char * | channame | ) | [static, read] |
Helper Function to walk through ALL channels checking NAME and STATE.
Definition at line 127 of file app_directed_pickup.c.
References pickup_by_name_args::len, pickup_by_name_args::name, ast_channel_callback(), and pickup_by_name_cb().
Referenced by pickup_by_channel().
{
char *chkchan;
struct pickup_by_name_args pickup_args;
/* Check if channel name contains a '-'.
* In this case the channel name will be interpreted as full channel name.
*/
if (strchr(channame, '-')) {
/* check full channel name */
pickup_args.len = strlen(channame);
pickup_args.name = channame;
} else {
/* need to append a '-' for the comparison so we check full channel name,
* i.e SIP/hgc- , use a temporary variable so original stays the same for
* debugging.
*/
pickup_args.len = strlen(channame) + 1;
chkchan = alloca(pickup_args.len + 1);
strcpy(chkchan, channame);
strcat(chkchan, "-");
pickup_args.name = chkchan;
}
return ast_channel_callback(pickup_by_name_cb, NULL, &pickup_args, 0);
}
| static int pickup_by_channel | ( | struct ast_channel * | chan, |
| char * | pickup | ||
| ) | [static] |
Attempt to pick up named channel, does not use context.
< Potential pickup target
Definition at line 155 of file app_directed_pickup.c.
References my_ast_get_channel_by_name_locked(), ast_do_pickup(), ast_channel_unlock, and ast_channel_unref.
Referenced by pickupchan_exec().
{
int res = -1;
struct ast_channel *target;/*!< Potential pickup target */
target = my_ast_get_channel_by_name_locked(pickup);
if (target) {
/* Just check that we are not picking up the SAME as target. (i.e. ourself) */
if (chan != target) {
res = ast_do_pickup(chan, target);
}
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
return res;
}
| static int pickup_by_exten | ( | struct ast_channel * | chan, |
| const char * | exten, | ||
| const char * | context | ||
| ) | [static] |
< Potential pickup target
Definition at line 174 of file app_directed_pickup.c.
References ast_channel_iterator_by_exten_new(), ast_channel_iterator_next(), ast_channel_lock, ast_can_pickup(), ast_log(), LOG_NOTICE, ast_channel::name, ast_channel_unlock, ast_channel_unref, ast_channel_iterator_destroy(), and ast_do_pickup().
Referenced by pickup_exec().
{
struct ast_channel *target = NULL;/*!< Potential pickup target */
struct ast_channel_iterator *iter;
int res = -1;
if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) {
return -1;
}
while ((target = ast_channel_iterator_next(iter))) {
ast_channel_lock(target);
if ((chan != target) && ast_can_pickup(target)) {
ast_log(LOG_NOTICE, "%s pickup by %s\n", target->name, chan->name);
break;
}
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
ast_channel_iterator_destroy(iter);
if (target) {
res = ast_do_pickup(chan, target);
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
return res;
}
| static int pickup_by_group | ( | struct ast_channel * | chan | ) | [static] |
< Potential pickup target
Definition at line 255 of file app_directed_pickup.c.
References ast_channel_callback(), find_channel_by_group(), ast_log(), LOG_NOTICE, ast_channel::name, ast_do_pickup(), ast_channel_unlock, and ast_channel_unref.
Referenced by pickup_exec().
{
struct ast_channel *target;/*!< Potential pickup target */
int res = -1;
/* The found channel is already locked. */
target = ast_channel_callback(find_channel_by_group, NULL, chan, 0);
if (target) {
ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", target->name, chan->name);
res = ast_do_pickup(chan, target);
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
return res;
}
| static int pickup_by_mark | ( | struct ast_channel * | chan, |
| const char * | mark | ||
| ) | [static] |
< Potential pickup target
Definition at line 223 of file app_directed_pickup.c.
References ast_channel_callback(), find_by_mark(), ast_do_pickup(), ast_channel_unlock, and ast_channel_unref.
Referenced by pickup_exec().
{
struct ast_channel *target;/*!< Potential pickup target */
int res = -1;
/* The found channel is already locked. */
target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0);
if (target) {
res = ast_do_pickup(chan, target);
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
return res;
}
| static int pickup_by_name_cb | ( | void * | obj, |
| void * | arg, | ||
| void * | data, | ||
| int | flags | ||
| ) | [static] |
< Potential pickup target
Definition at line 111 of file app_directed_pickup.c.
References args, ast_channel_lock, ast_channel::name, pickup_by_name_args::name, pickup_by_name_args::len, ast_can_pickup(), CMP_MATCH, CMP_STOP, and ast_channel_unlock.
Referenced by my_ast_get_channel_by_name_locked().
{
struct ast_channel *target = obj;/*!< Potential pickup target */
struct pickup_by_name_args *args = data;
ast_channel_lock(target);
if (!strncasecmp(target->name, args->name, args->len) && ast_can_pickup(target)) {
/* Return with the channel still locked on purpose */
return CMP_MATCH | CMP_STOP;
}
ast_channel_unlock(target);
return 0;
}
| static int pickup_by_part | ( | struct ast_channel * | chan, |
| const char * | part | ||
| ) | [static] |
< Potential pickup target
Definition at line 323 of file app_directed_pickup.c.
References ast_channel_callback(), find_by_part(), ast_do_pickup(), ast_channel_unlock, and ast_channel_unref.
Referenced by pickupchan_exec().
{
struct ast_channel *target;/*!< Potential pickup target */
int res = -1;
/* The found channel is already locked. */
target = ast_channel_callback(find_by_part, NULL, (char *) part, 0);
if (target) {
res = ast_do_pickup(chan, target);
ast_channel_unlock(target);
target = ast_channel_unref(target);
}
return res;
}
| static int pickup_exec | ( | struct ast_channel * | chan, |
| const char * | data | ||
| ) | [static] |
Definition at line 273 of file app_directed_pickup.c.
References ast_strdupa, exten, context, ast_strlen_zero(), pickup_by_group(), strsep(), PICKUPMARK, pickup_by_mark(), pickup_by_exten(), ast_channel::context, ast_log(), and LOG_NOTICE.
Referenced by load_module().
{
char *tmp = ast_strdupa(data);
char *exten = NULL, *context = NULL;
if (ast_strlen_zero(data)) {
return pickup_by_group(chan) ? 0 : -1;
}
/* Parse extension (and context if there) */
while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
if ((context = strchr(exten, '@')))
*context++ = '\0';
if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
if (!pickup_by_mark(chan, exten)) {
/* Pickup successful. Stop the dialplan this channel is a zombie. */
return -1;
}
} else {
if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) {
/* Pickup successful. Stop the dialplan this channel is a zombie. */
return -1;
}
}
ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
}
/* Pickup failed. Keep going in the dialplan. */
return 0;
}
| static int pickupchan_exec | ( | struct ast_channel * | chan, |
| const char * | data | ||
| ) | [static] |
Definition at line 340 of file app_directed_pickup.c.
References parse(), ast_strdupa, AST_DECLARE_APP_ARGS, args, AST_APP_ARG, AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_log(), LOG_WARNING, strsep(), ast_channel::name, LOG_NOTICE, pickup_by_part(), and pickup_by_channel().
Referenced by load_module().
{
int partial_pickup = 0;
char *pickup = NULL;
char *parse = ast_strdupa(data);
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(channel);
AST_APP_ARG(options);
);
AST_STANDARD_APP_ARGS(args, parse);
if (ast_strlen_zero(args.channel)) {
ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
/* Pickup failed. Keep going in the dialplan. */
return 0;
}
if (!ast_strlen_zero(args.options) && strchr(args.options, 'p')) {
partial_pickup = 1;
}
/* Parse channel */
while (!ast_strlen_zero(args.channel) && (pickup = strsep(&args.channel, "&"))) {
if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
} else {
if (partial_pickup) {
if (!pickup_by_part(chan, pickup)) {
/* Pickup successful. Stop the dialplan this channel is a zombie. */
return -1;
}
} else if (!pickup_by_channel(chan, pickup)) {
/* Pickup successful. Stop the dialplan this channel is a zombie. */
return -1;
}
ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
}
}
/* Pickup failed. Keep going in the dialplan. */
return 0;
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 383 of file app_directed_pickup.c.
References ast_unregister_application().
{
int res;
res = ast_unregister_application(app);
res |= ast_unregister_application(app2);
return res;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Directed Call Pickup Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "7a1b8b48c852d7a7061c7e499b9bd0d2" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 403 of file app_directed_pickup.c.
const char app[] = "Pickup" [static] |
Definition at line 102 of file app_directed_pickup.c.
const char app2[] = "PickupChan" [static] |
Definition at line 103 of file app_directed_pickup.c.
Referenced by _macro_exec(), and app_cmp().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 403 of file app_directed_pickup.c.