func_realtime.c File Reference

REALTIME dialplan function. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"

Include dependency graph for func_realtime.c:

Go to the source code of this file.

Functions

static void __init_buf1 (void)
static void __init_buf2 (void)
static void __init_buf3 (void)
static void __reg_module (void)
static void __unreg_module (void)
static int function_realtime_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int function_realtime_readdestroy (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int function_realtime_store (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int function_realtime_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int function_realtime_writedestroy (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 Wrapper to execute REALTIME_DESTROY from a write operation. Allows execution even if live_dangerously is disabled.
static int load_module (void)
static int realtimefield_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Read/Write/Store/Destroy values from a RealTime repository" , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_threadstorage buf1 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf1 , .custom_init = NULL , }
static struct ast_threadstorage buf2 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf2 , .custom_init = NULL , }
static struct ast_threadstorage buf3 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf3 , .custom_init = NULL , }
static struct ast_custom_function realtime_destroy_function
static struct ast_custom_function realtime_function
static struct ast_custom_function realtime_store_function
static struct ast_custom_function realtimefield_function
static struct ast_custom_function realtimehash_function


Detailed Description

REALTIME dialplan function.

Author:
BJ Weschke <bweschke@btwtech.com>

Definition in file func_realtime.c.


Function Documentation

static void __init_buf1 ( void   )  [static]

Definition at line 180 of file func_realtime.c.

00185 {

static void __init_buf2 ( void   )  [static]

Definition at line 181 of file func_realtime.c.

00185 {

static void __init_buf3 ( void   )  [static]

Definition at line 182 of file func_realtime.c.

00185 {

static void __reg_module ( void   )  [static]

Definition at line 543 of file func_realtime.c.

static void __unreg_module ( void   )  [static]

Definition at line 543 of file func_realtime.c.

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

Definition at line 184 of file func_realtime.c.

References args, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_load_realtime_all(), ast_log, AST_STANDARD_APP_ARGS, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero, ast_variables_destroy(), LOG_WARNING, ast_variable::next, out, SENTINEL, value, and var.

00185 {
00186    struct ast_variable *var, *head;
00187    struct ast_str *out;
00188    size_t resultslen;
00189    int n;
00190    AST_DECLARE_APP_ARGS(args,
00191       AST_APP_ARG(family);
00192       AST_APP_ARG(fieldmatch);
00193       AST_APP_ARG(value);
00194       AST_APP_ARG(delim1);
00195       AST_APP_ARG(delim2);
00196    );
00197 
00198    if (ast_strlen_zero(data)) {
00199       ast_log(LOG_WARNING, "Syntax: REALTIME(family,fieldmatch[,matchvalue[,delim1[,delim2]]]) - missing argument!\n");
00200       return -1;
00201    }
00202 
00203    AST_STANDARD_APP_ARGS(args, data);
00204 
00205    if (!args.delim1)
00206       args.delim1 = ",";
00207    if (!args.delim2)
00208       args.delim2 = "=";
00209 
00210    if (chan)
00211       ast_autoservice_start(chan);
00212 
00213    head = ast_load_realtime_all(args.family, args.fieldmatch, args.value, SENTINEL);
00214 
00215    if (!head) {
00216       if (chan)
00217          ast_autoservice_stop(chan);
00218       return -1;
00219    }
00220 
00221    resultslen = 0;
00222    n = 0;
00223    for (var = head; var; n++, var = var->next)
00224       resultslen += strlen(var->name) + strlen(var->value);
00225    /* add space for delimiters and final '\0' */
00226    resultslen += n * (strlen(args.delim1) + strlen(args.delim2)) + 1;
00227 
00228    if (resultslen > len) {
00229       ast_log(LOG_WARNING, "Failed to fetch. Realtime data is too large: need %zu, have %zu.\n", resultslen, len);
00230       return -1;
00231    }
00232 
00233    /* len is going to be sensible, so we don't need to check for stack
00234     * overflows here. */
00235    out = ast_str_alloca(resultslen);
00236    for (var = head; var; var = var->next)
00237       ast_str_append(&out, 0, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
00238    ast_copy_string(buf, ast_str_buffer(out), len);
00239 
00240    ast_variables_destroy(head);
00241 
00242    if (chan)
00243       ast_autoservice_stop(chan);
00244 
00245    return 0;
00246 }

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

Definition at line 411 of file func_realtime.c.

References args, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_destroy_realtime(), ast_load_realtime_all(), ast_log, AST_STANDARD_APP_ARGS, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_strlen_zero, ast_variables_destroy(), LOG_WARNING, ast_variable::next, out, SENTINEL, value, and var.

Referenced by function_realtime_writedestroy().

00412 {
00413    struct ast_variable *var, *head;
00414    struct ast_str *out;
00415    size_t resultslen;
00416    int n;
00417    AST_DECLARE_APP_ARGS(args,
00418       AST_APP_ARG(family);
00419       AST_APP_ARG(fieldmatch);
00420       AST_APP_ARG(value);
00421       AST_APP_ARG(delim1);
00422       AST_APP_ARG(delim2);
00423    );
00424 
00425    if (ast_strlen_zero(data)) {
00426       ast_log(LOG_WARNING, "Syntax: REALTIME_DESTROY(family,fieldmatch[,matchvalue[,delim1[,delim2]]]) - missing argument!\n");
00427       return -1;
00428    }
00429 
00430    AST_STANDARD_APP_ARGS(args, data);
00431 
00432    if (!args.delim1)
00433       args.delim1 = ",";
00434    if (!args.delim2)
00435       args.delim2 = "=";
00436 
00437    if (chan)
00438       ast_autoservice_start(chan);
00439 
00440    head = ast_load_realtime_all(args.family, args.fieldmatch, args.value, SENTINEL);
00441 
00442    if (!head) {
00443       if (chan)
00444          ast_autoservice_stop(chan);
00445       return -1;
00446    }
00447 
00448    if (len > 0) {
00449       resultslen = 0;
00450       n = 0;
00451       for (var = head; var; n++, var = var->next) {
00452          resultslen += strlen(var->name) + strlen(var->value);
00453       }
00454       /* add space for delimiters and final '\0' */
00455       resultslen += n * (strlen(args.delim1) + strlen(args.delim2)) + 1;
00456 
00457       if (resultslen > len) {
00458          /* Unfortunately this does mean that we cannot destroy
00459           * the row anymore. But OTOH, we're not destroying
00460           * someones data without giving him the chance to look
00461           * at it. */
00462          ast_log(LOG_WARNING, "Failed to fetch/destroy. Realtime data is too large: need %zu, have %zu.\n", resultslen, len);
00463          return -1;
00464       }
00465 
00466       /* len is going to be sensible, so we don't need to check for
00467        * stack overflows here. */
00468       out = ast_str_alloca(resultslen);
00469       for (var = head; var; var = var->next) {
00470          ast_str_append(&out, 0, "%s%s%s%s", var->name, args.delim2, var->value, args.delim1);
00471       }
00472       ast_copy_string(buf, ast_str_buffer(out), len);
00473    }
00474 
00475    ast_destroy_realtime(args.family, args.fieldmatch, args.value, SENTINEL);
00476    ast_variables_destroy(head);
00477 
00478    if (chan)
00479       ast_autoservice_stop(chan);
00480 
00481    return 0;
00482 }

static int function_realtime_store ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Definition at line 363 of file func_realtime.c.

References a, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_store_realtime(), ast_strdupa, ast_strlen_zero, f, LOG_WARNING, pbx_builtin_setvar_helper(), and SENTINEL.

00364 {
00365    int res = 0;
00366    char storeid[32];
00367    char *valcopy;
00368    AST_DECLARE_APP_ARGS(a,
00369       AST_APP_ARG(family);
00370       AST_APP_ARG(f)[30]; /* fields */
00371    );
00372 
00373    AST_DECLARE_APP_ARGS(v,
00374       AST_APP_ARG(v)[30]; /* values */
00375    );
00376 
00377    if (ast_strlen_zero(data)) {
00378       ast_log(LOG_WARNING, "Syntax: REALTIME_STORE(family,field1,field2,...,field30) - missing argument!\n");
00379       return -1;
00380    }
00381 
00382    if (chan)
00383       ast_autoservice_start(chan);
00384 
00385    valcopy = ast_strdupa(value);
00386    AST_STANDARD_APP_ARGS(a, data);
00387    AST_STANDARD_APP_ARGS(v, valcopy);
00388 
00389    res = ast_store_realtime(a.family,
00390       a.f[0], v.v[0], a.f[1], v.v[1], a.f[2], v.v[2], a.f[3], v.v[3], a.f[4], v.v[4],
00391       a.f[5], v.v[5], a.f[6], v.v[6], a.f[7], v.v[7], a.f[8], v.v[8], a.f[9], v.v[9],
00392       a.f[10], v.v[10], a.f[11], v.v[11], a.f[12], v.v[12], a.f[13], v.v[13], a.f[14], v.v[14],
00393       a.f[15], v.v[15], a.f[16], v.v[16], a.f[17], v.v[17], a.f[18], v.v[18], a.f[19], v.v[19],
00394       a.f[20], v.v[20], a.f[21], v.v[21], a.f[22], v.v[22], a.f[23], v.v[23], a.f[24], v.v[24],
00395       a.f[25], v.v[25], a.f[26], v.v[26], a.f[27], v.v[27], a.f[28], v.v[28], a.f[29], v.v[29], SENTINEL
00396    );
00397 
00398    if (res < 0) {
00399       ast_log(LOG_WARNING, "Failed to store. Check the debug log for possible data repository related entries.\n");
00400    } else {
00401       snprintf(storeid, sizeof(storeid), "%d", res);
00402       pbx_builtin_setvar_helper(chan, "RTSTOREID", storeid);
00403    }
00404 
00405    if (chan)
00406       ast_autoservice_stop(chan);
00407 
00408    return 0;
00409 }

static int function_realtime_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Definition at line 248 of file func_realtime.c.

References args, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strlen_zero, ast_update_realtime(), LOG_WARNING, and SENTINEL.

00249 {
00250    int res = 0;
00251    AST_DECLARE_APP_ARGS(args,
00252       AST_APP_ARG(family);
00253       AST_APP_ARG(fieldmatch);
00254       AST_APP_ARG(value);
00255       AST_APP_ARG(field);
00256    );
00257 
00258    if (ast_strlen_zero(data)) {
00259       ast_log(LOG_WARNING, "Syntax: %s(family,fieldmatch,matchvalue,updatecol) - missing argument!\n", cmd);
00260       return -1;
00261    }
00262 
00263    AST_STANDARD_APP_ARGS(args, data);
00264 
00265    if (ast_strlen_zero(args.fieldmatch) || ast_strlen_zero(args.field)) {
00266       ast_log(LOG_WARNING, "Syntax: %s(family,fieldmatch,matchvalue,updatecol) - missing argument!\n", cmd);
00267       return -1;
00268    }
00269 
00270    if (chan) {
00271       ast_autoservice_start(chan);
00272    }
00273 
00274    res = ast_update_realtime(args.family, args.fieldmatch, args.value, args.field, (char *)value, SENTINEL);
00275 
00276    if (res < 0) {
00277       ast_log(LOG_WARNING, "Failed to update. Check the debug log for possible data repository related entries.\n");
00278    }
00279 
00280    if (chan) {
00281       ast_autoservice_stop(chan);
00282    }
00283 
00284    return res;
00285 }

static int function_realtime_writedestroy ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Wrapper to execute REALTIME_DESTROY from a write operation. Allows execution even if live_dangerously is disabled.

Definition at line 488 of file func_realtime.c.

References function_realtime_readdestroy(), and NULL.

00489 {
00490    return function_realtime_readdestroy(chan, cmd, data, NULL, 0);
00491 }

static int load_module ( void   )  [static]

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

Definition at line 287 of file func_realtime.c.

References args, AST_APP_ARG, ast_autoservice_start(), ast_autoservice_stop(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_load_realtime_all(), ast_log, AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set_escapecommas(), ast_str_thread_get(), ast_strlen_zero, ast_variables_destroy(), buf1, buf2, buf3, first, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), SENTINEL, ast_variable::value, value, and var.

00288 {
00289    struct ast_variable *var, *head;
00290    struct ast_str *escapebuf = ast_str_thread_get(&buf1, 16);
00291    struct ast_str *fields = ast_str_thread_get(&buf2, 16);
00292    struct ast_str *values = ast_str_thread_get(&buf3, 16);
00293    int first = 0;
00294    enum { rtfield, rthash } which;
00295    AST_DECLARE_APP_ARGS(args,
00296       AST_APP_ARG(family);
00297       AST_APP_ARG(fieldmatch);
00298       AST_APP_ARG(value);
00299       AST_APP_ARG(fieldname);
00300    );
00301 
00302    if (!strcmp(cmd, "REALTIME_FIELD")) {
00303       which = rtfield;
00304    } else {
00305       which = rthash;
00306    }
00307 
00308    if (ast_strlen_zero(data)) {
00309       ast_log(LOG_WARNING, "Syntax: %s(family,fieldmatch,matchvalue%s) - missing argument!\n", cmd, which == rtfield ? ",fieldname" : "");
00310       return -1;
00311    }
00312 
00313    AST_STANDARD_APP_ARGS(args, data);
00314 
00315    if ((which == rtfield && args.argc != 4) || (which == rthash && args.argc != 3)) {
00316       ast_log(LOG_WARNING, "Syntax: %s(family,fieldmatch,matchvalue%s) - missing argument!\n", cmd, which == rtfield ? ",fieldname" : "");
00317       return -1;
00318    }
00319 
00320    if (chan) {
00321       ast_autoservice_start(chan);
00322    }
00323 
00324    if (!(head = ast_load_realtime_all(args.family, args.fieldmatch, args.value, SENTINEL))) {
00325       if (chan) {
00326          ast_autoservice_stop(chan);
00327       }
00328       return -1;
00329    }
00330 
00331    ast_str_reset(fields);
00332    ast_str_reset(values);
00333 
00334    for (var = head; var; var = var->next) {
00335       if (which == rtfield) {
00336          ast_debug(1, "Comparing %s to %s\n", var->name, args.fieldname);
00337          if (!strcasecmp(var->name, args.fieldname)) {
00338             ast_debug(1, "Match! Value is %s\n", var->value);
00339             ast_copy_string(buf, var->value, len);
00340             break;
00341          }
00342       } else if (which == rthash) {
00343          ast_debug(1, "Setting hash key %s to value %s\n", var->name, var->value);
00344          ast_str_append(&fields, 0, "%s%s", first ? "" : ",", ast_str_set_escapecommas(&escapebuf, 0, var->name, INT_MAX));
00345          ast_str_append(&values, 0, "%s%s", first ? "" : ",", ast_str_set_escapecommas(&escapebuf, 0, var->value, INT_MAX));
00346          first = 0;
00347       }
00348    }
00349    ast_variables_destroy(head);
00350 
00351    if (which == rthash) {
00352       pbx_builtin_setvar_helper(chan, "~ODBCFIELDS~", ast_str_buffer(fields));
00353       ast_copy_string(buf, ast_str_buffer(values), len);
00354    }
00355 
00356    if (chan) {
00357       ast_autoservice_stop(chan);
00358    }
00359 
00360    return 0;
00361 }

static int unload_module ( void   )  [static]


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Read/Write/Store/Destroy values from a RealTime repository" , .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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, } [static]

Definition at line 543 of file func_realtime.c.

Definition at line 543 of file func_realtime.c.

struct ast_threadstorage buf1 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf1 , .custom_init = NULL , } [static]

struct ast_threadstorage buf2 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf2 , .custom_init = NULL , } [static]

struct ast_threadstorage buf3 = { .once = PTHREAD_ONCE_INIT , .key_init = __init_buf3 , .custom_init = NULL , } [static]

Definition at line 182 of file func_realtime.c.

Referenced by realtimefield_read().

Initial value:

 {
   .name = "REALTIME_DESTROY",
   .read = function_realtime_readdestroy,
   .write = function_realtime_writedestroy,
}

Definition at line 515 of file func_realtime.c.

Initial value:

 {
   .name = "REALTIME",
   .read = function_realtime_read,
   .write = function_realtime_write,
}

Definition at line 493 of file func_realtime.c.

Initial value:

 {
   .name = "REALTIME_STORE",
   .write = function_realtime_store,
}

Definition at line 510 of file func_realtime.c.

Initial value:

 {
   .name = "REALTIME_FIELD",
   .read = realtimefield_read,
   .write = function_realtime_write,
}

Definition at line 499 of file func_realtime.c.

Initial value:

 {
   .name = "REALTIME_HASH",
   .read = realtimefield_read,
}

Definition at line 505 of file func_realtime.c.


Generated on Thu Apr 16 06:31:23 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6