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.