#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 = "ac1f6a56484a8820659555499174e588" , .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 }, [ '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 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 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 320 of file app_page.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 320 of file app_page.c.
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_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_random(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_flags::flags, LOG_WARNING, ast_channel::name, OPT_ARG_ARRAY_SIZE, ast_dial::options, page_opts, parse(), 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 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 320 of file app_page.c.
const char* const app_page = "Page" [static] |
Definition at line 112 of file app_page.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 320 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 }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} [static] |