Asterisk - The Open Source Telephony Project GIT-master-2de1a68
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
res_pjsip_notify.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/manager.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/sorcery.h"
Include dependency graph for res_pjsip_notify.c:

Go to the source code of this file.

Data Structures

struct  notify_cfg
 
struct  notify_channel_data
 
struct  notify_data
 
struct  notify_option
 
struct  notify_option_item
 
struct  notify_uri_data
 

Macros

#define CONTENT_SIZE   512
 
#define CONTENT_TYPE_SIZE   64
 

Typedefs

typedef struct notify_channel_data *(* task_channel_data_create) (struct ast_sip_session *session, void *info)
 
typedef struct notify_data *(* task_data_create) (struct ast_sip_endpoint *, void *info)
 
typedef struct notify_uri_data *(* task_uri_data_create) (const char *uri, void *info)
 

Enumerations

enum  notify_result {
  SUCCESS , INVALID_ENDPOINT , INVALID_CHANNEL , ALLOC_ERROR ,
  TASK_PUSH_ERROR
}
 
enum  notify_type { NOTIFY_ENDPOINT , NOTIFY_URI , NOTIFY_CHANNEL }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
 AO2_GLOBAL_OBJ_STATIC (globals)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void build_ami_notify (pjsip_tx_data *tdata, void *info)
 
static void build_cli_notify (pjsip_tx_data *tdata, void *info)
 
static void build_notify (pjsip_tx_data *tdata, const char *name, const char *value, struct ast_str **content_type, struct ast_str **content)
 
static void build_notify_body (pjsip_tx_data *tdata, struct ast_str *content_type, struct ast_str *content)
 
static char * cli_complete_endpoint (const char *word)
 
static char * cli_complete_notify (const char *line, const char *word, int pos, int state, int using_uri)
 
static char * cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
 CONFIG_INFO_STANDARD (notify_cfg, globals, notify_cfg_alloc,.files=ACO_FILES(&module_conf))
 
static int load_module (void)
 
static int manager_notify (struct mansession *s, const struct message *m)
 
static void manager_notify_channel (struct mansession *s, const struct message *m, const char *channel)
 
static void manager_notify_endpoint (struct mansession *s, const struct message *m, const char *endpoint_name)
 
static void manager_notify_uri (struct mansession *s, const struct message *m, const char *uri)
 
static void manager_send_response (struct mansession *s, const struct message *m, enum notify_type type, enum notify_result res, struct ast_variable *vars, const char *endpoint_name)
 
static int multiple_headers_allowed (const char *name)
 
static int not_allowed (const char *name)
 
static struct notify_channel_datanotify_ami_channel_data_create (struct ast_sip_session *session, void *info)
 
static void notify_ami_channel_data_destroy (void *obj)
 
static struct notify_datanotify_ami_data_create (struct ast_sip_endpoint *endpoint, void *info)
 
static void notify_ami_data_destroy (void *obj)
 
static struct notify_uri_datanotify_ami_uri_data_create (const char *uri, void *info)
 
static void notify_ami_uri_data_destroy (void *obj)
 
static void * notify_cfg_alloc (void)
 
static void notify_cfg_destroy (void *obj)
 
static int notify_channel (void *obj)
 
static struct notify_datanotify_cli_data_create (struct ast_sip_endpoint *endpoint, void *info)
 
static void notify_cli_data_destroy (void *obj)
 
static struct notify_uri_datanotify_cli_uri_data_create (const char *uri, void *info)
 
static void notify_cli_uri_data_destroy (void *obj)
 
static int notify_contact (void *obj, void *arg, int flags)
 
static int notify_endpoint (void *obj)
 
static void * notify_option_alloc (const char *category)
 
static int notify_option_cmp (void *obj, void *arg, int flags)
 
static void notify_option_destroy (void *obj)
 
static void * notify_option_find (struct ao2_container *container, const char *category)
 
static int notify_option_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int notify_option_hash (const void *obj, int flags)
 
static int notify_uri (void *obj)
 
static enum notify_result push_notify (const char *endpoint_name, void *info, task_data_create data_create)
 
static enum notify_result push_notify_channel (const char *channel_name, void *info, task_channel_data_create data_create)
 
static enum notify_result push_notify_uri (const char *uri, void *info, task_uri_data_create data_create)
 
static int reload_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CLI/AMI PJSIP NOTIFY Support" , .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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_options []
 
static struct aco_file module_conf
 
static const char notify_config [] = "pjsip_notify.conf"
 
static struct aco_type notify_option
 
static struct aco_typenotify_options [] = ACO_TYPES(&notify_option)
 

Macro Definition Documentation

◆ CONTENT_SIZE

#define CONTENT_SIZE   512

Definition at line 121 of file res_pjsip_notify.c.

◆ CONTENT_TYPE_SIZE

#define CONTENT_TYPE_SIZE   64

Definition at line 120 of file res_pjsip_notify.c.

Typedef Documentation

◆ task_channel_data_create

typedef struct notify_channel_data *(* task_channel_data_create) (struct ast_sip_session *session, void *info)

Definition at line 756 of file res_pjsip_notify.c.

◆ task_data_create

typedef struct notify_data *(* task_data_create) (struct ast_sip_endpoint *, void *info)

Definition at line 756 of file res_pjsip_notify.c.

◆ task_uri_data_create

typedef struct notify_uri_data *(* task_uri_data_create) (const char *uri, void *info)

Definition at line 756 of file res_pjsip_notify.c.

Enumeration Type Documentation

◆ notify_result

Enumerator
SUCCESS 
INVALID_ENDPOINT 
INVALID_CHANNEL 
ALLOC_ERROR 
TASK_PUSH_ERROR 

Definition at line 787 of file res_pjsip_notify.c.

787 {
788 SUCCESS,
793};
@ TASK_PUSH_ERROR
@ ALLOC_ERROR
@ SUCCESS
@ INVALID_ENDPOINT
@ INVALID_CHANNEL

◆ notify_type

Enumerator
NOTIFY_ENDPOINT 
NOTIFY_URI 
NOTIFY_CHANNEL 

Definition at line 1079 of file res_pjsip_notify.c.

1079 {
1081 NOTIFY_URI,
1083};
@ NOTIFY_CHANNEL
@ NOTIFY_ENDPOINT
@ NOTIFY_URI

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1295 of file res_pjsip_notify.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1295 of file res_pjsip_notify.c.

◆ AO2_GLOBAL_OBJ_STATIC()

