Fri Jul 24 00:41:45 2009

Asterisk developer's documentation


func_dialgroup.c File Reference

Dial group dialplan function. More...

#include "asterisk.h"
#include <sys/stat.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/astdb.h"

Go to the source code of this file.

Data Structures

struct  group
struct  group_entry

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int dialgroup_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int dialgroup_refreshdb (struct ast_channel *chan, const char *cdialgroup)
static int dialgroup_write (struct ast_channel *chan, const char *cmd, char *data, const char *cvalue)
static int entry_cmp_fn (void *obj1, void *name2, int flags)
static int entry_hash_fn (const void *obj, const int flags)
static int group_cmp_fn (void *obj1, void *name2, int flags)
static void group_destroy (void *vgroup)
static int group_hash_fn (const void *obj, const int flags)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Dialgroup dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function dialgroup_function
static struct ao2_containergroup_container = NULL


Detailed Description

Dial group dialplan function.

Author:
Tilghman Lesher <func_dialgroup__200709@the-tilghman.com>

Definition in file func_dialgroup.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 287 of file func_dialgroup.c.

static void __unreg_module ( void   )  [static]

Definition at line 287 of file func_dialgroup.c.

static int dialgroup_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 91 of file func_dialgroup.c.

References ao2_find, ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_copy_string(), ast_log(), ast_strlen_zero(), group::entries, group_container, LOG_WARNING, group_entry::name, and OBJ_POINTER.

Referenced by dialgroup_refreshdb().

00092 {
00093    struct ao2_iterator i;
00094    struct group *grhead = ao2_find(group_container, data, 0);
00095    struct group_entry *entry;
00096    size_t bufused = 0;
00097    int trunc_warning = 0;
00098    int res = 0;
00099 
00100    if (!grhead) {
00101       if (!ast_strlen_zero(cmd)) {
00102          ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data);
00103       }
00104       return -1;
00105    }
00106 
00107    buf[0] = '\0';
00108 
00109    i = ao2_iterator_init(grhead->entries, OBJ_POINTER);
00110    while ((entry = ao2_iterator_next(&i))) {
00111       int tmp = strlen(entry->name);
00112       /* Ensure that we copy only complete names, not partials */
00113       if (len - bufused > tmp + 2) {
00114          if (bufused != 0)
00115             buf[bufused++] = '&';
00116          ast_copy_string(buf + bufused, entry->name, len - bufused);
00117          bufused += tmp;
00118       } else if (trunc_warning++ == 0) {
00119          if (!ast_strlen_zero(cmd)) {
00120             ast_log(LOG_WARNING, "Dialgroup '%s' is too large.  Truncating list.\n", data);
00121          } else {
00122             res = 1;
00123             ao2_ref(entry, -1);
00124             break;
00125          }
00126       }
00127       ao2_ref(entry, -1);
00128    }
00129 
00130    return res;
00131 }

static int dialgroup_refreshdb ( struct ast_channel chan,
const char *  cdialgroup 
) [static]

Definition at line 133 of file func_dialgroup.c.

References ast_db_del(), ast_db_put(), ast_free, ast_realloc, ast_strdupa, ast_strlen_zero(), buf, chan, dialgroup_read(), and len().

00134 {
00135    int len = 500, res = 0;
00136    char *buf = NULL;
00137    char *dialgroup = ast_strdupa(cdialgroup);
00138 
00139    do {
00140       len *= 2;
00141       buf = ast_realloc(buf, len);
00142 
00143       if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) {
00144          ast_free(buf);
00145          return -1;
00146       }
00147    } while (res == 1);
00148 
00149    if (ast_strlen_zero(buf)) {
00150       ast_db_del("dialgroup", cdialgroup);
00151    } else {
00152       ast_db_put("dialgroup", cdialgroup, buf);
00153    }
00154    ast_free(buf);
00155    return 0;
00156 }

static int dialgroup_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  cvalue 
) [static]

Definition at line 158 of file func_dialgroup.c.

References ao2_alloc, ao2_container_alloc, ao2_find, ao2_link, ao2_ref, ao2_unlink, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), group::entries, entry_cmp_fn(), entry_hash_fn(), group_container, group_destroy(), LOG_WARNING, group::name, and OBJ_UNLINK.

Referenced by load_module().

