Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 122 of file res_pjsip_notify.c.

◆ CONTENT_TYPE_SIZE

#define CONTENT_TYPE_SIZE   64

Definition at line 121 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 788 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 788 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 788 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 819 of file res_pjsip_notify.c.

819 {
820 SUCCESS,
825};
@ TASK_PUSH_ERROR
@ ALLOC_ERROR
@ SUCCESS
@ INVALID_ENDPOINT
@ INVALID_CHANNEL

◆ notify_type

Enumerator
NOTIFY_ENDPOINT 
NOTIFY_URI 
NOTIFY_CHANNEL 

Definition at line 1129 of file res_pjsip_notify.c.

1129 {
1131 NOTIFY_URI,
1133};
@ NOTIFY_CHANNEL
@ NOTIFY_ENDPOINT
@ NOTIFY_URI

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1438 of file res_pjsip_notify.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

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

1330{
1331 RAII_VAR(struct notify_cfg *, cfg, NULL, ao2_cleanup);
1332 RAII_VAR(struct notify_option *, option, NULL, ao2_cleanup);
1333
1334 struct ast_variable *varlist = NULL;
1335 char *tmp;
1336 int res;
1338 AST_APP_ARG(to);
1339 AST_APP_ARG(headers);
1340 );
1341
1342
1343 if (ast_strlen_zero(data)) {
1344 ast_log(LOG_WARNING, "PJSIPNotify requires arguments (to, &header=...)\n");
1345 return -1;
1346 }
1347
1348 tmp = ast_strdupa(data);
1351
1352 if (!(option = notify_option_find(cfg->notify_options, args.headers))) {
1353 /* If the app is passed a list of headers, use the notify_ami_*_data_create
1354 functions as the option data is handled the same way as the ami command. */
1355 varlist = headers_to_variables(args.headers);
1356 if (ast_strlen_zero(args.to)) {
1358 } else {
1360 }
1361 } else {
1362 /* If the app is passed a configured notify option, use the notify_cli_*_data_create
1363 functions as the option data is handled the same way as the cli command. */
1364 if (ast_strlen_zero(args.to)) {
1366 } else {
1368 }
1369 }
1370
1371 switch (res) {
1372 case INVALID_CHANNEL:
1373 case INVALID_ENDPOINT:
1374 case ALLOC_ERROR:
1375 res = -1;
1376 ast_variables_destroy(varlist);
1377 break;
1378 case TASK_PUSH_ERROR:
1379 /* Don't need to destroy vars since it is handled by cleanup in push_notify_channel */
1380 res = -1;
1381 break;
1382 case SUCCESS:
1383 res = 0;
1384 break;
1385 }
1386
1387 return res;
1388}
#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 int tmp()
Definition: bt_open.c:389
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, TASK_PUSH_ERROR, and tmp().

Referenced by load_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1438 of file res_pjsip_notify.c.

◆ build_ami_notify()

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

Definition at line 659 of file res_pjsip_notify.c.

660{
661 struct ast_variable *vars = info;
662 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
663 RAII_VAR(struct ast_str *, content, NULL, ast_free);
664 struct ast_variable *i;
665
666 for (i = vars; i; i = i->next) {
667 if (!strcasecmp(i->name, "Content-Length")) {
668 ast_log(LOG_NOTICE, "It is not necessary to specify Content-Length, ignoring.\n");
669 continue;
670 }
671 build_notify(tdata, i->name, i->value,
672 &content_type, &content);
673 }
674
675 build_notify_body(tdata, content_type, content);
676}
#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 635 of file res_pjsip_notify.c.

636{
637 struct notify_option *option = info;
638 RAII_VAR(struct ast_str *, content_type, NULL, ast_free);
639 RAII_VAR(struct ast_str *, content, NULL, ast_free);
640
641 struct notify_option_item *item;
642 struct ao2_iterator i = ao2_iterator_init(option->items, 0);
643
644 while ((item = ao2_iterator_next(&i))) {
645 build_notify(tdata, item->name, item->value,
646 &content_type, &content);
648 }
650
651 build_notify_body(tdata, content_type, content);
652}
#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 590 of file res_pjsip_notify.c.

592{
593 if (not_allowed(name)) {
594 ast_log(LOG_WARNING, "Cannot specify %s header, "
595 "ignoring\n", name);
596 return;
597 }
598
599 if (!strcasecmp(name, "Content-type")) {
600 if (!(*content_type)) {
601 *content_type = ast_str_create(CONTENT_TYPE_SIZE);
602 }
603 ast_str_set(content_type, 0,"%s", value);
604 } else if (!strcasecmp(name, "Content")) {
605 if (!(*content)) {
606 *content = ast_str_create(CONTENT_SIZE);
607 }
608
609 if (ast_str_strlen(*content)) {
610 ast_str_append(content, 0, "\r\n");
611 }
612 ast_str_append(content, 0, "%s", value);
613 } else {
614 /* See if there is an existing one */
616 pj_str_t hdr_name;
617 pj_cstr(&hdr_name, name);
618
619 if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name, NULL)) {
620 ast_log(LOG_ERROR, "Only one '%s' header can be added to a NOTIFY, "
621 "ignoring \"%s: %s\"\n", name, name, value);
622 return;
623 }
624 }
625
627 }
628}
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 566 of file res_pjsip_notify.c.

