Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
func_presencestate.c File Reference

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"
#include "asterisk/test.h"
#include "asterisk/sem.h"
Include dependency graph for func_presencestate.c:

Go to the source code of this file.

Data Structures

struct  test_cb_data
 
struct  test_string
 

Macros

#define PRES_MESSAGE   "Quarterly financial meeting"
 
#define PRES_STATE   "away"
 
#define PRES_SUBTYPE   "down the hall"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_valid_parse_data)
 
 AST_TEST_DEFINE (test_invalid_parse_data)
 
 AST_TEST_DEFINE (test_presence_state_change)
 
 AST_TEST_DEFINE (test_presence_state_base64_encode)
 
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 enum ast_test_result_state presence_change_common (struct ast_test *test, const char *state, const char *subtype, const char *message, const char *options, char *out_state, size_t out_state_size, char *out_subtype, size_t out_subtype_size, char *out_message, size_t out_message_size)
 
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 void test_cb (void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
 
static struct test_cb_datatest_cb_data_alloc (void)
 
static void test_cb_data_destroy (struct test_cb_data *cb_data)
 
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const char astdb_family [] = "CustomPresence"
 
static struct ast_cli_entry cli_funcpresencestate []
 
static struct ast_custom_function presence_function
 

Detailed Description

Custom presence provider.

Definition in file func_presencestate.c.

Macro Definition Documentation

◆ PRES_MESSAGE

#define PRES_MESSAGE   "Quarterly financial meeting"

Definition at line 662 of file func_presencestate.c.

Referenced by AST_TEST_DEFINE().

◆ PRES_STATE

#define PRES_STATE   "away"

Definition at line 660 of file func_presencestate.c.

Referenced by AST_TEST_DEFINE().

◆ PRES_SUBTYPE

#define PRES_SUBTYPE   "down the hall"

Definition at line 661 of file func_presencestate.c.

Referenced by AST_TEST_DEFINE().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 884 of file func_presencestate.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 884 of file func_presencestate.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 884 of file func_presencestate.c.

◆ AST_TEST_DEFINE() [1/4]

AST_TEST_DEFINE ( test_valid_parse_data  )

Definition at line 460 of file func_presencestate.c.

References ARRAY_LEN, ast_free, AST_PRESENCE_AVAILABLE, AST_PRESENCE_AWAY, AST_PRESENCE_CHAT, AST_PRESENCE_DND, AST_PRESENCE_NOT_SET, AST_PRESENCE_UNAVAILABLE, AST_PRESENCE_XA, ast_strdup, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), test_string::message, test_string::options, test_string::outputs, parse_data(), test_string::parse_string, state, test_string::subtype, TEST_EXECUTE, and TEST_INIT.

461 {
462  int i;
464  char *subtype;
465  char *message;
466  char *options;
468 
469  struct test_string tests [] = {
470  { "away",
472  "",
473  "",
474  ""
475  }
476  },
477  { "not_set",
479  "",
480  "",
481  ""
482  }
483  },
484  { "unavailable",
486  "",
487  "",
488  ""
489  }
490  },
491  { "available",
493  "",
494  "",
495  ""
496  }
497  },
498  { "xa",
499  { AST_PRESENCE_XA,
500  "",
501  "",
502  ""
503  }
504  },
505  { "chat",
507  "",
508  "",
509  ""
510  }
511  },
512  { "dnd",
514  "",
515  "",
516  ""
517  }
518  },
519  { "away,down the hall",
521  "down the hall",
522  "",
523  ""
524  }
525  },
526  { "away,down the hall,Quarterly financial meeting",
528  "down the hall",
529  "Quarterly financial meeting",
530  ""
531  }
532  },
533  { "away,,Quarterly financial meeting",
535  "",
536  "Quarterly financial meeting",
537  ""
538  }
539  },
540  { "away,,,e",
542  "",
543  "",
544  "e",
545  }
546  },
547  { "away,down the hall,,e",
549  "down the hall",
550  "",
551  "e"
552  }
553  },
554  { "away,down the hall,Quarterly financial meeting,e",
556  "down the hall",
557  "Quarterly financial meeting",
558  "e"
559  }
560  },
561  { "away,,Quarterly financial meeting,e",
563  "",
564  "Quarterly financial meeting",
565  "e"
566  }
567  }
568  };
569 
570  switch (cmd) {
571  case TEST_INIT:
572  info->name = "parse_valid_presence_data";
573  info->category = "/funcs/func_presence/";
574  info->summary = "PRESENCESTATE parsing test";
575  info->description =
576  "Ensure that parsing function accepts proper values, and gives proper outputs";
577  return AST_TEST_NOT_RUN;
578  case TEST_EXECUTE:
579  break;
580  }
581 
582  for (i = 0; i < ARRAY_LEN(tests); ++i) {
583  int parse_result;
584  char *parse_string = ast_strdup(tests[i].parse_string);
585  if (!parse_string) {
586  res = AST_TEST_FAIL;
587  break;
588  }
589  parse_result = parse_data(parse_string, &state, &subtype, &message, &options);
590  if (parse_result == -1) {
591  res = AST_TEST_FAIL;
592  ast_free(parse_string);
593  break;
594  }
595  if (tests[i].outputs.value != state ||
596  strcmp(tests[i].outputs.subtype, subtype) ||
597  strcmp(tests[i].outputs.message, message) ||
598  strcmp(tests[i].outputs.options, options)) {
599  res = AST_TEST_FAIL;
600  ast_free(parse_string);
601  break;
602  }
603  ast_free(parse_string);
604  }
605 
606  return res;
607 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
ast_presence_state
Definition: presencestate.h:26
def info(msg)
struct test_string::@215 outputs
#define ast_free(a)
Definition: astmm.h:182
Definition: test.c:104
static struct test_options options
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [2/4]

