Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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. More...
 
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. More...
 
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 = "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 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:1262
#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)
#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.
const char * args
#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 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
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)
Support for dynamic strings.
Definition: strings.h:623
struct ast_variable * next

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 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
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_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
#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 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 * 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:2768
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:2317
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:1989
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:1872
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:666

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:1986
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
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:1738
@ 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:1991
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[]
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:2018
#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 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, sip_to_pjsip::info(), 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

◆ 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, 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 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, 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 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, sip_to_pjsip::info(), 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(), 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 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, sip_to_pjsip::info(), 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, 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 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, sip_to_pjsip::info(), 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:531

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: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 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:2972
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition: channel.c:1397
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
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 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(), sip_to_pjsip::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}
#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:7697
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 = "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 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.

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.

◆ 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.

◆ 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().