568{
569 if (content_type) {
570 char *p;
571 struct ast_sip_body body;
572
573 if (content) {
574 body.body_text = ast_str_buffer(content);
575 }
576
577 body.type = ast_str_buffer(content_type);
578 if ((p = strchr(body.type, '/'))) {
579 *p++ = '\0';
580 body.subtype = p;
581 }
582 ast_sip_add_body(tdata, &body);
583 }
584}
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:2324
const char * body_text
Definition: res_pjsip.h:2330

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

951{
952 int wordlen = strlen(word);
953 struct ao2_container * endpoints;
954 struct ast_sip_endpoint *endpoint;
955 struct ao2_iterator i;
956
958 "endpoint", word, wordlen);
959 if (endpoints == NULL) {
960 return NULL;
961 }
962
964 while ((endpoint = ao2_iterator_next(&i))) {
967 ao2_cleanup(endpoint);
968 }
970
971 ao2_ref(endpoints, -1);
972
973 return NULL;
974}
#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:958

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

981{
982 char *c = NULL;
983
984 if (a->pos == 3) {
985 int which = 0;
986 int wordlen = strlen(a->word);
987
988 RAII_VAR(struct notify_cfg *, cfg,
990 struct notify_option *option;
991
992 /* do completion for notify type */
993 struct ao2_iterator i = ao2_iterator_init(cfg->notify_options, 0);
994 while ((option = ao2_iterator_next(&i))) {
995 if (!strncasecmp(a->word, option->name, wordlen) && ++which > a->n) {
996 c = ast_strdup(option->name);
997 }
998
999 ao2_cleanup(option);
1000 if (c) {
1001 break;
1002 }
1003 }
1005 return c;
1006 }
1007
1008 if (a->pos == 4) {
1009 int wordlen = strlen(a->word);
1010
1011 if (ast_strlen_zero(a->word)) {
1012 if (a->n == 0) {
1013 c = ast_strdup("endpoint");
1014 } else if (a->n == 1) {
1015 c = ast_strdup("uri");
1016 } else if (a->n == 2) {
1017 c = ast_strdup("channel");
1018 }
1019 } else if (a->n == 0) {
1020 if (!strncasecmp(a->word, "endpoint", wordlen)) {
1021 c = ast_strdup("endpoint");
1022 } else if (!strncasecmp(a->word, "uri", wordlen)) {
1023 c = ast_strdup("uri");
1024 } else if (!strncasecmp(a->word, "channel", wordlen)) {
1025 c = ast_strdup("channel");
1026 }
1027 }
1028
1029 return c;
1030 }
1031
1032 if (a->pos > 4) {
1033 if (!strcasecmp(a->argv[4], "endpoint")) {
1034 return cli_complete_endpoint(a->word);
1035 } else if (!strcasecmp(a->argv[4], "channel")) {
1036 return ast_complete_channels(a->line, a->word, a->pos, a->n, 5);
1037 }
1038 }
1039 return NULL;
1040}
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 1050 of file res_pjsip_notify.c.

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

1302{
1303 struct ast_variable *varlist = NULL;
1304 struct ast_variable *var;
1305 char *cur;
1306 char *header;
1307
1308 cur = (char *)headers;
1309
1310 while( (header = strsep(&cur, "&")) ) {
1311 char *name;
1312 char *value;
1313
1314 name = value = header;
1315 strsep(&value, "=");
1316
1317 if (!value || ast_strlen_zero(name)) {
1318 continue;
1319 }
1320
1322 var->next = varlist;
1323 varlist = var;
1324 }
1325 return varlist;
1326}
#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 1390 of file res_pjsip_notify.c.

1391{
1392 if (aco_info_init(&notify_cfg)) {
1394 }
1395
1397 "", notify_option_handler, 0);
1398
1399 if (aco_process_config(&notify_cfg, 0)) {
1402 }
1403
1407
1409}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ ACO_PREFIX
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#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 1258 of file res_pjsip_notify.c.

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

1244{
1245 enum notify_result res;
1246 struct ast_variable *vars = NULL;
1247
1250
1251 manager_send_response(s, m, NOTIFY_CHANNEL, res, vars, NULL);
1252}
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:1721
@ ORDER_NATURAL
Definition: manager.h:288
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 1174 of file res_pjsip_notify.c.

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

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

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

