Mon Oct 8 12:39:07 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 = "ac1f6a56484a8820659555499174e588" , .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 419 of file app_directed_pickup.c.

static void __unreg_module ( void   )  [static]

Definition at line 419 of file app_directed_pickup.c.

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

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

00222 {
00223    struct ast_channel *target = obj;/*!< Potential pickup target */
00224    const char *mark = data;
00225    const char *tmp;
00226 
00227    ast_channel_lock(target);
00228    tmp = pbx_builtin_getvar_helper(target, PICKUPMARK);
00229    if (tmp && !strcasecmp(tmp, mark) && ast_can_pickup(target)) {
00230       /* Return with the channel still locked on purpose */
00231       return CMP_MATCH | CMP_STOP;
00232    }
00233    ast_channel_unlock(target);
00234 
00235    return 0;
00236 }

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

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

00322 {
00323    struct ast_channel *target = obj;/*!< Potential pickup target */
00324    const char *part = data;
00325    int len = strlen(part);
00326 
00327    ast_channel_lock(target);
00328    if (len <= strlen(target->name) && !strncmp(target->name, part, len)
00329       && ast_can_pickup(target)) {
00330       /* Return with the channel still locked on purpose */
00331       return CMP_MATCH | CMP_STOP;
00332    }
00333    ast_channel_unlock(target);
00334 
00335    return 0;
00336 }

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

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

00256 {
00257    struct ast_channel *target = obj;/*!< Potential pickup target */
00258    struct ast_channel *chan = data;/*!< Channel wanting to pickup call */
00259 
00260    ast_channel_lock(target);
00261    if (chan != target && (chan->pickupgroup & target->callgroup)
00262       && ast_can_pickup(target)) {
00263       /* Return with the channel still locked on purpose */
00264       return CMP_MATCH | CMP_STOP;
00265    }
00266    ast_channel_unlock(target);
00267 
00268    return 0;
00269 }

static int load_module ( void   )  [static]

Definition at line 409 of file app_directed_pickup.c.

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

00410 {
00411    int res;
00412 
00413    res = ast_register_application_xml(app, pickup_exec);
00414    res |= ast_register_application_xml(app2, pickupchan_exec);
00415 
00416    return res;
00417 }

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

00144 {
00145    char *chkchan;
00146    struct pickup_by_name_args pickup_args;
00147 
00148    /* Check if channel name contains a '-'.
00149     * In this case the channel name will be interpreted as full channel name.
00150     */
00151    if (strchr(channame, '-')) {
00152       /* check full channel name */
00153       pickup_args.len = strlen(channame);
00154       pickup_args.name = channame;
00155    } else {
00156       /* need to append a '-' for the comparison so we check full channel name,
00157        * i.e SIP/hgc- , use a temporary variable so original stays the same for
00158        * debugging.
00159        */
00160       pickup_args.len = strlen(channame) + 1;
00161       chkchan = alloca(pickup_args.len + 1);
00162       strcpy(chkchan, channame);
00163       strcat(chkchan, "-");
00164       pickup_args.name = chkchan;
00165    }
00166 
00167    return ast_channel_callback(pickup_by_name_cb, NULL, &pickup_args, 0);
00168 }

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

00172 {
00173    int res = -1;
00174    struct ast_channel *target;/*!< Potential pickup target */
00175 
00176    target = my_ast_get_channel_by_name_locked(pickup);
00177    if (target) {
00178       /* Just check that we are not picking up the SAME as target. (i.e. ourself) */
00179       if (chan != target) {
00180          res = ast_do_pickup(chan, target);
00181       }
00182       ast_channel_unlock(target);
00183       target = ast_channel_unref(target);
00184    }
00185 
00186    return res;
00187 }

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

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

00191 {
00192    struct ast_channel *target = NULL;/*!< Potential pickup target */
00193    struct ast_channel_iterator *iter;
00194    int res = -1;
00195 
00196    if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) {
00197       return -1;
00198    }
00199 
00200    while ((target = ast_channel_iterator_next(iter))) {
00201       ast_channel_lock(target);
00202       if ((chan != target) && ast_can_pickup(target)) {
00203          ast_log(LOG_NOTICE, "%s pickup by %s\n", target->name, chan->name);
00204          break;
00205       }
00206       ast_channel_unlock(target);
00207       target = ast_channel_unref(target);
00208    }
00209 
00210    ast_channel_iterator_destroy(iter);
00211 
00212    if (target) {
00213       res = ast_do_pickup(chan, target);
00214       ast_channel_unlock(target);
00215       target = ast_channel_unref(target);
00216    }
00217 
00218    return res;
00219 }

