121#define CONTENT_TYPE_SIZE 64
122#define CONTENT_SIZE 512
153 const char *key = flags &
OBJ_KEY ? arg : option2->
name;
166 int category_size = strlen(category) + 1;
197 int name_size = strlen(
var->name) + 1;
198 int value_size = strlen(
var->value) + 1;
205 item->value =
item->buf + name_size;
249 .category =
"general",
531 static const char *names[] = {
544 if (!strcasecmp(
name, names[i])) {
558 return strcasecmp(
"Event",
name);
578 if ((p = strchr(body.
type,
'/'))) {
599 if (!strcasecmp(
name,
"Content-type")) {
600 if (!(*content_type)) {
604 }
else if (!strcasecmp(
name,
"Content")) {
617 pj_cstr(&hdr_name,
name);
619 if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name,
NULL)) {
646 &content_type, &content);
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");
672 &content_type, &content);
686 pjsip_tx_data *tdata;
689 NULL, contact, &tdata)) {
691 "contact %s\n", contact->
uri);
700 "contact %s\n", contact->
uri);
717 char *aor_name, *aors;
721 "endpoint has no configured AORs\n");
751 pjsip_tx_data *tdata;
755 "NOTIFY requests to arbitrary URIs.\n");
765 data->uri,
NULL, &tdata)) {
767 "uri %s\n", data->uri);
773 data->build_notify(tdata, data->info);
777 "uri %s\n", data->uri);
791 pjsip_tx_data *tdata;
792 struct pjsip_dialog *dlg;
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) {
803 dlg = data->session->inv_session->dlg;
810 data->build_notify(tdata, data->info);
872 if (!(data = data_create(
uri,
info))) {
899 ast_debug(1,
"No channel found with name %s", channel_name);
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);
952 int wordlen = strlen(
word);
958 "endpoint",
word, wordlen);
986 int wordlen = strlen(
a->word);
995 if (!strncasecmp(
a->word, option->
name, wordlen) && ++which >
a->n) {
1009 int wordlen = strlen(
a->word);
1014 }
else if (
a->n == 1) {
1016 }
else if (
a->n == 2) {
1019 }
else if (
a->n == 0) {
1020 if (!strncasecmp(
a->word,
"endpoint", wordlen)) {
1022 }
else if (!strncasecmp(
a->word,
"uri", wordlen)) {
1024 }
else if (!strncasecmp(
a->word,
"channel", wordlen)) {
1033 if (!strcasecmp(
a->argv[4],
"endpoint")) {
1035 }
else if (!strcasecmp(
a->argv[4],
"channel")) {
1057 int using_channel = 0;
1061 e->
command =
"pjsip send notify";
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";
1075 if (!strcasecmp(
a->argv[4],
"uri")) {
1077 }
else if (!strcasecmp(
a->argv[4],
"channel")) {
1079 }
else if (strcasecmp(
a->argv[4],
"endpoint")) {
1087 ast_cli(
a->fd,
"Unable to find notify type '%s'\n",
1092 for (i = 5; i <
a->argc; ++i) {
1094 ast_cli(
a->fd,
"Sending NOTIFY of type '%s' to '%s'\n",
1095 a->argv[3],
a->argv[i]);
1099 }
else if (using_channel) {
1106 ast_cli(
a->fd,
"Unable to retrieve endpoint %s\n",
a->argv[i]);
1109 ast_cli(
a->fd,
"Unable to find channel %s\n",
a->argv[i]);
1112 ast_cli(
a->fd,
"Unable to allocate NOTIFY task data\n");
1115 ast_cli(
a->fd,
"Unable to push NOTIFY task\n");
1175 const struct message *m,
const char *endpoint_name)
1191 if (!strncasecmp(endpoint_name,
"sip/", 4)) {
1195 if (!strncasecmp(endpoint_name,
"pjsip/", 6)) {
1213 const struct message *m,
const char *uri)
1243 const struct message *m,
const char *channel)
1279 "PJSIPNotify requires either an Option or Variable(s)."
1280 "You must use only one of them.");
1281 }
else if (1 < count) {
1283 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel. "
1284 "You must use only one of them.");
1293 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.");
1308 cur = (
char *)headers;
1322 var->next = varlist;
1437 .
requires =
"res_pjsip",
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#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.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW
Allow objects with duplicate keys in container.
static struct console_pvt globals
const char * ast_channel_name(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
#define ast_channel_unref(c)
Decrease channel reference count.
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.
#define ast_channel_unlock(chan)
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_cli(int fd, const char *fmt,...)
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
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 ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
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.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#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.
char * strsep(char **str, const char *delims)
Configuration File Parser.
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
#define ast_debug(level,...)
Log a DEBUG message.
static struct ao2_container * endpoints
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define EVENT_FLAG_SYSTEM
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Core PBX routines and definitions.
struct ao2_container * container
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
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.
struct ast_sip_endpoint * ast_sip_default_outbound_endpoint(void)
Retrieve the default outbound endpoint.
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
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.
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
AO2_GLOBAL_OBJ_STATIC(globals)
static void build_notify_body(pjsip_tx_data *tdata, struct ast_str *content_type, struct ast_str *content)
static void * notify_option_find(struct ao2_container *container, const char *category)
static void notify_ami_channel_data_destroy(void *obj)
static void * notify_cfg_alloc(void)
static int notify_option_cmp(void *obj, void *arg, int flags)
static struct notify_channel_data * notify_cli_channel_data_create(struct ast_sip_session *session, void *info)
static void * notify_option_alloc(const char *category)
static void notify_ami_data_destroy(void *obj)
static int not_allowed(const char *name)
static enum notify_result push_notify_channel(const char *channel_name, void *info, task_channel_data_create data_create)
struct notify_channel_data *(* task_channel_data_create)(struct ast_sip_session *session, void *info)
static struct aco_type * notify_options[]
static void manager_notify_endpoint(struct mansession *s, const struct message *m, const char *endpoint_name)
CONFIG_INFO_STANDARD(notify_cfg, globals, notify_cfg_alloc,.files=ACO_FILES(&module_conf))
static void build_cli_notify(pjsip_tx_data *tdata, void *info)
static struct notify_data * notify_cli_data_create(struct ast_sip_endpoint *endpoint, void *info)
static struct aco_file module_conf
static struct notify_uri_data * notify_ami_uri_data_create(const char *uri, void *info)
struct notify_uri_data *(* task_uri_data_create)(const char *uri, void *info)
static char * cli_complete_endpoint(const char *word)
static char * cli_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void manager_notify_channel(struct mansession *s, const struct message *m, const char *channel)
static struct notify_data * notify_ami_data_create(struct ast_sip_endpoint *endpoint, void *info)
static int notify_contact(void *obj, void *arg, int flags)
static void build_notify(pjsip_tx_data *tdata, const char *name, const char *value, struct ast_str **content_type, struct ast_str **content)
static enum notify_result push_notify_uri(const char *uri, void *info, task_uri_data_create data_create)
static int reload_module(void)
static void build_ami_notify(pjsip_tx_data *tdata, void *info)
static int notify_uri(void *obj)
static int app_notify(struct ast_channel *chan, const char *data)
Application entry point to send a SIP notify to an endpoint.
static struct ast_variable * headers_to_variables(const char *headers)
Convert headers string such as "Event=hold&Event=answer&..." into ast variable list.
static int notify_channel(void *obj)
static int multiple_headers_allowed(const char *name)
static int manager_notify(struct mansession *s, const struct message *m)
static char * cli_complete_notify(struct ast_cli_args *a)
static struct ast_cli_entry cli_options[]
static int notify_option_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static int notify_endpoint(void *obj)
static void notify_cli_uri_data_destroy(void *obj)
static void notify_cfg_destroy(void *obj)
static void notify_cli_channel_data_destroy(void *obj)
static struct notify_channel_data * notify_ami_channel_data_create(struct ast_sip_session *session, void *info)
static int load_module(void)
static void notify_ami_uri_data_destroy(void *obj)
static int unload_module(void)
static struct notify_uri_data * notify_cli_uri_data_create(const char *uri, void *info)
static void manager_send_response(struct mansession *s, const struct message *m, enum notify_type type, enum notify_result res, struct ast_variable *vars, const char *endpoint_name)
static int notify_option_hash(const void *obj, int flags)
static enum notify_result push_notify(const char *endpoint_name, void *info, task_data_create data_create)
#define CONTENT_TYPE_SIZE
static void notify_cli_data_destroy(void *obj)
static void notify_option_destroy(void *obj)
struct notify_data *(* task_data_create)(struct ast_sip_endpoint *, void *info)
static const char notify_config[]
static void manager_notify_uri(struct mansession *s, const struct message *m, const char *uri)
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
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.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
The representation of a single configuration file to be processed.
Type information about a category-level configurable object.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Main Channel structure associated with a channel.
descriptor for a cli entry.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
An entity with which Asterisk communicates.
A structure describing a SIP session.
struct ast_sip_endpoint * endpoint
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
In case you didn't read that giant block of text above the mansession_session struct,...
struct ao2_container * notify_options
struct ast_sip_session * session
void(* build_notify)(pjsip_tx_data *, void *)
struct ast_sip_endpoint * endpoint
void(* build_notify)(pjsip_tx_data *, void *)
struct ao2_container * items
void(* build_notify)(pjsip_tx_data *, void *)
static struct aco_type item
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.