1136{
1137 switch (res) {
1138 case INVALID_CHANNEL:
1139 if (type == NOTIFY_CHANNEL) {
1141 astman_send_error(s, m, "Channel not found");
1142 } else {
1143 /* Shouldn't be possible. */
1144 ast_assert(0);
1145 }
1146 break;
1147 case INVALID_ENDPOINT:
1148 if (type == NOTIFY_ENDPOINT) {
1150 astman_send_error_va(s, m, "Unable to retrieve endpoint %s", endpoint_name);
1151 } else {
1152 /* Shouldn't be possible. */
1153 ast_assert(0);
1154 }
1155 break;
1156 case ALLOC_ERROR:
1158 astman_send_error(s, m, "Unable to allocate NOTIFY task data");
1159 break;
1160 case TASK_PUSH_ERROR:
1161 /* Don't need to destroy vars since it is handled by cleanup in push_notify, push_notify_uri, etc. */
1162 astman_send_error(s, m, "Unable to push Notify task");
1163 break;
1164 case SUCCESS:
1165 astman_send_ack(s, m, "NOTIFY sent");
1166 break;
1167 }
1168}
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:2001
#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 555 of file res_pjsip_notify.c.

556{
557 /* This can be extended to include additional headers */
558 return strcasecmp("Event", name);
559}

References name.

Referenced by build_notify().

◆ not_allowed()

static int not_allowed ( const char *  name)
static

Definition at line 528 of file res_pjsip_notify.c.

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

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

504{
505 struct notify_channel_data *data;
506
509 if (!data) {
510 return NULL;
511 }
512
513 data->session = session;
514 data->info = info;
516
517 return data;
518}
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 455 of file res_pjsip_notify.c.