AST_TEST_DEFINE ( test_invalid_parse_data  )

Definition at line 609 of file func_presencestate.c.

References ARRAY_LEN, ast_free, ast_log, ast_strdup, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), LOG_WARNING, test_string::message, test_string::options, parse_data(), test_string::parse_string, state, test_string::subtype, TEST_EXECUTE, and TEST_INIT.

610 {
611  int i;
613  char *subtype;
614  char *message;
615  char *options;
617 
618  char *tests[] = {
619  "",
620  "bored",
621  "away,,,i",
622  /* XXX The following actually is parsed correctly. Should that
623  * be changed?
624  * "away,,,,e",
625  */
626  };
627 
628  switch (cmd) {
629  case TEST_INIT:
630  info->name = "parse_invalid_presence_data";
631  info->category = "/funcs/func_presence/";
632  info->summary = "PRESENCESTATE parsing test";
633  info->description =
634  "Ensure that parsing function rejects improper values";
635  return AST_TEST_NOT_RUN;
636  case TEST_EXECUTE:
637  break;
638  }
639 
640  for (i = 0; i < ARRAY_LEN(tests); ++i) {
641  int parse_result;
642  char *parse_string = ast_strdup(tests[i]);
643  if (!parse_string) {
644  res = AST_TEST_FAIL;
645  break;
646  }
647  parse_result = parse_data(parse_string, &state, &subtype, &message, &options);
648  if (parse_result == 0) {
649  ast_log(LOG_WARNING, "Invalid string parsing failed on %s\n", tests[i]);
650  res = AST_TEST_FAIL;
651  ast_free(parse_string);
652  break;
653  }
654  ast_free(parse_string);
655  }
656 
657  return res;
658 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
#define LOG_WARNING
Definition: logger.h:274
const char * subtype
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define ast_log
Definition: astobj2.c:42
ast_presence_state
Definition: presencestate.h:26
def info(msg)
#define ast_free(a)
Definition: astmm.h:182
const char * message
Definition: test.c:104
static struct test_options options
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [3/4]

AST_TEST_DEFINE ( test_presence_state_change  )

Definition at line 742 of file func_presencestate.c.

References AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, PRES_MESSAGE, PRES_STATE, PRES_SUBTYPE, presence_change_common(), TEST_EXECUTE, and TEST_INIT.

743 {
744  char out_state[32];
745  char out_subtype[32];
746  char out_message[32];
747 
748  switch (cmd) {
749  case TEST_INIT:
750  info->name = "test_presence_state_change";
751  info->category = "/funcs/func_presence/";
752  info->summary = "presence state change subscription";
753  info->description =
754  "Ensure that presence state changes are communicated to subscribers";
755  return AST_TEST_NOT_RUN;
756  case TEST_EXECUTE:
757  break;
758  }
759 
761  out_state, sizeof(out_state),
762  out_subtype, sizeof(out_subtype),
763  out_message, sizeof(out_message)) == AST_TEST_FAIL) {
764  return AST_TEST_FAIL;
765  }
766 
767  if (strcmp(out_state, PRES_STATE) ||
768  strcmp(out_subtype, PRES_SUBTYPE) ||
769  strcmp(out_message, PRES_MESSAGE)) {
770  ast_test_status_update(test, "Unexpected presence values, %s != %s, %s != %s, or %s != %s\n",
771  PRES_STATE, out_state,
772  PRES_SUBTYPE, out_subtype,
773  PRES_MESSAGE, out_message);
774  return AST_TEST_FAIL;
775  }
776 
777  return AST_TEST_PASS;
778 }
#define PRES_MESSAGE
#define NULL
Definition: resample.c:96
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static enum ast_test_result_state presence_change_common(struct ast_test *test, const char *state, const char *subtype, const char *message, const char *options, char *out_state, size_t out_state_size, char *out_subtype, size_t out_subtype_size, char *out_message, size_t out_message_size)
def info(msg)
#define PRES_STATE
#define PRES_SUBTYPE

