[Asterisk-code-review] res pjsip session Added rtcp stats result vector into the se... (asterisk[master])

sungtae kim asteriskteam at digium.com
Tue Jan 22 06:31:37 CST 2019


sungtae kim has uploaded this change for review. ( https://gerrit.asterisk.org/10899


Change subject: res_pjsip_session Added rtcp stats result vector into the session
......................................................................

res_pjsip_session Added rtcp stats result vector into the session

Currently, the Asterisk's pjsip_session module does not keeping the
rtcp's stats info after it was removed. But by adding the results
vector and keeping it until session is destroying, it can give more
useful information for other modules.

Change-Id: Ib25c2d3fc4da084aecfde2a82c1b1d733bd64fa5
---
M channels/chan_pjsip.c
M channels/pjsip/dialplan_functions.c
M include/asterisk/res_pjsip_session.h
M res/res_pjsip_session.c
M res/res_pjsip_t38.c
5 files changed, 94 insertions(+), 9 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/99/10899/1

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

-- 
To view, visit https://gerrit.asterisk.org/10899
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib25c2d3fc4da084aecfde2a82c1b1d733bd64fa5
Gerrit-Change-Number: 10899
Gerrit-PatchSet: 1
Gerrit-Owner: sungtae kim <pchero21 at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190122/cd926ec3/attachment-0001.html>


More information about the asterisk-code-review mailing list