#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/file.h"
#include "asterisk/app.h"
#include "asterisk/chanvars.h"
#include "asterisk/utils.h"
#include "asterisk/devicestate.h"
#include "asterisk/dial.h"
Go to the source code of this file.
Enumerations | |
enum | { OPT_ARG_ANNOUNCE = 0, OPT_ARG_ARRAY_SIZE = 1 } |
enum | page_opt_flags { PAGE_DUPLEX = (1 << 0), PAGE_QUIET = (1 << 1), PAGE_RECORD = (1 << 2), PAGE_SKIP = (1 << 3), PAGE_IGNORE_FORWARDS = (1 << 4), PAGE_ANNOUNCE = (1 << 5), PAGE_NOCALLERANNOUNCE = (1 << 6) } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | load_module (void) |
static int | page_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 = "Page Multiple Phones" , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static const char *const | app_page = "Page" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_app_option | page_opts [128] = { [ 'd' ] = { .flag = PAGE_DUPLEX }, [ 'q' ] = { .flag = PAGE_QUIET }, [ 'r' ] = { .flag = PAGE_RECORD }, [ 's' ] = { .flag = PAGE_SKIP }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} |
Definition in file app_page.c.
anonymous enum |
Definition at line 123 of file app_page.c.
00123 { 00124 OPT_ARG_ANNOUNCE = 0, 00125 OPT_ARG_ARRAY_SIZE = 1, 00126 };
enum page_opt_flags |
PAGE_DUPLEX | |
PAGE_QUIET | |
PAGE_RECORD | |
PAGE_SKIP | |
PAGE_IGNORE_FORWARDS | |
PAGE_ANNOUNCE | |
PAGE_NOCALLERANNOUNCE |
Definition at line 113 of file app_page.c.
00113 { 00114 PAGE_DUPLEX = (1 << 0), 00115 PAGE_QUIET = (1 << 1), 00116 PAGE_RECORD = (1 << 2), 00117 PAGE_SKIP = (1 << 3), 00118 PAGE_IGNORE_FORWARDS = (1 << 4), 00119 PAGE_ANNOUNCE = (1 << 5), 00120 PAGE_NOCALLERANNOUNCE = (1 << 6), 00121 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 312 of file app_page.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 312 of file app_page.c.
static int load_module | ( | void | ) | [static] |
Definition at line 307 of file app_page.c.
References ast_register_application_xml, and page_exec().
00308 { 00309 return ast_register_application_xml(app_page, page_exec); 00310 }
static int page_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 140 of file app_page.c.
References app, args, AST_APP_ARG, ast_app_parse_options(), ast_calloc, AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DEVICE_NOT_INUSE, ast_device_state(), AST_DEVICE_UNKNOWN, ast_devstate2str(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_hangup(), ast_dial_join(), AST_DIAL_OPTION_ANSWER_EXEC, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, ast_dial_option_global_enable(), ast_dial_run(), ast_dial_set_global_timeout(), ast_log(), ast_random(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), ast_flags::flags, ast_channel::language, LOG_ERROR, LOG_WARNING, ast_channel::name, OPT_ARG_ANNOUNCE, OPT_ARG_ARRAY_SIZE, ast_dial::options, PAGE_ANNOUNCE, PAGE_DUPLEX, PAGE_IGNORE_FORWARDS, PAGE_NOCALLERANNOUNCE, page_opts, PAGE_QUIET, PAGE_RECORD, PAGE_SKIP, parse(), pbx_exec(), pbx_findapp(), strsep(), and ast_dial::timeout.
Referenced by load_module().
00141 { 00142 char *tech, *resource, *tmp; 00143 char meetmeopts[128], originator[AST_CHANNEL_NAME], *opts[OPT_ARG_ARRAY_SIZE]; 00144 struct ast_flags flags = { 0 }; 00145 unsigned int confid = ast_random(); 00146 struct ast_app *app; 00147 int res = 0, pos = 0, i = 0; 00148 struct ast_dial **dial_list; 00149 unsigned int num_dials; 00150 int timeout = 0; 00151 char *parse; 00152 00153 AST_DECLARE_APP_ARGS(args, 00154 AST_APP_ARG(devices); 00155 AST_APP_ARG(options); 00156 AST_APP_ARG(timeout); 00157 ); 00158 00159 if (ast_strlen_zero(data)) { 00160 ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n"); 00161 return -1; 00162 } 00163 00164 if (!(app = pbx_findapp("MeetMe"))) { 00165 ast_log(LOG_WARNING, "There is no MeetMe application available!\n"); 00166 return -1; 00167 }; 00168 00169 parse = ast_strdupa(data); 00170 00171 AST_STANDARD_APP_ARGS(args, parse); 00172 00173 ast_copy_string(originator, chan->name, sizeof(originator)); 00174 if ((tmp = strchr(originator, '-'))) { 00175 *tmp = '\0'; 00176 } 00177 00178 if (!ast_strlen_zero(args.options)) { 00179 ast_app_parse_options(page_opts, &flags, opts, args.options); 00180 } 00181 00182 if (!ast_strlen_zero(args.timeout)) { 00183 timeout = atoi(args.timeout); 00184 } 00185 00186 if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE])) { 00187 snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)G(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), 00188 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] ); 00189 } else { 00190 snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), 00191 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); 00192 } 00193 00194 /* Count number of extensions in list by number of ampersands + 1 */ 00195 num_dials = 1; 00196 tmp = args.devices; 00197 while (*tmp) { 00198 if (*tmp == '&') { 00199 num_dials++; 00200 } 00201 tmp++; 00202 } 00203 00204 if (!(dial_list = ast_calloc(num_dials, sizeof(struct ast_dial *)))) { 00205 ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (long)(sizeof(struct ast_dial *) * num_dials)); 00206 return -1; 00207 } 00208 00209 /* Go through parsing/calling each device */ 00210 while ((tech = strsep(&args.devices, "&"))) { 00211 int state = 0; 00212 struct ast_dial *dial = NULL; 00213 00214 /* don't call the originating device */ 00215 if (!strcasecmp(tech, originator)) 00216 continue; 00217 00218 /* If no resource is available, continue on */ 00219 if (!(resource = strchr(tech, '/'))) { 00220 ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech); 00221 continue; 00222 } 00223 00224 /* Ensure device is not in use if skip option is enabled */ 00225 if (ast_test_flag(&flags, PAGE_SKIP)) { 00226 state = ast_device_state(tech); 00227 if (state == AST_DEVICE_UNKNOWN) { 00228 ast_log(LOG_WARNING, "Destination '%s' has device state '%s'. Paging anyway.\n", tech, ast_devstate2str(state)); 00229 } else if (state != AST_DEVICE_NOT_INUSE) { 00230 ast_log(LOG_WARNING, "Destination '%s' has device state '%s'.\n", tech, ast_devstate2str(state)); 00231 continue; 00232 } 00233 } 00234 00235 *resource++ = '\0'; 00236 00237 /* Create a dialing structure */ 00238 if (!(dial = ast_dial_create())) { 00239 ast_log(LOG_WARNING, "Failed to create dialing structure.\n"); 00240 continue; 00241 } 00242 00243 /* Append technology and resource */ 00244 if (ast_dial_append(dial, tech, resource) == -1) { 00245 ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech); 00246 continue; 00247 } 00248 00249 /* Set ANSWER_EXEC as global option */ 00250 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts); 00251 00252 if (timeout) { 00253 ast_dial_set_global_timeout(dial, timeout * 1000); 00254 } 00255 00256 if (ast_test_flag(&flags, PAGE_IGNORE_FORWARDS)) { 00257 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL); 00258 } 00259 00260 /* Run this dial in async mode */ 00261 ast_dial_run(dial, chan, 1); 00262 00263 /* Put in our dialing array */ 00264 dial_list[pos++] = dial; 00265 } 00266 00267 if (!ast_test_flag(&flags, PAGE_QUIET)) { 00268 res = ast_streamfile(chan, "beep", chan->language); 00269 if (!res) 00270 res = ast_waitstream(chan, ""); 00271 } 00272 00273 if (!res) { 00274 /* Default behaviour */ 00275 snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 00276 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); 00277 if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE]) && 00278 !ast_test_flag(&flags, PAGE_NOCALLERANNOUNCE)) { 00279 snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxdG(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 00280 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] ); 00281 } 00282 pbx_exec(chan, app, meetmeopts); 00283 } 00284 00285 /* Go through each dial attempt cancelling, joining, and destroying */ 00286 for (i = 0; i < pos; i++) { 00287 struct ast_dial *dial = dial_list[i]; 00288 00289 /* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */ 00290 ast_dial_join(dial); 00291 00292 /* Hangup all channels */ 00293 ast_dial_hangup(dial); 00294 00295 /* Destroy dialing structure */ 00296 ast_dial_destroy(dial); 00297 } 00298 00299 return -1; 00300 }
static int unload_module | ( | void | ) | [static] |
Definition at line 302 of file app_page.c.
References ast_unregister_application().
00303 { 00304 return ast_unregister_application(app_page); 00305 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Page Multiple Phones" , .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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 312 of file app_page.c.
const char* const app_page = "Page" [static] |
Definition at line 111 of file app_page.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 312 of file app_page.c.
struct ast_app_option page_opts[128] = { [ 'd' ] = { .flag = PAGE_DUPLEX }, [ 'q' ] = { .flag = PAGE_QUIET }, [ 'r' ] = { .flag = PAGE_RECORD }, [ 's' ] = { .flag = PAGE_SKIP }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} [static] |