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 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <ctype.h>
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00035
00036 #include "asterisk/lock.h"
00037 #include "asterisk/file.h"
00038 #include "asterisk/logger.h"
00039 #include "asterisk/channel.h"
00040 #include "asterisk/pbx.h"
00041 #include "asterisk/options.h"
00042 #include "asterisk/config.h"
00043 #include "asterisk/module.h"
00044 #include "asterisk/utils.h"
00045 #include "asterisk/causes.h"
00046 #include "asterisk/astosp.h"
00047 #include "asterisk/app.h"
00048 #include "asterisk/options.h"
00049
00050 static char *tdesc = "OSP Lookup";
00051
00052 static char *app = "OSPLookup";
00053 static char *app2 = "OSPNext";
00054 static char *app3 = "OSPFinish";
00055
00056 static char *synopsis = "Lookup number in OSP";
00057 static char *synopsis2 = "Lookup next OSP entry";
00058 static char *synopsis3 = "Record OSP entry";
00059
00060 static char *descrip =
00061 " OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
00062 "the variables, where 'n' is the number of the result beginning with 1:\n"
00063 " ${OSPTECH}: The technology to use for the call\n"
00064 " ${OSPDEST}: The destination to use for the call\n"
00065 " ${OSPTOKEN}: The actual OSP token as a string\n"
00066 " ${OSPHANDLE}: The OSP Handle for anything remaining\n"
00067 " ${OSPRESULTS}: The number of OSP results total remaining\n"
00068 "\n"
00069 "The option string may contain the following character:\n"
00070 " 'j' -- jump to n+101 priority if the lookup was NOT successful\n"
00071 "This application sets the following channel variable upon completion:\n"
00072 " OSPLOOKUPSTATUS The status of the OSP Lookup attempt as a text string, one of\n"
00073 " SUCCESS | FAILED \n";
00074
00075
00076 static char *descrip2 =
00077 " OSPNext(cause[|options]): Looks up the next OSP Destination for ${OSPHANDLE}\n"
00078 "See OSPLookup for more information\n"
00079 "\n"
00080 "The option string may contain the following character:\n"
00081 " 'j' -- jump to n+101 priority if the lookup was NOT successful\n"
00082 "This application sets the following channel variable upon completion:\n"
00083 " OSPNEXTSTATUS The status of the OSP Next attempt as a text string, one of\n"
00084 " SUCCESS | FAILED \n";
00085
00086 static char *descrip3 =
00087 " OSPFinish(status[|options]): Records call state for ${OSPHANDLE}, according to\n"
00088 "status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or CHANUNAVAIL\n"
00089 "or coincidentally, just what the Dial application stores in its ${DIALSTATUS}.\n"
00090 "\n"
00091 "The option string may contain the following character:\n"
00092 " 'j' -- jump to n+101 priority if the finish attempt was NOT successful\n"
00093 "This application sets the following channel variable upon completion:\n"
00094 " OSPFINISHSTATUS The status of the OSP Finish attempt as a text string, one of\n"
00095 " SUCCESS | FAILED \n";
00096
00097 STANDARD_LOCAL_USER;
00098
00099 LOCAL_USER_DECL;
00100
00101 static int str2cause(char *cause)
00102 {
00103 if (!strcasecmp(cause, "BUSY"))
00104 return AST_CAUSE_BUSY;
00105 if (!strcasecmp(cause, "CONGESTION"))
00106 return AST_CAUSE_CONGESTION;
00107 if (!strcasecmp(cause, "ANSWER"))
00108 return AST_CAUSE_NORMAL;
00109 if (!strcasecmp(cause, "CANCEL"))
00110 return AST_CAUSE_NORMAL;
00111 if (!strcasecmp(cause, "NOANSWER"))
00112 return AST_CAUSE_NOANSWER;
00113 if (!strcasecmp(cause, "NOCHANAVAIL"))
00114 return AST_CAUSE_CONGESTION;
00115 ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause);
00116 return AST_CAUSE_NORMAL;
00117 }
00118
00119 static int osplookup_exec(struct ast_channel *chan, void *data)
00120 {
00121 int res=0;
00122 struct localuser *u;
00123 char *temp;
00124 struct ast_osp_result result;
00125 int priority_jump = 0;
00126 AST_DECLARE_APP_ARGS(args,
00127 AST_APP_ARG(extension);
00128 AST_APP_ARG(provider);
00129 AST_APP_ARG(options);
00130 );
00131
00132 if (ast_strlen_zero(data)) {
00133 ast_log(LOG_WARNING, "OSPLookup requires an argument OSPLookup(exten[|provider[|options]])\n");
00134 return -1;
00135 }
00136
00137 LOCAL_USER_ADD(u);
00138
00139 temp = ast_strdupa(data);
00140 if (!temp) {
00141 ast_log(LOG_ERROR, "Out of memory!\n");
00142 LOCAL_USER_REMOVE(u);
00143 return -1;
00144 }
00145
00146 AST_STANDARD_APP_ARGS(args, temp);
00147
00148 if (args.options) {
00149 if (strchr(args.options, 'j'))
00150 priority_jump = 1;
00151 }
00152
00153 ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", args.extension, args.provider ? args.provider : "<default>");
00154 if ((res = ast_osp_lookup(chan, args.provider, args.extension, chan->cid.cid_num, &result)) > 0) {
00155 char tmp[80];
00156 snprintf(tmp, sizeof(tmp), "%d", result.handle);
00157 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp);
00158 pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech);
00159 pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest);
00160 pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token);
00161 snprintf(tmp, sizeof(tmp), "%d", result.numresults);
00162 pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp);
00163 pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", "SUCCESS");
00164
00165 } else {
00166 if (!res) {
00167 ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", args.extension, args.provider ? args.provider : "<default>");
00168 pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", "FAILED");
00169 } else
00170 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, args.extension, args.provider ? args.provider : "<default>" );
00171 }
00172 if (!res) {
00173
00174 if (priority_jump || option_priority_jumping)
00175 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00176 } else if (res > 0)
00177 res = 0;
00178 LOCAL_USER_REMOVE(u);
00179 return res;
00180 }
00181
00182 static int ospnext_exec(struct ast_channel *chan, void *data)
00183 {
00184 int res=0;
00185 struct localuser *u;
00186 char *temp;
00187 int cause;
00188 struct ast_osp_result result;
00189 int priority_jump = 0;
00190 AST_DECLARE_APP_ARGS(args,
00191 AST_APP_ARG(cause);
00192 AST_APP_ARG(options);
00193 );
00194
00195 if (ast_strlen_zero(data)) {
00196 ast_log(LOG_WARNING, "OSPNext should have an argument (cause[|options])\n");
00197 return -1;
00198 }
00199
00200 LOCAL_USER_ADD(u);
00201
00202 temp = ast_strdupa(data);
00203 if (!temp) {
00204 ast_log(LOG_ERROR, "Out of memory!\n");
00205 LOCAL_USER_REMOVE(u);
00206 return -1;
00207 }
00208
00209 AST_STANDARD_APP_ARGS(args, temp);
00210
00211 if (args.options) {
00212 if (strchr(args.options, 'j'))
00213 priority_jump = 1;
00214 }
00215
00216 cause = str2cause(args.cause);
00217 temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
00218 result.handle = -1;
00219 if (!ast_strlen_zero(temp) && (sscanf(temp, "%d", &result.handle) == 1) && (result.handle > -1)) {
00220 temp = pbx_builtin_getvar_helper(chan, "OSPRESULTS");
00221 if (ast_strlen_zero(temp) || (sscanf(temp, "%d", &result.numresults) != 1)) {
00222 result.numresults = 0;
00223 }
00224 if ((res = ast_osp_next(&result, cause)) > 0) {
00225 char tmp[80];
00226 snprintf(tmp, sizeof(tmp), "%d", result.handle);
00227 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp);
00228 pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech);
00229 pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest);
00230 pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token);
00231 snprintf(tmp, sizeof(tmp), "%d", result.numresults);
00232 pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp);
00233 pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "SUCCESS");
00234 }
00235 } else {
00236 if (!res) {
00237 if (result.handle < 0)
00238 ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
00239 else
00240 ast_log(LOG_DEBUG, "No OSP handle specified\n");
00241 pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "FAILED");
00242 } else
00243 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
00244 }
00245 if (!res) {
00246
00247 if (priority_jump || option_priority_jumping)
00248 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00249 } else if (res > 0)
00250 res = 0;
00251 LOCAL_USER_REMOVE(u);
00252 return res;
00253 }
00254
00255 static int ospfinished_exec(struct ast_channel *chan, void *data)
00256 {
00257 int res=0;
00258 struct localuser *u;
00259 char *temp;
00260 int cause;
00261 time_t start=0, duration=0;
00262 struct ast_osp_result result;
00263 int priority_jump = 0;
00264 AST_DECLARE_APP_ARGS(args,
00265 AST_APP_ARG(status);
00266 AST_APP_ARG(options);
00267 );
00268
00269 if (ast_strlen_zero(data)) {
00270 ast_log(LOG_WARNING, "OSPFinish should have an argument (status[|options])\n");
00271 return -1;
00272 }
00273
00274 LOCAL_USER_ADD(u);
00275
00276 temp = ast_strdupa(data);
00277 if (!temp) {
00278 ast_log(LOG_ERROR, "Out of memory!\n");
00279 LOCAL_USER_REMOVE(u);
00280 return -1;
00281 }
00282
00283 AST_STANDARD_APP_ARGS(args, temp);
00284
00285 if (args.options) {
00286 if (strchr(args.options, 'j'))
00287 priority_jump = 1;
00288 }
00289
00290 if (chan->cdr) {
00291 start = chan->cdr->answer.tv_sec;
00292 if (start)
00293 duration = time(NULL) - start;
00294 else
00295 duration = 0;
00296 } else
00297 ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
00298
00299 cause = str2cause(args.status);
00300 temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
00301 result.handle = -1;
00302 if (!ast_strlen_zero(temp) && (sscanf(temp, "%d", &result.handle) == 1) && (result.handle > -1)) {
00303 if (!ast_osp_terminate(result.handle, cause, start, duration)) {
00304 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", "");
00305 pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "SUCCESS");
00306 res = 1;
00307 }
00308 } else {
00309 if (!res) {
00310 if (result.handle > -1)
00311 ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
00312 else
00313 ast_log(LOG_DEBUG, "No OSP handle specified\n");
00314 pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "FAILED");
00315 } else
00316 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
00317 }
00318 if (!res) {
00319
00320 if (priority_jump || option_priority_jumping)
00321 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00322 } else if (res > 0)
00323 res = 0;
00324 LOCAL_USER_REMOVE(u);
00325 return res;
00326 }
00327
00328
00329 int unload_module(void)
00330 {
00331 int res;
00332
00333 res = ast_unregister_application(app3);
00334 res |= ast_unregister_application(app2);
00335 res |= ast_unregister_application(app);
00336
00337 STANDARD_HANGUP_LOCALUSERS;
00338
00339 return res;
00340 }
00341
00342 int load_module(void)
00343 {
00344 int res;
00345
00346 res = ast_register_application(app, osplookup_exec, synopsis, descrip);
00347 res |= ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
00348 res |= ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
00349
00350 return res;
00351 }
00352
00353 int reload(void)
00354 {
00355 return 0;
00356 }
00357
00358
00359 char *description(void)
00360 {
00361 return tdesc;
00362 }
00363
00364 int usecount(void)
00365 {
00366 int res;
00367 STANDARD_USECOUNT(res);
00368 return res;
00369 }
00370
00371 char *key()
00372 {
00373 return ASTERISK_GPL_KEY;
00374 }
00375