Custom presence provider. More...
#include "asterisk.h"#include "asterisk/module.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/utils.h"#include "asterisk/linkedlists.h"#include "asterisk/presencestate.h"#include "asterisk/cli.h"#include "asterisk/astdb.h"#include "asterisk/app.h"
Go to the source code of this file.
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static enum ast_presence_state | custom_presence_callback (const char *data, char **subtype, char **message) |
| static char * | handle_cli_presencestate_change (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_presencestate_list (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static int | load_module (void) |
| static int | parse_data (char *data, enum ast_presence_state *state, char **subtype, char **message, char **options) |
| static int | presence_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | presence_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Gets or sets a presence state in the dialplan" , .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_DEVSTATE_PROVIDER, } |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static const char | astdb_family [] = "CustomPresence" |
| static struct ast_cli_entry | cli_funcpresencestate [] |
| static struct ast_custom_function | presence_function |
Custom presence provider.
Definition in file func_presencestate.c.
| static void __reg_module | ( | void | ) | [static] |
Definition at line 782 of file func_presencestate.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 782 of file func_presencestate.c.
| static enum ast_presence_state custom_presence_callback | ( | const char * | data, |
| char ** | subtype, | ||
| char ** | message | ||
| ) | [static] |
Definition at line 238 of file func_presencestate.c.
References ast_base64decode(), ast_db_get(), AST_PRESENCE_INVALID, ast_strdup, ast_strlen_zero(), parse_data(), and state.
Referenced by load_module().
{
char buf[1301] = "";
enum ast_presence_state state;
char *_options;
char *_message;
char *_subtype;
ast_db_get(astdb_family, data, buf, sizeof(buf));
if (parse_data(buf, &state, &_subtype, &_message, &_options)) {
return AST_PRESENCE_INVALID;
}
if ((strchr(_options, 'e'))) {
char tmp[1301];
if (ast_strlen_zero(_subtype)) {
*subtype = NULL;
} else {
memset(tmp, 0, sizeof(tmp));
ast_base64decode((unsigned char *) tmp, _subtype, sizeof(tmp) - 1);
*subtype = ast_strdup(tmp);
}
if (ast_strlen_zero(_message)) {
*message = NULL;
} else {
memset(tmp, 0, sizeof(tmp));
ast_base64decode((unsigned char *) tmp, _message, sizeof(tmp) - 1);
*message = ast_strdup(tmp);
}
} else {
*subtype = ast_strlen_zero(_subtype) ? NULL : ast_strdup(_subtype);
*message = ast_strlen_zero(_message) ? NULL : ast_strdup(_message);
}
return state;
}
| static char* handle_cli_presencestate_change | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 353 of file func_presencestate.c.
References ast_cli_args::argc, args, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_db_put(), AST_PRESENCE_NOT_SET, ast_presence_state_changed_literal(), ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), ast_cli_args::n, parse_data(), ast_cli_args::pos, state, ast_cli_entry::usage, and ast_cli_args::word.
{
size_t len;
const char *dev, *state, *full_dev;
enum ast_presence_state state_val;
char *message;
char *subtype;
char *options;
char *args;
switch (cmd) {
case CLI_INIT:
e->command = "presencestate change";
e->usage =
"Usage: presencestate change <entity> <state>[,<subtype>[,message[,options]]]\n"
" Change a custom presence to a new state.\n"
" The possible values for the state are:\n"
"NOT_SET | UNAVAILABLE | AVAILABLE | AWAY | XA | CHAT | DND\n"
"Optionally, a custom subtype and message may be provided, along with any options\n"
"accepted by func_presencestate. If the subtype or message provided contain spaces,\n"
"be sure to enclose the data in quotation marks (\"\")\n"
"\n"
"Examples:\n"
" presencestate change CustomPresence:mystate1 AWAY\n"
" presencestate change CustomPresence:mystate1 AVAILABLE\n"
" presencestate change CustomPresence:mystate1 \"Away,upstairs,eating lunch\"\n"
" \n";
return NULL;
case CLI_GENERATE:
{
static const char * const cmds[] = { "NOT_SET", "UNAVAILABLE", "AVAILABLE", "AWAY",
"XA", "CHAT", "DND", NULL };
if (a->pos == e->args + 1) {
return ast_cli_complete(a->word, cmds, a->n);
}
return NULL;
}
}
if (a->argc != e->args + 2) {
return CLI_SHOWUSAGE;
}
len = strlen("CustomPresence:");
full_dev = dev = a->argv[e->args];
state = a->argv[e->args + 1];
if (strncasecmp(dev, "CustomPresence:", len)) {
ast_cli(a->fd, "The presencestate command can only be used to set 'CustomPresence:' presence state!\n");
return CLI_FAILURE;
}
dev += len;
if (ast_strlen_zero(dev)) {
return CLI_SHOWUSAGE;
}
args = ast_strdupa(state);
if (parse_data(args, &state_val, &subtype, &message, &options)) {
return CLI_SHOWUSAGE;
}
if (state_val == AST_PRESENCE_NOT_SET) {
return CLI_SHOWUSAGE;
}
ast_cli(a->fd, "Changing %s to %s\n", dev, args);
ast_db_put(astdb_family, dev, state);
ast_presence_state_changed_literal(state_val, subtype, message, full_dev);
return CLI_SUCCESS;
}
| static char* handle_cli_presencestate_list | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Definition at line 282 of file func_presencestate.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_CLI_YESNO, ast_copy_string(), ast_db_freetree(), ast_db_gettree(), ast_log(), ast_presence_state2str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_db_entry::data, ast_cli_args::fd, ast_db_entry::key, LOG_WARNING, ast_db_entry::next, parse_data(), state, and ast_cli_entry::usage.
{
struct ast_db_entry *db_entry, *db_tree;
switch (cmd) {
case CLI_INIT:
e->command = "presencestate list";
e->usage =
"Usage: presencestate list\n"
" List all custom presence states that have been set by using\n"
" the PRESENCE_STATE dialplan function.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args) {
return CLI_SHOWUSAGE;
}
ast_cli(a->fd, "\n"
"---------------------------------------------------------------------\n"
"--- Custom Presence States ------------------------------------------\n"
"---------------------------------------------------------------------\n"
"---\n");
db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
if (!db_entry) {
ast_cli(a->fd, "No custom presence states defined\n");
return CLI_SUCCESS;
}
for (; db_entry; db_entry = db_entry->next) {
const char *object_name = strrchr(db_entry->key, '/') + 1;
char state_info[1301];
enum ast_presence_state state;
char *subtype;
char *message;
char *options;
ast_copy_string(state_info, db_entry->data, sizeof(state_info));
if (parse_data(state_info, &state, &subtype, &message, &options)) {
ast_log(LOG_WARNING, "Invalid CustomPresence entry %s encountered\n", db_entry->data);
continue;
}
if (object_name <= (const char *) 1) {
continue;
}
ast_cli(a->fd, "--- Name: 'CustomPresence:%s'\n"
" --- State: '%s'\n"
" --- Subtype: '%s'\n"
" --- Message: '%s'\n"
" --- Base64 Encoded: '%s'\n"
"---\n",
object_name,
ast_presence_state2str(state),
subtype,
message,
AST_CLI_YESNO(strchr(options, 'e')));
}
ast_db_freetree(db_tree);
db_tree = NULL;
ast_cli(a->fd,
"---------------------------------------------------------------------\n"
"---------------------------------------------------------------------\n"
"\n");
return CLI_SUCCESS;
}
| static int load_module | ( | void | ) | [static] |
Definition at line 738 of file func_presencestate.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_copy_string(), ast_custom_function_register, ast_db_freetree(), ast_db_gettree(), ast_log(), ast_presence_state_changed(), ast_presence_state_prov_add(), AST_TEST_REGISTER, custom_presence_callback(), ast_db_entry::data, ast_db_entry::key, LOG_WARNING, ast_db_entry::next, parse_data(), and state.
{
int res = 0;
struct ast_db_entry *db_entry, *db_tree;
/* Populate the presence state cache on the system with all of the currently
* known custom presence states. */
db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
for (; db_entry; db_entry = db_entry->next) {
const char *dev_name = strrchr(db_entry->key, '/') + 1;
char state_info[1301];
enum ast_presence_state state;
char *message;
char *subtype;
char *options;
if (dev_name <= (const char *) 1) {
continue;
}
ast_copy_string(state_info, db_entry->data, sizeof(state_info));
if (parse_data(state_info, &state, &subtype, &message, &options)) {
ast_log(LOG_WARNING, "Invalid CustomPresence entry %s encountered\n", db_entry->data);
continue;
}
ast_presence_state_changed(state, subtype, message, "CustomPresence:%s", dev_name);
}
ast_db_freetree(db_tree);
db_tree = NULL;
res |= ast_custom_function_register(&presence_function);
res |= ast_presence_state_prov_add("CustomPresence", custom_presence_callback);
res |= ast_cli_register_multiple(cli_funcpresencestate, ARRAY_LEN(cli_funcpresencestate));
#ifdef TEST_FRAMEWORK
AST_TEST_REGISTER(test_valid_parse_data);
AST_TEST_REGISTER(test_invalid_parse_data);
AST_TEST_REGISTER(test_presence_state_change);
#endif
return res;
}
| static int parse_data | ( | char * | data, |
| enum ast_presence_state * | state, | ||
| char ** | subtype, | ||
| char ** | message, | ||
| char ** | options | ||
| ) | [static] |
Definition at line 163 of file func_presencestate.c.
References ast_log(), AST_PRESENCE_INVALID, ast_presence_state_val(), ast_strlen_zero(), LOG_NOTICE, and LOG_WARNING.
Referenced by custom_presence_callback(), handle_cli_presencestate_change(), handle_cli_presencestate_list(), load_module(), and presence_write().
{
char *state_str;
/* data syntax is state,subtype,message,options */
*subtype = "";
*message = "";
*options = "";
state_str = strsep(&data, ",");
if (ast_strlen_zero(state_str)) {
return -1; /* state is required */
}
*state = ast_presence_state_val(state_str);
/* not a valid state */
if (*state == AST_PRESENCE_INVALID) {
ast_log(LOG_WARNING, "Unknown presence state value %s\n", state_str);
return -1;
}
if (!(*subtype = strsep(&data,","))) {
*subtype = "";
return 0;
}
if (!(*message = strsep(&data, ","))) {
*message = "";
return 0;
}
if (!(*options = strsep(&data, ","))) {
*options = "";
return 0;
}
if (!ast_strlen_zero(*options) && !(strchr(*options, 'e'))) {
ast_log(LOG_NOTICE, "Invalid options '%s'\n", *options);
return -1;
}
return 0;
}
| static int presence_read | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
Definition at line 103 of file func_presencestate.c.
References args, AST_APP_ARG, ast_base64encode(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_free, ast_log(), AST_PRESENCE_INVALID, ast_presence_state2str(), ast_presence_state_nocache(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), LOG_WARNING, parse(), and state.
{
int state;
char *message = NULL;
char *subtype = NULL;
char *parse;
int base64encode = 0;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(provider);
AST_APP_ARG(field);
AST_APP_ARG(options);
);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "PRESENCE_STATE reading requires an argument \n");
return -1;
}
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
if (ast_strlen_zero(args.provider) || ast_strlen_zero(args.field)) {
ast_log(LOG_WARNING, "PRESENCE_STATE reading requires both presence provider and presence field arguments. \n");
return -1;
}
state = ast_presence_state_nocache(args.provider, &subtype, &message);
if (state == AST_PRESENCE_INVALID) {
ast_log(LOG_WARNING, "PRESENCE_STATE unknown \n");
return -1;
}
if (!(ast_strlen_zero(args.options)) && (strchr(args.options, 'e'))) {
base64encode = 1;
}
if (!ast_strlen_zero(subtype) && !strcasecmp(args.field, "subtype")) {
if (base64encode) {
ast_base64encode(buf, (unsigned char *) subtype, strlen(subtype), len);
} else {
ast_copy_string(buf, subtype, len);
}
} else if (!ast_strlen_zero(message) && !strcasecmp(args.field, "message")) {
if (base64encode) {
ast_base64encode(buf, (unsigned char *) message, strlen(message), len);
} else {
ast_copy_string(buf, message, len);
}
} else if (!strcasecmp(args.field, "value")) {
ast_copy_string(buf, ast_presence_state2str(state), len);
}
ast_free(message);
ast_free(subtype);
return 0;
}
| static int presence_write | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| const char * | value | ||
| ) | [static] |
Definition at line 208 of file func_presencestate.c.
References args, ast_db_put(), ast_log(), ast_presence_state_changed_literal(), ast_strlen_zero(), len(), LOG_WARNING, parse_data(), and state.
{
size_t len = strlen("CustomPresence:");
char *tmp = data;
char *args = ast_strdupa(value);
enum ast_presence_state state;
char *options, *message, *subtype;
if (strncasecmp(data, "CustomPresence:", len)) {
ast_log(LOG_WARNING, "The PRESENCE_STATE function can only set CustomPresence: presence providers.\n");
return -1;
}
data += len;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "PRESENCE_STATE function called with no custom device name!\n");
return -1;
}
if (parse_data(args, &state, &subtype, &message, &options)) {
ast_log(LOG_WARNING, "Invalid arguments to PRESENCE_STATE\n");
return -1;
}
ast_db_put(astdb_family, data, value);
ast_presence_state_changed_literal(state, subtype, message, tmp);
return 0;
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 723 of file func_presencestate.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_presence_state_prov_del(), and AST_TEST_UNREGISTER.
{
int res = 0;
res |= ast_custom_function_unregister(&presence_function);
res |= ast_presence_state_prov_del("CustomPresence");
res |= ast_cli_unregister_multiple(cli_funcpresencestate, ARRAY_LEN(cli_funcpresencestate));
#ifdef TEST_FRAMEWORK
AST_TEST_UNREGISTER(test_valid_parse_data);
AST_TEST_UNREGISTER(test_invalid_parse_data);
AST_TEST_UNREGISTER(test_presence_state_change);
#endif
return res;
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Gets or sets a presence state in the dialplan" , .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_DEVSTATE_PROVIDER, } [static] |
Definition at line 782 of file func_presencestate.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 782 of file func_presencestate.c.
const char astdb_family[] = "CustomPresence" [static] |
Definition at line 101 of file func_presencestate.c.
struct ast_cli_entry cli_funcpresencestate[] [static] |
{
AST_CLI_DEFINE(handle_cli_presencestate_list, "List currently know custom presence states"),
AST_CLI_DEFINE(handle_cli_presencestate_change, "Change a custom presence state"),
}
Definition at line 430 of file func_presencestate.c.
struct ast_custom_function presence_function [static] |
{
.name = "PRESENCE_STATE",
.read = presence_read,
.write = presence_write,
}
Definition at line 276 of file func_presencestate.c.