115 #define CONTENT_TYPE_SIZE 64 116 #define CONTENT_SIZE 512 147 const char *key = flags &
OBJ_KEY ? arg : option2->
name;
160 int category_size = strlen(category) + 1;
191 int name_size = strlen(var->
name) + 1;
192 int value_size = strlen(var->
value) + 1;
199 item->value =
item->buf + name_size;
243 .category =
"general",
494 static const char *names[] = {
507 if (!strcasecmp(name, names[i])) {
521 return strcasecmp(
"Event", name);
541 if ((p = strchr(body.
type,
'/'))) {
562 if (!strcasecmp(name,
"Content-type")) {
563 if (!(*content_type)) {
567 }
else if (!strcasecmp(name,
"Content")) {
580 pj_cstr(&hdr_name, name);
582 if (pjsip_msg_find_hdr_by_name(tdata->msg, &hdr_name,
NULL)) {
584 "ignoring \"%s: %s\"\n", name, name, value);
600 struct notify_option *option =
info;
609 &content_type, &content);
629 for (i = vars; i; i = i->
next) {
630 if (!strcasecmp(i->
name,
"Content-Length")) {
631 ast_log(
LOG_NOTICE,
"It is not necessary to specify Content-Length, ignoring.\n");
635 &content_type, &content);
649 pjsip_tx_data *tdata;
652 NULL, contact, &tdata)) {
654 "contact %s\n", contact->
uri);
663 "contact %s\n", contact->
uri);
680 char *aor_name, *aors;
684 "endpoint has no configured AORs\n");
714 pjsip_tx_data *tdata;
718 "NOTIFY requests to arbitrary URIs.\n");
728 data->uri,
NULL, &tdata)) {
730 "uri %s\n", data->uri);
736 data->build_notify(tdata, data->info);
740 "uri %s\n", data->uri);
754 pjsip_tx_data *tdata;
755 struct pjsip_dialog *dlg;
757 if (!data->session->channel
758 || !data->session->inv_session
759 || data->session->inv_session->state < PJSIP_INV_STATE_EARLY
760 || data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
766 dlg = data->session->inv_session->dlg;
773 data->build_notify(tdata, data->info);
814 if (!(data = data_create(
endpoint, info))) {
835 if (!(data = data_create(uri, info))) {
862 ast_debug(1,
"No channel found with name %s", channel_name);
877 || session->
inv_session->state < PJSIP_INV_STATE_EARLY
878 || session->
inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
879 ast_debug(1,
"No active session for channel %s\n", channel_name);
895 data = data_create(session, info);
915 int wordlen = strlen(word);
921 "endpoint", word, wordlen);
922 if (endpoints ==
NULL) {
944 int pos,
int state,
int using_uri)
950 int wordlen = strlen(word);
954 struct notify_option *option;
959 if (!strncasecmp(word, option->
name, wordlen) && ++which > state) {
973 int wordlen = strlen(word);
978 }
else if (state == 1) {
981 }
else if (state == 0) {
982 if (!strncasecmp(word,
"endpoint", wordlen)) {
984 }
else if (!strncasecmp(word,
"uri", wordlen)) {
1013 e->
command =
"pjsip send notify";
1015 "Usage: pjsip send notify <type> {endpoint|uri} <peer> [<peer>...]\n" 1016 " Send a NOTIFY request to an endpoint\n" 1017 " Message types are defined in pjsip_notify.conf\n";
1020 if (a->
argc > 4 && (!strcasecmp(a->
argv[4],
"uri"))) {
1031 if (!strcasecmp(a->
argv[4],
"uri")) {
1033 }
else if (strcasecmp(a->
argv[4],
"endpoint")) {
1041 ast_cli(a->
fd,
"Unable to find notify type '%s'\n",
1046 for (i = 5; i < a->
argc; ++i) {
1047 ast_cli(a->
fd,
"Sending NOTIFY of type '%s' to '%s'\n",
1053 ast_cli(a->
fd,
"Unable to retrieve endpoint %s\n",
1057 ast_cli(a->
fd,
"Unable to allocate NOTIFY task data\n");
1060 ast_cli(a->
fd,
"Unable to push NOTIFY task\n");
1079 const struct message *m,
const char *endpoint_name)
1083 if (!strncasecmp(endpoint_name,
"sip/", 4)) {
1087 if (!strncasecmp(endpoint_name,
"pjsip/", 6)) {
1120 const struct message *m,
const char *uri)
1202 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel. " 1203 "You must use only one of them.");
1212 "PJSIPNotify requires either an endpoint name, a SIP URI, or a channel.");
1263 .requires =
"res_pjsip",
static char * cli_complete_notify(const char *line, const char *word, int pos, int state, int using_uri)
struct ast_variable * next
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
#define AST_CLI_DEFINE(fn, txt,...)
static int not_allowed(const char *name)
static int multiple_headers_allowed(const char *name)
Asterisk main include file. File version handling, generic pbx functions.
struct ao2_container * notify_options
static void build_notify_body(pjsip_tx_data *tdata, struct ast_str *content_type, struct ast_str *content)
static struct aco_file module_conf
static int notify_option_hash(const void *obj, int flags)
static void * notify_cfg_alloc(void)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_unref(c)
Decrease channel reference count.
static int reload_module(void)
descriptor for a cli entry.
struct ao2_container * items
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define ao2_callback(c, flags, cb_fn, arg)
struct ast_sip_session * session
Allow objects with duplicate keys in container.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Structure for variables, used for configurations and for channel variables.
#define CONTENT_TYPE_SIZE
static int load_module(void)
A structure which contains a channel implementation and session.
static void build_ami_notify(pjsip_tx_data *tdata, void *info)
struct ast_sip_session * session
Pointer to session.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
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.
static struct aco_type item
static void manager_notify_endpoint(struct mansession *s, const struct message *m, const char *endpoint_name)
Completes SIPNotify AMI command in Endpoint mode.
#define ao2_global_obj_ref(holder)
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
#define ao2_alloc_options(data_size, destructor_fn, options)
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
#define ast_strdup(str)
A wrapper for strdup()
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.
void(* build_notify)(pjsip_tx_data *, void *)
struct ast_sip_endpoint * ast_sip_default_outbound_endpoint(void)
Retrieve the default outbound endpoint.
The representation of a single configuration file to be processed.
AO2_GLOBAL_OBJ_STATIC(globals)
static void build_notify(pjsip_tx_data *tdata, const char *name, const char *value, struct ast_str **content_type, struct ast_str **content)
void ast_cli(int fd, const char *fmt,...)
static struct notify_data * notify_cli_data_create(struct ast_sip_endpoint *endpoint, void *info)
struct pjsip_inv_session * inv_session
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
A structure describing a SIP session.
static void notify_cfg_destroy(void *obj)
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.
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
static int notify_uri(void *obj)
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
#define ast_strlen_zero(foo)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
CONFIG_INFO_STANDARD(notify_cfg, globals, notify_cfg_alloc,.files=ACO_FILES(&module_conf))
static struct ast_cli_entry cli_options[]
struct ast_sip_endpoint * endpoint
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Configuration File Parser.
#define EVENT_FLAG_SYSTEM
#define ast_debug(level,...)
Log a DEBUG message.
static void notify_ami_channel_data_destroy(void *obj)
static struct notify_uri_data * notify_cli_uri_data_create(const char *uri, void *info)
static struct aco_type * notify_options[]
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
static void notify_ami_data_destroy(void *obj)
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static struct ast_mansession session
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
static struct ao2_container * endpoints
#define ao2_ref(o, delta)
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
#define ast_strdupa(s)
duplicate a string in memory from the stack
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
struct ao2_container * container
static struct console_pvt globals
static int notify_contact(void *obj, void *arg, int flags)
static int notify_endpoint(void *obj)
An entity with which Asterisk communicates.
Core PBX routines and definitions.
struct ast_taskprocessor * serializer
Their was an error and no changes were applied.
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
static void notify_ami_uri_data_destroy(void *obj)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
static enum notify_result push_notify(const char *endpoint_name, void *info, task_data_create data_create)
void(* build_notify)(pjsip_tx_data *, void *)
static void notify_cli_data_destroy(void *obj)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static void manager_notify_channel(struct mansession *s, const struct message *m, const char *channel)
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
static enum notify_result push_notify_uri(const char *uri, void *info, task_uri_data_create data_create)
#define ao2_global_obj_release(holder)
#define ao2_iterator_next(iter)
#define ao2_alloc(data_size, destructor_fn)
static void notify_option_destroy(void *obj)
struct notify_uri_data *(* task_uri_data_create)(const char *uri, void *info)
void(* build_notify)(pjsip_tx_data *, void *)
#define ast_channel_unlock(chan)
static void * notify_option_find(struct ao2_container *container, const char *category)
static void notify_cli_uri_data_destroy(void *obj)
Module has failed to load, may be in an inconsistent state.
static int notify_option_cmp(void *obj, void *arg, int flags)
static void manager_notify_uri(struct mansession *s, const struct message *m, const char *uri)
#define ao2_find(container, arg, flags)
static int manager_notify(struct mansession *s, const struct message *m)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int notify_option_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static void * notify_option_alloc(const char *category)
struct notify_data *(* task_data_create)(struct ast_sip_endpoint *, void *info)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
char * strsep(char **str, const char *delims)
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.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
Type information about a category-level configurable object.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
const char * ast_channel_name(const struct ast_channel *chan)
static struct notify_data * notify_ami_data_create(struct ast_sip_endpoint *endpoint, void *info)
static enum notify_result push_notify_channel(const char *channel_name, void *info, task_channel_data_create data_create)
static int unload_module(void)
static int notify_channel(void *obj)
static struct notify_channel_data * notify_ami_channel_data_create(struct ast_sip_session *session, void *info)
struct notify_channel_data *(* task_channel_data_create)(struct ast_sip_session *session, void *info)
static void build_cli_notify(pjsip_tx_data *tdata, void *info)
static char * cli_notify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
#define ASTERISK_GPL_KEY
The text the key() function should return.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
static struct notify_uri_data * notify_ami_uri_data_create(const char *uri, void *info)
static char * cli_complete_endpoint(const char *word)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
static const char notify_config[]
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
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.
Sorcery Data Access Layer API.
#define ao2_link(container, obj)