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
00034
00035
00036
00037
00038
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 370951 $")
00042
00043 #include "asterisk/file.h"
00044 #include "asterisk/channel.h"
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/app.h"
00048
00049 static const char app_originate[] = "Originate";
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 static int originate_exec(struct ast_channel *chan, const char *data)
00100 {
00101 AST_DECLARE_APP_ARGS(args,
00102 AST_APP_ARG(tech_data);
00103 AST_APP_ARG(type);
00104 AST_APP_ARG(arg1);
00105 AST_APP_ARG(arg2);
00106 AST_APP_ARG(arg3);
00107 AST_APP_ARG(timeout);
00108 );
00109 char *parse;
00110 char *chantech, *chandata;
00111 int res = -1;
00112 int outgoing_status = 0;
00113 unsigned int timeout = 30;
00114 static const char default_exten[] = "s";
00115 struct ast_format tmpfmt;
00116 struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
00117
00118 ast_autoservice_start(chan);
00119 if (!cap_slin) {
00120 goto return_cleanup;
00121 }
00122 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
00123 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR12, 0));
00124 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0));
00125 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR24, 0));
00126 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR32, 0));
00127 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR44, 0));
00128 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR48, 0));
00129 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR96, 0));
00130 ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR192, 0));
00131
00132 if (ast_strlen_zero(data)) {
00133 ast_log(LOG_ERROR, "Originate() requires arguments\n");
00134 goto return_cleanup;
00135 }
00136
00137 parse = ast_strdupa(data);
00138
00139 AST_STANDARD_APP_ARGS(args, parse);
00140
00141 if (args.argc < 3) {
00142 ast_log(LOG_ERROR, "Incorrect number of arguments\n");
00143 goto return_cleanup;
00144 }
00145
00146 if (!ast_strlen_zero(args.timeout)) {
00147 if(sscanf(args.timeout, "%u", &timeout) != 1) {
00148 ast_log(LOG_NOTICE, "Invalid timeout: '%s'. Setting timeout to 30 seconds\n", args.timeout);
00149 timeout = 30;
00150 }
00151 }
00152
00153 chandata = ast_strdupa(args.tech_data);
00154 chantech = strsep(&chandata, "/");
00155
00156 if (ast_strlen_zero(chandata) || ast_strlen_zero(chantech)) {
00157 ast_log(LOG_ERROR, "Channel Tech/Data invalid: '%s'\n", args.tech_data);
00158 goto return_cleanup;
00159 }
00160
00161 if (!strcasecmp(args.type, "exten")) {
00162 int priority = 1;
00163 const char *exten = args.arg2;
00164
00165 if (args.argc == 5) {
00166
00167 if (sscanf(args.arg3, "%30d", &priority) != 1) {
00168 ast_log(LOG_ERROR, "Invalid priority: '%s'\n", args.arg3);
00169 goto return_cleanup;
00170 }
00171 } else if (args.argc == 3) {
00172
00173 exten = default_exten;
00174 }
00175
00176 ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
00177 chantech, chandata, args.arg1, exten, priority);
00178
00179 ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
00180 timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
00181 NULL, NULL, NULL, NULL, 0);
00182 } else if (!strcasecmp(args.type, "app")) {
00183 ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
00184 chantech, chandata, args.arg1, S_OR(args.arg2, ""));
00185
00186 ast_pbx_outgoing_app(chantech, cap_slin, chandata,
00187 timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
00188 NULL, NULL, NULL, NULL);
00189 } else {
00190 ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
00191 args.type);
00192 goto return_cleanup;
00193 }
00194
00195 res = 0;
00196
00197 return_cleanup:
00198 if (res) {
00199 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "FAILED");
00200 } else {
00201 switch (outgoing_status) {
00202 case 0:
00203 case AST_CONTROL_ANSWER:
00204 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "SUCCESS");
00205 break;
00206 case AST_CONTROL_BUSY:
00207 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "BUSY");
00208 break;
00209 case AST_CONTROL_CONGESTION:
00210 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "CONGESTION");
00211 break;
00212 case AST_CONTROL_HANGUP:
00213 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "HANGUP");
00214 break;
00215 case AST_CONTROL_RINGING:
00216 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "RINGING");
00217 break;
00218 default:
00219 ast_log(LOG_WARNING, "Unknown originate status result of '%d'\n",
00220 outgoing_status);
00221 pbx_builtin_setvar_helper(chan, "ORIGINATE_STATUS", "UNKNOWN");
00222 break;
00223 }
00224 }
00225 cap_slin = ast_format_cap_destroy(cap_slin);
00226 ast_autoservice_stop(chan);
00227
00228 return res;
00229 }
00230
00231 static int unload_module(void)
00232 {
00233 return ast_unregister_application(app_originate);
00234 }
00235
00236 static int load_module(void)
00237 {
00238 int res;
00239
00240 res = ast_register_application_xml(app_originate, originate_exec);
00241
00242 return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
00243 }
00244
00245 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Originate call");