Sat Mar 10 01:54:31 2012

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 "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_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 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 = "88eaa8f5c1bd988bedd71113385e0886" , .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_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 51 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 402 of file app_directed_pickup.c.

static void __unreg_module ( void   )  [static]

Definition at line 402 of file app_directed_pickup.c.

static int find_by_mark ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 204 of file app_directed_pickup.c.

References ast_can_pickup(), ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, pbx_builtin_getvar_helper(), and PICKUPMARK.

Referenced by pickup_by_mark().

00205 {
00206    struct ast_channel *target = obj;/*!< Potential pickup target */
00207    const char *mark = data;
00208    const char *tmp;
00209 
00210    ast_channel_lock(target);
00211    tmp = pbx_builtin_getvar_helper(target, PICKUPMARK);
00212    if (tmp && !strcasecmp(tmp, mark) && ast_can_pickup(target)) {
00213       /* Return with the channel still locked on purpose */
00214       return CMP_MATCH | CMP_STOP;
00215    }
00216    ast_channel_unlock(target);
00217 
00218    return 0;
00219 }

static int find_by_part ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 304 of file app_directed_pickup.c.

References ast_can_pickup(), ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, len(), and ast_channel::name.

Referenced by pickup_by_part().

00305 {
00306    struct ast_channel *target = obj;/*!< Potential pickup target */
00307    const char *part = data;
00308    int len = strlen(part);
00309 
00310    ast_channel_lock(target);
00311    if (len <= strlen(target->name) && !strncmp(target->name, part, len)
00312       && ast_can_pickup(target)) {
00313       /* Return with the channel still locked on purpose */
00314       return CMP_MATCH | CMP_STOP;
00315    }
00316    ast_channel_unlock(target);
00317 
00318    return 0;
00319 }

static int find_channel_by_group ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 238 of file app_directed_pickup.c.

References ast_can_pickup(), ast_channel_lock, ast_channel_unlock, ast_channel::callgroup, CMP_MATCH, CMP_STOP, and ast_channel::pickupgroup.

Referenced by ast_pickup_call(), and pickup_by_group().

00239 {
00240    struct ast_channel *target = obj;/*!< Potential pickup target */
00241    struct ast_channel *chan = data;/*!< Channel wanting to pickup call */
00242 
00243    ast_channel_lock(target);
00244    if (chan != target && (chan->pickupgroup & target->callgroup)
00245       && ast_can_pickup(target)) {
00246       /* Return with the channel still locked on purpose */
00247       return CMP_MATCH | CMP_STOP;
00248    }
00249    ast_channel_unlock(target);
00250 
00251    return 0;
00252 }

static int load_module ( void   )  [static]

Definition at line 392 of file app_directed_pickup.c.

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

00393 {
00394    int res;
00395 
00396    res = ast_register_application_xml(app, pickup_exec);
00397    res |= ast_register_application_xml(app2, pickupchan_exec);
00398 
00399    return res;
00400 }

static struct ast_channel* my_ast_get_channel_by_name_locked ( const char *  channame  )  [static]

Helper Function to walk through ALL channels checking NAME and STATE.

Definition at line 126 of file app_directed_pickup.c.

References ast_channel_callback(), pickup_by_name_args::len, pickup_by_name_args::name, and pickup_by_name_cb().

Referenced by pickup_by_channel().

00127 {
00128    char *chkchan;
00129    struct pickup_by_name_args pickup_args;
00130 
00131    /* Check if channel name contains a '-'.
00132     * In this case the channel name will be interpreted as full channel name.
00133     */
00134    if (strchr(channame, '-')) {
00135       /* check full channel name */
00136       pickup_args.len = strlen(channame);
00137       pickup_args.name = channame;
00138    } else {
00139       /* need to append a '-' for the comparison so we check full channel name,
00140        * i.e SIP/hgc- , use a temporary variable so original stays the same for
00141        * debugging.
00142        */
00143       pickup_args.len = strlen(channame) + 1;
00144       chkchan = alloca(pickup_args.len + 1);
00145       strcpy(chkchan, channame);
00146       strcat(chkchan, "-");
00147       pickup_args.name = chkchan;
00148    }
00149 
00150    return ast_channel_callback(pickup_by_name_cb, NULL, &pickup_args, 0);
00151 }

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 154 of file app_directed_pickup.c.

