Tue Aug 20 16:35:04 2013

Asterisk developer's documentation


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"

Go to the source code of this file.

Functions

 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Read/Write/Store/Destroy values from a RealTime repository")
 AST_THREADSTORAGE (buf3)
 AST_THREADSTORAGE (buf2)
 AST_THREADSTORAGE (buf1)
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 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_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

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Read/Write/Store/Destroy values from a RealTime repository"   
)
AST_THREADSTORAGE ( buf3   ) 
AST_THREADSTORAGE ( buf2   ) 
AST_THREADSTORAGE ( buf1   ) 
static int function_realtime_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 178 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, SENTINEL, value, and var.

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

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

Definition at line 405 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, SENTINEL, value, and var.

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

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

Definition at line 357 of file func_realtime.c.

References 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.

00358 {
00359    int res = 0;
00360    char storeid[32];
00361    char *valcopy;
00362    AST_DECLARE_APP_ARGS(a,
00363       AST_APP_ARG(family);
00364       AST_APP_ARG(f)[30]; /* fields */
00365    );
00366 
00367    AST_DECLARE_APP_ARGS(v,
00368       AST_APP_ARG(v)[30]; /* values */
00369    );
00370 
00371    if (ast_strlen_zero(data)) {
00372       ast_log(LOG_WARNING, "Syntax: REALTIME_STORE(family,field1,field2,...,field30) - missing argument!\n");
00373       return -1;
00374    }
00375 
00376    if (chan)
00377       ast_autoservice_start(chan);
00378 
00379    valcopy = ast_strdupa(value);
00380    AST_STANDARD_APP_ARGS(a, data);
00381    AST_STANDARD_APP_ARGS(v, valcopy);
00382 
00383    res = ast_store_realtime(a.family,
00384       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],
00385       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],
00386       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],
00387       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],
00388       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],
00389       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
00390    );
00391 
00392    if (res < 0) {
00393       ast_log(LOG_WARNING, "Failed to store. Check the debug log for possible data repository related entries.\n");
00394    } else {
00395       snprintf(storeid, sizeof(storeid), "%d", res);
00396       pbx_builtin_setvar_helper(chan, "RTSTOREID", storeid);
00397    }
00398 
00399    if (chan)
00400       ast_autoservice_stop(chan);
00401 
00402    return 0;
00403 }

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

Definition at line 242 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.

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

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 281 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(), first, LOG_WARNING, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), SENTINEL, ast_variable::value, value, and var.

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

static int unload_module ( void   )  [static]

Variable Documentation

Initial value:
 {
   .name = "REALTIME_DESTROY",
   .read = function_realtime_readdestroy,
}

Definition at line 496 of file func_realtime.c.

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

Definition at line 474 of file func_realtime.c.

Initial value:
 {
   .name = "REALTIME_STORE",
   .write = function_realtime_store,
}

Definition at line 491 of file func_realtime.c.

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

Definition at line 480 of file func_realtime.c.

Initial value:
 {
   .name = "REALTIME_HASH",
   .read = realtimefield_read,
}

Definition at line 486 of file func_realtime.c.


Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1