]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_exten_state: Use the extension for publishing to. 08/2808/5
authorJoshua Colp <jcolp@digium.com>
Tue, 10 May 2016 16:28:04 +0000 (13:28 -0300)
committerJoshua Colp <jcolp@digium.com>
Wed, 18 May 2016 23:37:27 +0000 (18:37 -0500)
This change uses the newly added multi-user support for
outbound publish to publish to the specific user that an
extension state change is for.

This also extends the res_pjsip_outbound_publish support
to include the user specific From and To URI information in
the outbound publishing of extension state. Since the URI
is used when constructing the body it is important to ensure
that the correct local and remote URIs are used.

Finally the max string growths for the dialog-info+xml
body generator has been increased as through testing it has
proven to be too conservative.

ASTERISK-25965

Change-Id: I668fdf697b1e171d4c7e6f282b2e1590f8356ca1

include/asterisk/res_pjsip_outbound_publish.h
res/res_pjsip_dialog_info_body_generator.c
res/res_pjsip_exten_state.c
res/res_pjsip_outbound_publish.c

index 2831afb3517f944612130403fed05707c656038c..a578b5aece29ee8732d92df533532c792a6be1cf 100644 (file)
@@ -103,6 +103,21 @@ struct ast_sip_outbound_publish_client *ast_sip_publish_client_get(const char *n
  */
 const char *ast_sip_publish_client_get_from_uri(struct ast_sip_outbound_publish_client *client);
 
+/*!
+ * \brief Get the From URI the client will use for a specific user.
+ * \since 14.0.0
+ *
+ * \param client The publication client to get the From URI of a user
+ * \param user The user to retrieve the From URI for
+ * \param uri A buffer to place the URI into
+ * \param size The size of the buffer
+ *
+ * \retval From-uri on success
+ * \retval Empty-string on failure
+ */
+const char *ast_sip_publish_client_get_user_from_uri(struct ast_sip_outbound_publish_client *client, const char *user,
+       char *uri, size_t size);
+
 /*!
  * \brief Get the To URI the client will use.
  * \since 14.0.0
@@ -114,6 +129,21 @@ const char *ast_sip_publish_client_get_from_uri(struct ast_sip_outbound_publish_
  */
 const char *ast_sip_publish_client_get_to_uri(struct ast_sip_outbound_publish_client *client);
 
+/*!
+ * \brief Get the To URI the client will use for a specific user.
+ * \since 14.0.0
+ *
+ * \param client The publication client to get the To URI of a user
+ * \param user The user to retrieve the To URI for
+ * \param uri A buffer to place the URI into
+ * \param size The size of the buffer
+ *
+ * \retval To-uri on success
+ * \retval Empty-string on failure
+ */
+const char *ast_sip_publish_client_get_user_to_uri(struct ast_sip_outbound_publish_client *client, const char *user,
+       char *uri, size_t size);
+
 /*!
  * \brief Alternative for ast_datastore_alloc()
  *
index d21af2ae61c2b19b4df336e46cf78a8387a7e786..5006b9efb4ef0c1bfcc02a787fca3698adccb723 100644 (file)
@@ -157,7 +157,7 @@ static int dialog_info_generate_body_content(void *body, void *data)
 /* The maximum number of times the ast_str() for the body text can grow before we declare an XML body
  * too large to send.
  */
-#define MAX_STRING_GROWTHS 3
+#define MAX_STRING_GROWTHS 6
 
 static void dialog_info_to_string(void *body, struct ast_str **str)
 {
index 22fb69c29a58b492507a87d78af425cd0ebcab5e..25b9bf1fe84fcbfbb87e466250e9dd9e6355e739 100644 (file)
@@ -647,21 +647,21 @@ static int exten_state_publisher_cb(void *data)
 
                publisher = AST_VECTOR_GET(&pub_data->pubs, idx);
 
-               uri = ast_sip_publish_client_get_from_uri(publisher->client);
+               uri = ast_sip_publish_client_get_user_from_uri(publisher->client, pub_data->exten_state_data.exten,
+                       pub_data->exten_state_data.local, sizeof(pub_data->exten_state_data.local));
                if (ast_strlen_zero(uri)) {
                        ast_log(LOG_WARNING, "PUBLISH client '%s' has no from_uri or server_uri defined.\n",
                                publisher->name);
                        continue;
                }
-               ast_copy_string(pub_data->exten_state_data.local, uri, sizeof(pub_data->exten_state_data.local));
 
-               uri = ast_sip_publish_client_get_to_uri(publisher->client);
+               uri = ast_sip_publish_client_get_user_to_uri(publisher->client, pub_data->exten_state_data.exten,
+                       pub_data->exten_state_data.remote, sizeof(pub_data->exten_state_data.remote));
                if (ast_strlen_zero(uri)) {
                        ast_log(LOG_WARNING, "PUBLISH client '%s' has no to_uri or server_uri defined.\n",
                                publisher->name);
                        continue;
                }
-               ast_copy_string(pub_data->exten_state_data.remote, uri, sizeof(pub_data->exten_state_data.remote));
 
                pub_data->exten_state_data.datastores = publisher->datastores;
 
@@ -678,7 +678,7 @@ static int exten_state_publisher_cb(void *data)
                body.type = publisher->body_type;
                body.subtype = publisher->body_subtype;
                body.body_text = ast_str_buffer(body_text);
-               ast_sip_publish_client_send(publisher->client, &body);
+               ast_sip_publish_client_user_send(publisher->client, pub_data->exten_state_data.exten, &body);
        }
 
        pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
index f37ce2305f312c5c9096a024c8d6934e497a6dc3..1c3b0c6444da59a3247b4aa250e2e3c241ba4e70 100644 (file)
@@ -190,6 +190,10 @@ struct sip_outbound_publisher {
        struct ast_sip_outbound_publish_client *owner;
        /*! \brief Underlying publish client */
        pjsip_publishc *client;
+       /*! \brief The From URI for this specific publisher */
+       char *from_uri;
+       /*! \brief The To URI for this specific publisher */
+       char *to_uri;
        /*! \brief Timer entry for refreshing publish */
        pj_timer_entry timer;
        /*! \brief The number of auth attempts done */
@@ -525,6 +529,49 @@ const char *ast_sip_publish_client_get_from_uri(struct ast_sip_outbound_publish_
        return S_OR(publish->from_uri, S_OR(publish->server_uri, ""));
 }
 
+static struct sip_outbound_publisher *sip_outbound_publish_client_add_publisher(
+        struct ast_sip_outbound_publish_client *client, const char *user);
+
+static struct sip_outbound_publisher *sip_outbound_publish_client_get_publisher(
+       struct ast_sip_outbound_publish_client *client, const char *user)
+{
+       struct sip_outbound_publisher *publisher;
+
+       /*
+        * Lock before searching since there could be a race between searching and adding.
+        * Just use the load_lock since we might need to lock it anyway (if adding) and
+        * also it simplifies the code (otherwise we'd have to lock the publishers, no-
+        * lock the search and pass a flag to 'add publisher to no-lock the potential link).
+        */
+       ast_rwlock_wrlock(&load_lock);
+       publisher = ao2_find(client->publishers, user, OBJ_SEARCH_KEY);
+       if (!publisher) {
+               if (!(publisher = sip_outbound_publish_client_add_publisher(client, user))) {
+                       ast_rwlock_unlock(&load_lock);
+                       return NULL;
+               }
+       }
+       ast_rwlock_unlock(&load_lock);
+
+       return publisher;
+}
+
+const char *ast_sip_publish_client_get_user_from_uri(struct ast_sip_outbound_publish_client *client, const char *user,
+       char *uri, size_t size)
+{
+       struct sip_outbound_publisher *publisher;
+
+       publisher = sip_outbound_publish_client_get_publisher(client, user);
+       if (!publisher) {
+               return NULL;
+       }
+
+       ast_copy_string(uri, publisher->from_uri, size);
+       ao2_ref(publisher, -1);
+
+       return uri;
+}
+
 const char *ast_sip_publish_client_get_to_uri(struct ast_sip_outbound_publish_client *client)
 {
        struct ast_sip_outbound_publish *publish = client->publish;
@@ -532,6 +579,22 @@ const char *ast_sip_publish_client_get_to_uri(struct ast_sip_outbound_publish_cl
        return S_OR(publish->to_uri, S_OR(publish->server_uri, ""));
 }
 
+const char *ast_sip_publish_client_get_user_to_uri(struct ast_sip_outbound_publish_client *client, const char *user,
+       char *uri, size_t size)
+{
+       struct sip_outbound_publisher *publisher;
+
+       publisher = sip_outbound_publish_client_get_publisher(client, user);
+       if (!publisher) {
+               return NULL;
+       }
+
+       ast_copy_string(uri, publisher->to_uri, size);
+       ao2_ref(publisher, -1);
+
+       return uri;
+}
+
 int ast_sip_register_event_publisher_handler(struct ast_sip_event_publisher_handler *handler)
 {
        struct ast_sip_event_publisher_handler *existing;
@@ -828,6 +891,11 @@ static int sip_outbound_publisher_set_uris(
                return -1;
        }
 
+       publisher->to_uri = ast_strdup(to_uri->ptr);
+       if (!publisher->to_uri) {
+               return -1;
+       }
+
        if (ast_strlen_zero(publish->from_uri)) {
                from_uri->ptr = server_uri->ptr;
                from_uri->slen = server_uri->slen;
@@ -837,6 +905,11 @@ static int sip_outbound_publisher_set_uris(
                return -1;
        }
 
+       publisher->from_uri = ast_strdup(from_uri->ptr);
+       if (!publisher->from_uri) {
+               return -1;
+       }
+
        return 0;
 }
 
@@ -936,6 +1009,9 @@ static void sip_outbound_publisher_destroy(void *obj)
 
        ao2_cleanup(publisher->owner);
 
+       ast_free(publisher->from_uri);
+       ast_free(publisher->to_uri);
+
        /* if unloading the module and all objects have been unpublished
           send the signal to finish unloading */
        if (unloading.is_unloading) {
@@ -1018,21 +1094,10 @@ int ast_sip_publish_client_user_send(struct ast_sip_outbound_publish_client *cli
        struct sip_outbound_publisher *publisher;
        int res;
 
-       /*
-        * Lock before searching since there could be a race between searching and adding.
-        * Just use the load_lock since we might need to lock it anyway (if adding) and
-        * also it simplifies the code (otherwise we'd have to lock the publishers, no-
-        * lock the search and pass a flag to 'add publisher to no-lock the potential link).
-        */
-       ast_rwlock_wrlock(&load_lock);
-       publisher = ao2_find(client->publishers, user, OBJ_SEARCH_KEY);
+       publisher = sip_outbound_publish_client_get_publisher(client, user);
        if (!publisher) {
-               if (!(publisher = sip_outbound_publish_client_add_publisher(client, user))) {
-                       ast_rwlock_unlock(&load_lock);
-                       return -1;
-               }
+               return -1;
        }
-       ast_rwlock_unlock(&load_lock);
 
        publisher_client_send(publisher, (void *)body, &res, 0);
        ao2_ref(publisher, -1);