127#define CONTENT_TYPE_SIZE 64 
  128#define CONTENT_SIZE 512 
  159    const char *key = flags & 
OBJ_KEY ? arg : option2->
name;
 
 
  172    int category_size = strlen(category) + 1;
 
 
  203    int name_size = strlen(
var->name) + 1;
 
  204    int value_size = strlen(
var->value) + 1;
 
  211    item->value = 
item->buf + name_size;
 
 
  255    .category = 
"general",
 
 
  537    static const char *names[] = {
 
  550        if (!strcasecmp(
name, names[i])) {
 
 
  564    return strcasecmp(
"Event", 
name);
 
 
  584        if ((p = strchr(body.
type, 
'/'))) {
 
 
  605    if (!strcasecmp(
name, 
"Content-type")) {
 
  606        if (!(*content_type)) {
 
  610    } 
else if (!strcasecmp(
name, 
"Content")) {
 
  623            pj_cstr(&hdr_name, 
name);
 
  625            if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name, 
NULL)) {
 
 
  652                 &content_type, &content);
 
 
  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");
 
  678                 &content_type, &content);
 
 
  692    pjsip_tx_data *tdata;
 
  695                   NULL, contact, &tdata)) {
 
  697            "contact %s\n", contact->
uri);
 
  706            "contact %s\n", contact->
uri);
 
 
  723    char *aor_name, *aors;
 
  727            "endpoint has no configured AORs\n");
 
 
  757    pjsip_tx_data *tdata;
 
  761            "NOTIFY requests to arbitrary URIs.\n");
 
  771                   data->uri, 
NULL, &tdata)) {
 
  773            "uri %s\n", data->uri);
 
  779    data->build_notify(tdata, data->info);
 
  783            "uri %s\n", data->uri);
 
 
  797    pjsip_tx_data *tdata;
 
  798    struct pjsip_dialog *dlg;
 
  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) {
 
  809    dlg = data->session->inv_session->dlg;
 
  816    data->build_notify(tdata, data->info);
 
 
  878    if (!(data = data_create(
uri, 
info))) {
 
 
  905        ast_debug(1, 
"No channel found with name %s", channel_name);
 
  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);
 
  938    data = data_create(
session, info);
 
 
  958    int wordlen = strlen(
word);
 
  964        "endpoint", 
word, wordlen);
 
 
  992        int wordlen = strlen(
a->word);
 
 1001            if (!strncasecmp(
a->word, option->
name, wordlen) && ++which > 
a->n) {
 
 1015        int wordlen = strlen(
a->word);
 
 1020            } 
else if (
a->n == 1) {
 
 1022            } 
else if (
a->n == 2) {
 
 1025        } 
else if (
a->n == 0) {
 
 1026            if (!strncasecmp(
a->word, 
"endpoint", wordlen)) {
 
 1028            } 
else if (!strncasecmp(
a->word, 
"uri", wordlen)) {
 
 1030            } 
else if (!strncasecmp(
a->word, 
"channel", wordlen)) {
 
 1039        if (!strcasecmp(
a->argv[4], 
"endpoint")) {
 
 1041        } 
else if (!strcasecmp(
a->argv[4], 
"channel")) {
 
 
 1063    int using_channel = 0;
 
 1067        e->
command = 
"pjsip send notify";
 
 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";
 
 1081    if (!strcasecmp(
a->argv[4], 
"uri")) {
 
 1083    } 
else if (!strcasecmp(
a->argv[4], 
"channel")) {
 
 1085    } 
else if (strcasecmp(
a->argv[4], 
"endpoint")) {
 
 1093        ast_cli(
a->fd, 
"Unable to find notify type '%s'\n",
 
 1098    for (i = 5; i < 
a->argc; ++i) {
 
 1100        ast_cli(
a->fd, 
"Sending NOTIFY of type '%s' to '%s'\n",
 
 1101            a->argv[3], 
a->argv[i]);
 
 1105        } 
else if (using_channel) {
 
 1112            ast_cli(
a->fd, 
"Unable to retrieve endpoint %s\n", 
a->argv[i]);
 
 1115            ast_cli(
a->fd, 
"Unable to find channel %s\n", 
a->argv[i]);
 
 1118            ast_cli(
a->fd, 
"Unable to allocate NOTIFY task data\n");
 
 1121            ast_cli(
a->fd, 
"Unable to push NOTIFY task\n");
 
 
 1181    const struct message *m, 
const char *endpoint_name)
 
 1197    if (!strncasecmp(endpoint_name, 
"sip/", 4)) {
 
 1201    if (!strncasecmp(endpoint_name, 
"pjsip/", 6)) {
 
 
 1219    const struct message *m, 
const char *uri)
 
 
 1249    const struct message *m, 
const char *channel)
 
 
 1285            "PJSIPNotify requires either an Option or Variable(s)." 
 1286            "You must use only one of them.");
 
 1287    } 
else if (1 < count) {
 
 1289            "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.  " 
 1290            "You must use only one of them.");
 
 1299            "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.");
 
 
 1314    cur = (
char *)headers;
 
 1328        var->next = varlist;
 
 
 1443    .
requires = 
"res_pjsip",
 
void ast_cli_unregister_multiple(void)
char * strsep(char **str, const char *delims)
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_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
#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)
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
#define ast_channel_unref(c)
Decrease channel reference count.
#define ast_channel_unlock(chan)
Standard Command Line Interface.
#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.
#define CONFIG_INFO_STANDARD(name, arr, alloc,...)
Declare an aco_info struct with default module and preload values.
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.
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.
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)
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.
size_t attribute_pure 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_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.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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...
Structure to describe a channel "technology", ie a channel driver See for examples:
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.
struct ast_sip_endpoint_info_configuration info
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.