<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/20031">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_pubsub: Add new pubsub module capabilities.<br><br>The existing res_pjsip_pubsub APIs are somewhat limited in<br>what they can do. This adds a few API extensions that make<br>it possible for PJSIP pubsub modules to implement richer<br>features than is currently possible.<br><br>* Allow pubsub modules to get a handle to pjsip_rx_data on subscription<br>* Allow pubsub modules to run a callback when a subscription is renewed<br>* Allow pubsub modules to run a callback for outgoing NOTIFYs, with<br> a handle to the tdata, so that modules can append their own headers<br> to the NOTIFYs<br><br>This change does not add any features directly, but makes possible<br>several new features that will be added in future changes.<br><br>ASTERISK-30485 #close<br><br>Master-Only: True<br>Change-Id: I5c54d32223eedab7460ca28616ed50ba4ce1341f<br>---<br>M include/asterisk/res_pjsip_pubsub.h<br>M res/res_pjsip_pubsub.c<br>2 files changed, 139 insertions(+), 36 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/31/20031/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/res_pjsip_pubsub.h b/include/asterisk/res_pjsip_pubsub.h</span><br><span>index aca1141..ac4bda8 100644</span><br><span>--- a/include/asterisk/res_pjsip_pubsub.h</span><br><span>+++ b/include/asterisk/res_pjsip_pubsub.h</span><br><span>@@ -269,6 +269,18 @@</span><br><span> */</span><br><span> int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);</span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Same as new_subscribe, but also pass a handle to the pjsip_rx_data</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note If this callback exists, it will be executed, otherwise new_subscribe will be.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Only use this if you need the rdata. Otherwise, use new_subscribe.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param endpoint The endpoint from which we received the SUBSCRIBE</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param resource The name of the resource to which the subscription is being made</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param rdata The pjsip_rx_data for incoming subscription</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return The response code to send to the SUBSCRIBE.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ int (*new_subscribe_with_rdata)(struct ast_sip_endpoint *endpoint, const char *resource, pjsip_rx_data *rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span> * \brief Called when an inbound subscription has been accepted.</span><br><span> *</span><br><span> * This is a prime opportunity for notifiers to add any notifier-specific</span><br><span>@@ -283,6 +295,25 @@</span><br><span> */</span><br><span> int (*subscription_established)(struct ast_sip_subscription *sub);</span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Called when a SUBSCRIBE arrives for an already active subscription.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sub The existing subscription</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ int (*refresh_subscribe)(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Optional callback to execute before sending outgoing NOTIFY responses.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Because res_pjsip_pubsub creates the tdata internally, this allows modules</span><br><span style="color: hsl(120, 100%, 40%);">+ * to access the tdata if needed, e.g. to add custom headers.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sub The existing subscription</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param tdata The pjsip_tx_data to use for the outgoing NOTIFY</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ int (*tdata_callback)(struct ast_sip_subscription *sub, pjsip_tx_data *tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span> * \brief Supply data needed to create a NOTIFY body.</span><br><span> *</span><br><span> * The returned data must be an ao2 object. The caller of this function</span><br><span>diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c</span><br><span>index 6ddb2fd..c8923d6 100644</span><br><span>--- a/res/res_pjsip_pubsub.c</span><br><span>+++ b/res/res_pjsip_pubsub.c</span><br><span>@@ -807,6 +807,30 @@</span><br><span> return handler;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief Retrieve a handler using the Event header of a tdata message */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sip_subscription_handler *subscription_get_handler_from_tdata(pjsip_tx_data *tdata, const char *endpoint)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_event_hdr *event_header;</span><br><span style="color: hsl(120, 100%, 40%);">+ char event[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_subscription_handler *handler;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ event_header = pjsip_msg_find_hdr_by_name(tdata->msg, &str_event_name, tdata->msg->hdr.next);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!event_header) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "Incoming SUBSCRIBE request from %s with no Event header\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ endpoint ? endpoint : "Unknown");</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_pj_str(event, &event_header->event_type, sizeof(event));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ handler = find_sub_handler_for_event_name(event);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!handler) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_WARNING, "No registered subscribe handler for event %s from %s\n", event,</span><br><span style="color: hsl(120, 100%, 40%);">+ endpoint ? endpoint : "Unknown");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return handler;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief Accept headers that are exceptions to the rule</span><br><span> *</span><br><span>@@ -1018,6 +1042,8 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#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)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief Build child nodes for a given parent.</span><br><span> *</span><br><span>@@ -1040,7 +1066,7 @@</span><br><span> * \param visited The resources that have already been visited.</span><br><span> */</span><br><span> static void build_node_children(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,</span><br><span style="color: hsl(0, 100%, 40%);">- struct resource_list *list, struct tree_node *parent, struct resources *visited)</span><br><span style="color: hsl(120, 100%, 40%);">+ struct resource_list *list, struct tree_node *parent, struct resources *visited, pjsip_rx_data *rdata)</span><br><span> {</span><br><span> int i;</span><br><span> </span><br><span>@@ -1056,7 +1082,7 @@</span><br><span> </span><br><span> child_list = retrieve_resource_list(resource, list->event);</span><br><span> if (!child_list) {</span><br><span style="color: hsl(0, 100%, 40%);">- int resp = handler->notifier->new_subscribe(endpoint, resource);</span><br><span style="color: hsl(120, 100%, 40%);">+ int resp = NEW_SUBSCRIBE(handler->notifier, endpoint, resource, rdata);</span><br><span> if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {</span><br><span> char display_name[AST_MAX_EXTENSION] = "";</span><br><span> if (list->resource_display_name && handler->notifier->get_resource_display_name) {</span><br><span>@@ -1085,7 +1111,7 @@</span><br><span> ast_debug(1, "Cannot build children of resource %s due to allocation failure\n", resource);</span><br><span> continue;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- build_node_children(endpoint, handler, child_list, current, visited);</span><br><span style="color: hsl(120, 100%, 40%);">+ build_node_children(endpoint, handler, child_list, current, visited, rdata);</span><br><span> if (AST_VECTOR_SIZE(¤t->children) > 0) {</span><br><span> ast_debug(1, "List %s had no successful children.\n", resource);</span><br><span> if (AST_VECTOR_APPEND(&parent->children, current)) {</span><br><span>@@ -1158,7 +1184,7 @@</span><br><span> * \retval 300-699 Failure to subscribe to requested resource.</span><br><span> */</span><br><span> static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,</span><br><span style="color: hsl(0, 100%, 40%);">- const char *resource, struct resource_tree *tree, int has_eventlist_support)</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *resource, struct resource_tree *tree, int has_eventlist_support, pjsip_rx_data *rdata)</span><br><span> {</span><br><span> RAII_VAR(struct resource_list *, list, NULL, ao2_cleanup);</span><br><span> struct resources visited;</span><br><span>@@ -1170,7 +1196,7 @@</span><br><span> if (!tree->root) {</span><br><span> return 500;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- return handler->notifier->new_subscribe(endpoint, resource);</span><br><span style="color: hsl(120, 100%, 40%);">+ return NEW_SUBSCRIBE(handler->notifier, endpoint, resource, rdata);</span><br><span> }</span><br><span> </span><br><span> ast_debug(2, "Subscription '%s->%s' is a list\n",</span><br><span>@@ -1187,7 +1213,7 @@</span><br><span> </span><br><span> tree->notification_batch_interval = list->notification_batch_interval;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- build_node_children(endpoint, handler, list, tree->root, &visited);</span><br><span style="color: hsl(120, 100%, 40%);">+ build_node_children(endpoint, handler, list, tree->root, &visited, rdata);</span><br><span> AST_VECTOR_FREE(&visited);</span><br><span> </span><br><span> if (AST_VECTOR_SIZE(&tree->root->children) > 0) {</span><br><span>@@ -1380,6 +1406,7 @@</span><br><span> sub->handler->subscription_shutdown(sub);</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int subscription_unreference_dialog(void *obj)</span><br><span> {</span><br><span> struct sip_subscription_tree *sub_tree = obj;</span><br><span>@@ -1674,7 +1701,7 @@</span><br><span> </span><br><span> memset(&tree, 0, sizeof(tree));</span><br><span> resp = build_resource_tree(endpoint, handler, resource, &tree,</span><br><span style="color: hsl(0, 100%, 40%);">- ast_sip_pubsub_has_eventlist_support(rdata));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_pubsub_has_eventlist_support(rdata), rdata);</span><br><span> if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {</span><br><span> pj_status_t dlg_status;</span><br><span> </span><br><span>@@ -2454,6 +2481,16 @@</span><br><span> return require;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void set_state_terminated(struct ast_sip_subscription *sub)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sub->subscription_state = PJSIP_EVSUB_STATE_TERMINATED;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < AST_VECTOR_SIZE(&sub->children); ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+ set_state_terminated(AST_VECTOR_GET(&sub->children, i));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief Send a NOTIFY request to a subscriber</span><br><span> *</span><br><span>@@ -2468,6 +2505,7 @@</span><br><span> {</span><br><span> pjsip_evsub *evsub = sub_tree->evsub;</span><br><span> pjsip_tx_data *tdata;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_subscription_handler *handler;</span><br><span> </span><br><span> if (ast_shutdown_final()</span><br><span> && sub_tree->root->subscription_state == PJSIP_EVSUB_STATE_TERMINATED</span><br><span>@@ -2491,6 +2529,13 @@</span><br><span> pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) require);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ handler = subscription_get_handler_from_tdata(tdata, sub_tree->persistence->endpoint);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (handler->notifier->tdata_callback) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The module for this event wants a callback to the pjsip_tx_data,</span><br><span style="color: hsl(120, 100%, 40%);">+ * e.g. so it can add custom headers or do something custom to the response. */</span><br><span style="color: hsl(120, 100%, 40%);">+ handler->notifier->tdata_callback(sub_tree->root, tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (sip_subscription_send_request(sub_tree, tdata)) {</span><br><span> /* do not call pjsip_tx_data_dec_ref(tdata). The pjsip_dlg_send_request deletes the message on error */</span><br><span> return -1;</span><br><span>@@ -2954,6 +2999,7 @@</span><br><span> </span><br><span> notify_data = sub->handler->notifier->get_notify_data(sub);</span><br><span> if (!notify_data) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, "No notify data, terminating\n");</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span>@@ -3085,7 +3131,7 @@</span><br><span> </span><br><span> memset(&tree, 0, sizeof(tree));</span><br><span> resp = build_resource_tree(endpoint, handler, resource, &tree,</span><br><span style="color: hsl(0, 100%, 40%);">- ast_sip_pubsub_has_eventlist_support(rdata));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_pubsub_has_eventlist_support(rdata), rdata);</span><br><span> if (!PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {</span><br><span> pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, resp, NULL, NULL, NULL);</span><br><span> resource_tree_destroy(&tree);</span><br><span>@@ -3095,6 +3141,7 @@</span><br><span> sub_tree = create_subscription_tree(handler, endpoint, rdata, resource, generator, &tree, &dlg_status, NULL);</span><br><span> if (!sub_tree) {</span><br><span> if (dlg_status != PJ_EEXISTS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, "No dialog exists, rejecting\n");</span><br><span> pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);</span><br><span> }</span><br><span> } else {</span><br><span>@@ -3331,6 +3378,7 @@</span><br><span> publication->handler = handler;</span><br><span> if (publication->handler->publication_state_change(publication, rdata->msg_info.msg->body,</span><br><span> AST_SIP_PUBLISH_STATE_INITIALIZED)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(3, "Publication state change failed\n");</span><br><span> pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);</span><br><span> ao2_cleanup(publication);</span><br><span> return NULL;</span><br><span>@@ -3760,16 +3808,6 @@</span><br><span> return PJ_FALSE;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void set_state_terminated(struct ast_sip_subscription *sub)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- sub->subscription_state = PJSIP_EVSUB_STATE_TERMINATED;</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < AST_VECTOR_SIZE(&sub->children); ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">- set_state_terminated(AST_VECTOR_GET(&sub->children, i));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*!</span><br><span> * \brief Callback sequence for subscription terminate:</span><br><span> *</span><br><span>@@ -3852,7 +3890,8 @@</span><br><span> </span><br><span> </span><br><span> /* The code in this function was previously in pubsub_on_evsub_state. */</span><br><span style="color: hsl(0, 100%, 40%);">-static void clean_sub_tree(pjsip_evsub *evsub){</span><br><span style="color: hsl(120, 100%, 40%);">+static void clean_sub_tree(pjsip_evsub *evsub)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span> </span><br><span> struct sip_subscription_tree *sub_tree;</span><br><span> sub_tree = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);</span><br><span>@@ -3912,7 +3951,6 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* It's easier to write this as what we WANT to process, then negate it. */</span><br><span> if (!(sub_tree->state == SIP_SUB_TREE_TERMINATE_IN_PROGRESS</span><br><span> || (event->type == PJSIP_EVENT_TSX_STATE && sub_tree->state == SIP_SUB_TREE_NORMAL)</span><br><span>@@ -3927,9 +3965,8 @@</span><br><span> This was previously handled by pubsub_on_rx_refresh setting:</span><br><span> 'sub_tree->state = SIP_SUB_TREE_TERMINATE_PENDING' */</span><br><span> if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&</span><br><span style="color: hsl(0, 100%, 40%);">- !pjsip_method_cmp(&event->body.tsx_state.tsx->method, &pjsip_subscribe_method) &&</span><br><span style="color: hsl(0, 100%, 40%);">- pjsip_evsub_get_expires(evsub) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ !pjsip_method_cmp(&event->body.tsx_state.tsx->method, &pjsip_subscribe_method) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ pjsip_evsub_get_expires(evsub) == 0) {</span><br><span> ast_debug(3, "Subscription ending, do nothing.\n");</span><br><span> return;</span><br><span> }</span><br><span>@@ -4058,6 +4095,8 @@</span><br><span> int *p_st_code, pj_str_t **p_st_text, pjsip_hdr *res_hdr, pjsip_msg_body **p_body)</span><br><span> {</span><br><span> struct sip_subscription_tree *sub_tree;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sip_subscription_handler *handler = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);</span><br><span> </span><br><span> sub_tree = pjsip_evsub_get_mod_data(evsub, pubsub_module.id);</span><br><span> ast_debug(3, "evsub %p sub_tree %p sub_tree state %s\n", evsub, sub_tree,</span><br><span>@@ -4085,25 +4124,32 @@</span><br><span> sub_tree->state = SIP_SUB_TREE_TERMINATE_PENDING;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ endpoint = ast_pjsip_rdata_get_endpoint(rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+ handler = endpoint ? subscription_get_handler_from_rdata(rdata, ast_sorcery_object_get_id(endpoint)) : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If the handler wants a callback on refresh, then do it (some protocols require this). */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sub_tree->state == SIP_SUB_TREE_NORMAL && handler && handler->notifier->refresh_subscribe) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!handler->notifier->refresh_subscribe(sub_tree->root, rdata)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return; /* If the callback handled it, we're done. */</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (sub_tree->state == SIP_SUB_TREE_NORMAL && sub_tree->is_list) {</span><br><span> /* update RLS */</span><br><span> const char *resource = sub_tree->root->resource;</span><br><span> struct ast_sip_subscription *old_root = sub_tree->root;</span><br><span> struct ast_sip_subscription *new_root = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_sip_subscription_handler *handler = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct ast_sip_pubsub_body_generator *generator = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if ((endpoint = ast_pjsip_rdata_get_endpoint(rdata))</span><br><span style="color: hsl(0, 100%, 40%);">- && (handler = subscription_get_handler_from_rdata(rdata, ast_sorcery_object_get_id(endpoint)))</span><br><span style="color: hsl(0, 100%, 40%);">- && (generator = subscription_get_generator_from_rdata(rdata, handler))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endpoint && handler && (generator = subscription_get_generator_from_rdata(rdata, handler))) {</span><br><span> </span><br><span> struct resource_tree tree;</span><br><span> int resp;</span><br><span> </span><br><span> memset(&tree, 0, sizeof(tree));</span><br><span> resp = build_resource_tree(endpoint, handler, resource, &tree,</span><br><span style="color: hsl(0, 100%, 40%);">- ast_sip_pubsub_has_eventlist_support(rdata));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sip_pubsub_has_eventlist_support(rdata), rdata);</span><br><span> if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {</span><br><span> new_root = create_virtual_subscriptions(handler, resource, generator, sub_tree, tree.root);</span><br><span> if (new_root) {</span><br><span>@@ -5330,7 +5376,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5400,7 +5446,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5461,7 +5507,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5530,7 +5576,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5603,7 +5649,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5675,7 +5721,7 @@</span><br><span> }</span><br><span> </span><br><span> tree = ast_calloc(1, sizeof(*tree));</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "herp", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "herp", tree, 1, NULL);</span><br><span> if (resp == 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span>@@ -5722,7 +5768,7 @@</span><br><span> /* Since the test_handler is for event "test", this should not build a list, but</span><br><span> * instead result in a single resource being created, called "foo"</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">- resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ resp = build_resource_tree(NULL, &test_handler, "foo", tree, 1, NULL);</span><br><span> if (resp != 200) {</span><br><span> ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);</span><br><span> return AST_TEST_FAIL;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/20031">change 20031</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/20031"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I5c54d32223eedab7460ca28616ed50ba4ce1341f </div>
<div style="display:none"> Gerrit-Change-Number: 20031 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>