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"
Go to the source code of this file.
Data Structures | |
struct | pickup_criteria |
Defines | |
#define | PICKUPMARK "PICKUPMARK" |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | can_pickup (struct ast_channel *chan) |
static int | find_by_exten (struct ast_channel *c, void *data) |
static int | find_by_mark (struct ast_channel *c, void *data) |
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 specified channel named , does not use context. | |
static int | pickup_by_exten (struct ast_channel *chan, const char *exten, const char *context) |
static int | pickup_by_mark (struct ast_channel *chan, const char *mark) |
static int | pickup_do (struct ast_channel *chan, struct ast_channel *target) |
static int | pickup_exec (struct ast_channel *chan, void *data) |
static int | pickupchan_exec (struct ast_channel *chan, void *data) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Directed Call Pickup Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
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 44 of file app_directed_pickup.c.
Referenced by find_by_mark(), and pickup_exec().
static void __reg_module | ( | void | ) | [static] |
Definition at line 318 of file app_directed_pickup.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 318 of file app_directed_pickup.c.
static int can_pickup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 116 of file app_directed_pickup.c.
References ast_channel::_state, AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, and ast_channel::pbx.
Referenced by find_by_exten(), find_by_mark(), and my_ast_get_channel_by_name_locked().
{ if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN)) return 1; else return 0; }
static int find_by_exten | ( | struct ast_channel * | c, |
void * | data | ||
) | [static] |
Definition at line 186 of file app_directed_pickup.c.
References can_pickup(), pickup_criteria::chan, pickup_criteria::context, ast_channel::dialcontext, ast_channel::exten, pickup_criteria::exten, and ast_channel::macroexten.
Referenced by pickup_by_exten().
{ struct pickup_criteria *info = data; return (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) && !strcasecmp(c->dialcontext, info->context) && (info->chan != c) && can_pickup(c); }
static int find_by_mark | ( | struct ast_channel * | c, |
void * | data | ||
) | [static] |
Definition at line 217 of file app_directed_pickup.c.
References can_pickup(), pbx_builtin_getvar_helper(), and PICKUPMARK.
Referenced by pickup_by_mark().
{ const char *mark = data; const char *tmp; return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) && !strcasecmp(tmp, mark) && can_pickup(c); }
static int load_module | ( | void | ) | [static] |
Definition at line 308 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 125 of file app_directed_pickup.c.
References ast_channel_unlock, ast_walk_channel_by_name_prefix_locked(), can_pickup(), chan, and ast_channel::name.
Referenced by pickup_by_channel().
{ struct ast_channel *chan; char *chkchan; size_t channame_len, chkchan_len; channame_len = strlen(channame); /* 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 */ chkchan_len = channame_len; chkchan = (char *)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. */ chkchan_len = channame_len + 1; chkchan = alloca(chkchan_len + 1); strcpy(chkchan, channame); strcat(chkchan, "-"); } for (chan = ast_walk_channel_by_name_prefix_locked(NULL, channame, channame_len); chan; chan = ast_walk_channel_by_name_prefix_locked(chan, channame, channame_len)) { if (!strncasecmp(chan->name, chkchan, chkchan_len) && can_pickup(chan)) { return chan; } ast_channel_unlock(chan); } return NULL; }
static int pickup_by_channel | ( | struct ast_channel * | chan, |
char * | pickup | ||
) | [static] |
Attempt to pick up specified channel named , does not use context.
Definition at line 163 of file app_directed_pickup.c.
References ast_channel_unlock, my_ast_get_channel_by_name_locked(), ast_channel::name, and pickup_do().
Referenced by pickupchan_exec().
{ int res = 0; struct ast_channel *target; if (!(target = my_ast_get_channel_by_name_locked(pickup))) return -1; /* Just check that we are not picking up the SAME as target */ if (chan->name != target->name && chan != target) { res = pickup_do(chan, target); } ast_channel_unlock(target); return res; }
static int pickup_by_exten | ( | struct ast_channel * | chan, |
const char * | exten, | ||
const char * | context | ||
) | [static] |
Definition at line 196 of file app_directed_pickup.c.
References ast_channel_search_locked(), ast_channel_unlock, chan, context, exten, pickup_criteria::exten, find_by_exten(), and pickup_do().
Referenced by pickup_exec().
{ struct ast_channel *target = NULL; struct pickup_criteria search = { .exten = exten, .context = context, .chan = chan, }; target = ast_channel_search_locked(find_by_exten, &search); if (target) { int res = pickup_do(chan, target); ast_channel_unlock(target); target = NULL; return res; } return -1; }
static int pickup_by_mark | ( | struct ast_channel * | chan, |
const char * | mark | ||
) | [static] |
Definition at line 228 of file app_directed_pickup.c.
References ast_channel_search_locked(), ast_channel_unlock, find_by_mark(), and pickup_do().
Referenced by pickup_exec().
{ struct ast_channel *target = ast_channel_search_locked(find_by_mark, (char *) mark); if (target) { int res = pickup_do(chan, target); ast_channel_unlock(target); target = NULL; return res; } return -1; }
static int pickup_do | ( | struct ast_channel * | chan, |
struct ast_channel * | target | ||
) | [static] |
Definition at line 91 of file app_directed_pickup.c.
References ast_answer(), ast_channel_masquerade(), AST_CONTROL_ANSWER, ast_debug, ast_log(), ast_queue_control(), LOG_WARNING, and ast_channel::name.
Referenced by pickup_by_channel(), pickup_by_exten(), and pickup_by_mark().
{ int res = 0; ast_debug(1, "Call pickup on '%s' by '%s'\n", target->name, chan->name); if ((res = ast_answer(chan))) { ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name); return -1; } if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) { ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name); return -1; } if ((res = ast_channel_masquerade(target, chan))) { ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name); return -1; } return res; }
static int pickup_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 243 of file app_directed_pickup.c.
References ast_log(), ast_pickup_call(), ast_strdupa, ast_strlen_zero(), ast_channel::context, context, exten, LOG_NOTICE, pickup_by_exten(), pickup_by_mark(), PICKUPMARK, and strsep().
Referenced by load_module().
{ int res = 0; char *tmp = ast_strdupa(data); char *exten = NULL, *context = NULL; if (ast_strlen_zero(data)) { res = ast_pickup_call(chan); return res; } /* 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)) break; } else { if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) break; } ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten); } return res; }
static int pickupchan_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 272 of file app_directed_pickup.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, pickup_by_channel(), and strsep().
Referenced by load_module().
{ int res = 0; char *tmp = ast_strdupa(data); char *pickup = NULL; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n"); return -1; } /* Parse channel */ while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) { if (!strncasecmp(chan->name, pickup, strlen(pickup))) { ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup); } else { if (!pickup_by_channel(chan, pickup)) { break; } ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup); } } return res; }
static int unload_module | ( | void | ) | [static] |
Definition at line 298 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 __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Directed Call Pickup Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 318 of file app_directed_pickup.c.
const char* app = "Pickup" [static] |
Definition at line 86 of file app_directed_pickup.c.
const char* app2 = "PickupChan" [static] |
Definition at line 87 of file app_directed_pickup.c.
Referenced by _macro_exec().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 318 of file app_directed_pickup.c.