Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
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/app.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)
 
static int app_notify (struct ast_channel *chan, const char *data)
 Application entry point to send a SIP notify to an endpoint.
 
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 (struct ast_cli_args *a)
 
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 struct ast_variableheaders_to_variables (const char *headers)
 Convert headers string such as "Event=hold&Event=answer&..." into ast variable list.
 
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_channel_datanotify_cli_channel_data_create (struct ast_sip_session *session, void *info)
 
static void notify_cli_channel_data_destroy (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 = ASTERISK_GPL_KEY , .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 128 of file res_pjsip_notify.c.

◆ CONTENT_TYPE_SIZE

#define CONTENT_TYPE_SIZE   64

Definition at line 127 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 794 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 794 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 794 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 825 of file res_pjsip_notify.c.

825 {
826 SUCCESS,
831};
@ TASK_PUSH_ERROR
@ ALLOC_ERROR
@ SUCCESS
@ INVALID_ENDPOINT
@ INVALID_CHANNEL

◆ notify_type

Enumerator
NOTIFY_ENDPOINT 
NOTIFY_URI 
NOTIFY_CHANNEL 

Definition at line 1135 of file res_pjsip_notify.c.

1135 {
1137 NOTIFY_URI,
1139};
@ NOTIFY_CHANNEL
@ NOTIFY_ENDPOINT
@ NOTIFY_URI

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1444 of file res_pjsip_notify.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1444 of file res_pjsip_notify.c.

◆ AO2_GLOBAL_OBJ_STATIC()

AO2_GLOBAL_OBJ_STATIC ( globals  )

◆ app_notify()

static int app_notify ( struct ast_channel chan,
const char *  data 
)
static

Application entry point to send a SIP notify to an endpoint.

Definition at line 1335 of file res_pjsip_notify.c.

1336{
1337 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1338 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1339
1340 struct ast_variable *varlist = NULL;
1341 char *tmp;
1342 int res;
1344 AST_APP_ARG(to);
1345 AST_APP_ARG(headers);
1346 );
1347
1348
1349 if (ast_strlen_zero(data)) {
1350 ast_log(LOG_WARNING, "PJSIPNotify requires arguments (to, &header=...)\n");
1351 return -1;
1352 }
1353
1354 tmp = ast_strdupa(data);
1357
1358 if (!(option = notify_option_find(cfg->notify_options, args.headers))) {
1359 /* If the app is passed a list of headers, use the notify_ami_*_data_create
1360 functions as the option data is handled the same way as the ami command. */
1361 varlist = headers_to_variables(args.headers);
1362 if (ast_strlen_zero(args.to)) {
1364 } else {
1366 }
1367 } else {
1368 /* If the app is passed a configured notify option, use the notify_cli_*_data_create
1369 functions as the option data is handled the same way as the cli command. */
1370 if (ast_strlen_zero(args.to)) {
1372 } else {
1374 }
1375 }
1376
1377 switch (res) {
1378 case INVALID_CHANNEL:
1379 case INVALID_ENDPOINT:
1380 case ALLOC_ERROR:
1381 res = -1;
1382 ast_variables_destroy(varlist);
1383 break;
1384 case TASK_PUSH_ERROR:
1385 /* Don't need to destroy vars since it is handled by cleanup in push_notify_channel */
1386 res = -1;
1387 break;
1388 case SUCCESS:
1389 res = 0;
1390 break;
1391 }
1392
1393 return res;
1394}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_log
Definition astobj2.c:42
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#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
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
#define LOG_WARNING
static void * notify_option_find(struct ao2_container *container, const char *category)
static struct notify_channel_data * notify_cli_channel_data_create(struct ast_sip_session *session, void *info)
static enum notify_result push_notify_channel(const char *channel_name, void *info, task_channel_data_create data_create)
static struct notify_uri_data * notify_ami_uri_data_create(const char *uri, void *info)
static enum notify_result push_notify_uri(const char *uri, void *info, task_uri_data_create data_create)
static struct ast_variable * headers_to_variables(const char *headers)
Convert headers string such as "Event=hold&Event=answer&..." into ast variable list.
static struct notify_channel_data * notify_ami_channel_data_create(struct ast_sip_session *session, void *info)
static struct notify_uri_data * notify_cli_uri_data_create(const char *uri, void *info)
static struct @519 args
#define NULL
Definition resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
Structure for variables, used for configurations and for channel variables.
#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:978

