#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/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 | can_pickup (struct ast_channel *chan) |
| static int | find_by_mark (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 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_by_name_cb (void *obj, void *arg, void *data, int flags) |
| static int | pickup_do (struct ast_channel *chan, struct ast_channel *target) |
| 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_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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
| static const char | app [] = "Pickup" |
| static const char | app2 [] = "PickupChan" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
Definition in file app_directed_pickup.c.
| #define PICKUPMARK "PICKUPMARK" |
Definition at line 46 of file app_directed_pickup.c.
Referenced by find_by_mark(), and pickup_exec().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 347 of file app_directed_pickup.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 347 of file app_directed_pickup.c.
| static int can_pickup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 135 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_mark(), pickup_by_exten(), and pickup_by_name_cb().
00136 { 00137 if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN)) 00138 return 1; 00139 else 00140 return 0; 00141 }
| static int find_by_mark | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 237 of file app_directed_pickup.c.
References ast_channel_lock, ast_channel_unlock, can_pickup(), CMP_MATCH, CMP_STOP, pbx_builtin_getvar_helper(), and PICKUPMARK.
Referenced by pickup_by_mark().
00238 { 00239 struct ast_channel *c = obj; 00240 const char *mark = data; 00241 const char *tmp; 00242 int res; 00243 00244 ast_channel_lock(c); 00245 00246 res = (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) && 00247 !strcasecmp(tmp, mark) && 00248 can_pickup(c); 00249 00250 ast_channel_unlock(c); 00251 00252 return res ? CMP_MATCH | CMP_STOP : 0; 00253 }
| static int load_module | ( | void | ) | [static] |
Definition at line 337 of file app_directed_pickup.c.
References ast_register_application_xml, pickup_exec(), and pickupchan_exec().
00338 { 00339 int res; 00340 00341 res = ast_register_application_xml(app, pickup_exec); 00342 res |= ast_register_application_xml(app2, pickupchan_exec); 00343 00344 return res; 00345 }
| 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 164 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().
00165 { 00166 char *chkchan; 00167 struct pickup_by_name_args pickup_args; 00168 00169 pickup_args.len = strlen(channame) + 2; 00170 00171 chkchan = alloca(pickup_args.len); 00172 00173 /* need to append a '-' for the comparison so we check full channel name, 00174 * i.e SIP/hgc- , use a temporary variable so original stays the same for 00175 * debugging. 00176 */ 00177 strcpy(chkchan, channame); 00178 strcat(chkchan, "-"); 00179 00180 pickup_args.name = chkchan; 00181 00182 return ast_channel_callback(pickup_by_name_cb, NULL, &pickup_args, 0); 00183 }
| 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 186 of file app_directed_pickup.c.
References ast_channel_unlock, ast_channel_unref, my_ast_get_channel_by_name_locked(), and pickup_do().
Referenced by pickupchan_exec().
00187 { 00188 int res = 0; 00189 struct ast_channel *target; 00190 00191 if (!(target = my_ast_get_channel_by_name_locked(pickup))) { 00192 return -1; 00193 } 00194 00195 /* Just check that we are not picking up the SAME as target */ 00196 if (chan != target) { 00197 res = pickup_do(chan, target); 00198 } 00199 00200 ast_channel_unlock(target); 00201 target = ast_channel_unref(target); 00202 00203 return res; 00204 }
| static int pickup_by_exten | ( | struct ast_channel * | chan, | |
| const char * | exten, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 207 of file app_directed_pickup.c.
References ast_channel_iterator_by_exten_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, can_pickup(), and pickup_do().
Referenced by pickup_exec().
00208 { 00209 struct ast_channel *target = NULL; 00210 struct ast_channel_iterator *iter; 00211 int res = -1; 00212 00213 if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) { 00214 return -1; 00215 } 00216 00217 while ((target = ast_channel_iterator_next(iter))) { 00218 ast_channel_lock(target); 00219 if ((chan != target) && can_pickup(target)) { 00220 break; 00221 } 00222 ast_channel_unlock(target); 00223 target = ast_channel_unref(target); 00224 } 00225 00226 ast_channel_iterator_destroy(iter); 00227 00228 if (target) { 00229 res = pickup_do(chan, target); 00230 ast_channel_unlock(target); 00231 target = ast_channel_unref(target); 00232 } 00233 00234 return res; 00235 }
| static int pickup_by_mark | ( | struct ast_channel * | chan, | |
| const char * | mark | |||
| ) | [static] |
Definition at line 256 of file app_directed_pickup.c.
References ast_channel_callback(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, find_by_mark(), and pickup_do().
Referenced by pickup_exec().
00257 { 00258 struct ast_channel *target; 00259 int res = -1; 00260 00261 if ((target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0))) { 00262 ast_channel_lock(target); 00263 res = pickup_do(chan, target); 00264 ast_channel_unlock(target); 00265 target = ast_channel_unref(target); 00266 } 00267 00268 return res; 00269 }
| static int pickup_by_name_cb | ( | void * | obj, | |
| void * | arg, | |||
| void * | data, | |||
| int | flags | |||
| ) | [static] |
Definition at line 148 of file app_directed_pickup.c.
References ast_channel_lock, ast_channel_unlock, can_pickup(), chan, CMP_MATCH, CMP_STOP, pickup_by_name_args::len, pickup_by_name_args::name, and ast_channel::name.
Referenced by my_ast_get_channel_by_name_locked().
00149 { 00150 struct ast_channel *chan = obj; 00151 struct pickup_by_name_args *args = data; 00152 00153 ast_channel_lock(chan); 00154 if (!strncasecmp(chan->name, args->name, args->len) && can_pickup(chan)) { 00155 /* Return with the channel still locked on purpose */ 00156 return CMP_MATCH | CMP_STOP; 00157 } 00158 ast_channel_unlock(chan); 00159 00160 return 0; 00161 }
| static int pickup_do | ( | struct ast_channel * | chan, | |
| struct ast_channel * | target | |||
| ) | [static] |
Definition at line 93 of file app_directed_pickup.c.
References ast_answer(), AST_CEL_PICKUP, ast_cel_report_event(), ast_channel_connected_line_macro(), ast_channel_lock, ast_channel_masquerade(), ast_channel_queue_connected_line_update(), ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_copy_from_caller(), AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, ast_debug, ast_log(), ast_party_connected_line_copy(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_queue_control(), ast_channel::cid, ast_channel::connected, LOG_WARNING, ast_channel::name, and ast_party_connected_line::source.
Referenced by pickup_by_channel(), pickup_by_exten(), and pickup_by_mark().
00094 { 00095 int res = 0; 00096 struct ast_party_connected_line connected_caller; 00097 00098 ast_debug(1, "Call pickup on '%s' by '%s'\n", target->name, chan->name); 00099 ast_cel_report_event(target, AST_CEL_PICKUP, NULL, NULL, chan); 00100 00101 ast_party_connected_line_init(&connected_caller); 00102 ast_party_connected_line_copy(&connected_caller, &target->connected); 00103 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 00104 if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) { 00105 ast_channel_update_connected_line(chan, &connected_caller); 00106 } 00107 ast_party_connected_line_free(&connected_caller); 00108 00109 ast_channel_lock(chan); 00110 ast_connected_line_copy_from_caller(&connected_caller, &chan->cid); 00111 ast_channel_unlock(chan); 00112 connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; 00113 ast_channel_queue_connected_line_update(chan, &connected_caller); 00114 ast_party_connected_line_free(&connected_caller); 00115 00116 if ((res = ast_answer(chan))) { 00117 ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name); 00118 return -1; 00119 } 00120 00121 if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) { 00122 ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name); 00123 return -1; 00124 } 00125 00126 if ((res = ast_channel_masquerade(target, chan))) { 00127 ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name); 00128 return -1; 00129 } 00130 00131 return res; 00132 }
| 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_pickup_call(), ast_strdupa, ast_strlen_zero(), ast_channel::context, context, exten, LOG_NOTICE, pickup_by_exten(), pickup_by_mark(), PICKUPMARK, and strsep().
Referenced by load_module().
00273 { 00274 int res = 0; 00275 char *tmp = ast_strdupa(data); 00276 char *exten = NULL, *context = NULL; 00277 00278 if (ast_strlen_zero(data)) { 00279 res = ast_pickup_call(chan); 00280 return res; 00281 } 00282 00283 /* Parse extension (and context if there) */ 00284 while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) { 00285 if ((context = strchr(exten, '@'))) 00286 *context++ = '\0'; 00287 if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) { 00288 if (!pickup_by_mark(chan, exten)) 00289 break; 00290 } else { 00291 if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) 00292 break; 00293 } 00294 ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten); 00295 } 00296 00297 return res; 00298 }
| static int pickupchan_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 301 of file app_directed_pickup.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, pickup_by_channel(), and strsep().
Referenced by load_module().
00302 { 00303 int res = 0; 00304 char *tmp = ast_strdupa(data); 00305 char *pickup = NULL; 00306 00307 if (ast_strlen_zero(data)) { 00308 ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n"); 00309 return -1; 00310 } 00311 00312 /* Parse channel */ 00313 while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) { 00314 if (!strncasecmp(chan->name, pickup, strlen(pickup))) { 00315 ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup); 00316 } else { 00317 if (!pickup_by_channel(chan, pickup)) { 00318 break; 00319 } 00320 ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup); 00321 } 00322 } 00323 00324 return res; 00325 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 327 of file app_directed_pickup.c.
References ast_unregister_application().
00328 { 00329 int res; 00330 00331 res = ast_unregister_application(app); 00332 res |= ast_unregister_application(app2); 00333 00334 return res; 00335 }
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 347 of file app_directed_pickup.c.
const char app[] = "Pickup" [static] |
Definition at line 88 of file app_directed_pickup.c.
const char app2[] = "PickupChan" [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 347 of file app_directed_pickup.c.
1.5.6