◆ AST_TEST_DEFINE() [4/4]

AST_TEST_DEFINE ( test_presence_state_base64_encode  )

Definition at line 780 of file func_presencestate.c.

References ast_base64encode(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), PRES_MESSAGE, PRES_STATE, PRES_SUBTYPE, presence_change_common(), TEST_EXECUTE, and TEST_INIT.

781 {
782  char out_state[32];
783  char out_subtype[32];
784  char out_message[32];
785  char encoded_subtype[64];
786  char encoded_message[64];
787 
788  switch (cmd) {
789  case TEST_INIT:
790  info->name = "test_presence_state_base64_encode";
791  info->category = "/funcs/func_presence/";
792  info->summary = "presence state base64 encoding";
793  info->description =
794  "Ensure that base64-encoded presence state is stored base64-encoded but\n"
795  "is presented to consumers decoded.";
796  return AST_TEST_NOT_RUN;
797  case TEST_EXECUTE:
798  break;
799  }
800 
801  ast_base64encode(encoded_subtype, (unsigned char *) PRES_SUBTYPE, strlen(PRES_SUBTYPE), sizeof(encoded_subtype) - 1);
802  ast_base64encode(encoded_message, (unsigned char *) PRES_MESSAGE, strlen(PRES_MESSAGE), sizeof(encoded_message) - 1);
803 
804  if (presence_change_common(test, PRES_STATE, encoded_subtype, encoded_message, "e",
805  out_state, sizeof(out_state),
806  out_subtype, sizeof(out_subtype),
807  out_message, sizeof(out_message)) == AST_TEST_FAIL) {
808  return AST_TEST_FAIL;
809  }
810 
811  if (strcmp(out_state, PRES_STATE) ||
812  strcmp(out_subtype, PRES_SUBTYPE) ||
813  strcmp(out_message, PRES_MESSAGE)) {
814  ast_test_status_update(test, "Unexpected presence values, %s != %s, %s != %s, or %s != %s\n",
815  PRES_STATE, out_state,
816  PRES_SUBTYPE, out_subtype,
817  PRES_MESSAGE, out_message);
818  return AST_TEST_FAIL;
819  }
820 
821  return AST_TEST_PASS;
822 }
#define PRES_MESSAGE
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static enum ast_test_result_state presence_change_common(struct ast_test *test, const char *state, const char *subtype, const char *message, const char *options, char *out_state, size_t out_state_size, char *out_subtype, size_t out_subtype_size, char *out_message, size_t out_message_size)
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: main/utils.c:404
def info(msg)
#define PRES_STATE
#define PRES_SUBTYPE

◆ custom_presence_callback()

static enum ast_presence_state custom_presence_callback ( const char *  data,
char **  subtype,
char **  message 
)
static

Definition at line 248 of file func_presencestate.c.

References ast_base64decode(), ast_db_get(), AST_PRESENCE_INVALID, AST_PRESENCE_NOT_SET, ast_strdup, ast_strlen_zero, astdb_family, buf, NULL, parse_data(), state, and tmp().

Referenced by load_module().

249 {
250  char buf[1301] = "";
252  char *_options;
253  char *_message;
254  char *_subtype;
255 
256  if (ast_db_get(astdb_family, data, buf, sizeof(buf))) {
257  return AST_PRESENCE_NOT_SET;
258  }
259 
260  if (parse_data(buf, &state, &_subtype, &_message, &_options)) {
261  return AST_PRESENCE_INVALID;
262  }
263 
264  if ((strchr(_options, 'e'))) {
265  char tmp[1301];
266 
267  if (ast_strlen_zero(_subtype)) {
268  *subtype = NULL;
269  } else {
270  memset(tmp, 0, sizeof(tmp));
271  ast_base64decode((unsigned char *) tmp, _subtype, sizeof(tmp) - 1);
272  *subtype = ast_strdup(tmp);
273  }
274 
275  if (ast_strlen_zero(_message)) {
276  *message = NULL;
277  } else {
278  memset(tmp, 0, sizeof(tmp));
279  ast_base64decode((unsigned char *) tmp, _message, sizeof(tmp) - 1);
280  *message = ast_strdup(tmp);
281  }
282  } else {
283  *subtype = ast_strlen_zero(_subtype) ? NULL : ast_strdup(_subtype);
284  *message = ast_strlen_zero(_message) ? NULL : ast_strdup(_message);
285  }
286  return state;
287 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static const char astdb_family[]
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const char * subtype
static int tmp()
Definition: bt_open.c:389
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: main/utils.c:294
ast_presence_state
Definition: presencestate.h:26
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Definition: main/db.c:412

◆ handle_cli_presencestate_change()

static char* handle_cli_presencestate_change ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 366 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_strdupa, ast_strlen_zero, astdb_family, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), ast_cli_args::n, NULL, options, parse_data(), ast_cli_args::pos, state, ast_cli_entry::usage, and ast_cli_args::word.