References ALLOC_ERROR, ao2_cleanup, ao2_global_obj_ref, args, AST_APP_ARG, ast_channel_name(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variables_destroy(), globals, headers_to_variables(), INVALID_CHANNEL, INVALID_ENDPOINT, LOG_WARNING, notify_ami_channel_data_create(), notify_ami_uri_data_create(), notify_cli_channel_data_create(), notify_cli_uri_data_create(), notify_option_find(), NULL, push_notify_channel(), push_notify_uri(), RAII_VAR, SUCCESS, and TASK_PUSH_ERROR.

Referenced by load_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1444 of file res_pjsip_notify.c.

◆ build_ami_notify()

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

Definition at line 665 of file res_pjsip_notify.c.

666{
667 struct ast_variable *vars = info;
668 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
669 RAII_VAR(struct ast_str *, content, NULL, ast_free);
670 struct ast_variable *i;
671
672 for (i = vars; i; i = i->next) {
673 if (!strcasecmp(i->name, "Content-Length")) {
674 ast_log(LOG_NOTICE, "It is not necessary to specify Content-Length, ignoring.\n");
675 continue;
676 }
677 build_notify(tdata, i->name, i->value,
678 &content_type, &content);
679 }
680
681 build_notify_body(tdata, content_type, content);
682}
#define ast_free(a)
Definition astmm.h:180
#define LOG_NOTICE
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)
Support for dynamic strings.
Definition strings.h:623
struct ast_variable * next

References ast_free, ast_log, build_notify(), build_notify_body(), 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 641 of file res_pjsip_notify.c.

642{
643 struct notify_option *option = info;
644 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
645 RAII_VAR(struct ast_str *, content, NULL, ast_free);
646
647 struct notify_option_item *item;
648 struct ao2_iterator i = ao2_iterator_init(option->items, 0);
649
650 while ((item = ao2_iterator_next(&i))) {
651 build_notify(tdata, item->name, item->value,
652 &content_type, &content);
654 }
656
657 build_notify_body(tdata, content_type, content);
658}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
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

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

Referenced by notify_cli_channel_data_create(), 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 596 of file res_pjsip_notify.c.

598{
599 if (not_allowed(name)) {
600 ast_log(LOG_WARNING, "Cannot specify %s header, "
601 "ignoring\n", name);
602 return;
603 }
604
605 if (!strcasecmp(name, "Content-type")) {
606 if (!(*content_type)) {
607 *content_type = ast_str_create(CONTENT_TYPE_SIZE);
608 }
609 ast_str_set(content_type, 0,"%s", value);
610 } else if (!strcasecmp(name, "Content")) {
611 if (!(*content)) {
612 *content = ast_str_create(CONTENT_SIZE);
613 }
614
615 if (ast_str_strlen(*content)) {
616 ast_str_append(content, 0, "\r\n");
617 }
618 ast_str_append(content, 0, "%s", value);
619 } else {
620 /* See if there is an existing one */
622 pj_str_t hdr_name;
623 pj_cstr(&hdr_name, name);
624
625 if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name, NULL)) {
626 ast_log(LOG_ERROR, "Only one '%s' header can be added to a NOTIFY, "
627 "ignoring \"%s: %s\"\n", name, name, value);
628 return;
629 }
630 }
631
633 }
634}
static const char name[]
Definition format_mp3.c:68
#define LOG_ERROR
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
size_t attribute_pure ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition strings.h:730
#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
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 572 of file res_pjsip_notify.c.

574{
575 if (content_type) {
576 char *p;
577 struct ast_sip_body body;
578
579 if (content) {
580 body.body_text = ast_str_buffer(content);
581 }
582
583 body.type = ast_str_buffer(content_type);
584 if ((p = strchr(body.type, '/'))) {
585 *p++ = '\0';
586 body.subtype = p;
587 }
588 ast_sip_add_body(tdata, &body);
589 }
590}
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 *attribute_pure 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:2444
const char * body_text
Definition res_pjsip.h:2450

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 956 of file res_pjsip_notify.c.

957{
958 int wordlen = strlen(word);
959 struct ao2_container * endpoints;
960 struct ast_sip_endpoint *endpoint;
961 struct ao2_iterator i;
962
964 "endpoint", word, wordlen);
965 if (endpoints == NULL) {
966 return NULL;
967 }
968
970 while ((endpoint = ao2_iterator_next(&i))) {
973 ao2_cleanup(endpoint);
974 }
976
977 ao2_ref(endpoints, -1);
978
979 return NULL;
980}
#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:2737
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:2381
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:2053
Generic container type.
An entity with which Asterisk communicates.
Definition res_pjsip.h:1051

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 ( struct ast_cli_args a)
static

Definition at line 986 of file res_pjsip_notify.c.

