page() - Paging application More...
#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 | |
AST_APP_OPTIONS (page_opts,{AST_APP_OPTION('d', PAGE_DUPLEX), AST_APP_OPTION('q', PAGE_QUIET), AST_APP_OPTION('r', PAGE_RECORD), AST_APP_OPTION('s', PAGE_SKIP), AST_APP_OPTION('i', PAGE_IGNORE_FORWARDS), AST_APP_OPTION_ARG('A', PAGE_ANNOUNCE, OPT_ARG_ANNOUNCE), AST_APP_OPTION('n', PAGE_NOCALLERANNOUNCE),}) | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Page Multiple Phones") | |
static int | load_module (void) |
static int | page_exec (struct ast_channel *chan, const char *data) |
static int | unload_module (void) |
Variables | |
static const char *const | app_page = "Page" |
page() - Paging application
Definition in file app_page.c.
anonymous enum |
Definition at line 124 of file app_page.c.
00124 { 00125 OPT_ARG_ANNOUNCE = 0, 00126 OPT_ARG_ARRAY_SIZE = 1, 00127 };
enum page_opt_flags |
PAGE_DUPLEX | |
PAGE_QUIET | |
PAGE_RECORD | |
PAGE_SKIP | |
PAGE_IGNORE_FORWARDS | |
PAGE_ANNOUNCE | |
PAGE_NOCALLERANNOUNCE |
Definition at line 114 of file app_page.c.
00114 { 00115 PAGE_DUPLEX = (1 << 0), 00116 PAGE_QUIET = (1 << 1), 00117 PAGE_RECORD = (1 << 2), 00118 PAGE_SKIP = (1 << 3), 00119 PAGE_IGNORE_FORWARDS = (1 << 4), 00120 PAGE_ANNOUNCE = (1 << 5), 00121 PAGE_NOCALLERANNOUNCE = (1 << 6), 00122 };
AST_APP_OPTIONS | ( | page_opts | ) |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Page Multiple Phones" | ||||
) |
static int load_module | ( | void | ) | [static] |
Definition at line 315 of file app_page.c.
References ast_register_application_xml, and page_exec().
00316 { 00317 return ast_register_application_xml(app_page, page_exec); 00318 }
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_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_free, ast_log(), ast_random(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), devices, LOG_ERROR, LOG_WARNING, OPT_ARG_ANNOUNCE, OPT_ARG_ARRAY_SIZE, ast_dial::options, PAGE_ANNOUNCE, PAGE_DUPLEX, PAGE_IGNORE_FORWARDS, PAGE_NOCALLERANNOUNCE, PAGE_QUIET, PAGE_RECORD, PAGE_SKIP, parse(), pbx_exec(), pbx_findapp(), 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 } else { 00181 /* opts must be initialized if there wasn't an options string. */ 00182 for (i = 0; i < OPT_ARG_ARRAY_SIZE; i++) { 00183 opts[i] = NULL; 00184 } 00185 } 00186 00187 if (!ast_strlen_zero(args.timeout)) { 00188 timeout = atoi(args.timeout); 00189 } 00190 00191 if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE])) { 00192 snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)G(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), 00193 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] ); 00194 } else { 00195 snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), 00196 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); 00197 } 00198 00199 /* Count number of extensions in list by number of ampersands + 1 */ 00200 num_dials = 1; 00201 tmp = args.devices; 00202 while (*tmp) { 00203 if (*tmp == '&') { 00204 num_dials++; 00205 } 00206 tmp++; 00207 } 00208 00209 if (!(dial_list = ast_calloc(num_dials, sizeof(struct ast_dial *)))) { 00210 ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (long)(sizeof(struct ast_dial *) * num_dials)); 00211 return -1; 00212 } 00213 00214 /* Go through parsing/calling each device */ 00215 while ((tech = strsep(&args.devices, "&"))) { 00216 int state = 0; 00217 struct ast_dial *dial = NULL; 00218 00219 /* don't call the originating device */ 00220 if (!strcasecmp(tech, originator)) 00221 continue; 00222 00223 /* If no resource is available, continue on */ 00224 if (!(resource = strchr(tech, '/'))) { 00225 ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech); 00226 continue; 00227 } 00228 00229 /* Ensure device is not in use if skip option is enabled */ 00230 if (ast_test_flag(&flags, PAGE_SKIP)) { 00231 state = ast_device_state(tech); 00232 if (state == AST_DEVICE_UNKNOWN) { 00233 ast_log(LOG_WARNING, "Destination '%s' has device state '%s'. Paging anyway.\n", tech, ast_devstate2str(state)); 00234 } else if (state != AST_DEVICE_NOT_INUSE) { 00235 ast_log(LOG_WARNING, "Destination '%s' has device state '%s'.\n", tech, ast_devstate2str(state)); 00236 continue; 00237 } 00238 } 00239 00240 *resource++ = '\0'; 00241 00242 /* Create a dialing structure */ 00243 if (!(dial = ast_dial_create())) { 00244 ast_log(LOG_WARNING, "Failed to create dialing structure.\n"); 00245 continue; 00246 } 00247 00248 /* Append technology and resource */ 00249 if (ast_dial_append(dial, tech, resource) == -1) { 00250 ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech); 00251 ast_dial_destroy(dial); 00252 continue; 00253 } 00254 00255 /* Set ANSWER_EXEC as global option */ 00256 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts); 00257 00258 if (timeout) { 00259 ast_dial_set_global_timeout(dial, timeout * 1000); 00260 } 00261 00262 if (ast_test_flag(&flags, PAGE_IGNORE_FORWARDS)) { 00263 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL); 00264 } 00265 00266 /* Run this dial in async mode */ 00267 ast_dial_run(dial, chan, 1); 00268 00269 /* Put in our dialing array */ 00270 dial_list[pos++] = dial; 00271 } 00272 00273 if (!ast_test_flag(&flags, PAGE_QUIET)) { 00274 res = ast_streamfile(chan, "beep", chan->language); 00275 if (!res) 00276 res = ast_waitstream(chan, ""); 00277 } 00278 00279 if (!res) { 00280 /* Default behaviour */ 00281 snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 00282 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); 00283 if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE]) && 00284 !ast_test_flag(&flags, PAGE_NOCALLERANNOUNCE)) { 00285 snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxdG(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 00286 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] ); 00287 } 00288 pbx_exec(chan, app, meetmeopts); 00289 } 00290 00291 /* Go through each dial attempt cancelling, joining, and destroying */ 00292 for (i = 0; i < pos; i++) { 00293 struct ast_dial *dial = dial_list[i]; 00294 00295 /* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */ 00296 ast_dial_join(dial); 00297 00298 /* Hangup all channels */ 00299 ast_dial_hangup(dial); 00300 00301 /* Destroy dialing structure */ 00302 ast_dial_destroy(dial); 00303 } 00304 00305 ast_free(dial_list); 00306 00307 return -1; 00308 }
static int unload_module | ( | void | ) | [static] |
Definition at line 310 of file app_page.c.
References ast_unregister_application().
00311 { 00312 return ast_unregister_application(app_page); 00313 }
const char* const app_page = "Page" [static] |
Definition at line 112 of file app_page.c.