References ast_channel_unlock, ast_channel_unref, ast_do_pickup(), and my_ast_get_channel_by_name_locked().

Referenced by pickupchan_exec().

00155 {
00156    int res = -1;
00157    struct ast_channel *target;/*!< Potential pickup target */
00158 
00159    target = my_ast_get_channel_by_name_locked(pickup);
00160    if (target) {
00161       /* Just check that we are not picking up the SAME as target. (i.e. ourself) */
00162       if (chan != target) {
00163          res = ast_do_pickup(chan, target);
00164       }
00165       ast_channel_unlock(target);
00166       target = ast_channel_unref(target);
00167    }
00168 
00169    return res;
00170 }

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

Definition at line 173 of file app_directed_pickup.c.

References ast_can_pickup(), ast_channel_iterator_by_exten_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_do_pickup(), ast_log(), LOG_NOTICE, and ast_channel::name.

Referenced by pickup_exec().

00174 {
00175    struct ast_channel *target = NULL;/*!< Potential pickup target */
00176    struct ast_channel_iterator *iter;
00177    int res = -1;
00178 
00179    if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) {
00180       return -1;
00181    }
00182 
00183    while ((target = ast_channel_iterator_next(iter))) {
00184       ast_channel_lock(target);
00185       if ((chan != target) && ast_can_pickup(target)) {
00186          ast_log(LOG_NOTICE, "%s pickup by %s\n", target->name, chan->name);
00187          break;
00188       }
00189       ast_channel_unlock(target);
00190       target = ast_channel_unref(target);
00191    }
00192 
00193    ast_channel_iterator_destroy(iter);
00194 
00195    if (target) {
00196       res = ast_do_pickup(chan, target);
00197       ast_channel_unlock(target);
00198       target = ast_channel_unref(target);
00199    }
00200 
00201    return res;
00202 }

static int pickup_by_group ( struct ast_channel chan  )  [static]

Definition at line 254 of file app_directed_pickup.c.

References ast_channel_callback(), ast_channel_unlock, ast_channel_unref, ast_do_pickup(), ast_log(), find_channel_by_group(), LOG_NOTICE, and ast_channel::name.

Referenced by pickup_exec().

00255 {
00256    struct ast_channel *target;/*!< Potential pickup target */
00257    int res = -1;
00258 
00259    /* The found channel is already locked. */
00260    target = ast_channel_callback(find_channel_by_group, NULL, chan, 0);
00261    if (target) {
00262       ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", target->name, chan->name);
00263       res = ast_do_pickup(chan, target);
00264       ast_channel_unlock(target);
00265       target = ast_channel_unref(target);
00266    }
00267 
00268    return res;
00269 }

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

Definition at line 222 of file app_directed_pickup.c.

References ast_channel_callback(), ast_channel_unlock, ast_channel_unref, ast_do_pickup(), and find_by_mark().

Referenced by pickup_exec().

00223 {
00224    struct ast_channel *target;/*!< Potential pickup target */
00225    int res = -1;
00226 
00227    /* The found channel is already locked. */
00228    target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0);
00229    if (target) {
00230       res = ast_do_pickup(chan, target);
00231       ast_channel_unlock(target);
00232       target = ast_channel_unref(target);
00233    }
00234 
00235    return res;
00236 }

static int pickup_by_name_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 110 of file app_directed_pickup.c.

References args, ast_can_pickup(), ast_channel_lock, ast_channel_unlock, CMP_MATCH, CMP_STOP, and ast_channel::name.

Referenced by my_ast_get_channel_by_name_locked().

