00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039 #include <string.h>
00040 #include <errno.h>
00041
00042 #include "asterisk/options.h"
00043 #include "asterisk/logger.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/file.h"
00048 #include "asterisk/app.h"
00049 #include "asterisk/chanvars.h"
00050 #include "asterisk/utils.h"
00051 #include "asterisk/dial.h"
00052 #include "asterisk/devicestate.h"
00053
00054 static const char *app_page= "Page";
00055
00056 static const char *page_synopsis = "Pages phones";
00057
00058 static const char *page_descrip =
00059 "Page(Technology/Resource&Technology2/Resource2[|options])\n"
00060 " Places outbound calls to the given technology / resource and dumps\n"
00061 "them into a conference bridge as muted participants. The original\n"
00062 "caller is dumped into the conference as a speaker and the room is\n"
00063 "destroyed when the original caller leaves. Valid options are:\n"
00064 " d - full duplex audio\n"
00065 " q - quiet, do not play beep to caller\n"
00066 " r - record the page into a file (see 'r' for app_meetme)\n";
00067
00068 enum {
00069 PAGE_DUPLEX = (1 << 0),
00070 PAGE_QUIET = (1 << 1),
00071 PAGE_RECORD = (1 << 2),
00072 } page_opt_flags;
00073
00074 AST_APP_OPTIONS(page_opts, {
00075 AST_APP_OPTION('d', PAGE_DUPLEX),
00076 AST_APP_OPTION('q', PAGE_QUIET),
00077 AST_APP_OPTION('r', PAGE_RECORD),
00078 });
00079
00080 #define MAX_DIALS 128
00081
00082 static int page_exec(struct ast_channel *chan, void *data)
00083 {
00084 struct ast_module_user *u;
00085 char *options, *tech, *resource, *tmp;
00086 char meetmeopts[88], originator[AST_CHANNEL_NAME];
00087 struct ast_flags flags = { 0 };
00088 unsigned int confid = ast_random();
00089 struct ast_app *app;
00090 int res = 0, pos = 0, i = 0;
00091 struct ast_dial *dials[MAX_DIALS];
00092
00093 if (ast_strlen_zero(data)) {
00094 ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
00095 return -1;
00096 }
00097
00098 u = ast_module_user_add(chan);
00099
00100 if (!(app = pbx_findapp("MeetMe"))) {
00101 ast_log(LOG_WARNING, "There is no MeetMe application available!\n");
00102 ast_module_user_remove(u);
00103 return -1;
00104 };
00105
00106 options = ast_strdupa(data);
00107
00108 ast_copy_string(originator, chan->name, sizeof(originator));
00109 if ((tmp = strchr(originator, '-')))
00110 *tmp = '\0';
00111
00112 tmp = strsep(&options, "|");
00113 if (options)
00114 ast_app_parse_options(page_opts, &flags, NULL, options);
00115
00116 snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
00117 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
00118
00119
00120 while ((tech = strsep(&tmp, "&"))) {
00121 struct ast_dial *dial = NULL;
00122
00123
00124 if (!strcasecmp(tech, originator))
00125 continue;
00126
00127
00128 if (!(resource = strchr(tech, '/'))) {
00129 ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech);
00130 continue;
00131 }
00132
00133 *resource++ = '\0';
00134
00135
00136 if (!(dial = ast_dial_create())) {
00137 ast_log(LOG_WARNING, "Failed to create dialing structure.\n");
00138 continue;
00139 }
00140
00141
00142 ast_dial_append(dial, tech, resource);
00143
00144
00145 ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts);
00146
00147
00148 ast_dial_run(dial, chan, 1);
00149
00150
00151 dials[pos++] = dial;
00152 }
00153
00154 if (!ast_test_flag(&flags, PAGE_QUIET)) {
00155 res = ast_streamfile(chan, "beep", chan->language);
00156 if (!res)
00157 res = ast_waitstream(chan, "");
00158 }
00159
00160 if (!res) {
00161 snprintf(meetmeopts, sizeof(meetmeopts), "%ud|A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"),
00162 (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
00163 pbx_exec(chan, app, meetmeopts);
00164 }
00165
00166
00167 for (i = 0; i < pos; i++) {
00168 struct ast_dial *dial = dials[i];
00169
00170
00171 ast_dial_join(dial);
00172
00173
00174 ast_dial_hangup(dial);
00175
00176
00177 ast_dial_destroy(dial);
00178 }
00179
00180 ast_module_user_remove(u);
00181
00182 return -1;
00183 }
00184
00185 static int unload_module(void)
00186 {
00187 int res;
00188
00189 res = ast_unregister_application(app_page);
00190
00191 ast_module_user_hangup_all();
00192
00193 return res;
00194 }
00195
00196 static int load_module(void)
00197 {
00198 return ast_register_application(app_page, page_exec, page_synopsis, page_descrip);
00199 }
00200
00201 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Page Multiple Phones");
00202