31#include <pjsip_simple.h>
239 .name = {
"PubSub Module", 13 },
240 .priority = PJSIP_MOD_PRIORITY_APPLICATION,
244#define MOD_DATA_PERSISTENCE "sub_persistence"
245#define MOD_DATA_MSG "sub_msg"
253#define PUBLICATIONS_BUCKETS 37
256#define DEFAULT_PUBLISH_EXPIRES 3600
259#define DATASTORE_BUCKETS 53
262#define DEFAULT_EXPIRES 3600
429 "TerminateInProgress",
560 int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
562 pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body);
593 if (!sub_tree->
evsub) {
599 ast_debug(3,
"Transport destroyed. Removing subscription '%s->%s' prune on boot: %d\n",
604 pjsip_evsub_terminate(sub_tree->
evsub, PJ_TRUE);
654 char tag[PJ_GUID_STRING_LENGTH + 1];
660 "subscription_persistence",
NULL);
662 pjsip_dialog *dlg = sub_tree->
dlg;
686 ast_debug(3,
"Updating persistence for '%s->%s' prune on boot: %s\n",
695 pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES,
NULL);
696 pjsip_contact_hdr *contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
706 (pjsip_sip_uri *)pjsip_uri_get_uri(contact_hdr->uri),
710 ast_debug(3,
"adding transport monitor on %s for '%s->%s' prune on boot: %d\n",
711 rdata->tp_info.transport->obj_name,
725 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
739 if (rdata->msg_info.msg_buf) {
768 ast_debug(3,
"Unregistering transport monitor on %s '%s->%s'\n",
784 size_t num_accept,
const char *
body_type);
789 pjsip_event_hdr *event_header;
793 event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &
str_event_name, rdata->msg_info.msg->hdr.next);
796 endpoint ? endpoint :
"Unknown");
804 endpoint ? endpoint :
"Unknown");
824 "application/rlmi+xml",
850 pjsip_accept_hdr *accept_header = (pjsip_accept_hdr *) &rdata->msg_info.msg->hdr;
852 size_t num_accept_headers = 0;
854 while ((accept_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, accept_header->next)) &&
858 for (i = 0; i < accept_header->count && num_accept_headers <
AST_SIP_MAX_ACCEPT; ++i) {
860 ast_copy_pj_str(accept[num_accept_headers], &accept_header->values[i],
sizeof(accept[num_accept_headers]));
861 ++num_accept_headers;
866 if (num_accept_headers == 0) {
871 num_accept_headers = 1;
884 pjsip_supported_hdr *supported_header = (pjsip_supported_hdr *) &rdata->msg_info.msg->hdr;
886 while ((supported_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, supported_header->next))) {
889 for (i = 0; i < supported_header->count; i++) {
890 if (!pj_stricmp2(&supported_header->values[i],
"eventlist")) {
929 ast_log(
LOG_WARNING,
"Found resource list %s, but its event type (%s) does not match SUBSCRIBE's (%s)\n",
1021#define NEW_SUBSCRIBE(notifier, endpoint, resource, rdata) notifier->new_subscribe_with_rdata ? notifier->new_subscribe_with_rdata(endpoint, resource, rdata) : notifier->new_subscribe(endpoint, resource)
1055 ast_debug(1,
"Already visited resource %s. Avoiding duplicate resource or potential loop.\n", resource);
1062 if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
1065 handler->notifier->get_resource_display_name(endpoint, resource, display_name,
sizeof(display_name));
1070 "Subscription to leaf resource %s was successful, but encountered allocation error afterwards\n",
1074 ast_debug(2,
"Subscription to leaf resource %s resulted in success. Adding to parent %s\n",
1080 ast_debug(2,
"Subscription to leaf resource %s resulted in error response %d\n",
1084 ast_debug(2,
"Resource %s (child of %s) is a list\n", resource, parent->
resource);
1087 ast_debug(1,
"Cannot build children of resource %s due to allocation failure\n", resource);
1092 ast_debug(1,
"List %s had no successful children.\n", resource);
1097 ast_debug(2,
"List %s had successful children. Adding to parent %s\n",
1171 ast_debug(2,
"Subscription '%s->%s' is not to a list\n",
1180 ast_debug(2,
"Subscription '%s->%s' is a list\n",
1220 ast_debug(2,
"Removing subscription '%s->%s' from list of subscriptions\n",
1232 ast_debug(3,
"Destroying SIP subscription from '%s->%s'\n",
1268 pjsip_sip_uri *request_uri;
1272 ast_log(
LOG_ERROR,
"No dialog message saved for SIP subscription. Cannot allocate subscription for resource %s\n",
resource);
1285 if (!
sub->datastores) {
1291 if (!
sub->body_text) {
1296 sub->uri = pjsip_sip_uri_create(
tree->
dlg->pool, PJ_FALSE);
1297 request_uri = pjsip_uri_get_uri(msg->line.req.uri);
1298 pjsip_sip_uri_assign(
tree->
dlg->pool,
sub->uri, request_uri);
1310 sub->subscription_state = PJSIP_EVSUB_STATE_ACTIVE;
1338 sub->body_generator = generator;
1349 ast_debug(1,
"Child subscription to resource %s could not be created\n",
1355 ast_debug(1,
"Child subscription to resource %s could not be appended\n",
1383 if (
sub->handler->subscription_shutdown) {
1384 sub->handler->subscription_shutdown(
sub);
1411 ast_debug(3,
"Destroying subscription tree %p '%s->%s'\n",
1418 if (sub_tree->
dlg) {
1431 ast_debug(3,
"Removing subscription %p '%s->%s' reference to subscription tree %p\n",
1516 *dlg_status = PJ_ENOMEM;
1523 if (*dlg_status != PJ_EEXISTS) {
1534 pjsip_ua_unregister_dlg(pjsip_ua_instance(),
dlg);
1536 dlg->local.tag_hval = pj_hash_calc_tolower(0,
NULL, &
dlg->local.info->tag);
1537 pjsip_ua_register_dlg(pjsip_ua_instance(),
dlg);
1550 pjsip_dlg_dec_lock(
dlg);
1552#ifdef HAVE_PJSIP_EVSUB_GRP_LOCK
1553 pjsip_evsub_add_ref(sub_tree->
evsub);
1557 pjsip_msg_clone(
dlg->pool, rdata->msg_info.msg));
1601 pjsip_rx_data *rdata = recreate_data->
rdata;
1607 size_t resource_size;
1610 pjsip_expires_hdr *expires_header;
1612 const pj_str_t *
user;
1615 resource_size = pj_strlen(
user) + 1;
1627 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Could not get subscription handler.\n",
1635 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Body generator not available.\n",
1648 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: The endpoint was not found\n",
1655 expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES,
1656 rdata->msg_info.msg->hdr.next);
1657 if (!expires_header) {
1658 expires_header = pjsip_expires_hdr_create(rdata->tp_info.pool, 0);
1659 if (!expires_header) {
1660 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Could not update expires header.\n",
1666 pjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr *) expires_header);
1672 ast_debug(3,
"Expired subscription retrived from persistent store '%s' %s\n",
1678 expires_header->ivalue = expires;
1680 memset(&tree, 0,
sizeof(tree));
1683 if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
1684 pj_status_t dlg_status;
1687 &tree, &dlg_status, persistence);
1689 if (dlg_status != PJ_EEXISTS) {
1690 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Could not create subscription tree.\n",
1703 ind->
expires = expires_header->ivalue;
1728 pj_pool_t *pool = arg;
1730 pjsip_rx_data rdata;
1735 ast_debug(3,
"Deleting subscription marked as 'prune' from persistent store '%s' %s\n",
1743 ast_debug(3,
"Expired subscription retrived from persistent store '%s' %s\n",
1750 pj_pool_reset(pool);
1751 rdata.tp_info.pool = pool;
1756 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: The message could not be parsed\n",
1762 if (
rdata.msg_info.msg->type != PJSIP_REQUEST_MSG) {
1763 ast_log(
LOG_NOTICE,
"Failed recreating '%s' subscription: Stored a SIP response instead of a request.\n",
1772 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Could not get distributor serializer.\n",
1781 ast_log(
LOG_WARNING,
"Failed recreating '%s' subscription: Could not continue under distributor serializer.\n",
1798 PJSIP_POOL_RDATA_INC);
1800 ast_log(
LOG_WARNING,
"Could not create a memory pool for recreating SIP subscriptions\n");
1808 ao2_ref(persisted_subscriptions, -1);
1828 if (strcmp(
type,
"FullyBooted")) {
1846 if (!on_subscription) {
1852 if (on_subscription(i, arg)) {
1872 if (sub_tree->
dlg) {
1901 dlg =
sub->tree->dlg;
1905 return pjsip_msg_find_hdr_by_name(msg, &
name,
NULL);
1916 pjsip_tx_data *tdata;
1933 ast_log(
LOG_WARNING,
"No contacts configured for endpoint %s. Unable to create SIP subsription\n",
1954 if (pjsip_evsub_initiate(
evsub,
NULL, -1, &tdata) == PJ_SUCCESS) {
1955 pjsip_evsub_send_request(sub_tree->
evsub, tdata);
1961 pjsip_evsub_terminate(
evsub, PJ_TRUE);
1974 return sub->tree->dlg;
1986 return sub->tree->serializer;
2014 for (buf_size = PJSIP_MAX_PKT_LEN; size == -1 && buf_size < (PJSIP_MAX_PKT_LEN * 2); buf_size *= 2) {
2015 buf = pj_pool_alloc(tdata->pool, buf_size);
2016 size = pjsip_msg_print(tdata->msg,
buf, buf_size);
2023 tdata->buf.start =
buf;
2024 tdata->buf.cur = tdata->buf.start;
2025 tdata->buf.end = tdata->buf.start + buf_size;
2032#ifdef TEST_FRAMEWORK
2034 pjsip_evsub *evsub = sub_tree->
evsub;
2040 pjsip_tx_data_dec_ref(tdata);
2044 res = pjsip_evsub_send_request(sub_tree->
evsub, tdata);
2051 pjsip_evsub_get_state_name(evsub),
2054 return (res == PJ_SUCCESS ? 0 : -1);
2071static void add_rlmi_resource(pj_pool_t *pool, pj_xml_node *rlmi,
const pjsip_generic_string_hdr *cid,
2072 const char *resource_name,
const pjsip_sip_uri *resource_uri, pjsip_evsub_state
state)
2074 static pj_str_t cid_name = {
"cid", 3 };
2075 pj_xml_node *resource;
2077 pj_xml_node *instance;
2078 pj_xml_attr *cid_attr;
2080 char uri[PJSIP_MAX_URL_SIZE];
2081 char name_sanitized[PJSIP_MAX_URL_SIZE];
2084 const pj_str_t cid_stripped = {
2085 .ptr = cid->hvalue.ptr + 1,
2086 .slen = cid->hvalue.slen - 2,
2093 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, resource_uri, uri,
sizeof(uri));
2097 pj_strdup2(pool, &
name->content, name_sanitized);
2103 state == PJSIP_EVSUB_STATE_TERMINATED ?
"terminated" :
"active");
2109 cid_attr = pj_xml_attr_new(pool, &cid_name, &cid_stripped);
2110 pj_xml_add_attr(instance, cid_attr);
2126 pjsip_generic_string_hdr *
cid;
2156 static const pj_str_t cid_name = {
"Content-ID", 10 };
2157 pjsip_generic_string_hdr *cid;
2163 alloc_size =
sizeof(
id) + pj_strlen(&
sub->uri->host) + 3;
2164 cid_value.ptr = pj_pool_alloc(pool, alloc_size);
2165 cid_value.slen = sprintf(cid_value.ptr,
"<%s@%.*s>",
2167 (
int) pj_strlen(&
sub->uri->host), pj_strbuf(&
sub->uri->host));
2168 cid = pjsip_generic_string_hdr_create(pool, &cid_name, &cid_value);
2176 pj_xml_node *rlmi = msg_body->data;
2178 num_printed = pj_xml_print(rlmi,
buf, size, PJ_TRUE);
2188 const pj_xml_node *rlmi = data;
2190 return pj_xml_clone(pool, rlmi);
2213 pjsip_multipart_part *rlmi_part;
2214 char version_str[32];
2215 char uri[PJSIP_MAX_URL_SIZE];
2216 pjsip_generic_string_hdr *cid;
2225 snprintf(version_str,
sizeof(version_str),
"%u",
sub->version++);
2238 rlmi_part = pjsip_multipart_create_part(pool);
2240 rlmi_part->body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);
2241 pjsip_media_type_cp(pool, &rlmi_part->body->content_type, &
rlmi_media_type);
2243 rlmi_part->body->data = pj_xml_clone(pool, rlmi);
2248 pj_list_insert_before(&rlmi_part->hdr,
cid);
2254 unsigned int force_full_state);
2290 bp->
state =
sub->subscription_state;
2309 pjsip_msg_body *body;
2323 bp->
part = pjsip_multipart_create_part(pool);
2324 bp->
part->body = body;
2325 pj_list_insert_before(&bp->
part->hdr, bp->
cid);
2340 pjsip_media_type media_type;
2341 pjsip_param *media_type_param;
2343 pj_str_t pj_boundary;
2345 pjsip_media_type_init2(&media_type,
"multipart",
"related");
2347 media_type_param = pj_pool_alloc(pool,
sizeof(*media_type_param));
2348 pj_list_init(media_type_param);
2350 pj_strdup2(pool, &media_type_param->name,
"type");
2351 pj_strdup2(pool, &media_type_param->value,
"\"application/rlmi+xml\"");
2353 pj_list_insert_before(&media_type.param, media_type_param);
2356 return pjsip_multipart_create(pool, &media_type, &pj_boundary);
2372 unsigned int force_full_state)
2375 pjsip_multipart_part *rlmi_part;
2376 pjsip_msg_body *multipart;
2378 unsigned int use_full_state = force_full_state ? 1 :
sub->full_state;
2401 pjsip_multipart_add_part(pool, multipart, rlmi_part);
2404 pjsip_multipart_add_part(pool, multipart,
AST_VECTOR_GET(&body_parts, i)->part);
2419 unsigned int force_full_state)
2421 pjsip_msg_body *body;
2436 body = pjsip_msg_body_create(pool, &
type, &subtype, &
text);
2453 pjsip_require_hdr *require;
2455 require = pjsip_require_hdr_create(pool);
2456 pj_strdup2(pool, &require->values[0],
"eventlist");
2466 sub->subscription_state = PJSIP_EVSUB_STATE_TERMINATED;
2484 pjsip_evsub *evsub = sub_tree->
evsub;
2485 pjsip_tx_data *tdata;
2494 NULL,
NULL, &tdata) != PJ_SUCCESS) {
2499 if (!tdata->msg->body) {
2500 pjsip_tx_data_dec_ref(tdata);
2506 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) require);
2528 pjsip_dialog *
dlg = sub_tree->
dlg;
2530 pjsip_dlg_inc_lock(
dlg);
2543 pjsip_dlg_dec_lock(
dlg);
2556 ?
"SUBSCRIPTION_TERMINATED" :
"SUBSCRIPTION_STATE_CHANGED",
2559 pjsip_dlg_dec_lock(
dlg);
2597 pjsip_dialog *
dlg =
sub->tree->dlg;
2599 pjsip_dlg_inc_lock(
dlg);
2602 pjsip_dlg_dec_lock(
dlg);
2608 pjsip_dlg_dec_lock(
dlg);
2612 sub->body_changed = 1;
2614 sub->subscription_state = PJSIP_EVSUB_STATE_TERMINATED;
2618 if (
sub->tree->notification_batch_interval) {
2629 sub->tree->root->resource);
2633 pjsip_dlg_dec_lock(
dlg);
2644 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,
sub->uri,
buf, size);
2653 uri = pjsip_uri_get_uri(
dlg->remote.info->uri);
2655 if (pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, uri,
buf, size) < 0) {
2662 return sub->resource;
2667 return sub->subscription_state == PJSIP_EVSUB_STATE_TERMINATED ? 1 : 0;
2679 pj_list_init(&res_hdr);
2685 return pjsip_evsub_accept(sub_tree->
evsub, rdata, response, &res_hdr) == PJ_SUCCESS ? 0 : -1;
2785 ast_log(
LOG_ERROR,
"No event package specified for publish handler. Cannot register\n");
2792 ast_log(
LOG_ERROR,
"Could not allocate publications container for event '%s'\n",
2849 ast_log(
LOG_ERROR,
"No event package specified for subscription handler. Cannot register\n");
2856 "Unable to register subscription handler for event %s. A handler is already registered\n",
2927 size_t num_accept,
const char *
body_type)
2932 for (i = 0; i < num_accept; ++i) {
2935 ast_debug(3,
"Body generator %p found for accept type %s\n", generator, accept[i]);
2937 ast_log(
LOG_WARNING,
"Body generator '%s/%s'(%p) does not accept the type of data this event generates\n",
2944 ast_debug(3,
"No body generator found for accept type %s\n", accept[i]);
2972 if (
sub->handler->notifier->subscription_established(
sub)) {
2978 ast_debug(3,
"No notify data, not generating any body content\n");
3023 ast_log(
LOG_ERROR,
"Unable to create expiration timer of %d seconds for %s\n",
3036 pjsip_expires_hdr *expires_header;
3042 pjsip_uri *request_uri;
3043 size_t resource_size;
3046 pj_status_t dlg_status;
3047 const pj_str_t *
user;
3052 if (!endpoint->subscription.allow) {
3058 request_uri = rdata->msg_info.msg->line.req.uri;
3061 char uri_str[PJSIP_MAX_URL_SIZE];
3063 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, request_uri, uri_str,
sizeof(uri_str));
3070 resource_size = pj_strlen(
user) + 1;
3080 expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
3081 if (expires_header) {
3082 if (expires_header->ivalue == 0) {
3083 ast_debug(1,
"Subscription request from endpoint %s rejected. Expiration of 0 is invalid\n",
3088 if (expires_header->ivalue < endpoint->subscription.minexpiry) {
3089 ast_log(
LOG_WARNING,
"Subscription expiration %d is too brief for endpoint %s. Minimum is %u\n",
3108 memset(&tree, 0,
sizeof(tree));
3111 if (!PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
3119 if (dlg_status != PJ_EEXISTS) {
3120 ast_debug(3,
"No dialog exists, rejecting\n");
3169 pjsip_generic_string_hdr *etag_hdr,
unsigned int *expires,
int *entity_id)
3171 pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES,
NULL);
3174 char etag[pj_strlen(&etag_hdr->hvalue) + 1];
3178 if (sscanf(etag,
"%30d", entity_id) != 1) {
3187 }
else if (!etag_hdr && rdata->msg_info.msg->body) {
3189 }
else if (etag_hdr && !rdata->msg_info.msg->body) {
3191 }
else if (etag_hdr && rdata->msg_info.msg->body) {
3203 ast_debug(3,
"Destroying SIP publication\n");
3215 pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES,
NULL);
3237 dst = publication->
data;
3239 dst += resource_len;
3246 pjsip_rx_data *rdata)
3248 pjsip_tx_data *tdata;
3249 pjsip_transaction *tsx;
3255 if (PJSIP_IS_STATUS_IN_CLASS(status_code, 200)) {
3265 if (pjsip_tsx_create_uas(&
pubsub_module, rdata, &tsx) != PJ_SUCCESS) {
3266 pjsip_tx_data_dec_ref(tdata);
3270 pjsip_tsx_recv_msg(tsx, rdata);
3272 if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
3273 pjsip_tx_data_dec_ref(tdata);
3284 char *resource_name;
3285 size_t resource_size;
3288 pjsip_uri *request_uri;
3290 const pj_str_t *
user;
3292 request_uri = rdata->msg_info.msg->line.req.uri;
3295 char uri_str[PJSIP_MAX_URL_SIZE];
3297 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, request_uri, uri_str,
sizeof(uri_str));
3304 resource_size = pj_strlen(
user) + 1;
3316 ast_debug(1,
"No 'inbound-publication' defined for resource '%s'\n", resource_name);
3322 ast_debug(1,
"Resource %s has a defined endpoint '%s', but does not match endpoint '%s' that received the request\n",
3328 for (event_configuration_name = resource->events; event_configuration_name; event_configuration_name = event_configuration_name->
next) {
3329 if (!strcmp(event_configuration_name->
name,
handler->event_name)) {
3334 if (!event_configuration_name) {
3335 ast_debug(1,
"Event '%s' is not configured for '%s'\n",
handler->event_name, resource_name);
3340 resp =
handler->new_publication(endpoint, resource_name, event_configuration_name->
value);
3342 if (!PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
3357 ast_debug(3,
"Publication state change failed\n");
3372 if (publication->handler->publish_expire) {
3373 publication->handler->publish_expire(publication);
3395 pjsip_event_hdr *event_header;
3399 static const pj_str_t str_sip_if_match = {
"SIP-If-Match", 12 };
3400 pjsip_generic_string_hdr *etag_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_sip_if_match,
NULL);
3403 unsigned int expires = 0;
3404 int entity_id, response = 0;
3409 event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &
str_event_name, rdata->msg_info.msg->hdr.next);
3410 if (!event_header) {
3431 static const pj_str_t str_conditional_request_failed = {
"Conditional Request Failed", 26 };
3442 publication->expires = expires;
3445 switch (publish_type) {
3451 if (
handler->publication_state_change(publication, rdata->msg_info.msg->body,
3459 handler->publication_state_change(publication, rdata->msg_info.msg->body,
3511 pj_size_t accept_len;
3525 accept_len = strlen(generator->
type) + strlen(generator->
subtype) + 1;
3528 pj_strset(&accept,
ast_alloca(accept_len + 1), accept_len);
3529 sprintf((
char *) pj_strbuf(&accept),
"%s/%s", generator->
type, generator->
subtype);
3532 PJSIP_H_ACCEPT,
NULL, 1, &accept);
3543 if (iter == generator) {
3567 if (iter == supplement) {
3578 return sub->body_generator->type;
3583 return sub->body_generator->subtype;
3602 ast_log(
LOG_WARNING,
"%s/%s body generator does not accept the type of data provided\n",
3621 if (!strcmp(generator->
type, supplement->
type) &&
3657 int found_counts = 0;
3664 memset(summary, 0,
sizeof(*summary));
3669 if (sscanf(line,
"voice-message: %d/%d (%d/%d)",
3678 return !found_counts;
3685 const char *endpoint_name;
3694 ast_debug(1,
"Incoming MWI: Endpoint not found in rdata (%p)\n", rdata);
3700 ast_debug(1,
"Incoming MWI: Found endpoint: %s\n", endpoint_name);
3702 ast_debug(1,
"Incoming MWI: No incoming mailbox specified for endpoint '%s'\n", endpoint_name);
3704 "Endpoint: %s", endpoint_name);
3710 atsign = strchr(
mailbox,
'@');
3712 ast_debug(1,
"Incoming MWI: No '@' found in endpoint %s's incoming mailbox '%s'. Can't parse context\n",
3713 endpoint_name, endpoint->incoming_mwi_mailbox);
3721 body =
ast_alloca(rdata->msg_info.msg->body->len + 1);
3722 rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, body,
3723 rdata->msg_info.msg->body->len + 1);
3726 ast_debug(1,
"Incoming MWI: Endpoint: '%s' There was an issue getting message info from body '%s'\n",
3734 ast_log(
LOG_ERROR,
"Incoming MWI: Endpoint: '%s' Could not publish MWI to stasis. "
3735 "Mailbox: %s Message-Account: %s Voice-Messages: %d/%d (%d/%d)\n",
3736 endpoint_name, endpoint->incoming_mwi_mailbox, summary.
message_account,
3741 ast_debug(1,
"Incoming MWI: Endpoint: '%s' Mailbox: %s Message-Account: %s Voice-Messages: %d/%d (%d/%d)\n",
3742 endpoint_name, endpoint->incoming_mwi_mailbox, summary.
message_account,
3748 "MessageAccount: %s\r\n"
3749 "VoiceMessagesNew: %d\r\n"
3750 "VoiceMessagesOld: %d\r\n"
3751 "VoiceMessagesUrgentNew: %d\r\n"
3752 "VoiceMessagesUrgentOld: %d",
3753 endpoint_name, endpoint->incoming_mwi_mailbox, summary.
message_account,
3766 if (rdata->msg_info.msg->body &&
3768 "application",
"simple-message-summary")) {
3776 if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method())) {
3780 }
else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_notify_method)) {
3878 char task_name[256];
3881 ast_debug(3,
"Cancelling timer: %s\n", task_name);
3891#ifdef HAVE_PJSIP_EVSUB_GRP_LOCK
3892 pjsip_evsub_dec_ref(sub_tree->
evsub);
3909#if PJ_VERSION_NUM >= 0x020D0000
3910# define HAVE_PJSIP_EVSUB_PENDING_NOTIFY 1
3927 ast_debug(3,
"evsub %p state %s event %s sub_tree %p sub_tree state %s\n",
evsub,
3928 pjsip_evsub_get_state_name(
evsub), pjsip_event_str(
event->type), sub_tree,
3931 if (!sub_tree || pjsip_evsub_get_state(
evsub) != PJSIP_EVSUB_STATE_TERMINATED) {
3943#ifdef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
3948 if (
event->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&
3949 !pjsip_method_cmp(&
event->body.tsx_state.tsx->method, &pjsip_subscribe_method) &&
3950 pjsip_evsub_get_expires(
evsub) == 0) {
3951 ast_debug(3,
"Subscription ending, do nothing.\n");
3963 pjsip_dialog *
dlg = sub_tree->
dlg;
3965 ast_debug(3,
"sub_tree %p sub_tree state %s\n", sub_tree,
3968 pjsip_dlg_inc_lock(
dlg);
3970 pjsip_dlg_dec_lock(
dlg);
3982 pjsip_evsub_terminate(sub_tree->
evsub, PJ_TRUE);
3983 pjsip_dlg_dec_lock(
dlg);
3991 "SUBSCRIPTION_TERMINATED" :
"SUBSCRIPTION_REFRESHED",
3994 pjsip_dlg_dec_lock(
dlg);
4003 ast_debug(3,
"sub_tree %p sub_tree state %s\n", sub_tree,
4024 return strcmp(s1, s2);
4076 int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
4082 ast_debug(3,
"evsub %p sub_tree %p sub_tree state %s\n",
evsub, sub_tree,
4090 char task_name[256];
4093 ast_debug(3,
"Cancelling timer: %s\n", task_name);
4103 if (pjsip_evsub_get_state(sub_tree->
evsub) == PJSIP_EVSUB_STATE_TERMINATED) {
4129 memset(&tree, 0,
sizeof(tree));
4132 if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
4138 sub_tree->
root = new_root;
4156 ast_log(
LOG_ERROR,
"Failed to push task to destroy old subscriptions for RLS '%s->%s'.\n",
4165 pjsip_evsub_terminate(sub_tree->
evsub, PJ_TRUE);
4174#ifdef HAVE_PJSIP_EVSUB_PENDING_NOTIFY
4196 pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)
4204 sub->handler->subscriber->state_change(
sub, rdata->msg_info.msg->body,
4205 pjsip_evsub_get_state(evsub));
4211 pjsip_tx_data *tdata;
4213 if (!sub_tree->
evsub) {
4218 if (pjsip_evsub_initiate(sub_tree->
evsub,
NULL, -1, &tdata) == PJ_SUCCESS) {
4219 pjsip_evsub_send_request(sub_tree->
evsub, tdata);
4221 pjsip_evsub_terminate(sub_tree->
evsub, PJ_TRUE);
4292 sub_tree, arg,
"InboundSubscriptionDetail") : 0;
4298 sub_tree, arg,
"OutboundSubscriptionDetail") : 0;
4364 astman_send_listack(s, m,
"A listing of resource lists follows, presented as ResourceListDetail events",
4374#define AMI_SHOW_SUBSCRIPTIONS_INBOUND "PJSIPShowSubscriptionsInbound"
4375#define AMI_SHOW_SUBSCRIPTIONS_OUTBOUND "PJSIPShowSubscriptionsOutbound"
4377#define MAX_REGEX_ERROR_LEN 128
4403 if (!sub_tree->
dlg) {
4407 callid = &sub_tree->
dlg->call_id->id;
4408 if (
cli->wordlen <= pj_strlen(callid)
4409 && !strncasecmp(
cli->a->word, pj_strbuf(callid),
cli->wordlen)
4410 && (++
cli->which >
cli->a->n)) {
4441 if (!strcasecmp(
a->argv[3],
"inbound")) {
4443 }
else if (!strcasecmp(
a->argv[3],
"outbound")) {
4453 cli.wordlen = strlen(
a->word);
4476 const char *
callid = (
const char *)
cli->buf;
4477 pj_str_t *sub_callid;
4485 int key_filler_width;
4488 if (!sub_tree->
dlg) {
4491 sub_callid = &sub_tree->
dlg->call_id->id;
4492 if (pj_strcmp2(sub_callid,
callid)) {
4503 "===========================================================================\n",
4504 "ParameterName",
"ParameterValue");
4531 value = strchr(key,
':');
4535 value_end = strchr(
value,
'\n');
4541 key_len =
value - key;
4542 key_filler_width = 20 - key_len;
4543 if (key_filler_width < 0) {
4544 key_filler_width = 0;
4546 value_len = value_end -
value;
4549 key_len, key, key_filler_width,
"",
4552 key = value_end + 1;