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 |
REALTIME dialplan function.
Definition in file func_realtime.c.
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] |
Definition at line 512 of file func_realtime.c.
References ast_custom_function_register.
00513 { 00514 int res = 0; 00515 res |= ast_custom_function_register(&realtime_function); 00516 res |= ast_custom_function_register(&realtime_store_function); 00517 res |= ast_custom_function_register(&realtime_destroy_function); 00518 res |= ast_custom_function_register(&realtimefield_function); 00519 res |= ast_custom_function_register(&realtimehash_function); 00520 return res; 00521 }
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] |
Definition at line 501 of file func_realtime.c.
References ast_custom_function_unregister().
00502 { 00503 int res = 0; 00504 res |= ast_custom_function_unregister(&realtime_function); 00505 res |= ast_custom_function_unregister(&realtime_store_function); 00506 res |= ast_custom_function_unregister(&realtime_destroy_function); 00507 res |= ast_custom_function_unregister(&realtimefield_function); 00508 res |= ast_custom_function_unregister(&realtimehash_function); 00509 return res; 00510 }
struct ast_custom_function realtime_destroy_function [static] |
{ .name = "REALTIME_DESTROY", .read = function_realtime_readdestroy, }
Definition at line 496 of file func_realtime.c.
struct ast_custom_function realtime_function [static] |
{ .name = "REALTIME", .read = function_realtime_read, .write = function_realtime_write, }
Definition at line 474 of file func_realtime.c.
struct ast_custom_function realtime_store_function [static] |
{ .name = "REALTIME_STORE", .write = function_realtime_store, }
Definition at line 491 of file func_realtime.c.
struct ast_custom_function realtimefield_function [static] |
{ .name = "REALTIME_FIELD", .read = realtimefield_read, .write = function_realtime_write, }
Definition at line 480 of file func_realtime.c.
struct ast_custom_function realtimehash_function [static] |
{ .name = "REALTIME_HASH", .read = realtimefield_read, }
Definition at line 486 of file func_realtime.c.