#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 = "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_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 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 }
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.