367 {
368  size_t len;
369  const char *dev, *state, *full_dev;
370  enum ast_presence_state state_val;
371  char *message;
372  char *subtype;
373  char *options;
374  char *args;
375 
376  switch (cmd) {
377  case CLI_INIT:
378  e->command = "presencestate change";
379  e->usage =
380  "Usage: presencestate change <entity> <state>[,<subtype>[,message[,options]]]\n"
381  " Change a custom presence to a new state.\n"
382  " The possible values for the state are:\n"
383  "NOT_SET | UNAVAILABLE | AVAILABLE | AWAY | XA | CHAT | DND\n"
384  "Optionally, a custom subtype and message may be provided, along with any options\n"
385  "accepted by func_presencestate. If the subtype or message provided contain spaces,\n"
386  "be sure to enclose the data in quotation marks (\"\")\n"
387  "\n"
388  "Examples:\n"
389  " presencestate change CustomPresence:mystate1 AWAY\n"
390  " presencestate change CustomPresence:mystate1 AVAILABLE\n"
391  " presencestate change CustomPresence:mystate1 \"Away,upstairs,eating lunch\"\n"
392  " \n";
393  return NULL;
394  case CLI_GENERATE:
395  {
396  static const char * const cmds[] = { "NOT_SET", "UNAVAILABLE", "AVAILABLE", "AWAY",
397  "XA", "CHAT", "DND", NULL };
398 
399  if (a->pos == e->args + 1) {
400  return ast_cli_complete(a->word, cmds, a->n);
401  }
402 
403  return NULL;
404  }
405  }
406 
407  if (a->argc != e->args + 2) {
408  return CLI_SHOWUSAGE;
409  }
410 
411  len = strlen("CustomPresence:");
412  full_dev = dev = a->argv[e->args];
413  state = a->argv[e->args + 1];
414 
415  if (strncasecmp(dev, "CustomPresence:", len)) {
416  ast_cli(a->fd, "The presencestate command can only be used to set 'CustomPresence:' presence state!\n");
417  return CLI_FAILURE;
418  }
419 
420  dev += len;
421  if (ast_strlen_zero(dev)) {
422  return CLI_SHOWUSAGE;
423  }
424 
425  args = ast_strdupa(state);
426  if (parse_data(args, &state_val, &subtype, &message, &options)) {
427  return CLI_SHOWUSAGE;
428  }
429 
430  if (state_val == AST_PRESENCE_NOT_SET) {
431  return CLI_SHOWUSAGE;
432  }
433 
434  ast_cli(a->fd, "Changing %s to %s\n", dev, args);
435 
436  ast_db_put(astdb_family, dev, state);
437 
438  ast_presence_state_changed_literal(state_val, subtype, message, full_dev);
439 
440  return CLI_SUCCESS;
441 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static const char astdb_family[]
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
int ast_presence_state_changed_literal(enum ast_presence_state state, const char *subtype, const char *message, const char *presence_provider)
Notify the world that a presence provider state changed.
const int argc
Definition: cli.h:160
const char * subtype
Definition: cli.h:152
const char * args
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
const int fd
Definition: cli.h:159
ast_presence_state
Definition: presencestate.h:26
const int n
Definition: cli.h:165
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * message
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
static struct test_options options

◆ handle_cli_presencestate_list()

static char* handle_cli_presencestate_list ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 295 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(), astdb_family, 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, NULL, options, parse_data(), state, and ast_cli_entry::usage.

296 {
297  struct ast_db_entry *db_entry, *db_tree;
298 
299  switch (cmd) {
300  case CLI_INIT:
301  e->command = "presencestate list";
302  e->usage =
303  "Usage: presencestate list\n"
304  " List all custom presence states that have been set by using\n"
305  " the PRESENCE_STATE dialplan function.\n";
306  return NULL;
307  case CLI_GENERATE:
308  return NULL;
309  }
310 
311  if (a->argc != e->args) {
312  return CLI_SHOWUSAGE;
313  }
314 
315  ast_cli(a->fd, "\n"
316  "---------------------------------------------------------------------\n"
317  "--- Custom Presence States ------------------------------------------\n"
318  "---------------------------------------------------------------------\n"
319  "---\n");
320 
321  db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
322  if (!db_entry) {
323  ast_cli(a->fd, "No custom presence states defined\n");
324  return CLI_SUCCESS;
325  }
326  for (; db_entry; db_entry = db_entry->next) {
327  const char *object_name = strrchr(db_entry->key, '/') + 1;
328  char state_info[1301];
330  char *subtype;
331  char *message;
332  char *options;
333 
334  ast_copy_string(state_info, db_entry->data, sizeof(state_info));
335  if (parse_data(state_info, &state, &subtype, &message, &options)) {
336  ast_log(LOG_WARNING, "Invalid CustomPresence entry %s encountered\n", db_entry->data);
337  continue;
338  }
339 
340  if (object_name <= (const char *) 1) {
341  continue;
342  }
343  ast_cli(a->fd, "--- Name: 'CustomPresence:%s'\n"
344  " --- State: '%s'\n"
345  " --- Subtype: '%s'\n"
346  " --- Message: '%s'\n"
347  " --- Base64 Encoded: '%s'\n"
348  "---\n",
349  object_name,
350  ast_presence_state2str(state),
351  subtype,
352  message,
353  AST_CLI_YESNO(strchr(options, 'e')));
354  }
355  ast_db_freetree(db_tree);
356  db_tree = NULL;
357 
358  ast_cli(a->fd,
359  "---------------------------------------------------------------------\n"
360  "---------------------------------------------------------------------\n"
361  "\n");
362 
363  return CLI_SUCCESS;
364 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static const char astdb_family[]
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
const int argc
Definition: cli.h:160
#define LOG_WARNING
Definition: logger.h:274
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
Definition: main/db.c:598
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_log
Definition: astobj2.c:42
struct ast_db_entry * next
Definition: astdb.h:32
const int fd
Definition: cli.h:159
ast_presence_state
Definition: presencestate.h:26
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
Definition: main/db.c:531
#define CLI_SHOWUSAGE
Definition: cli.h:45
Definition: astdb.h:31
char data[0]
Definition: astdb.h:34
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static struct test_options options
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.
char * key
Definition: astdb.h:33

◆ load_module()

static int load_module ( void  )
static

Definition at line 842 of file func_presencestate.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_custom_function_register, ast_db_freetree(), ast_db_gettree(), ast_free, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEVSTATE_PROVIDER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ast_presence_state_changed(), ast_presence_state_prov_add(), AST_TEST_REGISTER, astdb_family, ASTERISK_GPL_KEY, custom_presence_callback(), ast_db_entry::key, test_string::message, ast_db_entry::next, NULL, state, test_string::subtype, and unload_module().

843 {
844  int res = 0;
845  struct ast_db_entry *db_entry, *db_tree;
846 
847  /* Populate the presence state cache on the system with all of the currently
848  * known custom presence states. */
849  db_entry = db_tree = ast_db_gettree(astdb_family, NULL);
850  for (; db_entry; db_entry = db_entry->next) {
851  const char *dev_name = strrchr(db_entry->key, '/') + 1;
853  char *message;
854  char *subtype;
855  if (dev_name <= (const char *) 1) {
856  continue;
857  }
858  state = custom_presence_callback(dev_name, &subtype, &message);
859  ast_presence_state_changed(state, subtype, message, "CustomPresence:%s", dev_name);
860  ast_free(subtype);
861  ast_free(message);
862  }
863  ast_db_freetree(db_tree);
864  db_tree = NULL;
865 
867  res |= ast_presence_state_prov_add("CustomPresence", custom_presence_callback);
869 #ifdef TEST_FRAMEWORK
870  AST_TEST_REGISTER(test_valid_parse_data);
871  AST_TEST_REGISTER(test_invalid_parse_data);
872  AST_TEST_REGISTER(test_presence_state_change);
873  AST_TEST_REGISTER(test_presence_state_base64_encode);
874 #endif
875 
876  return res;
877 }
static struct ast_custom_function presence_function
enum sip_cc_notify_state state
Definition: chan_sip.c:959
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char astdb_family[]
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
Definition: main/db.c:598
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define NULL
Definition: resample.c:96
static enum ast_presence_state custom_presence_callback(const char *data, char **subtype, char **message)
struct ast_db_entry * next
Definition: astdb.h:32
ast_presence_state
Definition: presencestate.h:26
int ast_presence_state_prov_add(const char *label, ast_presence_state_prov_cb_type callback)
Add presence state provider.
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
Definition: main/db.c:531
Definition: astdb.h:31
#define ast_free(a)
Definition: astmm.h:182
int ast_presence_state_changed(enum ast_presence_state state, const char *subtype, const char *message, const char *fmt,...)
Notify the world that a presence provider state changed.
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
char * key
Definition: astdb.h:33
static struct ast_cli_entry cli_funcpresencestate[]

◆ parse_data()

static int parse_data ( char *  data,
enum ast_presence_state state,
char **  subtype,
char **  message,
char **  options 
)
static

Definition at line 162 of file func_presencestate.c.

References ast_log, AST_PRESENCE_INVALID, ast_presence_state_val(), ast_strlen_zero, LOG_NOTICE, LOG_WARNING, and strsep().

Referenced by AST_TEST_DEFINE(), custom_presence_callback(), handle_cli_presencestate_change(), handle_cli_presencestate_list(), and presence_write().

163 {
164  char *state_str;
165 
166  /* data syntax is state,subtype,message,options */
167  *subtype = "";
168  *message = "";
169  *options = "";
170 
171  state_str = strsep(&data, ",");
172  if (ast_strlen_zero(state_str)) {
173  return -1; /* state is required */
174  }
175 
176  *state = ast_presence_state_val(state_str);
177 
178  /* not a valid state */
179  if (*state == AST_PRESENCE_INVALID) {
180  ast_log(LOG_WARNING, "Unknown presence state value %s\n", state_str);
181  return -1;
182  }
183 
184  if (!(*subtype = strsep(&data,","))) {
185  *subtype = "";
186  return 0;
187  }
188 
189  if (!(*message = strsep(&data, ","))) {
190  *message = "";
191  return 0;
192  }
193 
194  if (!(*options = strsep(&data, ","))) {
195  *options = "";
196  return 0;
197  }
198 
199  if (!ast_strlen_zero(*options) && !(strchr(*options, 'e'))) {
200  ast_log(LOG_NOTICE, "Invalid options '%s'\n", *options);
201  return -1;
202  }
203 
204  return 0;
205 }
enum ast_presence_state ast_presence_state_val(const char *val)
Convert presence state from text to integer value.
#define LOG_WARNING
Definition: logger.h:274
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
Definition: logger.h:263
char data[0]
Definition: astdb.h:34
char * strsep(char **str, const char *delims)
static struct test_options options

◆ presence_change_common()

static enum ast_test_result_state presence_change_common ( struct ast_test test,
const char *  state,
const char *  subtype,
const char *  message,
const char *  options,
char *  out_state,
size_t  out_state_size,
char *  out_subtype,
size_t  out_subtype_size,
char *  out_message,
size_t  out_message_size 
)
static

Definition at line 705 of file func_presencestate.c.

References ast_copy_string(), ast_db_del(), ast_presence_state2str(), ast_presence_state_topic_all(), ast_sem_wait(), ast_strlen_zero, AST_TEST_FAIL, AST_TEST_PASS, NULL, presence_write(), RAII_VAR, stasis_subscribe, stasis_unsubscribe_and_join(), test_cb(), test_cb_data_alloc(), test_cb_data_destroy(), and test_sub().

Referenced by AST_TEST_DEFINE().

710 {
713  char pres[1301];
714 
715  if (!(test_sub = stasis_subscribe(ast_presence_state_topic_all(), test_cb, cb_data))) {
716  return AST_TEST_FAIL;
717  }
718 
719  if (ast_strlen_zero(options)) {
720  snprintf(pres, sizeof(pres), "%s,%s,%s", state, subtype, message);
721  } else {
722  snprintf(pres, sizeof(pres), "%s,%s,%s,%s", state, subtype, message, options);
723  }
724 
725  if (presence_write(NULL, "PRESENCESTATE", "CustomPresence:TestPresenceStateChange", pres)) {
726  test_sub = stasis_unsubscribe_and_join(test_sub);
727  return AST_TEST_FAIL;
728  }
729 
730  ast_sem_wait(&cb_data->sem);
731 
732  ast_copy_string(out_state, ast_presence_state2str(cb_data->presence_state->state), out_state_size);
733  ast_copy_string(out_subtype, cb_data->presence_state->subtype, out_subtype_size);
734  ast_copy_string(out_message, cb_data->presence_state->message, out_message_size);
735 
736  test_sub = stasis_unsubscribe_and_join(test_sub);
737  ast_db_del("CustomPresence", "TestPresenceStateChange");
738 
739  return AST_TEST_PASS;
740 }
static struct test_cb_data * test_cb_data_alloc(void)
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static void test_sub(struct ast_event *event)
Definition: test_cel.c:1790
int ast_sem_wait(struct ast_sem *sem)
Decrements the semaphore.
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
static int presence_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Definition: main/db.c:429
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct test_options options
struct stasis_topic * ast_presence_state_topic_all(void)
Get presence state topic.
static void test_cb(void *userdata, struct stasis_subscription *sub, struct stasis_message *msg)
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.
static void test_cb_data_destroy(struct test_cb_data *cb_data)

◆ presence_read()

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

Definition at line 102 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_strdupa, ast_strlen_zero, LOG_WARNING, NULL, options, parse(), provider, and state.

103 {
104  int state;
105  char *message = NULL;
106  char *subtype = NULL;
107  char *parse;
108  int base64encode = 0;
111  AST_APP_ARG(field);
113  );
114 
115  if (ast_strlen_zero(data)) {
116  ast_log(LOG_WARNING, "PRESENCE_STATE reading requires an argument \n");
117  return -1;
118  }
119 
120  parse = ast_strdupa(data);
121 
122  AST_STANDARD_APP_ARGS(args, parse);
123 
124  if (ast_strlen_zero(args.provider) || ast_strlen_zero(args.field)) {
125  ast_log(LOG_WARNING, "PRESENCE_STATE reading requires both presence provider and presence field arguments. \n");
126  return -1;
127  }
128 
129  state = ast_presence_state_nocache(args.provider, &subtype, &message);
130  if (state == AST_PRESENCE_INVALID) {
131  ast_log(LOG_WARNING, "PRESENCE_STATE unknown \n");
132  return -1;
133  }
134 
135  if (!(ast_strlen_zero(args.options)) && (strchr(args.options, 'e'))) {
136  base64encode = 1;
137  }
138 
139  if (!ast_strlen_zero(subtype) && !strcasecmp(args.field, "subtype")) {
140  if (base64encode) {
141  ast_base64encode(buf, (unsigned char *) subtype, strlen(subtype), len);
142  } else {
143  ast_copy_string(buf, subtype, len);
144  }
145  } else if (!ast_strlen_zero(message) && !strcasecmp(args.field, "message")) {
146  if (base64encode) {
147  ast_base64encode(buf, (unsigned char *) message, strlen(message), len);
148  } else {
149  ast_copy_string(buf, message, len);
150  }
151 
152  } else if (!strcasecmp(args.field, "value")) {
154  }
155 
156  ast_free(message);
157  ast_free(subtype);
158 
159  return 0;
160 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
enum ast_presence_state ast_presence_state_nocache(const char *presence_provider, char **subtype, char **message)
Asks a presence state provider for the current presence state, bypassing the event cache...
const char * args
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: main/utils.c:404
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
#define ast_free(a)
Definition: astmm.h:182
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct test_options options
static struct prometheus_metrics_provider provider
Definition: bridges.c:178
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.
#define AST_APP_ARG(name)
Define an application argument.

◆ presence_write()

static int presence_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 207 of file func_presencestate.c.

References args, ast_base64decode(), ast_db_put(), ast_log, ast_presence_state_changed_literal(), ast_strdupa, ast_strlen_zero, astdb_family, len(), LOG_WARNING, options, parse_data(), state, and tmp().

Referenced by presence_change_common().

208 {
209  size_t len = strlen("CustomPresence:");
210  char *tmp = data;
211  char *args = ast_strdupa(value);
213  char *options, *message, *subtype;
214 
215  if (strncasecmp(data, "CustomPresence:", len)) {
216  ast_log(LOG_WARNING, "The PRESENCE_STATE function can only set CustomPresence: presence providers.\n");
217  return -1;
218  }
219  data += len;
220  if (ast_strlen_zero(data)) {
221  ast_log(LOG_WARNING, "PRESENCE_STATE function called with no custom device name!\n");
222  return -1;
223  }
224 
225  if (parse_data(args, &state, &subtype, &message, &options)) {
226  ast_log(LOG_WARNING, "Invalid arguments to PRESENCE_STATE\n");
227  return -1;
228  }
229 
231 
232  if (strchr(options, 'e')) {
233  /* Let's decode the values before sending them to stasis, yes? */
234  char decoded_subtype[256] = { 0, };
235  char decoded_message[256] = { 0, };
236 
237  ast_base64decode((unsigned char *) decoded_subtype, subtype, sizeof(decoded_subtype) -1);
238  ast_base64decode((unsigned char *) decoded_message, message, sizeof(decoded_message) -1);
239 
240  ast_presence_state_changed_literal(state, decoded_subtype, decoded_message, tmp);
241  } else {
242  ast_presence_state_changed_literal(state, subtype, message, tmp);
243  }
244 
245  return 0;
246 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
static const char astdb_family[]
static int parse_data(char *data, enum ast_presence_state *state, char **subtype, char **message, char **options)
int ast_presence_state_changed_literal(enum ast_presence_state state, const char *subtype, const char *message, const char *presence_provider)
Notify the world that a presence provider state changed.
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
const char * args
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: main/utils.c:294
#define ast_log
Definition: astobj2.c:42
ast_presence_state
Definition: presencestate.h:26
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
Definition: main/db.c:327
static struct test_options options

◆ test_cb()

static void test_cb ( void *  userdata,
struct stasis_subscription sub,
struct stasis_message msg 
)
static

Definition at line 693 of file func_presencestate.c.

References ao2_ref, ast_presence_state_message_type(), ast_sem_post(), test_cb_data::presence_state, test_cb_data::sem, stasis_message_data(), and stasis_message_type().

Referenced by presence_change_common().

694 {
695  struct test_cb_data *cb_data = userdata;
697  return;
698  }
699  cb_data->presence_state = stasis_message_data(msg);
700  ao2_ref(cb_data->presence_state, +1);
701 
702  ast_sem_post(&cb_data->sem);
703 }
struct ast_presence_state_message * presence_state
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message_type * ast_presence_state_message_type(void)
Get presence state message type.
struct ast_sem sem

◆ test_cb_data_alloc()

static struct test_cb_data* test_cb_data_alloc ( void  )
static

Definition at line 670 of file func_presencestate.c.

References ast_calloc, ast_free, ast_sem_init(), NULL, and test_cb_data::sem.

Referenced by presence_change_common().

671 {
672  struct test_cb_data *cb_data = ast_calloc(1, sizeof(*cb_data));
673 
674  if (!cb_data) {
675  return NULL;
676  }
677 
678  if (ast_sem_init(&cb_data->sem, 0, 0)) {
679  ast_free(cb_data);
680  return NULL;
681  }
682 
683  return cb_data;
684 }
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
struct ast_sem sem

◆ test_cb_data_destroy()

static void test_cb_data_destroy ( struct test_cb_data cb_data)
static

Definition at line 686 of file func_presencestate.c.

References ao2_cleanup, ast_free, ast_sem_destroy(), test_cb_data::presence_state, and test_cb_data::sem.

Referenced by presence_change_common().

687 {
688  ao2_cleanup(cb_data->presence_state);
689  ast_sem_destroy(&cb_data->sem);
690  ast_free(cb_data);
691 }
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
struct ast_presence_state_message * presence_state
#define ast_free(a)
Definition: astmm.h:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_sem sem

◆ unload_module()

static int unload_module ( void  )
static

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

Referenced by load_module().

827 {
828  int res = 0;
829 
831  res |= ast_presence_state_prov_del("CustomPresence");
833 #ifdef TEST_FRAMEWORK
834  AST_TEST_UNREGISTER(test_valid_parse_data);
835  AST_TEST_UNREGISTER(test_invalid_parse_data);
836  AST_TEST_UNREGISTER(test_presence_state_change);
837  AST_TEST_UNREGISTER(test_presence_state_base64_encode);
838 #endif
839  return res;
840 }
static struct ast_custom_function presence_function
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
int ast_presence_state_prov_del(const char *label)
Remove presence state provider.
static struct ast_cli_entry cli_funcpresencestate[]

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEVSTATE_PROVIDER, }
static

Definition at line 884 of file func_presencestate.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 884 of file func_presencestate.c.

◆ astdb_family

const char astdb_family[] = "CustomPresence"
static

◆ cli_funcpresencestate

struct ast_cli_entry cli_funcpresencestate[]
static
Initial value:
= {
{ .handler = handle_cli_presencestate_list , .summary = "List currently know custom presence states" ,},
{ .handler = handle_cli_presencestate_change , .summary = "Change a custom presence state" ,},
}
static char * handle_cli_presencestate_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_presencestate_change(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 443 of file func_presencestate.c.

◆ presence_function

struct ast_custom_function presence_function
static
Initial value:
= {
.name = "PRESENCE_STATE",
.read = presence_read,
.write = presence_write,
}
static int presence_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int presence_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 289 of file func_presencestate.c.