static int pickup_by_group ( struct ast_channel chan  )  [static]

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

00272 {
00273    struct ast_channel *target;/*!< Potential pickup target */
00274    int res = -1;
00275 
00276    /* The found channel is already locked. */
00277    target = ast_channel_callback(find_channel_by_group, NULL, chan, 0);
00278    if (target) {
00279       ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", target->name, chan->name);
00280       res = ast_do_pickup(chan, target);
00281       ast_channel_unlock(target);
00282       target = ast_channel_unref(target);
00283    }
00284 
00285    return res;
00286 }

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

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

00240 {
00241    struct ast_channel *target;/*!< Potential pickup target */
00242    int res = -1;
00243 
00244    /* The found channel is already locked. */
00245    target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0);
00246    if (target) {
00247       res = ast_do_pickup(chan, target);
00248       ast_channel_unlock(target);
00249       target = ast_channel_unref(target);
00250    }
00251 
00252    return res;
00253 }

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

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

00128 {
00129    struct ast_channel *target = obj;/*!< Potential pickup target */
00130    struct pickup_by_name_args *args = data;
00131 
00132    ast_channel_lock(target);
00133    if (!strncasecmp(target->name, args->name, args->len) && ast_can_pickup(target)) {
00134       /* Return with the channel still locked on purpose */
00135       return CMP_MATCH | CMP_STOP;
00136    }
00137    ast_channel_unlock(target);
00138 
00139    return 0;
00140 }

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

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

00340 {
00341    struct ast_channel *target;/*!< Potential pickup target */
00342    int res = -1;
00343 
00344    /* The found channel is already locked. */
00345    target = ast_channel_callback(find_by_part, NULL, (char *) part, 0);
00346    if (target) {
00347       res = ast_do_pickup(chan, target);
00348       ast_channel_unlock(target);
00349       target = ast_channel_unref(target);
00350    }
00351 
00352    return res;
00353 }

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

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

00290 {
00291    char *tmp = ast_strdupa(data);
00292    char *exten = NULL, *context = NULL;
00293 
00294    if (ast_strlen_zero(data)) {
00295       return pickup_by_group(chan) ? 0 : -1;
00296    }
00297 
00298    /* Parse extension (and context if there) */
00299    while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
00300       if ((context = strchr(exten, '@')))
00301          *context++ = '\0';
00302       if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
00303          if (!pickup_by_mark(chan, exten)) {
00304             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00305             return -1;
00306          }
00307       } else {
00308          if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) {
00309             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00310             return -1;
00311          }
00312       }
00313       ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
00314    }
00315 
00316    /* Pickup failed.  Keep going in the dialplan. */
00317    return 0;
00318 }

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

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

00357 {
00358    int partial_pickup = 0;
00359    char *pickup = NULL;
00360    char *parse = ast_strdupa(data);
00361    AST_DECLARE_APP_ARGS(args,
00362       AST_APP_ARG(channel);
00363       AST_APP_ARG(options);
00364    );
00365    AST_STANDARD_APP_ARGS(args, parse);
00366 
00367    if (ast_strlen_zero(args.channel)) {
00368       ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
00369       /* Pickup failed.  Keep going in the dialplan. */
00370       return 0;
00371    }
00372 
00373    if (!ast_strlen_zero(args.options) && strchr(args.options, 'p')) {
00374       partial_pickup = 1;
00375    }
00376 
00377    /* Parse channel */
00378    while (!ast_strlen_zero(args.channel) && (pickup = strsep(&args.channel, "&"))) {
00379       if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
00380          ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
00381       } else {
00382          if (partial_pickup) {
00383             if (!pickup_by_part(chan, pickup)) {
00384                /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00385                return -1;
00386             }
00387          } else if (!pickup_by_channel(chan, pickup)) {
00388             /* Pickup successful.  Stop the dialplan this channel is a zombie. */
00389             return -1;
00390          }
00391          ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
00392       }
00393    }
00394 
00395    /* Pickup failed.  Keep going in the dialplan. */
00396    return 0;
00397 }

static int unload_module ( void   )  [static]

Definition at line 399 of file app_directed_pickup.c.

References ast_unregister_application().

00400 {
00401    int res;
00402 
00403    res = ast_unregister_application(app);
00404    res |= ast_unregister_application(app2);
00405 
00406    return res;
00407 }


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

Definition at line 419 of file app_directed_pickup.c.

const char app[] = "Pickup" [static]

Definition at line 119 of file app_directed_pickup.c.

const char app2[] = "PickupChan" [static]

Definition at line 120 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 419 of file app_directed_pickup.c.


Generated on Mon Oct 8 12:39:07 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7