00111 {
00112    struct ast_channel *target = obj;/*!< Potential pickup target */
00113    struct pickup_by_name_args *args = data;
00114 
00115    ast_channel_lock(target);
00116    if (!strncasecmp(target->name, args->name, args->len) && ast_can_pickup(target)) {
00117       /* Return with the channel still locked on purpose */
00118       return CMP_MATCH | CMP_STOP;
00119    }
00120    ast_channel_unlock(target);
00121 
00122    return 0;
00123 }

static int pickup_by_part ( struct ast_channel chan,
const char *  part 
) [static]

Definition at line 322 of file app_directed_pickup.c.

References ast_channel_callback(), ast_channel_unlock, ast_channel_unref, ast_do_pickup(), and find_by_part().

Referenced by pickupchan_exec().

00323 {
00324    struct ast_channel *target;/*!< Potential pickup target */
00325    int res = -1;
00326 
00327    /* The found channel is already locked. */
00328    target = ast_channel_callback(find_by_part, NULL, (char *) part, 0);
00329    if (target) {
00330       res = ast_do_pickup(chan, target);
00331       ast_channel_unlock(target);
00332       target = ast_channel_unref(target);
00333    }
00334 
00335    return res;
00336 }

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

Definition at line 272 of file app_directed_pickup.c.

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

Referenced by load_module().

00273 {
00274    char *tmp = ast_strdupa(data);
00275    char *exten = NULL, *context = NULL;
00276 
00277    if (ast_strlen_zero(data)) {
00278       return pickup_by_group(chan) ? 0 : -1;
00279    }
00280 
00281    /* Parse extension (and context if there) */
00282    while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
00283       if ((context = strchr(exten, '@')))
00284          *context++ = '\0';
00285       if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
00286          if (!pickup_by_mark(chan, exten)) {
00287             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00288             return -1;
00289          }
00290       } else {
00291          if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) {
00292             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00293             return -1;
00294          }
00295       }
00296       ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
00297    }
00298 
00299    /* Pickup failed.  Keep going in the dialplan. */
00300    return 0;
00301 }

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

Definition at line 339 of file app_directed_pickup.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, parse(), pickup_by_channel(), pickup_by_part(), and strsep().

Referenced by load_module().

00340 {
00341    int partial_pickup = 0;
00342    char *pickup = NULL;
00343    char *parse = ast_strdupa(data);
00344    AST_DECLARE_APP_ARGS(args,
00345       AST_APP_ARG(channel);
00346       AST_APP_ARG(options);
00347    );
00348    AST_STANDARD_APP_ARGS(args, parse);
00349 
00350    if (ast_strlen_zero(args.channel)) {
00351       ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
00352       /* Pickup failed.  Keep going in the dialplan. */
00353       return 0;
00354    }
00355 
00356    if (!ast_strlen_zero(args.options) && strchr(args.options, 'p')) {
00357       partial_pickup = 1;
00358    }
00359 
00360    /* Parse channel */
00361    while (!ast_strlen_zero(args.channel) && (pickup = strsep(&args.channel, "&"))) {
00362       if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
00363          ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
00364       } else {
00365          if (partial_pickup) {
00366             if (!pickup_by_part(chan, pickup)) {
00367                /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00368                return -1;
00369             }
00370          } else if (!pickup_by_channel(chan, pickup)) {
00371             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00372             return -1;
00373          }
00374          ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
00375       }
00376    }
00377 
00378    /* Pickup failed.  Keep going in the dialplan. */
00379    return 0;
00380 }

static int unload_module ( void   )  [static]

Definition at line 382 of file app_directed_pickup.c.

References ast_unregister_application().

00383 {
00384    int res;
00385 
00386    res = ast_unregister_application(app);
00387    res |= ast_unregister_application(app2);
00388 
00389    return res;
00390 }


Variable Documentation

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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 402 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(), app_cmp(), load_module(), and unload_module().

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 402 of file app_directed_pickup.c.


Generated on Sat Mar 10 01:54:31 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7