Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:48 2009

## 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: 211526 $")
    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, "%30d", &result.handle) != 1)) {
    00220       result.handle = -1;
    00221    }
    00222    temp = pbx_builtin_getvar_helper(chan, "OSPRESULTS");
    00223    if (ast_strlen_zero(temp) || (sscanf(temp, "%30d", &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, "%30d", &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