#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_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 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_info * | ast_module_info = &__mod_info |
Gary Cook
Definition in file app_directed_pickup.c.
#define PICKUPMARK "PICKUPMARK" |
Definition at line 51 of file app_directed_pickup.c.
Referenced by find_by_mark(), and pickup_exec().
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 }
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.