AO2_GLOBAL_OBJ_STATIC ( globals  )

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1295 of file res_pjsip_notify.c.

◆ build_ami_notify()

static void build_ami_notify ( pjsip_tx_data *  tdata,
void *  info 
)
static

Definition at line 627 of file res_pjsip_notify.c.

628{
629 struct ast_variable *vars = info;
630 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
631 RAII_VAR(struct ast_str *, content, NULL, ast_free);
632 struct ast_variable *i;
633
634 for (i = vars; i; i = i->next) {
635 if (!strcasecmp(i->name, "Content-Length")) {
636 ast_log(LOG_NOTICE, "It is not necessary to specify Content-Length, ignoring.\n");
637 continue;
638 }
639 build_notify(tdata, i->name, i->value,
640 &content_type, &content);
641 }
642
643 build_notify_body(tdata, content_type, content);
644}
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
def info(msg)
static void build_notify_body(pjsip_tx_data *tdata, struct ast_str *content_type, struct ast_str *content)
static void build_notify(pjsip_tx_data *tdata, const char *name, const char *value, struct ast_str **content_type, struct ast_str **content)
#define NULL
Definition: resample.c:96
Support for dynamic strings.
Definition: strings.h:623
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
#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:941

References ast_free, ast_log, build_notify(), build_notify_body(), sip_to_pjsip::info(), LOG_NOTICE, ast_variable::name, ast_variable::next, NULL, RAII_VAR, and ast_variable::value.

Referenced by notify_ami_channel_data_create(), notify_ami_data_create(), and notify_ami_uri_data_create().

◆ build_cli_notify()

static void build_cli_notify ( pjsip_tx_data *  tdata,
void *  info 
)
static

Definition at line 603 of file res_pjsip_notify.c.

604{
605 struct notify_option *option = info;
606 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
607 RAII_VAR(struct ast_str *, content, NULL, ast_free);
608
609 struct notify_option_item *item;
610 struct ao2_iterator i = ao2_iterator_init(option->items, 0);
611
612 while ((item = ao2_iterator_next(&i))) {
613 build_notify(tdata, item->name, item->value,
614 &content_type, &content);
616 }
618
619 build_notify_body(tdata, content_type, content);
620}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * name
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ao2_container * items
static struct aco_type item
Definition: test_config.c:1463

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_free, build_notify(), build_notify_body(), sip_to_pjsip::info(), item, notify_option::items, aco_type::name, NULL, and RAII_VAR.

Referenced by notify_cli_data_create(), and notify_cli_uri_data_create().

◆ build_notify()

static void build_notify ( pjsip_tx_data *  tdata,
const char *  name,
const char *  value,
struct ast_str **  content_type,
struct ast_str **  content 
)
static

Definition at line 558 of file res_pjsip_notify.c.

560{
561 if (not_allowed(name)) {
562 ast_log(LOG_WARNING, "Cannot specify %s header, "
563 "ignoring\n", name);
564 return;
565 }
566
567 if (!strcasecmp(name, "Content-type")) {
568 if (!(*content_type)) {
569 *content_type = ast_str_create(CONTENT_TYPE_SIZE);
570 }
571 ast_str_set(content_type, 0,"%s", value);
572 } else if (!strcasecmp(name, "Content")) {
573 if (!(*content)) {
574 *content = ast_str_create(CONTENT_SIZE);
575 }
576
577 if (ast_str_strlen(*content)) {
578 ast_str_append(content, 0, "\r\n");
579 }
580 ast_str_append(content, 0, "%s", value);
581 } else {
582 /* See if there is an existing one */
584 pj_str_t hdr_name;
585 pj_cstr(&hdr_name, name);
586
587 if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name, NULL)) {
588 ast_log(LOG_ERROR, "Only one '%s' header can be added to a NOTIFY, "
589 "ignoring \"%s: %s\"\n", name, name, value);
590 return;
591 }
592 }
593
595 }
596}
static const char name[]
Definition: format_mp3.c:68
#define LOG_ERROR
#define LOG_WARNING
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition: res_pjsip.c:2008
static int not_allowed(const char *name)
static int multiple_headers_allowed(const char *name)
#define CONTENT_TYPE_SIZE
#define CONTENT_SIZE
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
int value
Definition: syslog.c:37

References ast_log, ast_sip_add_header(), ast_str_append(), ast_str_create, ast_str_set(), ast_str_strlen(), CONTENT_SIZE, CONTENT_TYPE_SIZE, LOG_ERROR, LOG_WARNING, multiple_headers_allowed(), name, not_allowed(), NULL, and value.

Referenced by build_ami_notify(), and build_cli_notify().

◆ build_notify_body()

static void build_notify_body ( pjsip_tx_data *  tdata,
struct ast_str content_type,
struct ast_str content 
)
static

Definition at line 534 of file res_pjsip_notify.c.

536{
537 if (content_type) {
538 char *p;
539 struct ast_sip_body body;
540
541 if (content) {
542 body.body_text = ast_str_buffer(content);
543 }
544
545 body.type = ast_str_buffer(content_type);
546 if ((p = strchr(body.type, '/'))) {
547 *p++ = '\0';
548 body.subtype = p;
549 }
550 ast_sip_add_body(tdata, &body);
551 }
552}
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition: res_pjsip.c:2052
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
SIP body description.
Definition: res_pjsip.h:2313
const char * body_text
Definition: res_pjsip.h:2319

References ast_sip_add_body(), ast_str_buffer(), ast_sip_body::body_text, ast_sip_body::subtype, and ast_sip_body::type.

Referenced by build_ami_notify(), and build_cli_notify().

◆ cli_complete_endpoint()

static char * cli_complete_endpoint ( const char *  word)
static

Definition at line 918 of file res_pjsip_notify.c.

919{
920 int wordlen = strlen(word);
921 struct ao2_container * endpoints;
922 struct ast_sip_endpoint *endpoint;
923 struct ao2_iterator i;
924
926 "endpoint", word, wordlen);
927 if (endpoints == NULL) {
928 return NULL;
929 }
930
932 while ((endpoint = ao2_iterator_next(&i))) {
935 ao2_cleanup(endpoint);
936 }
938
939 ao2_ref(endpoints, -1);
940
941 return NULL;
942}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2758
short word
static struct ao2_container * endpoints
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
struct ao2_container * ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
Retrieve multiple objects whose id begins with the specified prefix.
Definition: sorcery.c:1984
Generic container type.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:951

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_completion_add(), ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_prefix(), ast_strdup, endpoints, and NULL.

