Thu May 24 14:21:05 2007

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: 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       /* 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)) {
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       /* Look for a "busy" place */
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       /* Look for a "busy" place */
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 

Generated on Thu May 24 14:21:05 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.7