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"
Go to the source code of this file.
Data Structures | |
| struct | pickup_criteria |
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_exten (struct ast_channel *c, void *data) |
| static int | find_by_mark (struct ast_channel *c, void *data) |
| 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_do (struct ast_channel *chan, struct ast_channel *target) |
| static int | pickup_exec (struct ast_channel *chan, void *data) |
| static int | pickupchan_exec (struct ast_channel *chan, void *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 = "0901e4e500243c855563a2d78b0c03e4" , .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 |
Directed Call Pickup Support.
Definition in file app_directed_pickup.c.
| #define PICKUPMARK "PICKUPMARK" |
Definition at line 44 of file app_directed_pickup.c.
Referenced by find_by_mark(), and pickup_exec().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 310 of file app_directed_pickup.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 310 of file app_directed_pickup.c.
| static int can_pickup | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 116 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_exten(), find_by_mark(), and my_ast_get_channel_by_name_locked().
00117 { 00118 if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN)) 00119 return 1; 00120 else 00121 return 0; 00122 }
| static int find_by_exten | ( | struct ast_channel * | c, | |
| void * | data | |||
| ) | [static] |
Definition at line 178 of file app_directed_pickup.c.
References can_pickup(), pickup_criteria::chan, pickup_criteria::context, ast_channel::dialcontext, ast_channel::exten, pickup_criteria::exten, and ast_channel::macroexten.
Referenced by pickup_by_exten().
00179 { 00180 struct pickup_criteria *info = data; 00181 00182 return (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) && 00183 !strcasecmp(c->dialcontext, info->context) && 00184 (info->chan != c) && can_pickup(c); 00185 }
| static int find_by_mark | ( | struct ast_channel * | c, | |
| void * | data | |||
| ) | [static] |
Definition at line 209 of file app_directed_pickup.c.
References can_pickup(), pbx_builtin_getvar_helper(), and PICKUPMARK.
Referenced by pickup_by_mark().
00210 { 00211 const char *mark = data; 00212 const char *tmp; 00213 00214 return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) && 00215 !strcasecmp(tmp, mark) && 00216 can_pickup(c); 00217 }
| static int load_module | ( | void | ) | [static] |
Definition at line 300 of file app_directed_pickup.c.
References ast_register_application_xml, pickup_exec(), and pickupchan_exec().
00301 { 00302 int res; 00303 00304 res = ast_register_application_xml(app, pickup_exec); 00305 res |= ast_register_application_xml(app2, pickupchan_exec); 00306 00307 return res; 00308 }
| 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 125 of file app_directed_pickup.c.
References ast_channel_unlock, ast_walk_channel_by_name_prefix_locked(), can_pickup(), chan, and ast_channel::name.
Referenced by pickup_by_channel().
00126 { 00127 struct ast_channel *chan; 00128 char *chkchan; 00129 size_t channame_len, chkchan_len; 00130 00131 channame_len = strlen(channame); 00132 chkchan_len = channame_len + 2; 00133 00134 chkchan = alloca(chkchan_len); 00135 00136 /* need to append a '-' for the comparison so we check full channel name, 00137 * i.e SIP/hgc- , use a temporary variable so original stays the same for 00138 * debugging. 00139 */ 00140 strcpy(chkchan, channame); 00141 strcat(chkchan, "-"); 00142 00143 for (chan = ast_walk_channel_by_name_prefix_locked(NULL, channame, channame_len); 00144 chan; 00145 chan = ast_walk_channel_by_name_prefix_locked(chan, channame, channame_len)) { 00146 if (!strncasecmp(chan->name, chkchan, chkchan_len) && can_pickup(chan)) { 00147 return chan; 00148 } 00149 ast_channel_unlock(chan); 00150 } 00151 return NULL; 00152 }
| 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 155 of file app_directed_pickup.c.
References ast_channel_unlock, my_ast_get_channel_by_name_locked(), ast_channel::name, and pickup_do().
Referenced by pickupchan_exec().
00156 { 00157 int res = 0; 00158 struct ast_channel *target; 00159 00160 if (!(target = my_ast_get_channel_by_name_locked(pickup))) 00161 return -1; 00162 00163 /* Just check that we are not picking up the SAME as target */ 00164 if (chan->name != target->name && chan != target) { 00165 res = pickup_do(chan, target); 00166 } 00167 ast_channel_unlock(target); 00168 00169 return res; 00170 }
| static int pickup_by_exten | ( | struct ast_channel * | chan, | |
| const char * | exten, | |||
| const char * | context | |||
| ) | [static] |
Definition at line 188 of file app_directed_pickup.c.
References ast_channel_search_locked(), ast_channel_unlock, pickup_criteria::exten, find_by_exten(), and pickup_do().
Referenced by pickup_exec().
00189 { 00190 struct ast_channel *target = NULL; 00191 struct pickup_criteria search = { 00192 .exten = exten, 00193 .context = context, 00194 .chan = chan, 00195 }; 00196 00197 target = ast_channel_search_locked(find_by_exten, &search); 00198 00199 if (target) { 00200 int res = pickup_do(chan, target); 00201 ast_channel_unlock(target); 00202 target = NULL; 00203 return res; 00204 } 00205 00206 return -1; 00207 }
| static int pickup_by_mark | ( | struct ast_channel * | chan, | |
| const char * | mark | |||
| ) | [static] |
Definition at line 220 of file app_directed_pickup.c.
References ast_channel_search_locked(), ast_channel_unlock, find_by_mark(), and pickup_do().
Referenced by pickup_exec().
00221 { 00222 struct ast_channel *target = ast_channel_search_locked(find_by_mark, (char *) mark); 00223 00224 if (target) { 00225 int res = pickup_do(chan, target); 00226 ast_channel_unlock(target); 00227 target = NULL; 00228 return res; 00229 } 00230 00231 return -1; 00232 }
| static int pickup_do | ( | struct ast_channel * | chan, | |
| struct ast_channel * | target | |||
| ) | [static] |
Definition at line 91 of file app_directed_pickup.c.
References ast_answer(), ast_channel_masquerade(), AST_CONTROL_ANSWER, ast_debug, ast_log(), ast_queue_control(), LOG_WARNING, and ast_channel::name.
Referenced by pickup_by_channel(), pickup_by_exten(), and pickup_by_mark().
00092 { 00093 int res = 0; 00094 00095 ast_debug(1, "Call pickup on '%s' by '%s'\n", target->name, chan->name); 00096 00097 if ((res = ast_answer(chan))) { 00098 ast_log(LOG_WARNING, "Unable to answer '%s'\n", chan->name); 00099 return -1; 00100 } 00101 00102 if ((res = ast_queue_control(chan, AST_CONTROL_ANSWER))) { 00103 ast_log(LOG_WARNING, "Unable to queue answer on '%s'\n", chan->name); 00104 return -1; 00105 } 00106 00107 if ((res = ast_channel_masquerade(target, chan))) { 00108 ast_log(LOG_WARNING, "Unable to masquerade '%s' into '%s'\n", chan->name, target->name); 00109 return -1; 00110 } 00111 00112 return res; 00113 }
| static int pickup_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 235 of file app_directed_pickup.c.
References ast_log(), ast_pickup_call(), ast_strlen_zero(), ast_channel::context, context, exten, LOG_NOTICE, pickup_by_exten(), pickup_by_mark(), and PICKUPMARK.
Referenced by load_module().
00236 { 00237 int res = 0; 00238 char *tmp = ast_strdupa(data); 00239 char *exten = NULL, *context = NULL; 00240 00241 if (ast_strlen_zero(data)) { 00242 res = ast_pickup_call(chan); 00243 return res; 00244 } 00245 00246 /* Parse extension (and context if there) */ 00247 while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) { 00248 if ((context = strchr(exten, '@'))) 00249 *context++ = '\0'; 00250 if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) { 00251 if (!pickup_by_mark(chan, exten)) 00252 break; 00253 } else { 00254 if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context)) 00255 break; 00256 } 00257 ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten); 00258 } 00259 00260 return res; 00261 }
| static int pickupchan_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 264 of file app_directed_pickup.c.
References ast_log(), ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, and pickup_by_channel().
Referenced by load_module().
00265 { 00266 int res = 0; 00267 char *tmp = ast_strdupa(data); 00268 char *pickup = NULL; 00269 00270 if (ast_strlen_zero(data)) { 00271 ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n"); 00272 return -1; 00273 } 00274 00275 /* Parse channel */ 00276 while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) { 00277 if (!strncasecmp(chan->name, pickup, strlen(pickup))) { 00278 ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup); 00279 } else { 00280 if (!pickup_by_channel(chan, pickup)) { 00281 break; 00282 } 00283 ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup); 00284 } 00285 } 00286 00287 return res; 00288 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 290 of file app_directed_pickup.c.
References ast_unregister_application().
00291 { 00292 int res; 00293 00294 res = ast_unregister_application(app); 00295 res |= ast_unregister_application(app2); 00296 00297 return res; 00298 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 310 of file app_directed_pickup.c.
const char* app = "Pickup" [static] |
Definition at line 86 of file app_directed_pickup.c.
const char* app2 = "PickupChan" [static] |
Definition at line 87 of file app_directed_pickup.c.
Referenced by _macro_exec().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 310 of file app_directed_pickup.c.
1.6.2