Fri May 26 01:45:27 2006

Asterisk developer's documentation


app_osplookup.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Open Settlement Protocol Lookup
00022  * 
00023  * \ingroup applications
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       /* Look for a "busy" place */
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       /* Look for a "busy" place */
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       /* Look for a "busy" place */
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 

Generated on Fri May 26 01:45:27 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6