00159 {
00160    struct group *grhead;
00161    struct group_entry *entry;
00162    int j, needrefresh = 1;
00163    AST_DECLARE_APP_ARGS(args,
00164       AST_APP_ARG(group);
00165       AST_APP_ARG(op);
00166    );
00167    AST_DECLARE_APP_ARGS(inter,
00168       AST_APP_ARG(faces)[100];
00169    );
00170    char *value = ast_strdupa(cvalue);
00171 
00172    AST_STANDARD_APP_ARGS(args, data);
00173    AST_NONSTANDARD_APP_ARGS(inter, value, '&');
00174 
00175    if (!(grhead = ao2_find(group_container, args.group, 0))) {
00176       /* Create group */
00177       grhead = ao2_alloc(sizeof(*grhead), group_destroy);
00178       if (!grhead)
00179          return -1;
00180       grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn);
00181       if (!grhead->entries) {
00182          ao2_ref(grhead, -1);
00183          return -1;
00184       }
00185       ast_copy_string(grhead->name, args.group, sizeof(grhead->name));
00186       ao2_link(group_container, grhead);
00187    }
00188 
00189    if (ast_strlen_zero(args.op)) {
00190       /* Wholesale replacement of the group */
00191       args.op = "add";
00192 
00193       /* Remove all existing */
00194       ao2_ref(grhead->entries, -1);
00195       if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) {
00196          ao2_unlink(group_container, grhead);
00197          ao2_ref(grhead, -1);
00198          return -1;
00199       }
00200    }
00201 
00202    if (strcasecmp(args.op, "add") == 0) {
00203       for (j = 0; j < inter.argc; j++) {
00204          if ((entry = ao2_alloc(sizeof(*entry), NULL))) {
00205             ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name));
00206             ao2_link(grhead->entries, entry);
00207             ao2_ref(entry, -1);
00208          } else {
00209             ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name);
00210          }
00211       }
00212    } else if (strncasecmp(args.op, "del", 3) == 0) {
00213       for (j = 0; j < inter.argc; j++) {
00214          if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) {
00215             ao2_ref(entry, -1);
00216          } else {
00217             ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name);
00218          }
00219       }
00220    } else {
00221       ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op);
00222       needrefresh = 0;
00223    }
00224    ao2_ref(grhead, -1);
00225 
00226    if (needrefresh) {
00227       dialgroup_refreshdb(chan, args.group);
00228    }
00229 
00230    return 0;
00231 }

static int entry_cmp_fn ( void *  obj1,
void *  name2,
int  flags 
) [static]

Definition at line 81 of file func_dialgroup.c.

References CMP_MATCH, CMP_STOP, group_entry::name, name, and OBJ_POINTER.

Referenced by dialgroup_write().

00082 {
00083    struct group_entry *e1 = obj1, *e2 = name2;
00084    char *name = name2;
00085    if (flags & OBJ_POINTER)
00086       return strcmp(e1->name, e2->name) ? 0 : CMP_MATCH | CMP_STOP;
00087    else
00088       return strcmp(e1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
00089 }

static int entry_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 75 of file func_dialgroup.c.

References ast_str_hash(), and group_entry::name.

Referenced by dialgroup_write().

00076 {
00077    const struct group_entry *e = obj;
00078    return ast_str_hash(e->name);
00079 }

static int group_cmp_fn ( void *  obj1,
void *  name2,
int  flags 
) [static]

Definition at line 65 of file func_dialgroup.c.

References CMP_MATCH, CMP_STOP, group::name, name, and OBJ_POINTER.

Referenced by load_module().

00066 {
00067    struct group *g1 = obj1, *g2 = name2;
00068    char *name = name2;
00069    if (flags & OBJ_POINTER)
00070       return strcmp(g1->name, g2->name) ? 0 : CMP_MATCH | CMP_STOP;
00071    else
00072       return strcmp(g1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
00073 }

static void group_destroy ( void *  vgroup  )  [static]

Definition at line 53 of file func_dialgroup.c.

References ao2_ref, and group.

Referenced by dialgroup_write().

00054 {
00055    struct group *group = vgroup;
00056    ao2_ref(group->entries, -1);
00057 }

static int group_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 59 of file func_dialgroup.c.

References ast_str_hash(), and group::name.

Referenced by load_module().

00060 {
00061    const struct group *g = obj;
00062    return ast_str_hash(g->name);
00063 }

static int load_module ( void   )  [static]

Definition at line 264 of file func_dialgroup.c.

References ao2_container_alloc, ast_copy_string(), ast_custom_function_register, ast_db_freetree(), ast_db_gettree(), AST_MAX_EXTENSION, AST_MODULE_LOAD_DECLINE, ast_db_entry::data, dialgroup_function, dialgroup_write(), group_cmp_fn(), group_container, group_hash_fn(), ast_db_entry::key, and ast_db_entry::next.

00265 {
00266    struct ast_db_entry *dbtree, *tmp;
00267    char groupname[AST_MAX_EXTENSION], *ptr;
00268 
00269    if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) {
00270       /* Refresh groups from astdb */
00271       if ((dbtree = ast_db_gettree("dialgroup", NULL))) {
00272          for (tmp = dbtree; tmp; tmp = tmp->next) {
00273             ast_copy_string(groupname, tmp->key, sizeof(groupname));
00274             if ((ptr = strrchr(groupname, '/'))) {
00275                ptr++;
00276                dialgroup_write(NULL, "", ptr, tmp->data);
00277             }
00278          }
00279          ast_db_freetree(dbtree);
00280       }
00281       return ast_custom_function_register(&dialgroup_function);
00282    } else {
00283       return AST_MODULE_LOAD_DECLINE;
00284    }
00285 }

static int unload_module ( void   )  [static]

Definition at line 257 of file func_dialgroup.c.

References ao2_ref, ast_custom_function_unregister(), dialgroup_function, and group_container.

00258 {
00259    int res = ast_custom_function_unregister(&dialgroup_function);
00260    ao2_ref(group_container, -1);
00261    return res;
00262 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Dialgroup dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 287 of file func_dialgroup.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 287 of file func_dialgroup.c.

struct ast_custom_function dialgroup_function [static]

Definition at line 233 of file func_dialgroup.c.

Referenced by load_module(), and unload_module().

struct ao2_container* group_container = NULL [static]

Definition at line 42 of file func_dialgroup.c.

Referenced by dialgroup_read(), dialgroup_write(), load_module(), and unload_module().


Generated on Fri Jul 24 00:41:45 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7