Fri Nov 12 11:49:01 2010

Asterisk developer's documentation


app_directed_pickup.c File Reference

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 dependency graph for app_directed_pickup.c:

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_channelmy_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 __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static const char * app = "Pickup"
static const char * app2 = "PickupChan"
static struct ast_module_infoast_module_info = &__mod_info

Detailed Description

Directed Call Pickup Support.

Author:
Joshua Colp <jcolp@digium.com>
Gary Cook

Definition in file app_directed_pickup.c.


Define Documentation

#define PICKUPMARK   "PICKUPMARK"

Definition at line 44 of file app_directed_pickup.c.

Referenced by find_by_mark(), and pickup_exec().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 310 of file app_directed_pickup.c.

static void __unreg_module ( void   )  [static]

Definition at line 310 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().

00117 {
00118    if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN))
00119       return 1;
00120    else
00121       return 0;
00122 }

static int find_by_exten ( struct ast_channel c,
void *  data 
) [static]

Definition at line 178 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().

00179 {
00180    struct pickup_criteria *info = data;
00181 
00182    return (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) &&
00183       !strcasecmp(c->dialcontext, info->context) &&
00184       (info->chan != c) && can_pickup(c);
00185 }

static int find_by_mark ( struct ast_channel c,
void *  data 
) [static]

Definition at line 209 of file app_directed_pickup.c.

References can_pickup(), pbx_builtin_getvar_helper(), and PICKUPMARK.

Referenced by pickup_by_mark().

00210 {
00211    const char *mark = data;
00212    const char *tmp;
00213 
00214    return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) &&
00215       !strcasecmp(tmp, mark) &&
00216       can_pickup(c);
00217 }

static int load_module ( void   )  [static]

Definition at line 300 of file app_directed_pickup.c.

References ast_register_application_xml, pickup_exec(), and pickupchan_exec().

00301 {
00302    int res;
00303 
00304    res = ast_register_application_xml(app, pickup_exec);
00305    res |= ast_register_application_xml(app2, pickupchan_exec);
00306 
00307    return res;
00308 }

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().

00126 {
00127    struct ast_channel *chan;
00128    char *chkchan;
00129    size_t channame_len, chkchan_len;
00130 
00131    channame_len = strlen(channame);
00132    chkchan_len = channame_len + 2;
00133 
00134    chkchan = alloca(chkchan_len);
00135 
00136    /* need to append a '-' for the comparison so we check full channel name,
00137     * i.e SIP/hgc- , use a temporary variable so original stays the same for
00138     * debugging.
00139     */
00140    strcpy(chkchan, channame);
00141    strcat(chkchan, "-");
00142 
00143    for (chan = ast_walk_channel_by_name_prefix_locked(NULL, channame, channame_len);
00144        chan;
00145        chan = ast_walk_channel_by_name_prefix_locked(chan, channame, channame_len)) {
00146       if (!strncasecmp(chan->name, chkchan, chkchan_len) && can_pickup(chan)) {
00147          return chan;
00148       }
00149       ast_channel_unlock(chan);
00150    }
00151    return NULL;
00152 }

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 155 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().

00156 {
00157    int res = 0;
00158    struct ast_channel *target;
00159 
00160    if (!(target = my_ast_get_channel_by_name_locked(pickup)))
00161       return -1;
00162 
00163    /* Just check that we are not picking up the SAME as target */
00164    if (chan->name != target->name && chan != target) {
00165       res = pickup_do(chan, target);
00166    }
00167    ast_channel_unlock(target);
00168 
00169    return res;
00170 }

static int pickup_by_exten ( struct ast_channel chan,
const char *  exten,
const char *  context 
) [static]

Definition at line 188 of file app_directed_pickup.c.

References ast_channel_search_locked(), ast_channel_unlock, pickup_criteria::exten, find_by_exten(), and pickup_do().

Referenced by pickup_exec().

00189 {
00190    struct ast_channel *target = NULL;
00191    struct pickup_criteria search = {
00192       .exten = exten,
00193       .context = context,
00194       .chan = chan,
00195    };
00196 
00197    target = ast_channel_search_locked(find_by_exten, &search);
00198 
00199    if (target) {
00200       int res = pickup_do(chan, target);
00201       ast_channel_unlock(target);
00202       target = NULL;
00203       return res;
00204    }
00205 
00206    return -1;
00207 }

static int pickup_by_mark ( struct ast_channel chan,
const char *  mark 
) [static]

Definition at line 220 of file app_directed_pickup.c.

References ast_channel_search_locked(), ast_channel_unlock, find_by_mark(), and pickup_do().

Referenced by pickup_exec().

00221 {
00222    struct ast_channel *target = ast_channel_search_locked(find_by_mark, (char *) mark);
00223 
00224    if (target) {
00225       int res = pickup_do(chan, target);
00226       ast_channel_unlock(target);
00227       target = NULL;
00228       return res;
00229    }
00230 
00231    return -1;
00232 }

static int pickup_do ( struct ast_channel chan,
struct ast_channel target 
) [static]
Todo:
This application should return a result code, like PICKUPRESULT

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().

00092 {
00093    int res = 0;
00094 
00095    ast_debug(1, "Call pickup on '%s' by '%s'\n", target->name, chan->name);
00096 
00097    if ((res = ast_answer(chan))) {
00098       ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name);
00099       return -1;
00100    }
00101 
00102    if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) {
00103       ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name);
00104       return -1;
00105    }
00106 
00107    if ((res = ast_channel_masquerade(target, chan))) {
00108       ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name);
00109       return -1;
00110    }
00111 
00112    return res;
00113 }

static int pickup_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 235 of file app_directed_pickup.c.

References ast_log(), ast_pickup_call(), ast_strlen_zero(), ast_channel::context, context, exten, LOG_NOTICE, pickup_by_exten(), pickup_by_mark(), and PICKUPMARK.

Referenced by load_module().

00236 {
00237    int res = 0;
00238    char *tmp = ast_strdupa(data);
00239    char *exten = NULL, *context = NULL;
00240 
00241    if (ast_strlen_zero(data)) {
00242       res = ast_pickup_call(chan);
00243       return res;
00244    }
00245    
00246    /* Parse extension (and context if there) */
00247    while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
00248       if ((context = strchr(exten, '@')))
00249          *context++ = '\0';
00250       if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
00251          if (!pickup_by_mark(chan, exten))
00252             break;
00253       } else {
00254          if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context))
00255             break;
00256       }
00257       ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
00258    }
00259 
00260    return res;
00261 }

static int pickupchan_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 264 of file app_directed_pickup.c.

References ast_log(), ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, and pickup_by_channel().

Referenced by load_module().

00265 {
00266    int res = 0;
00267    char *tmp = ast_strdupa(data);
00268    char *pickup = NULL;
00269 
00270    if (ast_strlen_zero(data)) {
00271       ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
00272       return -1;  
00273    }
00274 
00275    /* Parse channel */
00276    while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) {
00277       if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
00278          ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
00279       } else {
00280          if (!pickup_by_channel(chan, pickup)) {
00281             break;
00282          }
00283          ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
00284       }
00285    }
00286 
00287    return res;
00288 }

static int unload_module ( void   )  [static]

Definition at line 290 of file app_directed_pickup.c.

References ast_unregister_application().

00291 {
00292    int res;
00293 
00294    res = ast_unregister_application(app);
00295    res |= ast_unregister_application(app2);
00296 
00297    return res;
00298 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 310 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().

Definition at line 310 of file app_directed_pickup.c.


Generated by  doxygen 1.6.2