Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:47 2009

## Asterisk developer's documentation

# app_enumlookup.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 Enumlookup - lookup entry in ENUM
    00022  *
    00023  * \ingroup applications
    00024  */
    00025
    00026 #include <stdlib.h>
    00027 #include <stdio.h>
    00028 #include <string.h>
    00029 #include <unistd.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/enum.h"
    00045 #include "asterisk/utils.h"
    00046 #include "asterisk/app.h"
    00047 #include "asterisk/options.h"
    00048
    00049 static char *tdesc = "ENUM Lookup";
    00050
    00051 static char *app = "EnumLookup";
    00052
    00053 static char *synopsis = "Lookup number in ENUM";
    00054
    00055 static char *descrip =
    00056 "  EnumLookup(exten[|option]):  Looks up an extension via ENUM and sets\n"
    00057 "the variable 'ENUM'. For VoIP URIs this variable will \n"
    00058 "look like 'TECHNOLOGY/URI' with the appropriate technology.\n"
    00059 "Currently, the enumservices SIP, H323, IAX, IAX2 and TEL are recognized. \n"
    00060 "\nReturns status in the ENUMSTATUS channel variable:\n"
    00061 "    ERROR  Failed to do a lookup\n"
    00062 "    <tech> Technology of the successful lookup: SIP, H323, IAX, IAX2 or TEL\n"
    00063 "    BADURI Got URI Asterisk does not understand.\n"
    00064 "  The option string may contain zero or the following character:\n"
    00065 "       'j' -- jump to +101 priority if the lookup isn't successful.\n"
    00066 "         and jump to +51 priority on a TEL entry.\n";
    00067
    00068 #define ENUM_CONFIG "enum.conf"
    00069
    00070 static char h323driver[80] = "";
    00071 #define H323DRIVERDEFAULT "H323"
    00072
    00073 STANDARD_LOCAL_USER;
    00074
    00075 LOCAL_USER_DECL;
    00076
    00077 /*--- enumlookup_exec: Look up number in ENUM and return result */
    00078 static int enumlookup_exec(struct ast_channel *chan, void *data)
    00079 {
    00080    int res=0,priority_jump=0;
    00081    char tech[80];
    00082    char dest[80];
    00083    char tmp[256];
    00084    char *c,*t = NULL;
    00085    static int dep_warning=0;
    00086    struct localuser *u;
    00087    char *parse;
    00088    AST_DECLARE_APP_ARGS(args,
    00089       AST_APP_ARG(d);
    00090       AST_APP_ARG(o);
    00091    );
    00092
    00093    if (ast_strlen_zero(data)) {
    00094       ast_log(LOG_WARNING, "EnumLookup requires an argument (extension)\n");
    00095       return -1;
    00096    }
    00097
    00098    if (!dep_warning) {
    00099       ast_log(LOG_WARNING, "The application EnumLookup is deprecated.  Please use the ENUMLOOKUP() function instead.\n");
    00100       dep_warning = 1;
    00101    }
    00102
    00103    LOCAL_USER_ADD(u);
    00104
    00105    parse = ast_strdupa(data);
    00106    if (!parse) {
    00107       ast_log(LOG_ERROR, "Out of memory!\n");
    00108       LOCAL_USER_REMOVE(u);
    00109       return -1;
    00110    }
    00111
    00112    AST_STANDARD_APP_ARGS(args, parse);
    00113
    00114    tech[0] = '\0';
    00115    dest[0] = '\0';
    00116
    00117    if (args.o) {
    00118       if (strchr(args.o, 'j'))
    00119          priority_jump = 1;
    00120    }
    00121
    00122    res = ast_get_enum(chan, args.d, dest, sizeof(dest), tech, sizeof(tech), NULL, NULL);
    00123
    00124    if (!res) { /* Failed to do a lookup */
    00125       if (priority_jump || option_priority_jumping) {
    00126          /* Look for a "busy" place */
    00127          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
    00128       }
    00129       pbx_builtin_setvar_helper(chan, "ENUMSTATUS", "ERROR");
    00130       LOCAL_USER_REMOVE(u);
    00131       return 0;
    00132    }
    00133    pbx_builtin_setvar_helper(chan, "ENUMSTATUS", tech);
    00134    /* Parse it out */
    00135    if (res > 0) {
    00136       if (!strcasecmp(tech, "SIP")) {
    00137          c = dest;
    00138          if (!strncmp(c, "sip:", 4))
    00139             c += 4;
    00140          snprintf(tmp, sizeof(tmp), "SIP/%s", c);
    00141          pbx_builtin_setvar_helper(chan, "ENUM", tmp);
    00142       } else if (!strcasecmp(tech, "h323")) {
    00143          c = dest;
    00144          if (!strncmp(c, "h323:", 5))
    00145             c += 5;
    00146          snprintf(tmp, sizeof(tmp), "%s/%s", h323driver, c);
    00147 /* do a s!;.*!! on the H323 URI */
    00148          t = strchr(c,';');
    00149                        if (t)
    00150             *t = 0;
    00151          pbx_builtin_setvar_helper(chan, "ENUM", tmp);
    00152       } else if (!strcasecmp(tech, "iax")) {
    00153          c = dest;
    00154          if (!strncmp(c, "iax:", 4))
    00155             c += 4;
    00156          snprintf(tmp, sizeof(tmp), "IAX/%s", c);
    00157          pbx_builtin_setvar_helper(chan, "ENUM", tmp);
    00158       } else if (!strcasecmp(tech, "iax2")) {
    00159          c = dest;
    00160          if (!strncmp(c, "iax2:", 5))
    00161             c += 5;
    00162          snprintf(tmp, sizeof(tmp), "IAX2/%s", c);
    00163          pbx_builtin_setvar_helper(chan, "ENUM", tmp);
    00164       } else if (!strcasecmp(tech, "tel")) {
    00165          c = dest;
    00166          if (!strncmp(c, "tel:", 4))
    00167             c += 4;
    00168
    00169          if (c[0] != '+') {
    00170             ast_log(LOG_NOTICE, "tel: uri must start with a \"+\" (got '%s')\n", c);
    00171             res = 0;
    00172          } else {
    00173 /* now copy over the number, skipping all non-digits and stop at ; or NULL */
    00174                                t = tmp;
    00175             while( *c && (*c != ';') && (t - tmp < (sizeof(tmp) - 1))) {
    00176                if (isdigit(*c))
    00177                   *t++ = *c;
    00178                c++;
    00179             }
    00180             *t = 0;
    00181             pbx_builtin_setvar_helper(chan, "ENUM", tmp);
    00182             ast_log(LOG_NOTICE, "tel: ENUM set to \"%s\"\n", tmp);
    00183             if (priority_jump || option_priority_jumping) {
    00184                if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 51))
    00185                   res = 0;
    00186             }
    00187          }
    00188       } else if (!ast_strlen_zero(tech)) {
    00189          ast_log(LOG_NOTICE, "Don't know how to handle technology '%s'\n", tech);
    00190          pbx_builtin_setvar_helper(chan, "ENUMSTATUS", "BADURI");
    00191          res = 0;
    00192       }
    00193    }
    00194
    00195    LOCAL_USER_REMOVE(u);
    00196
    00197    return 0;
    00198 }
    00199
    00200 /*--- load_config: Load enum.conf and find out how to handle H.323 */
    00201 static int load_config(void)
    00202 {
    00203    struct ast_config *cfg;
    00204    char *s;
    00205
    00206    cfg = ast_config_load(ENUM_CONFIG);
    00207    if (cfg) {
    00208       if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) {
    00209          strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1);
    00210       } else {
    00211          strncpy(h323driver, s, sizeof(h323driver) - 1);
    00212       }
    00213       ast_config_destroy(cfg);
    00214       return 0;
    00215    }
    00216    ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n");
    00217    return 0;
    00218 }
    00219
    00220
    00221 /*--- unload_module: Unload this application from PBX */
    00222 int unload_module(void)
    00223 {
    00224    int res;
    00225
    00226    res = ast_unregister_application(app);
    00227
    00228    STANDARD_HANGUP_LOCALUSERS;
    00229
    00230    return res;
    00231 }
    00232
    00233 /*--- load_module: Load this application into PBX */
    00234 int load_module(void)
    00235 {
    00236    int res;
    00237
    00238    res = ast_register_application(app, enumlookup_exec, synopsis, descrip);
    00239
    00240    if (!res)
    00241       res = load_config();
    00242
    00243    return res;
    00244 }
    00245
    00246 /*--- reload: Reload configuration file */
    00247 int reload(void)
    00248 {
    00249    return load_config();
    00250 }
    00251
    00252
    00253 /*--- description: Describe module */
    00254 char *description(void)
    00255 {
    00256    return tdesc;
    00257 }
    00258
    00259 int usecount(void)
    00260 {
    00261    int res;
    00262    STANDARD_USECOUNT(res);
    00263    return res;
    00264 }
    00265
    00266 char *key()
    00267 {
    00268    return ASTERISK_GPL_KEY;
    00269 }
    00270