457{
458 struct notify_data *data = ao2_alloc(sizeof(*data),
460 if (!data) {
461 return NULL;
462 }
463
464 data->endpoint = endpoint;
465 ao2_ref(data->endpoint, +1);
466
467 data->info = info;
469
470 return data;
471}
#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 414 of file res_pjsip_notify.c.

415{
416 struct notify_data *data = obj;
417 struct ast_variable *info = data->info;
418
419 ao2_cleanup(data->endpoint);
421}

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

479{
480 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
482 if (!data) {
483 return NULL;
484 }
485
486 data->uri = ast_strdup(uri);
487 if (!data->uri) {
488 ao2_ref(data, -1);
489 return NULL;
490 }
491
492 data->info = info;
494
495 return data;
496}
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 427 of file res_pjsip_notify.c.

428{
429 struct notify_uri_data *data = obj;
430 struct ast_variable *info = data->info;
431
432 ast_free(data->uri);
434}

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

228{
229 struct notify_cfg *cfg;
230
231 if (!(cfg = ao2_alloc(sizeof(*cfg), notify_cfg_destroy))) {
232 return NULL;
233 }
234
237 if (!cfg->notify_options) {
238 ao2_cleanup(cfg);
239 return NULL;
240 }
241
242 return cfg;
243}
#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 221 of file res_pjsip_notify.c.

222{
223 struct notify_cfg *cfg = obj;
225}

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

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

393{
394 struct notify_channel_data *data = ao2_alloc_options(sizeof(*data),
396
397 if (!data) {
398 return NULL;
399 }
400
401 data->session = session;
402 data->info = info;
403 ao2_ref(data->info, +1);
404
406
407 return data;
408}
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 321 of file res_pjsip_notify.c.

322{
323 struct notify_channel_data *data = obj;
324
325 ao2_cleanup(data->info);
326 ao2_cleanup(data->session);
327}

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

341{
342 struct notify_data *data = ao2_alloc(sizeof(*data),
344 if (!data) {
345 return NULL;
346 }
347
348 data->endpoint = endpoint;
349 ao2_ref(data->endpoint, +1);
350
351 data->info = info;
352 ao2_ref(data->info, +1);
353
355
356 return data;
357}
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 285 of file res_pjsip_notify.c.

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

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

365{
366 struct notify_uri_data *data = ao2_alloc(sizeof(*data),
368
369 if (!data) {
370 return NULL;
371 }
372
373 data->uri = ast_strdup(uri);
374 if (!data->uri) {
375 ao2_ref(data, -1);
376 return NULL;
377 }
378
379 data->info = info;
380 ao2_ref(data->info, +1);
381
383
384 return data;
385}
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 313 of file res_pjsip_notify.c.

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

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

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

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

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

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

165{
166 int category_size = strlen(category) + 1;
167
168 struct notify_option *option = ao2_alloc(
169 sizeof(*option) + category_size, notify_option_destroy);
170
171 if (!option) {
172 return NULL;
173 }
174
175 ast_copy_string(option->name, category, category_size);
176
177 if (!(option->items = ao2_container_alloc_list(
180 ao2_cleanup(option);
181 return NULL;
182 }
183
184 return option;
185}
#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 149 of file res_pjsip_notify.c.

150{
151 struct notify_option *option1 = obj;
152 struct notify_option *option2 = arg;
153 const char *key = flags & OBJ_KEY ? arg : option2->name;
154
155 return strcasecmp(option1->name, key) ? 0 : CMP_MATCH;
156}
@ 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 158 of file res_pjsip_notify.c.

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

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

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

References ao2_find, container, and OBJ_KEY.

Referenced by 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 192 of file res_pjsip_notify.c.

194{
195 struct notify_option *option = obj;
196
197 int name_size = strlen(var->name) + 1;
198 int value_size = strlen(var->value) + 1;
199
201 ao2_alloc(sizeof(*item) + name_size + value_size,
202 NULL), ao2_cleanup);
203
204 item->name = item->buf;
205 item->value = item->buf + name_size;
206
207 ast_copy_string(item->buf, var->name, name_size);
208 ast_copy_string(item->buf + name_size, var->value, value_size);
209
210 if (!ao2_link(option->items, item)) {
211 return -1;
212 }
213
214 return 0;
215}
#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 143 of file res_pjsip_notify.c.

144{
145 const struct notify_option *option = obj;
146 return ast_str_case_hash(flags & OBJ_KEY ? obj : option->name);
147}
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 746 of file res_pjsip_notify.c.

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

842{
843 RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
844 struct notify_data *data;
845
847 ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
848 return INVALID_ENDPOINT;
849 }
850
851 if (!(data = data_create(endpoint, info))) {
852 return ALLOC_ERROR;
853 }
854
856 ao2_cleanup(data);
857 return TASK_PUSH_ERROR;
858 }
859
860 return SUCCESS;
861}
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 888 of file res_pjsip_notify.c.

890{
891 struct notify_channel_data *data;
892 struct ast_channel *ch;
893 struct ast_sip_session *session;
894 struct ast_sip_channel_pvt *ch_pvt;
895
896 /* note: this increases the refcount of the channel */
897 ch = ast_channel_get_by_name(channel_name);
898 if (!ch) {
899 ast_debug(1, "No channel found with name %s", channel_name);
900 return INVALID_CHANNEL;
901 }
902
903 if (strcmp(ast_channel_tech(ch)->type, "PJSIP")) {
904 ast_log(LOG_WARNING, "Channel was a non-PJSIP channel: %s\n", channel_name);
906 return INVALID_CHANNEL;
907 }
908
910 ch_pvt = ast_channel_tech_pvt(ch);
911 session = ch_pvt->session;
912
913 if (!session || !session->inv_session
914 || session->inv_session->state < PJSIP_INV_STATE_EARLY
915 || session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
916 ast_debug(1, "No active session for channel %s\n", channel_name);
919 return INVALID_CHANNEL;
920 }
921
922 ao2_ref(session, +1);
924
925 /* don't keep a reference to the channel, we've got a reference to the session */
927
928 /*
929 * data_create will take ownership of the session,
930 * and take care of releasing the ref.
931 */
932 data = data_create(session, info);
933 if (!data) {
934 ao2_ref(session, -1);
935 return ALLOC_ERROR;
936 }
937
938 if (ast_sip_push_task(session->serializer, notify_channel, data)) {
939 ao2_ref(data, -1);
940 return TASK_PUSH_ERROR;
941 }
942
943 return SUCCESS;
944}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2968
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1473
#define ast_channel_unlock(chan)
Definition: channel.h:2969
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 867 of file res_pjsip_notify.c.

869{
870 struct notify_uri_data *data;
871
872 if (!(data = data_create(uri, info))) {
873 return ALLOC_ERROR;
874 }
875
876 if (ast_sip_push_task(NULL, notify_uri, data)) {
877 ao2_cleanup(data);
878 return TASK_PUSH_ERROR;
879 }
880
881 return SUCCESS;
882}
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 1411 of file res_pjsip_notify.c.

1412{
1415 }
1416
1417 return 0;
1418}
@ 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 1420 of file res_pjsip_notify.c.

1421{
1422 ast_manager_unregister("PJSIPNotify");
1423 ast_unregister_application("PJSIPNotify");
1427
1428 return 0;
1429}
#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:7608
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 1438 of file res_pjsip_notify.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1438 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 1125 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 257 of file res_pjsip_notify.c.

◆ notify_config

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

Definition at line 128 of file res_pjsip_notify.c.

◆ notify_option

struct aco_type notify_option
static

Definition at line 245 of file res_pjsip_notify.c.

◆ notify_options

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

Definition at line 255 of file res_pjsip_notify.c.

Referenced by load_module().