Referenced by cli_complete_notify().

◆ cli_complete_notify()

static char * cli_complete_notify ( const char *  line,
const char *  word,
int  pos,
int  state,
int  using_uri 
)
static

Definition at line 948 of file res_pjsip_notify.c.

950{
951 char *c = NULL;
952
953 if (pos == 3) {
954 int which = 0;
955 int wordlen = strlen(word);
956
957 RAII_VAR(struct notify_cfg *, cfg,
959 struct notify_option *option;
960
961 /* do completion for notify type */
962 struct ao2_iterator i = ao2_iterator_init(cfg->notify_options, 0);
963 while ((option = ao2_iterator_next(&i))) {
964 if (!strncasecmp(word, option->name, wordlen) && ++which > state) {
965 c = ast_strdup(option->name);
966 }
967
968 ao2_cleanup(option);
969 if (c) {
970 break;
971 }
972 }
974 return c;
975 }
976
977 if (pos == 4) {
978 int wordlen = strlen(word);
979
980 if (ast_strlen_zero(word)) {
981 if (state == 0) {
982 c = ast_strdup("endpoint");
983 } else if (state == 1) {
984 c = ast_strdup("uri");
985 }
986 } else if (state == 0) {
987 if (!strncasecmp(word, "endpoint", wordlen)) {
988 c = ast_strdup("endpoint");
989 } else if (!strncasecmp(word, "uri", wordlen)) {
990 c = ast_strdup("uri");
991 }
992 }
993
994 return c;
995 }
996
997 return pos > 4 && !using_uri ? cli_complete_endpoint(word) : NULL;
998}
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static struct console_pvt globals
static char * cli_complete_endpoint(const char *word)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
static struct test_val c

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_strlen_zero(), c, cli_complete_endpoint(), globals, notify_option::name, NULL, and RAII_VAR.

Referenced by cli_notify().

◆ cli_notify()

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

Definition at line 1008 of file res_pjsip_notify.c.

1009{
1010 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1011 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1012
1013 int i;
1014 int using_uri = 0;
1015
1016 switch (cmd) {
1017 case CLI_INIT:
1018 e->command = "pjsip send notify";
1019 e->usage =
1020 "Usage: pjsip send notify <type> {endpoint|uri} <peer> [<peer>...]\n"
1021 " Send a NOTIFY request to an endpoint\n"
1022 " Message types are defined in pjsip_notify.conf\n";
1023 return NULL;
1024 case CLI_GENERATE:
1025 if (a->argc > 4 && (!strcasecmp(a->argv[4], "uri"))) {
1026 using_uri = 1;
1027 }
1028
1029 return cli_complete_notify(a->line, a->word, a->pos, a->n, using_uri);
1030 }
1031
1032 if (a->argc < 6) {
1033 return CLI_SHOWUSAGE;
1034 }
1035
1036 if (!strcasecmp(a->argv[4], "uri")) {
1037 using_uri = 1;
1038 } else if (strcasecmp(a->argv[4], "endpoint")) {
1039 return CLI_SHOWUSAGE;
1040 }
1041
1043
1044 if (!(option = notify_option_find(cfg->notify_options, a->argv[3])))
1045 {
1046 ast_cli(a->fd, "Unable to find notify type '%s'\n",
1047 a->argv[3]);
1048 return CLI_FAILURE;
1049 }
1050
1051 for (i = 5; i < a->argc; ++i) {
1052 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n",
1053 a->argv[3], a->argv[i]);
1054
1055 switch (using_uri ? push_notify_uri(a->argv[i], option, notify_cli_uri_data_create) :
1056 push_notify(a->argv[i], option, notify_cli_data_create)) {
1057 case INVALID_ENDPOINT:
1058 ast_cli(a->fd, "Unable to retrieve endpoint %s\n",
1059 a->argv[i]);
1060 break;
1061 case ALLOC_ERROR:
1062 ast_cli(a->fd, "Unable to allocate NOTIFY task data\n");
1063 return CLI_FAILURE;
1064 case TASK_PUSH_ERROR:
1065 ast_cli(a->fd, "Unable to push NOTIFY task\n");
1066 return CLI_FAILURE;
1067 default:
1068 break;
1069 }
1070 }
1071
1072 return CLI_SUCCESS;
1073}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
static void * notify_option_find(struct ao2_container *container, const char *category)
static char * cli_complete_notify(const char *line, const char *word, int pos, int state, int using_uri)
static struct notify_data * notify_cli_data_create(struct ast_sip_endpoint *endpoint, void *info)
static enum notify_result push_notify_uri(const char *uri, void *info, task_uri_data_create data_create)
static struct notify_uri_data * notify_cli_uri_data_create(const char *uri, void *info)
static enum notify_result push_notify(const char *endpoint_name, void *info, task_data_create data_create)
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

References a, ALLOC_ERROR, ao2_cleanup, ao2_global_obj_ref, ast_cli(), cli_complete_notify(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, globals, INVALID_ENDPOINT, notify_cli_data_create(), notify_cli_uri_data_create(), notify_option_find(), NULL, push_notify(), push_notify_uri(), RAII_VAR, TASK_PUSH_ERROR, and ast_cli_entry::usage.

◆ CONFIG_INFO_STANDARD()

CONFIG_INFO_STANDARD ( notify_cfg  ,
globals  ,
notify_cfg_alloc  ,
files = ACO_FILES(&module_conf) 
)

◆ load_module()

static int load_module ( void  )
static

Definition at line 1249 of file res_pjsip_notify.c.

1250{
1251 if (aco_info_init(&notify_cfg)) {
1253 }
1254
1256 "", notify_option_handler, 0);
1257
1258 if (aco_process_config(&notify_cfg, 0)) {
1261 }
1262
1265
1267}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ ACO_PREFIX
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct aco_type * notify_options[]
static int manager_notify(struct mansession *s, const struct message *m)
static struct ast_cli_entry cli_options[]
static int notify_option_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
#define ARRAY_LEN(a)
Definition: utils.h:666

References aco_info_destroy(), aco_info_init(), aco_option_register_custom, ACO_PREFIX, aco_process_config(), ARRAY_LEN, ast_cli_register_multiple, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, cli_options, EVENT_FLAG_SYSTEM, manager_notify(), notify_option_handler(), and notify_options.

◆ manager_notify()

static int manager_notify ( struct mansession s,
const struct message m 
)
static

Definition at line 1208 of file res_pjsip_notify.c.

