Fri Nov 12 12:02:17 2010

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"
Include dependency graph for func_dialgroup.c:

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 = "0901e4e500243c855563a2d78b0c03e4" , .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 304 of file func_dialgroup.c.

static void __unreg_module ( void   )  [static]

Definition at line 304 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 125 of file func_dialgroup.c.

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

Referenced by dialgroup_refreshdb().

00126 {
00127    struct ao2_iterator i;
00128    struct group *grhead = ao2_find(group_container, data, 0);
00129    struct group_entry *entry;
00130    size_t bufused = 0;
00131    int trunc_warning = 0;
00132    int res = 0;
00133 
00134    if (!grhead) {
00135       if (!ast_strlen_zero(cmd)) {
00136          ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data);
00137       }
00138       return -1;
00139    }
00140 
00141    buf[0] = '\0';
00142 
00143    i = ao2_iterator_init(grhead->entries, OBJ_POINTER);
00144    while ((entry = ao2_iterator_next(&i))) {
00145       int tmp = strlen(entry->name);
00146       /* Ensure that we copy only complete names, not partials */
00147       if (len - bufused > tmp + 2) {
00148          if (bufused != 0)
00149             buf[bufused++] = '&';
00150          ast_copy_string(buf + bufused, entry->name, len - bufused);
00151          bufused += tmp;
00152       } else if (trunc_warning++ == 0) {
00153          if (!ast_strlen_zero(cmd)) {
00154             ast_log(LOG_WARNING, "Dialgroup '%s' is too large.  Truncating list.\n", data);
00155          } else {
00156             res = 1;
00157             ao2_ref(entry, -1);
00158             break;
00159          }
00160       }
00161       ao2_ref(entry, -1);
00162    }
00163    ao2_iterator_destroy(&i);
00164 
00165    return res;
00166 }

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

Definition at line 168 of file func_dialgroup.c.

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

Referenced by dialgroup_write().

00169 {
00170    int len = 500, res = 0;
00171    char *buf = NULL;
00172    char *dialgroup = ast_strdupa(cdialgroup);
00173 
00174    do {
00175       len *= 2;
00176       buf = ast_realloc(buf, len);
00177 
00178       if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) {
00179          ast_free(buf);
00180          return -1;
00181       }
00182    } while (res == 1);
00183 
00184    if (ast_strlen_zero(buf)) {
00185       ast_db_del("dialgroup", cdialgroup);
00186    } else {
00187       ast_db_put("dialgroup", cdialgroup, buf);
00188    }
00189    ast_free(buf);
00190    return 0;
00191 }

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

Definition at line 193 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_strlen_zero(), dialgroup_refreshdb(), group::entries, entry_cmp_fn(), entry_hash_fn(), group_destroy(), LOG_ERROR, LOG_WARNING, group_entry::name, group::name, and OBJ_UNLINK.

Referenced by load_module().

00194 {
00195    struct group *grhead;
00196    struct group_entry *entry;
00197    int j, needrefresh = 1;
00198    AST_DECLARE_APP_ARGS(args,
00199       AST_APP_ARG(group);
00200       AST_APP_ARG(op);
00201    );
00202    AST_DECLARE_APP_ARGS(inter,
00203       AST_APP_ARG(faces)[100];
00204    );
00205    char *value = ast_strdupa(cvalue);
00206 
00207    AST_STANDARD_APP_ARGS(args, data);
00208    AST_NONSTANDARD_APP_ARGS(inter, value, '&');
00209 
00210    if (!(grhead = ao2_find(group_container, args.group, 0))) {
00211       /* Create group */
00212       grhead = ao2_alloc(sizeof(*grhead), group_destroy);
00213       if (!grhead)
00214          return -1;
00215       grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn);
00216       if (!grhead->entries) {
00217          ao2_ref(grhead, -1);
00218          return -1;
00219       }
00220       ast_copy_string(grhead->name, args.group, sizeof(grhead->name));
00221       ao2_link(group_container, grhead);
00222    }
00223 
00224    if (ast_strlen_zero(args.op)) {
00225       /* Wholesale replacement of the group */
00226       args.op = "add";
00227 
00228       /* Remove all existing */
00229       ao2_ref(grhead->entries, -1);
00230       if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) {
00231          ao2_unlink(group_container, grhead);
00232          ao2_ref(grhead, -1);
00233          return -1;
00234       }
00235    }
00236 
00237    if (strcasecmp(args.op, "add") == 0) {
00238       for (j = 0; j < inter.argc; j++) {
00239          if ((entry = ao2_alloc(sizeof(*entry), NULL))) {
00240             ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name));
00241             ao2_link(grhead->entries, entry);
00242             ao2_ref(entry, -1);
00243          } else {
00244             ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name);
00245          }
00246       }
00247    } else if (strncasecmp(args.op, "del", 3) == 0) {
00248       for (j = 0; j < inter.argc; j++) {
00249          if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) {
00250             ao2_ref(entry, -1);
00251          } else {
00252             ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name);
00253          }
00254       }
00255    } else {
00256       ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op);
00257       needrefresh = 0;
00258    }
00259    ao2_ref(grhead, -1);
00260 
00261    if (needrefresh) {
00262       dialgroup_refreshdb(chan, args.group);
00263    }
00264 
00265    return 0;
00266 }

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