987{
988 char *c = NULL;
989
990 if (a->pos == 3) {
991 int which = 0;
992 int wordlen = strlen(a->word);
993
994 RAII_VAR(struct notify_cfg *, cfg,
996 struct notify_option *option;
997
998 /* do completion for notify type */
999 struct ao2_iterator i = ao2_iterator_init(cfg->notify_options, 0);
1000 while ((option = ao2_iterator_next(&i))) {
1001 if (!strncasecmp(a->word, option->name, wordlen) && ++which > a->n) {
1002 c = ast_strdup(option->name);
1003 }
1004
1005 ao2_cleanup(option);
1006 if (c) {
1007 break;
1008 }
1009 }
1011 return c;
1012 }
1013
1014 if (a->pos == 4) {
1015 int wordlen = strlen(a->word);
1016
1017 if (ast_strlen_zero(a->word)) {
1018 if (a->n == 0) {
1019 c = ast_strdup("endpoint");
1020 } else if (a->n == 1) {
1021 c = ast_strdup("uri");
1022 } else if (a->n == 2) {
1023 c = ast_strdup("channel");
1024 }
1025 } else if (a->n == 0) {
1026 if (!strncasecmp(a->word, "endpoint", wordlen)) {
1027 c = ast_strdup("endpoint");
1028 } else if (!strncasecmp(a->word, "uri", wordlen)) {
1029 c = ast_strdup("uri");
1030 } else if (!strncasecmp(a->word, "channel", wordlen)) {
1031 c = ast_strdup("channel");
1032 }
1033 }
1034
1035 return c;
1036 }
1037
1038 if (a->pos > 4) {
1039 if (!strcasecmp(a->argv[4], "endpoint")) {
1040 return cli_complete_endpoint(a->word);
1041 } else if (!strcasecmp(a->argv[4], "channel")) {
1042 return ast_complete_channels(a->line, a->word, a->pos, a->n, 5);
1043 }
1044 }
1045 return NULL;
1046}
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition main/cli.c:1842
static char * cli_complete_endpoint(const char *word)
static struct test_val a
static struct test_val c

References a, ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_complete_channels(), 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 1056 of file res_pjsip_notify.c.

1057{
1058 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1059 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1060
1061 int i;
1062 int using_uri = 0;
1063 int using_channel = 0;
1064
1065 switch (cmd) {
1066 case CLI_INIT:
1067 e->command = "pjsip send notify";
1068 e->usage =
1069 "Usage: pjsip send notify <type> {endpoint|uri|channel} <peer> [<peer>...]\n"
1070 " Send a NOTIFY request to an endpoint\n"
1071 " Message types are defined in pjsip_notify.conf\n";
1072 return NULL;
1073 case CLI_GENERATE:
1074 return cli_complete_notify(a);
1075 }
1076
1077 if (a->argc < 6) {
1078 return CLI_SHOWUSAGE;
1079 }
1080
1081 if (!strcasecmp(a->argv[4], "uri")) {
1082 using_uri = 1;
1083 } else if (!strcasecmp(a->argv[4], "channel")) {
1084 using_channel = 1;
1085 } else if (strcasecmp(a->argv[4], "endpoint")) {
1086 return CLI_SHOWUSAGE;
1087 }
1088
1090
1091 if (!(option = notify_option_find(cfg->notify_options, a->argv[3])))
1092 {
1093 ast_cli(a->fd, "Unable to find notify type '%s'\n",
1094 a->argv[3]);
1095 return CLI_FAILURE;
1096 }
1097
1098 for (i = 5; i < a->argc; ++i) {
1099 enum notify_result result;
1100 ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n",
1101 a->argv[3], a->argv[i]);
1102
1103 if (using_uri) {
1105 } else if (using_channel) {
1107 } else {
1108 result = push_notify(a->argv[i], option, notify_cli_data_create);
1109 }
1110 switch(result) {
1111 case INVALID_ENDPOINT:
1112 ast_cli(a->fd, "Unable to retrieve endpoint %s\n", a->argv[i]);
1113 break;
1114 case INVALID_CHANNEL:
1115 ast_cli(a->fd, "Unable to find channel %s\n", a->argv[i]);
1116 break;
1117 case ALLOC_ERROR:
1118 ast_cli(a->fd, "Unable to allocate NOTIFY task data\n");
1119 return CLI_FAILURE;
1120 case TASK_PUSH_ERROR:
1121 ast_cli(a->fd, "Unable to push NOTIFY task\n");
1122 return CLI_FAILURE;
1123 default:
1124 break;
1125 }
1126 }
1127
1128 return CLI_SUCCESS;
1129}
static PGresult * result
Definition cel_pgsql.c:84
#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 struct notify_data * notify_cli_data_create(struct ast_sip_endpoint *endpoint, void *info)
notify_result
static char * cli_complete_notify(struct ast_cli_args *a)
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

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_CHANNEL, INVALID_ENDPOINT, notify_cli_channel_data_create(), notify_cli_data_create(), notify_cli_uri_data_create(), notify_option_find(), NULL, push_notify(), push_notify_channel(), push_notify_uri(), RAII_VAR, result, 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) 
)

◆ headers_to_variables()

static struct ast_variable * headers_to_variables ( const char *  headers)
static

Convert headers string such as "Event=hold&Event=answer&..." into ast variable list.

