<p>sungtae kim has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10899">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_session Added rtcp stats result vector into the session<br><br>Currently, the Asterisk's pjsip_session module does not keeping the<br>rtcp's stats info after it was removed. But by adding the results<br>vector and keeping it until session is destroying, it can give more<br>useful information for other modules.<br><br>Change-Id: Ib25c2d3fc4da084aecfde2a82c1b1d733bd64fa5<br>---<br>M channels/chan_pjsip.c<br>M channels/pjsip/dialplan_functions.c<br>M include/asterisk/res_pjsip_session.h<br>M res/res_pjsip_session.c<br>M res/res_pjsip_t38.c<br>5 files changed, 94 insertions(+), 9 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/99/10899/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c</span><br><span>index e44f328..1e9170c 100644</span><br><span>--- a/channels/chan_pjsip.c</span><br><span>+++ b/channels/chan_pjsip.c</span><br><span>@@ -1494,6 +1494,7 @@</span><br><span> {</span><br><span>  ao2_cleanup(refresh_data->session);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_session_media_stats_save(refresh_data->media_state);</span><br><span>      ast_sip_session_media_state_free(refresh_data->media_state);</span><br><span>      ast_free(refresh_data);</span><br><span> }</span><br><span>@@ -1509,7 +1510,7 @@</span><br><span>         }</span><br><span> </span><br><span>        refresh_data->session = ao2_bump(session);</span><br><span style="color: hsl(0, 100%, 40%);">-   refresh_data->media_state = ast_sip_session_media_state_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+   refresh_data->media_state = ast_sip_session_media_state_alloc(session);</span><br><span>   if (!refresh_data->media_state) {</span><br><span>                 topology_change_refresh_data_free(refresh_data);</span><br><span>             return NULL;</span><br><span>@@ -1534,6 +1535,7 @@</span><br><span>                 }</span><br><span>    } else if (300 <= rdata->msg_info.msg->line.status.code) {</span><br><span>          /* The topology change failed, so drop the current pending media state */</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>           ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>  }</span><br><span> </span><br><span>diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c</span><br><span>index 70507bb..12dc501 100644</span><br><span>--- a/channels/pjsip/dialplan_functions.c</span><br><span>+++ b/channels/pjsip/dialplan_functions.c</span><br><span>@@ -1051,6 +1051,7 @@</span><br><span> {</span><br><span>  struct session_refresh_state *state = obj;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sip_session_media_stats_save(state->media_state);</span><br><span>     ast_sip_session_media_state_free(state->media_state);</span><br><span>     ast_free(obj);</span><br><span> }</span><br><span>@@ -1079,7 +1080,7 @@</span><br><span>  }</span><br><span> </span><br><span>        state = datastore->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     state->media_state = ast_sip_session_media_state_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+  state->media_state = ast_sip_session_media_state_alloc(session);</span><br><span>  if (!state->media_state) {</span><br><span>                ast_sip_session_remove_datastore(session, "pjsip_session_refresh");</span><br><span>                return NULL;</span><br><span>diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h</span><br><span>index 34f4783..32b63e8 100644</span><br><span>--- a/include/asterisk/res_pjsip_session.h</span><br><span>+++ b/include/asterisk/res_pjsip_session.h</span><br><span>@@ -141,6 +141,8 @@</span><br><span>      struct ast_sip_session_media *default_session[AST_MEDIA_TYPE_END];</span><br><span>   /*! \brief The media stream topology */</span><br><span>      struct ast_stream_topology *topology;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Related sip session */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ast_sip_session *sip_session;</span><br><span> };</span><br><span> </span><br><span> /*!</span><br><span>@@ -215,6 +217,8 @@</span><br><span>  enum ast_sip_dtmf_mode dtmf;</span><br><span>         /*! Initial incoming INVITE Request-URI.  NULL otherwise. */</span><br><span>         pjsip_uri *request_uri;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Media stats result saving */</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats;</span><br><span> };</span><br><span> </span><br><span> typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);</span><br><span>@@ -800,10 +804,12 @@</span><br><span>  * \brief Allocate a session media state structure</span><br><span>  * \since 15.0.0</span><br><span>  *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sip_session The session to related.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span>  * \retval non-NULL success</span><br><span>  * \retval NULL failure</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(void);</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(struct ast_sip_session *sip_session);</span><br><span> </span><br><span> /*!</span><br><span>  * \brief Allocate an ast_session_media and add it to the media state's vector.</span><br><span>@@ -831,6 +837,13 @@</span><br><span>     struct ast_sip_session_media_state *media_state, enum ast_media_type type, int position);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Save a media stats.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param media_state The media state to save</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_media_stats_save(struct ast_sip_session_media_state *media_state);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Reset a media state to a clean state</span><br><span>  * \since 15.0.0</span><br><span>  *</span><br><span>diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c</span><br><span>index 99e0ca4..73ed0e2 100644</span><br><span>--- a/res/res_pjsip_session.c</span><br><span>+++ b/res/res_pjsip_session.c</span><br><span>@@ -48,6 +48,7 @@</span><br><span> #include "asterisk/pickup.h"</span><br><span> #include "asterisk/test.h"</span><br><span> #include "asterisk/stream.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/vector.h"</span><br><span> </span><br><span> #define SDP_HANDLER_BUCKETS 11</span><br><span> </span><br><span>@@ -177,7 +178,7 @@</span><br><span> }</span><br><span> </span><br><span> static struct ast_sip_session_media_state *internal_sip_session_media_state_alloc(</span><br><span style="color: hsl(0, 100%, 40%);">- size_t sessions, size_t read_callbacks)</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sip_session *sip_session, size_t sessions, size_t read_callbacks)</span><br><span> {</span><br><span>    struct ast_sip_session_media_state *media_state;</span><br><span> </span><br><span>@@ -186,6 +187,8 @@</span><br><span>           return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ media_state->sip_session = sip_session;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         if (AST_VECTOR_INIT(&media_state->sessions, sessions) < 0) {</span><br><span>               ast_free(media_state);</span><br><span>               return NULL;</span><br><span>@@ -200,12 +203,43 @@</span><br><span>         return media_state;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(void)</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(struct ast_sip_session *session)</span><br><span> {</span><br><span>         return internal_sip_session_media_state_alloc(</span><br><span style="color: hsl(0, 100%, 40%);">-          DEFAULT_NUM_SESSION_MEDIA, DEFAULT_NUM_SESSION_MEDIA);</span><br><span style="color: hsl(120, 100%, 40%);">+                session, DEFAULT_NUM_SESSION_MEDIA, DEFAULT_NUM_SESSION_MEDIA);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sip_session_media_stats_save(struct ast_sip_session_media_state *media_state)</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%);">+        int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!media_state || !media_state->sip_session) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</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%);">+   for (i = 0; i < AST_VECTOR_SIZE(&media_state->sessions); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             struct ast_sip_session_media *media = AST_VECTOR_GET(&media_state->sessions, i);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!media || !media->rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</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%);">+           struct ast_rtp_instance *rtp = ao2_bump(media->rtp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             struct ast_rtp_instance_stats *stats = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));</span><br><span style="color: hsl(120, 100%, 40%);">+          ret = ast_rtp_instance_get_stats(rtp, stats, AST_RTP_INSTANCE_STAT_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+              ao2_cleanup(rtp);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ret) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    ast_free(stats);</span><br><span style="color: hsl(120, 100%, 40%);">+                      continue;</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%);">+           AST_VECTOR_APPEND(&media_state->sip_session->media_stats, stats);</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)</span><br><span> {</span><br><span>   int index;</span><br><span>@@ -235,6 +269,7 @@</span><br><span>     }</span><br><span> </span><br><span>        cloned = internal_sip_session_media_state_alloc(</span><br><span style="color: hsl(120, 100%, 40%);">+              media_state->sip_session,</span><br><span>                 AST_VECTOR_SIZE(&media_state->sessions),</span><br><span>              AST_VECTOR_SIZE(&media_state->read_callbacks));</span><br><span>       if (!cloned) {</span><br><span>@@ -901,6 +936,7 @@</span><br><span>                                 return -1;</span><br><span>                   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                 ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                   ast_sip_session_media_state_free(session->pending_media_state);</span><br><span>                   session->pending_media_state = active_media_state_clone;</span><br><span>          } else {</span><br><span>@@ -1011,6 +1047,7 @@</span><br><span> </span><br><span>         /* Active and pending flip flop as needed */</span><br><span>         SWAP(session->active_media_state, session->pending_media_state);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>   ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span> </span><br><span>      ast_channel_unlock(session->channel);</span><br><span>@@ -1176,6 +1213,7 @@</span><br><span> </span><br><span> static void delayed_request_free(struct ast_sip_session_delayed_request *delay)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_sip_session_media_stats_save(delay->media_state);</span><br><span>     ast_sip_session_media_state_free(delay->media_state);</span><br><span>     ast_free(delay);</span><br><span> }</span><br><span>@@ -1373,6 +1411,7 @@</span><br><span>                        on_request, on_sdp_creation, on_response, generate_new_sdp, media_state);</span><br><span> </span><br><span>        if (!delay) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_sip_session_media_stats_save(media_state);</span><br><span>               ast_sip_session_media_state_free(media_state);</span><br><span>               return -1;</span><br><span>   }</span><br><span>@@ -1494,6 +1533,7 @@</span><br><span>    pjsip_tx_data *tdata;</span><br><span> </span><br><span>    if (media_state && (!media_state->topology || !generate_new_sdp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_sip_session_media_stats_save(media_state);</span><br><span>               ast_sip_session_media_state_free(media_state);</span><br><span>               return -1;</span><br><span>   }</span><br><span>@@ -1502,6 +1542,7 @@</span><br><span>            /* Don't try to do anything with a hung-up call */</span><br><span>               ast_debug(3, "Not sending reinvite to %s because of disconnected state...\n",</span><br><span>                              ast_sorcery_object_get_id(session->endpoint));</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sip_session_media_stats_save(media_state);</span><br><span>               ast_sip_session_media_state_free(media_state);</span><br><span>               return 0;</span><br><span>    }</span><br><span>@@ -1530,6 +1571,7 @@</span><br><span>                     */</span><br><span>                  ast_debug(3, "Not sending reinvite to %s because not in confirmed state...\n",</span><br><span>                                     ast_sorcery_object_get_id(session->endpoint));</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_sip_session_media_stats_save(media_state);</span><br><span>                       ast_sip_session_media_state_free(media_state);</span><br><span>                       return 0;</span><br><span>            }</span><br><span>@@ -1600,6 +1642,7 @@</span><br><span> </span><br><span>                                        joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);</span><br><span>                                       if (!joint_cap) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                             ast_sip_session_media_stats_save(media_state);</span><br><span>                                               ast_sip_session_media_state_free(media_state);</span><br><span>                                               return 0;</span><br><span>                                    }</span><br><span>@@ -1651,6 +1694,7 @@</span><br><span> </span><br><span>                                        cloned = ast_stream_clone(stream, NULL);</span><br><span>                                     if (!cloned) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                ast_sip_session_media_stats_save(media_state);</span><br><span>                                               ast_sip_session_media_state_free(media_state);</span><br><span>                                               return -1;</span><br><span>                                   }</span><br><span>@@ -1658,6 +1702,7 @@</span><br><span>                                    ast_stream_set_state(cloned, AST_STREAM_STATE_REMOVED);</span><br><span>                                      if (ast_stream_topology_append_stream(media_state->topology, cloned) < 0) {</span><br><span>                                            ast_stream_free(cloned);</span><br><span style="color: hsl(120, 100%, 40%);">+                                              ast_sip_session_media_stats_save(media_state);</span><br><span>                                               ast_sip_session_media_state_free(media_state);</span><br><span>                                               return -1;</span><br><span>                                   }</span><br><span>@@ -1665,11 +1710,13 @@</span><br><span> </span><br><span>                              /* If the resulting media state matches the existing active state don't bother doing a session refresh */</span><br><span>                                if (ast_stream_topology_equal(session->active_media_state->topology, media_state->topology)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                       ast_sip_session_media_stats_save(media_state);</span><br><span>                                       ast_sip_session_media_state_free(media_state);</span><br><span>                                       return 0;</span><br><span>                            }</span><br><span>                    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                 ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                   ast_sip_session_media_state_free(session->pending_media_state);</span><br><span>                   session->pending_media_state = media_state;</span><br><span>               }</span><br><span>@@ -1677,11 +1724,13 @@</span><br><span>          new_sdp = generate_session_refresh_sdp(session);</span><br><span>             if (!new_sdp) {</span><br><span>                      ast_log(LOG_ERROR, "Failed to generate session refresh SDP. Not sending session refresh\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                   ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>                  return -1;</span><br><span>           }</span><br><span>            if (on_sdp_creation) {</span><br><span>                       if (on_sdp_creation(session, new_sdp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                           ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>                          return -1;</span><br><span>                   }</span><br><span>@@ -1692,6 +1741,7 @@</span><br><span>            if (pjsip_inv_reinvite(inv_session, NULL, new_sdp, &tdata)) {</span><br><span>                    ast_log(LOG_WARNING, "Failed to create reinvite properly.\n");</span><br><span>                     if (generate_new_sdp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                           ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>                  }</span><br><span>                    return -1;</span><br><span>@@ -1699,6 +1749,7 @@</span><br><span>   } else if (pjsip_inv_update(inv_session, NULL, new_sdp, &tdata)) {</span><br><span>               ast_log(LOG_WARNING, "Failed to create UPDATE properly.\n");</span><br><span>               if (generate_new_sdp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                   ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>          }</span><br><span>            return -1;</span><br><span>@@ -1706,6 +1757,7 @@</span><br><span>   if (on_request_creation) {</span><br><span>           if (on_request_creation(session, tdata)) {</span><br><span>                   if (generate_new_sdp) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>                           ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>                  }</span><br><span>                    return -1;</span><br><span>@@ -2090,6 +2142,7 @@</span><br><span> </span><br><span> static void session_destructor(void *obj)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      int idx;</span><br><span>     struct ast_sip_session *session = obj;</span><br><span>       struct ast_sip_session_delayed_request *delay;</span><br><span>       const char *endpoint_name = session->endpoint ?</span><br><span>@@ -2113,6 +2166,14 @@</span><br><span>  ast_sip_session_remove_supplements(session);</span><br><span>         AST_LIST_HEAD_DESTROY(&session->supplements);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* remove all saved media stats */</span><br><span style="color: hsl(120, 100%, 40%);">+    for (idx = 0; idx < AST_VECTOR_SIZE(&session->media_stats); idx++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                struct ast_rtp_instance_stats* tmp_stats = AST_VECTOR_GET(&session->media_stats, idx);</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_free(tmp_stats);</span><br><span style="color: hsl(120, 100%, 40%);">+          AST_VECTOR_REMOVE(&session->media_stats, idx, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_VECTOR_FREE(&session->media_stats);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     ast_taskprocessor_unreference(session->serializer);</span><br><span>       ao2_cleanup(session->datastores);</span><br><span>         ast_sip_session_media_state_free(session->active_media_state);</span><br><span>@@ -2186,14 +2247,17 @@</span><br><span>  if (!session->datastores) {</span><br><span>               return NULL;</span><br><span>         }</span><br><span style="color: hsl(0, 100%, 40%);">-       session->active_media_state = ast_sip_session_media_state_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ session->active_media_state = ast_sip_session_media_state_alloc(session);</span><br><span>         if (!session->active_media_state) {</span><br><span>               return NULL;</span><br><span>         }</span><br><span style="color: hsl(0, 100%, 40%);">-       session->pending_media_state = ast_sip_session_media_state_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+        session->pending_media_state = ast_sip_session_media_state_alloc(session);</span><br><span>        if (!session->pending_media_state) {</span><br><span>              return NULL;</span><br><span>         }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (AST_VECTOR_INIT(&session->media_stats, 1) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> </span><br><span>        if (endpoint->dtmf == AST_SIP_DTMF_INBAND || endpoint->dtmf == AST_SIP_DTMF_AUTO) {</span><br><span>            dsp_features |= DSP_FEATURE_DIGIT_DETECT;</span><br><span>@@ -2638,6 +2702,7 @@</span><br><span>     * media sessions here.</span><br><span>       */</span><br><span>  SWAP(session->active_media_state, session->pending_media_state);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>   ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span> </span><br><span>      switch (session->inv_session->state) {</span><br><span>diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c</span><br><span>index 11804e2..41a014a 100644</span><br><span>--- a/res/res_pjsip_t38.c</span><br><span>+++ b/res/res_pjsip_t38.c</span><br><span>@@ -74,6 +74,7 @@</span><br><span> {</span><br><span>       struct t38_state *state = obj;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_session_media_stats_save(state->media_state);</span><br><span>     ast_sip_session_media_state_free(state->media_state);</span><br><span>     ast_free(obj);</span><br><span> }</span><br><span>@@ -339,8 +340,11 @@</span><br><span>           t38_change_state(session, session_media, state, T38_REJECTED);</span><br><span> </span><br><span>           /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_sip_session_media_stats_save(state->media_state);</span><br><span>             ast_sip_session_media_state_free(state->media_state);</span><br><span>             state->media_state = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_sip_session_media_stats_save(session->pending_media_state);</span><br><span>           ast_sip_session_media_state_reset(session->pending_media_state);</span><br><span>  }</span><br><span> </span><br><span>@@ -355,7 +359,7 @@</span><br><span>  struct ast_format_cap *caps;</span><br><span>         struct ast_sip_session_media *session_media;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        media_state = ast_sip_session_media_state_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+    media_state = ast_sip_session_media_state_alloc(session);</span><br><span>    if (!media_state) {</span><br><span>          return NULL;</span><br><span>         }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10899">change 10899</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/10899"/><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-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ib25c2d3fc4da084aecfde2a82c1b1d733bd64fa5 </div>
<div style="display:none"> Gerrit-Change-Number: 10899 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: sungtae kim <pchero21@gmail.com> </div>