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: 27767 $")
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)) {
00220 result.handle = -1;
00221 }
00222 temp = pbx_builtin_getvar_helper(chan, "OSPRESULTS");
00223 if (ast_strlen_zero(temp) || (sscanf(temp, "%d", &result.numresults) != 1)) {
00224 result.numresults = 0;
00225 }
00226 if ((res = ast_osp_next(&result, cause)) > 0) {
00227 char tmp[80];
00228 snprintf(tmp, sizeof(tmp), "%d", result.handle);
00229 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp);
00230 pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech);
00231 pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest);
00232 pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token);
00233 snprintf(tmp, sizeof(tmp), "%d", result.numresults);
00234 pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp);
00235 pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "SUCCESS");
00236 } else {
00237 if (!res) {
00238 if (result.handle < 0)
00239 ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
00240 else
00241 ast_log(LOG_DEBUG, "No OSP handle specified\n");
00242 } else
00243 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
00244
00245 pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "FAILED");
00246 }
00247 if (!res) {
00248
00249 if (priority_jump || option_priority_jumping)
00250 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00251 } else if (res > 0)
00252 res = 0;
00253 LOCAL_USER_REMOVE(u);
00254 return res;
00255 }
00256
00257 static int ospfinished_exec(struct ast_channel *chan, void *data)
00258 {
00259 int res=0;
00260 struct localuser *u;
00261 char *temp;
00262 int cause;
00263 time_t start=0, duration=0;
00264 struct ast_osp_result result;
00265 int priority_jump = 0;
00266 AST_DECLARE_APP_ARGS(args,
00267 AST_APP_ARG(status);
00268 AST_APP_ARG(options);
00269 );
00270
00271 if (ast_strlen_zero(data)) {
00272 ast_log(LOG_WARNING, "OSPFinish should have an argument (status[|options])\n");
00273 return -1;
00274 }
00275
00276 LOCAL_USER_ADD(u);
00277
00278 temp = ast_strdupa(data);
00279 if (!temp) {
00280 ast_log(LOG_ERROR, "Out of memory!\n");
00281 LOCAL_USER_REMOVE(u);
00282 return -1;
00283 }
00284
00285 AST_STANDARD_APP_ARGS(args, temp);
00286
00287 if (args.options) {
00288 if (strchr(args.options, 'j'))
00289 priority_jump = 1;
00290 }
00291
00292 if (chan->cdr) {
00293 start = chan->cdr->answer.tv_sec;
00294 if (start)
00295 duration = time(NULL) - start;
00296 else
00297 duration = 0;
00298 } else
00299 ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
00300
00301 cause = str2cause(args.status);
00302 temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
00303 result.handle = -1;
00304 if (!ast_strlen_zero(temp) && (sscanf(temp, "%d", &result.handle) == 1) && (result.handle > -1)) {
00305 if (!ast_osp_terminate(result.handle, cause, start, duration)) {
00306 pbx_builtin_setvar_helper(chan, "_OSPHANDLE", "");
00307 pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "SUCCESS");
00308 res = 1;
00309 }
00310 } else {
00311 if (!res) {
00312 if (result.handle > -1)
00313 ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
00314 else
00315 ast_log(LOG_DEBUG, "No OSP handle specified\n");
00316 pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "FAILED");
00317 } else
00318 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
00319 }
00320 if (!res) {
00321
00322 if (priority_jump || option_priority_jumping)
00323 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
00324 } else if (res > 0)
00325 res = 0;
00326 LOCAL_USER_REMOVE(u);
00327 return res;
00328 }
00329
00330
00331 int unload_module(void)
00332 {
00333 int res;
00334
00335 res = ast_unregister_application(app3);
00336 res |= ast_unregister_application(app2);
00337 res |= ast_unregister_application(app);
00338
00339 STANDARD_HANGUP_LOCALUSERS;
00340
00341 return res;
00342 }
00343
00344 int load_module(void)
00345 {
00346 int res;
00347
00348 res = ast_register_application(app, osplookup_exec, synopsis, descrip);
00349 res |= ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
00350 res |= ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
00351
00352 return res;
00353 }
00354
00355 int reload(void)
00356 {
00357 return 0;
00358 }
00359
00360
00361 char *description(void)
00362 {
00363 return tdesc;
00364 }
00365
00366 int usecount(void)
00367 {
00368 int res;
00369 STANDARD_USECOUNT(res);
00370 return res;
00371 }
00372
00373 char *key()
00374 {
00375 return ASTERISK_GPL_KEY;
00376 }
00377