Definition at line 1307 of file res_pjsip_notify.c.

1308{
1309 struct ast_variable *varlist = NULL;
1310 struct ast_variable *var;
1311 char *cur;
1312 char *header;
1313
1314 cur = (char *)headers;
1315
1316 while( (header = strsep(&cur, "&")) ) {
1317 char *name;
1318 char *value;
1319
1320 name = value = header;
1321 strsep(&value, "=");
1322
1323 if (!value || ast_strlen_zero(name)) {
1324 continue;
1325 }
1326
1328 var->next = varlist;
1329 varlist = var;
1330 }
1331 return varlist;
1332}
#define var
Definition ast_expr2f.c:605
char * strsep(char **str, const char *delims)
#define ast_variable_new(name, value, filename)

References ast_strlen_zero(), ast_variable_new, name, NULL, strsep(), value, and var.

Referenced by app_notify().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1396 of file res_pjsip_notify.c.

1397{
1398 if (aco_info_init(&notify_cfg)) {
1400 }
1401
1403 "", notify_option_handler, 0);
1404
1405 if (aco_process_config(&notify_cfg, 0)) {
1408 }
1409
1413
1415}
#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:192
@ 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
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition module.h:640
static struct aco_type * notify_options[]
static int app_notify(struct ast_channel *chan, const char *data)
Application entry point to send a SIP notify to an endpoint.
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:703

References aco_info_destroy(), aco_info_init(), aco_option_register_custom, ACO_PREFIX, aco_process_config(), app_notify(), ARRAY_LEN, ast_cli_register_multiple, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, 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 1264 of file res_pjsip_notify.c.