1209{
1210 const char *endpoint_name = astman_get_header(m, "Endpoint");
1211 const char *uri = astman_get_header(m, "URI");
1212 const char *channel = astman_get_header(m, "Channel");
1213 const char *variables = astman_get_header(m, "Variable");
1214 const char *option = astman_get_header(m, "Option");
1215 int count = 0;
1216
1217 if (!ast_strlen_zero(endpoint_name)) {
1218 ++count;
1219 }
1220 if (!ast_strlen_zero(uri)) {
1221 ++count;
1222 }
1223 if (!ast_strlen_zero(channel)) {
1224 ++count;
1225 }
1226
1227 if ((!ast_strlen_zero(option) && !ast_strlen_zero(variables)) || (ast_strlen_zero(option) && ast_strlen_zero(variables))) {
1228 astman_send_error(s, m,
1229 "PJSIPNotify requires either an Option or Variable(s)."
1230 "You must use only one of them.");
1231 } else if (1 < count) {
1232 astman_send_error(s, m,
1233 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel. "
1234 "You must use only one of them.");
1235 } else if (!ast_strlen_zero(endpoint_name)) {
1236 manager_notify_endpoint(s, m, endpoint_name);
1237 } else if (!ast_strlen_zero(uri)) {
1238 manager_notify_uri(s, m, uri);
1239 } else if (!ast_strlen_zero(channel)) {
1240 manager_notify_channel(s, m, channel);
1241 } else {
1242 astman_send_error(s, m,
1243 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.");
1244 }
1245
1246 return 0;
1247}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3354
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3015
static void manager_notify_endpoint(struct mansession *s, const struct message *m, const char *endpoint_name)
static void manager_notify_channel(struct mansession *s, const struct message *m, const char *channel)
static void manager_notify_uri(struct mansession *s, const struct message *m, const char *uri)

References ast_strlen_zero(), astman_get_header(), astman_send_error(), manager_notify_channel(), manager_notify_endpoint(), and manager_notify_uri().

Referenced by load_module().

◆ manager_notify_channel()

static void manager_notify_channel ( struct mansession s,
const struct message m,
const char *  channel 
)
static

Definition at line 1192 of file res_pjsip_notify.c.

1194{
1195 enum notify_result res;
1196 struct ast_variable *vars = NULL;
1197
1200
1201 manager_send_response(s, m, NOTIFY_CHANNEL, res, vars, NULL);
1202}
struct ast_variable * astman_get_variables_order(const struct message *m, enum variable_orders order)
Get a linked list of the Variable: headers with order specified.
Definition: manager.c:3106
@ ORDER_NATURAL
Definition: manager.h:288
static enum notify_result push_notify_channel(const char *channel_name, void *info, task_channel_data_create data_create)
notify_result
static struct notify_channel_data * notify_ami_channel_data_create(struct ast_sip_session *session, void *info)
static void manager_send_response(struct mansession *s, const struct message *m, enum notify_type type, enum notify_result res, struct ast_variable *vars, const char *endpoint_name)

References astman_get_variables_order(), manager_send_response(), notify_ami_channel_data_create(), NOTIFY_CHANNEL, NULL, ORDER_NATURAL, and push_notify_channel().

Referenced by manager_notify().

◆ manager_notify_endpoint()

static void manager_notify_endpoint ( struct mansession s,
const struct message m,
const char *  endpoint_name 
)
static

Definition at line 1124 of file res_pjsip_notify.c.

1126{
1127 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1128 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1129 struct ast_variable *vars = NULL;
1130 enum notify_result res;
1131 const char *option_name = astman_get_header(m, "Option");
1132
1133 if (!ast_strlen_zero(option_name) && (cfg = ao2_global_obj_ref(globals)) && !(option = notify_option_find(cfg->notify_options, option_name))) {
1134 astman_send_error_va(s, m, "Unable to find notify type '%s'\n", option_name);
1135 return;
1136 }
1137 if (!option) {
1139 }
1140
1141 if (!strncasecmp(endpoint_name, "sip/", 4)) {
1142 endpoint_name += 4;
1143 }
1144
1145 if (!strncasecmp(endpoint_name, "pjsip/", 6)) {
1146 endpoint_name += 6;
1147 }
1148
1149 if (option) {
1150 res = push_notify(endpoint_name, option, notify_cli_data_create); /* The CLI version happens to be suitable for options. */
1151 } else {
1152 res = push_notify(endpoint_name, vars, notify_ami_data_create);
1153 }
1154
1155 manager_send_response(s, m, NOTIFY_ENDPOINT, res, vars, endpoint_name);
1156}
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
Definition: manager.c:3359
static struct notify_data * notify_ami_data_create(struct ast_sip_endpoint *endpoint, void *info)

References ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero(), astman_get_header(), astman_get_variables_order(), astman_send_error_va(), globals, manager_send_response(), notify_ami_data_create(), notify_cli_data_create(), NOTIFY_ENDPOINT, notify_option_find(), NULL, ORDER_NATURAL, push_notify(), and RAII_VAR.

Referenced by manager_notify().

◆ manager_notify_uri()

static void manager_notify_uri ( struct mansession s,
const struct message m,
const char *  uri 
)
static

Definition at line 1162 of file res_pjsip_notify.c.

1164{
1165 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1166 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1167 enum notify_result res;
1168 const char *option_name = astman_get_header(m, "Option");
1169 struct ast_variable *vars = NULL;
1170
1171 if (!ast_strlen_zero(option_name) && (cfg = ao2_global_obj_ref(globals)) && !(option = notify_option_find(cfg->notify_options, option_name))) {
1172 astman_send_error_va(s, m, "Unable to find notify type '%s'\n", option_name);
1173 return;
1174 }
1175 if (!option) {
1177 }
1178
1179 if (option) {
1180 res = push_notify_uri(uri, option, notify_cli_uri_data_create);
1181 } else {
1183 }
1184
1185 manager_send_response(s, m, NOTIFY_URI, res, vars, NULL);
1186}
static struct notify_uri_data * notify_ami_uri_data_create(const char *uri, void *info)

References ao2_cleanup, ao2_global_obj_ref, ast_strlen_zero(), astman_get_header(), astman_get_variables_order(), astman_send_error_va(), globals, manager_send_response(), notify_ami_uri_data_create(), notify_cli_uri_data_create(), notify_option_find(), NOTIFY_URI, NULL, ORDER_NATURAL, push_notify_uri(), and RAII_VAR.

Referenced by manager_notify().

◆ manager_send_response()

static void manager_send_response ( struct mansession s,
const struct message m,
enum notify_type  type,
enum notify_result  res,
struct ast_variable vars,
const char *  endpoint_name 
)
static

Definition at line 1085 of file res_pjsip_notify.c.

1086{
1087 switch (res) {
1088 case INVALID_CHANNEL:
1089 if (type == NOTIFY_CHANNEL) {
1091 astman_send_error(s, m, "Channel not found");
1092 } else {
1093 /* Shouldn't be possible. */
1094 ast_assert(0);
1095 }
1096 break;
1097 case INVALID_ENDPOINT:
1098 if (type == NOTIFY_ENDPOINT) {
1100 astman_send_error_va(s, m, "Unable to retrieve endpoint %s", endpoint_name);
1101 } else {
1102 /* Shouldn't be possible. */
1103 ast_assert(0);
1104 }
1105 break;
1106 case ALLOC_ERROR:
1108 astman_send_error(s, m, "Unable to allocate NOTIFY task data");
1109 break;
1110 case TASK_PUSH_ERROR:
1111 /* Don't need to destroy vars since it is handled by cleanup in push_notify, push_notify_uri, etc. */
1112 astman_send_error(s, m, "Unable to push Notify task");
1113 break;
1114 case SUCCESS:
1115 astman_send_ack(s, m, "NOTIFY sent");
1116 break;
1117 }
1118}
static const char type[]
Definition: chan_ooh323.c:109
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3386
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
#define ast_assert(a)
Definition: utils.h:739

References ALLOC_ERROR, ast_assert, ast_variables_destroy(), astman_send_ack(), astman_send_error(), astman_send_error_va(), INVALID_CHANNEL, INVALID_ENDPOINT, NOTIFY_CHANNEL, NOTIFY_ENDPOINT, SUCCESS, TASK_PUSH_ERROR, and type.

Referenced by manager_notify_channel(), manager_notify_endpoint(), and manager_notify_uri().

◆ multiple_headers_allowed()

static int multiple_headers_allowed ( const char *  name)
static

Definition at line 523 of file res_pjsip_notify.c.

524{
525 /* This can be extended to include additional headers */
526 return strcasecmp("Event", name);
527}

References name.

Referenced by build_notify().

◆ not_allowed()

static int not_allowed ( const char *  name)
static

Definition at line 496 of file res_pjsip_notify.c.

497{
498 int i;
499 static const char *names[] = {
500 "Call-ID",
501 "Contact",
502 "CSeq",
503 "To",
504 "From",
505 "Record-Route",
506 "Route",
507 "Request-URI",
508 "Via",
509 };
510
511 for (i = 0; i < ARRAY_LEN(names); ++i) {
512 if (!strcasecmp(name, names[i])) {
513 return 1;
514 }
515 }
516 return 0;
517}

References ARRAY_LEN, and name.

Referenced by build_notify().

◆ notify_ami_channel_data_create()

static struct notify_channel_data * notify_ami_channel_data_create ( struct ast_sip_session session,
void *  info 
)
static

Definition at line 470 of file res_pjsip_notify.c.

472{
473 struct notify_channel_data *data;
474
477 if (!data) {
478 return NULL;
479 }
480
481 data->session = session;
482 data->info = info;
484
485 return data;
486}
static struct ast_mansession session
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void notify_ami_channel_data_destroy(void *obj)
static void build_ami_notify(pjsip_tx_data *tdata, void *info)
struct ast_sip_session * session
void(* build_notify)(pjsip_tx_data *, void *)

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, build_ami_notify(), notify_channel_data::build_notify, sip_to_pjsip::info(), notify_channel_data::info, notify_ami_channel_data_destroy(), NULL, notify_channel_data::session, and session.

Referenced by manager_notify_channel().

◆ notify_ami_channel_data_destroy()

static void notify_ami_channel_data_destroy ( void *  obj)
static

◆ notify_ami_data_create()

static struct notify_data * notify_ami_data_create ( struct ast_sip_endpoint endpoint,
void *  info 
)
static

Definition at line 423 of file res_pjsip_notify.c.

425{
426 struct notify_data *data = ao2_alloc(sizeof(*data),
428 if (!data) {
429 return NULL;
430 }
431
432 data->endpoint = endpoint;
433 ao2_ref(data->endpoint, +1);
434
435 data->info = info;
437
438 return data;
439}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void notify_ami_data_destroy(void *obj)
struct ast_sip_endpoint * endpoint
void(* build_notify)(pjsip_tx_data *, void *)

References ao2_alloc, ao2_ref, build_ami_notify(), notify_data::build_notify, notify_data::endpoint, sip_to_pjsip::info(), notify_data::info, notify_ami_data_destroy(), and NULL.

Referenced by manager_notify_endpoint().

◆ notify_ami_data_destroy()

static void notify_ami_data_destroy ( void *  obj)
static

Definition at line 382 of file res_pjsip_notify.c.

383{
384 struct notify_data *data = obj;
385 struct ast_variable *info = data->info;
386
387 ao2_cleanup(data->endpoint);
389}

References ao2_cleanup, ast_variables_destroy(), notify_data::endpoint, sip_to_pjsip::info(), and notify_data::info.

Referenced by notify_ami_data_create().

◆ notify_ami_uri_data_create()

static struct notify_uri_data * notify_ami_uri_data_create ( const char *  uri,
void *  info 
)
static

Definition at line 445 of file res_pjsip_notify.c.

447{
448 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
450 if (!data) {
451 return NULL;
452 }
453
454 data->uri = ast_strdup(uri);
455 if (!data->uri) {
456 ao2_ref(data, -1);
457 return NULL;
458 }
459
460 data->info = info;
462
463 return data;
464}
static void notify_ami_uri_data_destroy(void *obj)
void(* build_notify)(pjsip_tx_data *, void *)

References ao2_alloc, ao2_ref, ast_strdup, build_ami_notify(), notify_uri_data::build_notify, sip_to_pjsip::info(), notify_uri_data::info, notify_ami_uri_data_destroy(), NULL, and notify_uri_data::uri.

Referenced by manager_notify_uri().

◆ notify_ami_uri_data_destroy()

static void notify_ami_uri_data_destroy ( void *  obj)
static

Definition at line 395 of file res_pjsip_notify.c.

396{
397 struct notify_uri_data *data = obj;
398 struct ast_variable *info = data->info;
399
400 ast_free(data->uri);
402}

References ast_free, ast_variables_destroy(), sip_to_pjsip::info(), notify_uri_data::info, and notify_uri_data::uri.

Referenced by notify_ami_uri_data_create().

◆ notify_cfg_alloc()

static void * notify_cfg_alloc ( void  )
static

Definition at line 226 of file res_pjsip_notify.c.

227{
228 struct notify_cfg *cfg;
229
230 if (!(cfg = ao2_alloc(sizeof(*cfg), notify_cfg_destroy))) {
231 return NULL;
232 }
233
236 if (!cfg->notify_options) {
237 ao2_cleanup(cfg);
238 return NULL;
239 }
240
241 return cfg;
242}
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
static int notify_option_cmp(void *obj, void *arg, int flags)
static void notify_cfg_destroy(void *obj)
static int notify_option_hash(const void *obj, int flags)
struct ao2_container * notify_options

References ao2_alloc, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_hash, notify_cfg_destroy(), notify_option_cmp(), notify_option_hash(), notify_cfg::notify_options, and NULL.

◆ notify_cfg_destroy()

static void notify_cfg_destroy ( void *  obj)
static

Definition at line 220 of file res_pjsip_notify.c.

221{
222 struct notify_cfg *cfg = obj;
224}

References ao2_cleanup, and notify_cfg::notify_options.

Referenced by notify_cfg_alloc().

◆ notify_channel()

static int notify_channel ( void *  obj)
static

Definition at line 756 of file res_pjsip_notify.c.

757{
758 RAII_VAR(struct notify_channel_data *, data, obj, ao2_cleanup);
759 pjsip_tx_data *tdata;
760 struct pjsip_dialog *dlg;
761
762 if (!data->session->channel
763 || !data->session->inv_session
764 || data->session->inv_session->state < PJSIP_INV_STATE_EARLY
765 || data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
766 return -1;
767 }
768
769 ast_debug(1, "Sending notify on channel %s\n", ast_channel_name(data->session->channel));
770
771 dlg = data->session->inv_session->dlg;
772
773 if (ast_sip_create_request("NOTIFY", dlg, NULL, NULL, NULL, &tdata)) {
774 return -1;
775 }
776
777 ast_sip_add_header(tdata, "Subscription-State", "terminated");
778 data->build_notify(tdata, data->info);
779
780 if (ast_sip_send_request(tdata, dlg, NULL, NULL, NULL)) {
781 return -1;
782 }
783
784 return 0;
785}
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
Definition: res_pjsip.c:1979
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition: res_pjsip.c:1435

References ao2_cleanup, ast_channel_name(), ast_debug, ast_sip_add_header(), ast_sip_create_request(), ast_sip_send_request(), NULL, and RAII_VAR.

Referenced by build_calendar(), and push_notify_channel().

◆ notify_cli_data_create()

static struct notify_data * notify_cli_data_create ( struct ast_sip_endpoint endpoint,
void *  info 
)
static

Definition at line 330 of file res_pjsip_notify.c.

332{
333 struct notify_data *data = ao2_alloc(sizeof(*data),
335 if (!data) {
336 return NULL;
337 }
338
339 data->endpoint = endpoint;
340 ao2_ref(data->endpoint, +1);
341
342 data->info = info;
343 ao2_ref(data->info, +1);
344
346
347 return data;
348}
static void build_cli_notify(pjsip_tx_data *tdata, void *info)
static void notify_cli_data_destroy(void *obj)

References ao2_alloc, ao2_ref, build_cli_notify(), notify_data::build_notify, notify_data::endpoint, sip_to_pjsip::info(), notify_data::info, notify_cli_data_destroy(), and NULL.

Referenced by cli_notify(), and manager_notify_endpoint().

◆ notify_cli_data_destroy()

static void notify_cli_data_destroy ( void *  obj)
static

Definition at line 284 of file res_pjsip_notify.c.

285{
286 struct notify_data *data = obj;
287
288 ao2_cleanup(data->endpoint);
289 ao2_cleanup(data->info);
290}

References ao2_cleanup, notify_data::endpoint, and notify_data::info.

Referenced by notify_cli_data_create().

◆ notify_cli_uri_data_create()

static struct notify_uri_data * notify_cli_uri_data_create ( const char *  uri,
void *  info 
)
static

Definition at line 354 of file res_pjsip_notify.c.

356{
357 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
359
360 if (!data) {
361 return NULL;
362 }
363
364 data->uri = ast_strdup(uri);
365 if (!data->uri) {
366 ao2_ref(data, -1);
367 return NULL;
368 }
369
370 data->info = info;
371 ao2_ref(data->info, +1);
372
374
375 return data;
376}
static void notify_cli_uri_data_destroy(void *obj)

References ao2_alloc, ao2_ref, ast_strdup, build_cli_notify(), notify_uri_data::build_notify, sip_to_pjsip::info(), notify_uri_data::info, notify_cli_uri_data_destroy(), NULL, and notify_uri_data::uri.

Referenced by cli_notify(), and manager_notify_uri().

◆ notify_cli_uri_data_destroy()

static void notify_cli_uri_data_destroy ( void *  obj)
static

Definition at line 312 of file res_pjsip_notify.c.

313{
314 struct notify_uri_data *data = obj;
315
316 ast_free(data->uri);
317 ao2_cleanup(data->info);
318}

References ao2_cleanup, ast_free, notify_uri_data::info, and notify_uri_data::uri.

Referenced by notify_cli_uri_data_create().

◆ notify_contact()

static int notify_contact ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 650 of file res_pjsip_notify.c.

651{
652 struct ast_sip_contact *contact = obj;
653 struct notify_data *data = arg;
654 pjsip_tx_data *tdata;
655
656 if (ast_sip_create_request("NOTIFY", NULL, data->endpoint,
657 NULL, contact, &tdata)) {
658 ast_log(LOG_WARNING, "SIP NOTIFY - Unable to create request for "
659 "contact %s\n", contact->uri);
660 return -1;
661 }
662
663 ast_sip_add_header(tdata, "Subscription-State", "terminated");
664 data->build_notify(tdata, data->info);
665
666 if (ast_sip_send_request(tdata, NULL, data->endpoint, NULL, NULL)) {
667 ast_log(LOG_ERROR, "SIP NOTIFY - Unable to send request for "
668 "contact %s\n", contact->uri);
669 return -1;
670 }
671
672 return 0;
673}
Contact associated with an address of record.
Definition: res_pjsip.h:384
const ast_string_field uri
Definition: res_pjsip.h:406

References ast_log, ast_sip_add_header(), ast_sip_create_request(), ast_sip_send_request(), notify_data::build_notify, notify_data::endpoint, notify_data::info, LOG_ERROR, LOG_WARNING, NULL, and ast_sip_contact::uri.

Referenced by notify_endpoint().

◆ notify_endpoint()

static int notify_endpoint ( void *  obj)
static

Definition at line 682 of file res_pjsip_notify.c.

683{
684 RAII_VAR(struct notify_data *, data, obj, ao2_cleanup);
685 char *aor_name, *aors;
686
687 if (ast_strlen_zero(data->endpoint->aors)) {
688 ast_log(LOG_WARNING, "Unable to NOTIFY - "
689 "endpoint has no configured AORs\n");
690 return -1;
691 }
692
693 aors = ast_strdupa(data->endpoint->aors);
694
695 while ((aor_name = ast_strip(strsep(&aors, ",")))) {
696 RAII_VAR(struct ast_sip_aor *, aor,
698 RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
699
700 if (!aor || !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
701 continue;
702 }
703
704 ao2_callback(contacts, OBJ_NODATA, notify_contact, data);
705 }
706
707 return 0;
708}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
char * strsep(char **str, const char *delims)
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition: location.c:147
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
Definition: location.c:247
static int notify_contact(void *obj, void *arg, int flags)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
A SIP address of record.
Definition: res_pjsip.h:470

References ao2_callback, ao2_cleanup, ast_log, ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_aor_contacts(), ast_strdupa, ast_strip(), ast_strlen_zero(), LOG_WARNING, notify_contact(), NULL, OBJ_NODATA, RAII_VAR, and strsep().

Referenced by push_notify().

◆ notify_option_alloc()

static void * notify_option_alloc ( const char *  category)
static

Definition at line 163 of file res_pjsip_notify.c.

164{
165 int category_size = strlen(category) + 1;
166
167 struct notify_option *option = ao2_alloc(
168 sizeof(*option) + category_size, notify_option_destroy);
169
170 if (!option) {
171 return NULL;
172 }
173
174 ast_copy_string(option->name, category, category_size);
175
176 if (!(option->items = ao2_container_alloc_list(
179 ao2_cleanup(option);
180 return NULL;
181 }
182
183 return option;
184}
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
@ AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW
Allow objects with duplicate keys in container.
Definition: astobj2.h:1181
static void notify_option_destroy(void *obj)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

References ao2_alloc, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW, ast_copy_string(), notify_option::items, notify_option::name, notify_option_destroy(), and NULL.

◆ notify_option_cmp()

static int notify_option_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 148 of file res_pjsip_notify.c.

149{
150 struct notify_option *option1 = obj;
151 struct notify_option *option2 = arg;
152 const char *key = flags & OBJ_KEY ? arg : option2->name;
153
154 return strcasecmp(option1->name, key) ? 0 : CMP_MATCH;
155}
@ CMP_MATCH
Definition: astobj2.h:1027
#define OBJ_KEY
Definition: astobj2.h:1151

References CMP_MATCH, notify_option::name, and OBJ_KEY.

Referenced by notify_cfg_alloc().

◆ notify_option_destroy()

static void notify_option_destroy ( void *  obj)
static

Definition at line 157 of file res_pjsip_notify.c.

158{
159 struct notify_option *option = obj;
160 ao2_cleanup(option->items);
161}

References ao2_cleanup, and notify_option::items.

Referenced by notify_option_alloc().

◆ notify_option_find()

static void * notify_option_find ( struct ao2_container container,
const char *  category 
)
static

Definition at line 186 of file res_pjsip_notify.c.

187{
188 return ao2_find(container, category, OBJ_KEY);
189}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
struct ao2_container * container
Definition: res_fax.c:501

References ao2_find, container, and OBJ_KEY.

Referenced by cli_notify(), manager_notify_endpoint(), and manager_notify_uri().

◆ notify_option_handler()

static int notify_option_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 191 of file res_pjsip_notify.c.

193{
194 struct notify_option *option = obj;
195
196 int name_size = strlen(var->name) + 1;
197 int value_size = strlen(var->value) + 1;
198
200 ao2_alloc(sizeof(*item) + name_size + value_size,
201 NULL), ao2_cleanup);
202
203 item->name = item->buf;
204 item->value = item->buf + name_size;
205
206 ast_copy_string(item->buf, var->name, name_size);
207 ast_copy_string(item->buf + name_size, var->value, value_size);
208
209 if (!ao2_link(option->items, item)) {
210 return -1;
211 }
212
213 return 0;
214}
#define var
Definition: ast_expr2f.c:605
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532

References ao2_alloc, ao2_cleanup, ao2_link, ast_copy_string(), item, notify_option::items, aco_type::name, NULL, RAII_VAR, and var.

Referenced by load_module().

◆ notify_option_hash()

static int notify_option_hash ( const void *  obj,
int  flags 
)
static

Definition at line 142 of file res_pjsip_notify.c.

143{
144 const struct notify_option *option = obj;
145 return ast_str_case_hash(flags & OBJ_KEY ? obj : option->name);
146}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

References ast_str_case_hash(), notify_option::name, and OBJ_KEY.

Referenced by notify_cfg_alloc().

◆ notify_uri()

static int notify_uri ( void *  obj)
static

Definition at line 714 of file res_pjsip_notify.c.

715{
716 RAII_VAR(struct notify_uri_data *, data, obj, ao2_cleanup);
717 RAII_VAR(struct ast_sip_endpoint *, endpoint,
719 pjsip_tx_data *tdata;
720
721 if (!endpoint) {
722 ast_log(LOG_WARNING, "No default outbound endpoint set, can not send "
723 "NOTIFY requests to arbitrary URIs.\n");
724 return -1;
725 }
726
727 if (ast_strlen_zero(data->uri)) {
728 ast_log(LOG_WARNING, "Unable to NOTIFY - URI is blank.\n");
729 return -1;
730 }
731
732 if (ast_sip_create_request("NOTIFY", NULL, endpoint,
733 data->uri, NULL, &tdata)) {
734 ast_log(LOG_WARNING, "SIP NOTIFY - Unable to create request for "
735 "uri %s\n", data->uri);
736 return -1;
737 }
738
739 ast_sip_add_header(tdata, "Subscription-State", "terminated");
740
741 data->build_notify(tdata, data->info);
742
743 if (ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL)) {
744 ast_log(LOG_ERROR, "SIP NOTIFY - Unable to send request for "
745 "uri %s\n", data->uri);
746 return -1;
747 }
748
749 return 0;
750}
struct ast_sip_endpoint * ast_sip_default_outbound_endpoint(void)
Retrieve the default outbound endpoint.

References ao2_cleanup, ast_log, ast_sip_add_header(), ast_sip_create_request(), ast_sip_default_outbound_endpoint(), ast_sip_send_request(), ast_strlen_zero(), notify_data::endpoint, LOG_ERROR, LOG_WARNING, NULL, and RAII_VAR.

Referenced by push_notify_uri().

◆ push_notify()

static enum notify_result push_notify ( const char *  endpoint_name,
void *  info,
task_data_create  data_create 
)
static

Definition at line 808 of file res_pjsip_notify.c.

810{
811 RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
812 struct notify_data *data;
813
815 ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
816 return INVALID_ENDPOINT;
817 }
818
819 if (!(data = data_create(endpoint, info))) {
820 return ALLOC_ERROR;
821 }
822
824 ao2_cleanup(data);
825 return TASK_PUSH_ERROR;
826 }
827
828 return SUCCESS;
829}
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:2099
static int notify_endpoint(void *obj)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853

References ALLOC_ERROR, ao2_cleanup, ast_sip_get_sorcery(), ast_sip_push_task(), ast_sorcery_retrieve_by_id(), ast_sip_session::endpoint, notify_data::endpoint, sip_to_pjsip::info(), INVALID_ENDPOINT, notify_endpoint(), NULL, RAII_VAR, SUCCESS, and TASK_PUSH_ERROR.

Referenced by cli_notify(), and manager_notify_endpoint().

◆ push_notify_channel()

static enum notify_result push_notify_channel ( const char *  channel_name,
void *  info,
task_channel_data_create  data_create 
)
static

Definition at line 856 of file res_pjsip_notify.c.

858{
859 struct notify_channel_data *data;
860 struct ast_channel *ch;
861 struct ast_sip_session *session;
862 struct ast_sip_channel_pvt *ch_pvt;
863
864 /* note: this increases the refcount of the channel */
865 ch = ast_channel_get_by_name(channel_name);
866 if (!ch) {
867 ast_debug(1, "No channel found with name %s", channel_name);
868 return INVALID_CHANNEL;
869 }
870
871 if (strcmp(ast_channel_tech(ch)->type, "PJSIP")) {
872 ast_log(LOG_WARNING, "Channel was a non-PJSIP channel: %s\n", channel_name);
874 return INVALID_CHANNEL;
875 }
876
878 ch_pvt = ast_channel_tech_pvt(ch);
879 session = ch_pvt->session;
880
881 if (!session || !session->inv_session
882 || session->inv_session->state < PJSIP_INV_STATE_EARLY
883 || session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
884 ast_debug(1, "No active session for channel %s\n", channel_name);
887 return INVALID_CHANNEL;
888 }
889
890 ao2_ref(session, +1);
892
893 /* don't keep a reference to the channel, we've got a reference to the session */
895
896 /*
897 * data_create will take ownership of the session,
898 * and take care of releasing the ref.
899 */
900 data = data_create(session, info);
901 if (!data) {
902 ao2_ref(session, -1);
903 return ALLOC_ERROR;
904 }
905
906 if (ast_sip_push_task(session->serializer, notify_channel, data)) {
907 ao2_ref(data, -1);
908 return TASK_PUSH_ERROR;
909 }
910
911 return SUCCESS;
912}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define ast_channel_unlock(chan)
Definition: channel.h:2923
static int notify_channel(void *obj)
Main Channel structure associated with a channel.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
A structure describing a SIP session.

References ALLOC_ERROR, ao2_ref, ast_channel_get_by_name(), ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_log, ast_sip_push_task(), sip_to_pjsip::info(), INVALID_CHANNEL, LOG_WARNING, notify_channel(), ast_sip_channel_pvt::session, session, SUCCESS, TASK_PUSH_ERROR, and type.

Referenced by manager_notify_channel().

◆ push_notify_uri()

static enum notify_result push_notify_uri ( const char *  uri,
void *  info,
task_uri_data_create  data_create 
)
static

Definition at line 835 of file res_pjsip_notify.c.

837{
838 struct notify_uri_data *data;
839
840 if (!(data = data_create(uri, info))) {
841 return ALLOC_ERROR;
842 }
843
844 if (ast_sip_push_task(NULL, notify_uri, data)) {
845 ao2_cleanup(data);
846 return TASK_PUSH_ERROR;
847 }
848
849 return SUCCESS;
850}
static int notify_uri(void *obj)

References ALLOC_ERROR, ao2_cleanup, ast_sip_push_task(), sip_to_pjsip::info(), notify_uri(), NULL, SUCCESS, TASK_PUSH_ERROR, and notify_uri_data::uri.

Referenced by cli_notify(), and manager_notify_uri().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1269 of file res_pjsip_notify.c.

1270{
1273 }
1274
1275 return 0;
1276}
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.

References aco_process_config(), ACO_PROCESS_ERROR, and AST_MODULE_LOAD_DECLINE.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1278 of file res_pjsip_notify.c.

1279{
1280 ast_manager_unregister("PJSIPNotify");
1284
1285 return 0;
1286}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8014

References aco_info_destroy(), ao2_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), cli_options, and globals.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CLI/AMI PJSIP NOTIFY Support" , .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, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip", }
static

Definition at line 1295 of file res_pjsip_notify.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1295 of file res_pjsip_notify.c.

◆ cli_options

struct ast_cli_entry cli_options[]
static
Initial value:
= {
{ .handler = cli_notify , .summary = "Send a NOTIFY request to a SIP endpoint" ,}
}
static char * cli_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 1075 of file res_pjsip_notify.c.

Referenced by load_module(), and unload_module().

◆ module_conf

struct aco_file module_conf
static
Initial value:
= {
.filename = notify_config,
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static const char notify_config[]

Definition at line 256 of file res_pjsip_notify.c.

◆ notify_config

const char notify_config[] = "pjsip_notify.conf"
static

Definition at line 127 of file res_pjsip_notify.c.

◆ notify_option

struct aco_type notify_option
static

Definition at line 244 of file res_pjsip_notify.c.

◆ notify_options

struct aco_type* notify_options[] = ACO_TYPES(&notify_option)
static

Definition at line 254 of file res_pjsip_notify.c.

Referenced by load_module().