Definition at line 115 of file func_dialgroup.c.

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

Referenced by dialgroup_write().

00116 {
00117    struct group_entry *e1 = obj1, *e2 = name2;
00118    char *name = name2;
00119    if (flags & OBJ_POINTER)
00120       return strcmp(e1->name, e2->name) ? 0 : CMP_MATCH | CMP_STOP;
00121    else
00122       return strcmp(e1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
00123 }

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

Definition at line 109 of file func_dialgroup.c.

References ast_str_hash(), and group_entry::name.

Referenced by dialgroup_write().

00110 {
00111    const struct group_entry *e = obj;
00112    return ast_str_hash(e->name);
00113 }

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

Definition at line 99 of file func_dialgroup.c.

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

Referenced by load_module().

00100 {
00101    struct group *g1 = obj1, *g2 = name2;
00102    char *name = name2;
00103    if (flags & OBJ_POINTER)
00104       return strcmp(g1->name, g2->name) ? 0 : CMP_MATCH | CMP_STOP;
00105    else
00106       return strcmp(g1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
00107 }

static void group_destroy ( void *  vgroup  )  [static]

Definition at line 87 of file func_dialgroup.c.

References ao2_ref, and group::entries.

Referenced by dialgroup_write().

00088 {
00089    struct group *group = vgroup;
00090    ao2_ref(group->entries, -1);
00091 }

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

Definition at line 93 of file func_dialgroup.c.

References ast_str_hash(), and group::name.

Referenced by load_module().

00094 {
00095    const struct group *g = obj;
00096    return ast_str_hash(g->name);
00097 }

static int load_module ( void   )  [static]

Definition at line 281 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_write(), group_cmp_fn(), group_hash_fn(), ast_db_entry::key, and ast_db_entry::next.

00282 {
00283    struct ast_db_entry *dbtree, *tmp;
00284    char groupname[AST_MAX_EXTENSION], *ptr;
00285 
00286    if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) {
00287       /* Refresh groups from astdb */
00288       if ((dbtree = ast_db_gettree("dialgroup", NULL))) {
00289          for (tmp = dbtree; tmp; tmp = tmp->next) {
00290             ast_copy_string(groupname, tmp->key, sizeof(groupname));
00291             if ((ptr = strrchr(groupname, '/'))) {
00292                ptr++;
00293                dialgroup_write(NULL, "", ptr, tmp->data);
00294             }
00295          }
00296          ast_db_freetree(dbtree);
00297       }
00298       return ast_custom_function_register(&dialgroup_function);
00299    } else {
00300       return AST_MODULE_LOAD_DECLINE;
00301    }
00302 }

static int unload_module ( void   )  [static]

Definition at line 274 of file func_dialgroup.c.

References ao2_ref, and ast_custom_function_unregister().

00275 {
00276    int res = ast_custom_function_unregister(&dialgroup_function);
00277    ao2_ref(group_container, -1);
00278    return res;
00279 }


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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 304 of file func_dialgroup.c.

Definition at line 304 of file func_dialgroup.c.

Initial value:
 {
   .name = "DIALGROUP",
   .read = dialgroup_read,
   .write = dialgroup_write,
}

Definition at line 268 of file func_dialgroup.c.

struct ao2_container* group_container = NULL [static]

Definition at line 76 of file func_dialgroup.c.


Generated by  doxygen 1.6.2