1265{
1266 const char *endpoint_name = astman_get_header(m, "Endpoint");
1267 const char *uri = astman_get_header(m, "URI");
1268 const char *channel = astman_get_header(m, "Channel");
1269 const char *variables = astman_get_header(m, "Variable");
1270 const char *option = astman_get_header(m, "Option");
1271 int count = 0;
1272
1273 if (!ast_strlen_zero(endpoint_name)) {
1274 ++count;
1275 }
1276 if (!ast_strlen_zero(uri)) {
1277 ++count;
1278 }
1279 if (!ast_strlen_zero(channel)) {
1280 ++count;
1281 }
1282
1283 if ((!ast_strlen_zero(option) && !ast_strlen_zero(variables)) || (ast_strlen_zero(option) && ast_strlen_zero(variables))) {
1284 astman_send_error(s, m,
1285 "PJSIPNotify requires either an Option or Variable(s)."
1286 "You must use only one of them.");
1287 } else if (1 < count) {
1288 astman_send_error(s, m,
1289 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel. "
1290 "You must use only one of them.");
1291 } else if (!ast_strlen_zero(endpoint_name)) {
1292 manager_notify_endpoint(s, m, endpoint_name);
1293 } else if (!ast_strlen_zero(uri)) {
1294 manager_notify_uri(s, m, uri);
1295 } else if (!ast_strlen_zero(channel)) {
1296 manager_notify_channel(s, m, channel);
1297 } else {
1298 astman_send_error(s, m,
1299 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.");
1300 }
1301
1302 return 0;
1303}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition manager.c:1982
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition manager.c:1643
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 1248 of file res_pjsip_notify.c.

1250{
1251 enum notify_result res;
1252 struct ast_variable *vars = NULL;
1253
1256
1257 manager_send_response(s, m, NOTIFY_CHANNEL, res, vars, NULL);
1258}
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:1734
@ ORDER_NATURAL
Definition manager.h:289
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 1180 of file res_pjsip_notify.c.

1182{
1183 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1184 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1185 struct ast_variable *vars = NULL;
1186 enum notify_result res;
1187 const char *option_name = astman_get_header(m, "Option");
1188
1189 if (!ast_strlen_zero(option_name) && (cfg = ao2_global_obj_ref(globals)) && !(option = notify_option_find(cfg->notify_options, option_name))) {
1190 astman_send_error_va(s, m, "Unable to find notify type '%s'\n", option_name);
1191 return;
1192 }
1193 if (!option) {
1195 }
1196
1197 if (!strncasecmp(endpoint_name, "sip/", 4)) {
1198 endpoint_name += 4;
1199 }
1200
1201 if (!strncasecmp(endpoint_name, "pjsip/", 6)) {
1202 endpoint_name += 6;
1203 }
1204
1205 if (option) {
1206 res = push_notify(endpoint_name, option, notify_cli_data_create); /* The CLI version happens to be suitable for options. */
1207 } else {
1208 res = push_notify(endpoint_name, vars, notify_ami_data_create);
1209 }
1210
1211 manager_send_response(s, m, NOTIFY_ENDPOINT, res, vars, endpoint_name);
1212}
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:1987
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 1218 of file res_pjsip_notify.c.

1220{
1221 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1222 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1223 enum notify_result res;
1224 const char *option_name = astman_get_header(m, "Option");
1225 struct ast_variable *vars = NULL;
1226
1227 if (!ast_strlen_zero(option_name) && (cfg = ao2_global_obj_ref(globals)) && !(option = notify_option_find(cfg->notify_options, option_name))) {
1228 astman_send_error_va(s, m, "Unable to find notify type '%s'\n", option_name);
1229 return;
1230 }
1231 if (!option) {
1233 }
1234
1235 if (option) {
1236 res = push_notify_uri(uri, option, notify_cli_uri_data_create);
1237 } else {
1239 }
1240
1241 manager_send_response(s, m, NOTIFY_URI, res, vars, NULL);
1242}

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 1141 of file res_pjsip_notify.c.

1142{
1143 switch (res) {
1144 case INVALID_CHANNEL:
1145 if (type == NOTIFY_CHANNEL) {
1147 astman_send_error(s, m, "Channel not found");
1148 } else {
1149 /* Shouldn't be possible. */
1150 ast_assert(0);
1151 }
1152 break;
1153 case INVALID_ENDPOINT:
1154 if (type == NOTIFY_ENDPOINT) {
1156 astman_send_error_va(s, m, "Unable to retrieve endpoint %s", endpoint_name);
1157 } else {
1158 /* Shouldn't be possible. */
1159 ast_assert(0);
1160 }
1161 break;
1162 case ALLOC_ERROR:
1164 astman_send_error(s, m, "Unable to allocate NOTIFY task data");
1165 break;
1166 case TASK_PUSH_ERROR:
1167 /* Don't need to destroy vars since it is handled by cleanup in push_notify, push_notify_uri, etc. */
1168 astman_send_error(s, m, "Unable to push Notify task");
1169 break;
1170 case SUCCESS:
1171 astman_send_ack(s, m, "NOTIFY sent");
1172 break;
1173 }
1174}
static const char type[]
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition manager.c:2014
#define ast_assert(a)
Definition utils.h:776

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 561 of file res_pjsip_notify.c.

562{
563 /* This can be extended to include additional headers */
564 return strcasecmp("Event", name);
565}

References name.

Referenced by build_notify().

◆ not_allowed()

static int not_allowed ( const char *  name)
static

Definition at line 534 of file res_pjsip_notify.c.

535{
536 int i;
537 static const char *names[] = {
538 "Call-ID",
539 "Contact",
540 "CSeq",
541 "To",
542 "From",
543 "Record-Route",
544 "Route",
545 "Request-URI",
546 "Via",
547 };
548
549 for (i = 0; i < ARRAY_LEN(names); ++i) {
550 if (!strcasecmp(name, names[i])) {
551 return 1;
552 }
553 }
554 return 0;
555}

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 508 of file res_pjsip_notify.c.

510{
511 struct notify_channel_data *data;
512
515 if (!data) {
516 return NULL;
517 }
518
519 data->session = session;
520 data->info = info;
522
523 return data;
524}
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, notify_channel_data::info, notify_ami_channel_data_destroy(), NULL, notify_channel_data::session, and session.

Referenced by app_notify(), and manager_notify_channel().

◆ notify_ami_channel_data_destroy()

static void notify_ami_channel_data_destroy ( void *  obj)
static

Definition at line 446 of file res_pjsip_notify.c.

447{
448 struct notify_channel_data *data = obj;
449 struct ast_variable *info = data->info;
450
451 ao2_cleanup(data->session);
453}

References ao2_cleanup, ast_variables_destroy(), notify_channel_data::info, and notify_channel_data::session.

Referenced by notify_ami_channel_data_create().

◆ notify_ami_data_create()

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

Definition at line 461 of file res_pjsip_notify.c.

463{
464 struct notify_data *data = ao2_alloc(sizeof(*data),
466 if (!data) {
467 return NULL;
468 }
469
470 data->endpoint = endpoint;
471 ao2_ref(data->endpoint, +1);
472
473 data->info = info;
475
476 return data;
477}
#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, 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 420 of file res_pjsip_notify.c.

421{
422 struct notify_data *data = obj;
423 struct ast_variable *info = data->info;
424
425 ao2_cleanup(data->endpoint);
427}

References ao2_cleanup, ast_variables_destroy(), notify_data::endpoint, 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 483 of file res_pjsip_notify.c.

485{
486 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
488 if (!data) {
489 return NULL;
490 }
491
492 data->uri = ast_strdup(uri);
493 if (!data->uri) {
494 ao2_ref(data, -1);
495 return NULL;
496 }
497
498 data->info = info;
500
501 return data;
502}
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, notify_uri_data::info, notify_ami_uri_data_destroy(), NULL, and notify_uri_data::uri.

Referenced by app_notify(), and manager_notify_uri().

◆ notify_ami_uri_data_destroy()

static void notify_ami_uri_data_destroy ( void *  obj)
static

Definition at line 433 of file res_pjsip_notify.c.

434{
435 struct notify_uri_data *data = obj;
436 struct ast_variable *info = data->info;
437
438 ast_free(data->uri);
440}

References ast_free, ast_variables_destroy(), 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 233 of file res_pjsip_notify.c.

234{
235 struct notify_cfg *cfg;
236
237 if (!(cfg = ao2_alloc(sizeof(*cfg), notify_cfg_destroy))) {
238 return NULL;
239 }
240
243 if (!cfg->notify_options) {
244 ao2_cleanup(cfg);
245 return NULL;
246 }
247
248 return cfg;
249}
#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 227 of file res_pjsip_notify.c.

228{
229 struct notify_cfg *cfg = obj;
231}

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 794 of file res_pjsip_notify.c.

795{
796 RAII_VAR(struct notify_channel_data *, data, obj, ao2_cleanup);
797 pjsip_tx_data *tdata;
798 struct pjsip_dialog *dlg;
799
800 if (!data->session->channel
801 || !data->session->inv_session
802 || data->session->inv_session->state < PJSIP_INV_STATE_EARLY
803 || data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
804 return -1;
805 }
806
807 ast_debug(1, "Sending notify on channel %s\n", ast_channel_name(data->session->channel));
808
809 dlg = data->session->inv_session->dlg;
810
811 if (ast_sip_create_request("NOTIFY", dlg, NULL, NULL, NULL, &tdata)) {
812 return -1;
813 }
814
815 ast_sip_add_header(tdata, "Subscription-State", "terminated");
816 data->build_notify(tdata, data->info);
817
818 if (ast_sip_send_request(tdata, dlg, NULL, NULL, NULL)) {
819 return -1;
820 }
821
822 return 0;
823}
#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_channel_data_create()

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

Definition at line 397 of file res_pjsip_notify.c.

399{
400 struct notify_channel_data *data = ao2_alloc_options(sizeof(*data),
402
403 if (!data) {
404 return NULL;
405 }
406
407 data->session = session;
408 data->info = info;
409 ao2_ref(data->info, +1);
410
412
413 return data;
414}
static void build_cli_notify(pjsip_tx_data *tdata, void *info)
static void notify_cli_channel_data_destroy(void *obj)

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_ref, build_cli_notify(), notify_channel_data::build_notify, notify_channel_data::info, notify_cli_channel_data_destroy(), NULL, notify_channel_data::session, and session.

Referenced by app_notify(), and cli_notify().

◆ notify_cli_channel_data_destroy()

static void notify_cli_channel_data_destroy ( void *  obj)
static

Definition at line 327 of file res_pjsip_notify.c.

328{
329 struct notify_channel_data *data = obj;
330
331 ao2_cleanup(data->info);
332 ao2_cleanup(data->session);
333}

References ao2_cleanup, notify_channel_data::info, and notify_channel_data::session.

Referenced by notify_cli_channel_data_create().

◆ notify_cli_data_create()

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

Definition at line 345 of file res_pjsip_notify.c.

347{
348 struct notify_data *data = ao2_alloc(sizeof(*data),
350 if (!data) {
351 return NULL;
352 }
353
354 data->endpoint = endpoint;
355 ao2_ref(data->endpoint, +1);
356
357 data->info = info;
358 ao2_ref(data->info, +1);
359
361
362 return data;
363}
static void notify_cli_data_destroy(void *obj)

References ao2_alloc, ao2_ref, build_cli_notify(), notify_data::build_notify, notify_data::endpoint, 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 291 of file res_pjsip_notify.c.

292{
293 struct notify_data *data = obj;
294
295 ao2_cleanup(data->endpoint);
296 ao2_cleanup(data->info);
297}

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 369 of file res_pjsip_notify.c.

371{
372 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
374
375 if (!data) {
376 return NULL;
377 }
378
379 data->uri = ast_strdup(uri);
380 if (!data->uri) {
381 ao2_ref(data, -1);
382 return NULL;
383 }
384
385 data->info = info;
386 ao2_ref(data->info, +1);
387
389
390 return data;
391}
static void notify_cli_uri_data_destroy(void *obj)

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

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

◆ notify_cli_uri_data_destroy()

static void notify_cli_uri_data_destroy ( void *  obj)
static

Definition at line 319 of file res_pjsip_notify.c.

320{
321 struct notify_uri_data *data = obj;
322
323 ast_free(data->uri);
324 ao2_cleanup(data->info);
325}

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 688 of file res_pjsip_notify.c.

689{
690 struct ast_sip_contact *contact = obj;
691 struct notify_data *data = arg;
692 pjsip_tx_data *tdata;
693
694 if (ast_sip_create_request("NOTIFY", NULL, data->endpoint,
695 NULL, contact, &tdata)) {
696 ast_log(LOG_WARNING, "SIP NOTIFY - Unable to create request for "
697 "contact %s\n", contact->uri);
698 return -1;
699 }
700
701 ast_sip_add_header(tdata, "Subscription-State", "terminated");
702 data->build_notify(tdata, data->info);
703
704 if (ast_sip_send_request(tdata, NULL, data->endpoint, NULL, NULL)) {
705 ast_log(LOG_ERROR, "SIP NOTIFY - Unable to send request for "
706 "contact %s\n", contact->uri);
707 return -1;
708 }
709
710 return 0;
711}
Contact associated with an address of record.
Definition res_pjsip.h:390
const ast_string_field uri
Definition res_pjsip.h:412

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 720 of file res_pjsip_notify.c.

721{
722 RAII_VAR(struct notify_data *, data, obj, ao2_cleanup);
723 char *aor_name, *aors;
724
725 if (ast_strlen_zero(data->endpoint->aors)) {
726 ast_log(LOG_WARNING, "Unable to NOTIFY - "
727 "endpoint has no configured AORs\n");
728 return -1;
729 }
730
731 aors = ast_strdupa(data->endpoint->aors);
732
733 while ((aor_name = ast_strip(strsep(&aors, ",")))) {
734 RAII_VAR(struct ast_sip_aor *, aor,
736 RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
737
738 if (!aor || !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
739 continue;
740 }
741
742 ao2_callback(contacts, OBJ_NODATA, notify_contact, data);
743 }
744
745 return 0;
746}
#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
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:478

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 170 of file res_pjsip_notify.c.

171{
172 int category_size = strlen(category) + 1;
173
174 struct notify_option *option = ao2_alloc(
175 sizeof(*option) + category_size, notify_option_destroy);
176
177 if (!option) {
178 return NULL;
179 }
180
181 ast_copy_string(option->name, category, category_size);
182
183 if (!(option->items = ao2_container_alloc_list(
186 ao2_cleanup(option);
187 return NULL;
188 }
189
190 return option;
191}
#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 155 of file res_pjsip_notify.c.

156{
157 struct notify_option *option1 = obj;
158 struct notify_option *option2 = arg;
159 const char *key = flags & OBJ_KEY ? arg : option2->name;
160
161 return strcasecmp(option1->name, key) ? 0 : CMP_MATCH;
162}
@ 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 164 of file res_pjsip_notify.c.

165{
166 struct notify_option *option = obj;
167 ao2_cleanup(option->items);
168}

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 193 of file res_pjsip_notify.c.

194{
195 return ao2_find(container, category, OBJ_KEY);
196}
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
struct ao2_container * container
Definition res_fax.c:603

References ao2_find, container, and OBJ_KEY.

Referenced by app_notify(), 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 198 of file res_pjsip_notify.c.

200{
201 struct notify_option *option = obj;
202
203 int name_size = strlen(var->name) + 1;
204 int value_size = strlen(var->value) + 1;
205
207 ao2_alloc(sizeof(*item) + name_size + value_size,
208 NULL), ao2_cleanup);
209
210 item->name = item->buf;
211 item->value = item->buf + name_size;
212
213 ast_copy_string(item->buf, var->name, name_size);
214 ast_copy_string(item->buf + name_size, var->value, value_size);
215
216 if (!ao2_link(option->items, item)) {
217 return -1;
218 }
219
220 return 0;
221}
#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 149 of file res_pjsip_notify.c.

150{
151 const struct notify_option *option = obj;
152 return ast_str_case_hash(flags & OBJ_KEY ? obj : option->name);
153}
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 752 of file res_pjsip_notify.c.

753{
754 RAII_VAR(struct notify_uri_data *, data, obj, ao2_cleanup);
755 RAII_VAR(struct ast_sip_endpoint *, endpoint,
757 pjsip_tx_data *tdata;
758
759 if (!endpoint) {
760 ast_log(LOG_WARNING, "No default outbound endpoint set, can not send "
761 "NOTIFY requests to arbitrary URIs.\n");
762 return -1;
763 }
764
765 if (ast_strlen_zero(data->uri)) {
766 ast_log(LOG_WARNING, "Unable to NOTIFY - URI is blank.\n");
767 return -1;
768 }
769
770 if (ast_sip_create_request("NOTIFY", NULL, endpoint,
771 data->uri, NULL, &tdata)) {
772 ast_log(LOG_WARNING, "SIP NOTIFY - Unable to create request for "
773 "uri %s\n", data->uri);
774 return -1;
775 }
776
777 ast_sip_add_header(tdata, "Subscription-State", "terminated");
778
779 data->build_notify(tdata, data->info);
780
781 if (ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL)) {
782 ast_log(LOG_ERROR, "SIP NOTIFY - Unable to send request for "
783 "uri %s\n", data->uri);
784 return -1;
785 }
786
787 return 0;
788}
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 846 of file res_pjsip_notify.c.

848{
849 RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
850 struct notify_data *data;
851
853 ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
854 return INVALID_ENDPOINT;
855 }
856
857 if (!(data = data_create(endpoint, info))) {
858 return ALLOC_ERROR;
859 }
860
862 ao2_cleanup(data);
863 return TASK_PUSH_ERROR;
864 }
865
866 return SUCCESS;
867}
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:1917

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, notify_data::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 894 of file res_pjsip_notify.c.

896{
897 struct notify_channel_data *data;
898 struct ast_channel *ch;
899 struct ast_sip_session *session;
900 struct ast_sip_channel_pvt *ch_pvt;
901
902 /* note: this increases the refcount of the channel */
903 ch = ast_channel_get_by_name(channel_name);
904 if (!ch) {
905 ast_debug(1, "No channel found with name %s", channel_name);
906 return INVALID_CHANNEL;
907 }
908
909 if (strcmp(ast_channel_tech(ch)->type, "PJSIP")) {
910 ast_log(LOG_WARNING, "Channel was a non-PJSIP channel: %s\n", channel_name);
912 return INVALID_CHANNEL;
913 }
914
916 ch_pvt = ast_channel_tech_pvt(ch);
917 session = ch_pvt->session;
918
919 if (!session || !session->inv_session
920 || session->inv_session->state < PJSIP_INV_STATE_EARLY
921 || session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
922 ast_debug(1, "No active session for channel %s\n", channel_name);
925 return INVALID_CHANNEL;
926 }
927
928 ao2_ref(session, +1);
930
931 /* don't keep a reference to the channel, we've got a reference to the session */
933
934 /*
935 * data_create will take ownership of the session,
936 * and take care of releasing the ref.
937 */
938 data = data_create(session, info);
939 if (!data) {
940 ao2_ref(session, -1);
941 return ALLOC_ERROR;
942 }
943
944 if (ast_sip_push_task(session->serializer, notify_channel, data)) {
945 ao2_ref(data, -1);
946 return TASK_PUSH_ERROR;
947 }
948
949 return SUCCESS;
950}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition channel.h:2982
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition channel.c:1398
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3018
#define ast_channel_unlock(chan)
Definition channel.h:2983
static int notify_channel(void *obj)
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
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_pvt(), ast_channel_unlock, ast_channel_unref, ast_debug, ast_log, ast_sip_push_task(), INVALID_CHANNEL, LOG_WARNING, notify_channel(), ast_sip_channel_pvt::session, session, SUCCESS, TASK_PUSH_ERROR, and type.

Referenced by app_notify(), cli_notify(), and 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 873 of file res_pjsip_notify.c.

875{
876 struct notify_uri_data *data;
877
878 if (!(data = data_create(uri, info))) {
879 return ALLOC_ERROR;
880 }
881
882 if (ast_sip_push_task(NULL, notify_uri, data)) {
883 ao2_cleanup(data);
884 return TASK_PUSH_ERROR;
885 }
886
887 return SUCCESS;
888}
static int notify_uri(void *obj)

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

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

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1417 of file res_pjsip_notify.c.

1418{
1421 }
1422
1423 return 0;
1424}
@ 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 1426 of file res_pjsip_notify.c.

1427{
1428 ast_manager_unregister("PJSIPNotify");
1429 ast_unregister_application("PJSIPNotify");
1433
1434 return 0;
1435}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition astobj2.h:859
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition manager.c:7698
int ast_unregister_application(const char *app)
Unregister an application.
Definition pbx_app.c:392

References aco_info_destroy(), ao2_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_unregister_application(), 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 = ASTERISK_GPL_KEY , .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 1444 of file res_pjsip_notify.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1444 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 1131 of file res_pjsip_notify.c.

1131 {
1132 AST_CLI_DEFINE(cli_notify, "Send a NOTIFY request to a SIP endpoint")
1133};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

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 263 of file res_pjsip_notify.c.

263 {
264 .filename = notify_config,
265 .types = ACO_TYPES(&notify_option),
266};

◆ notify_config

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

Definition at line 134 of file res_pjsip_notify.c.

◆ notify_option

struct aco_type notify_option
static

Definition at line 251 of file res_pjsip_notify.c.

251 {
252 .type = ACO_ITEM,
253 .name = "notify",
254 .category_match = ACO_BLACKLIST_EXACT,
255 .category = "general",
256 .item_offset = offsetof(struct notify_cfg, notify_options),
257 .item_alloc = notify_option_alloc,
258 .item_find = notify_option_find
259};
@ ACO_ITEM
@ ACO_BLACKLIST_EXACT
static void * notify_option_alloc(const char *category)

◆ notify_options

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

Definition at line 261 of file res_pjsip_notify.c.

Referenced by load_module().