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