[Asterisk-code-review] codec_negotiation: Implement SDP answer preferences (asterisk[master])

George Joseph asteriskteam at digium.com
Mon Apr 27 13:41:03 CDT 2020


George Joseph has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/14328 )


Change subject: codec_negotiation: Implement SDP answer preferences
......................................................................

codec_negotiation: Implement SDP answer preferences

* Added outgoing_call_answer_pref and incoming_call_answer_pref
  to structures, endpoint config, and sample pjsip.conf.

* Added a new function ast_sip_session_create_joint_cap_from_stream
  which takes a stream from pending topology and the capabilities
  of the peer and creates the joint caps.

* Replaced the call to ast_format_get_compatible from
  res_pjsip_sdp_rtp:set_caps with the new function just created.

* Slightly refactored the ast_sip_call_codec_str_to_pref function
  in res_pjsip.

* Added a new function ast_sip_session_get_name which can be used
  to get a meaningful name for error/warning/debug messages.
  If a session->channel is not NULL, it returns the channel
  name.  Then it checks session->endpoint and if not NULL,
  returns the endpoint's sorcery id.  If all else fails, it
  returns "unknown".

* Added a lot of debug messages to res_pjsip_session and
  res_pjsip_sdp_rtp.

There is still more to come.

ASTERISK-28856

Change-Id: Iad188ae997bdcb5c28e2eb12c6bb2b732538ad45
---
M configs/samples/pjsip.conf.sample
M include/asterisk/res_pjsip.h
M include/asterisk/res_pjsip_session.h
M include/asterisk/res_pjsip_session_caps.h
M res/res_pjsip.c
M res/res_pjsip/pjsip_configuration.c
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_session.c
M res/res_pjsip_session/pjsip_session_caps.c
9 files changed, 262 insertions(+), 33 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/28/14328/1

diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index 93fb701..a96bec0 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -839,6 +839,48 @@
                            ; at the end of the joint list.
                            ; remote_first - Include only the first codec in
                            ; the remote list.
+;outgoing_call_answer_pref=; Based on this setting, a joint list of
+                           ; preferred codecs between those received in an
+                           ; SDP answer (remote), and those originally
+                           ; sent in the SDP offer (local) is created and is
+                           ; passed to the Asterisk core.
+                           ;
+                           ; local - Include all codecs in the local list that
+                           ; are also in the remote list preserving the local
+                           ; order. (default).
+                           ; local_first - Include only the first codec in the
+                           ; local list that is also in the remote list.
+                           ; remote - Include all codecs in the remote list that
+                           ; are also in the local list preserving remote list
+                           ; order.
+                           ; remote_first - Include only the first codec in
+                           ; the remote list that is also in the local list.
+;incoming_call_answer_pref= ; Based on this setting, a joint list of
+                           ; preferred codecs between those received from the
+                           ; Asterisk core (local), and those specified in
+                           ; the original list sent to the core when the SDP
+                           ; offer was received (local) is
+                           ; created and is used to create the SDP
+                           ; answer.
+                           ;
+                           ; local - Include all codecs in the local list that
+                           ; are also in the remote list preserving the local
+                           ; order.
+                           ; local_merge - Include all codecs in BOTH lists
+                           ; preserving the local list order.  Codes in the
+                           ; remote list not in the local list will be placed
+                           ; at the end of the joint list.
+                           ; local_first - Include only the first codec in the
+                           ; local list.
+                           ; remote - Include all codecs in the remote list that
+                           ; are also in the local list preserving remote list
+                           ; order. (default)
+                           ; remote_merge - Include all codecs in BOTH lists
+                           ; preserving the remote list order.  Codes in the
+                           ; local list not in the remote list will be placed
+                           ; at the end of the joint list.
+                           ; remote_first - Include only the first codec in
+                           ; the remote list.
 ;preferred_codec_only=no   ; Respond to a SIP invite with the single most
                            ; preferred codec rather than advertising all joint
                            ; codec capabilities. This limits the other side's
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index fd80581..6def942 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -790,6 +790,10 @@
 	struct ast_flags incoming_call_offer_pref;
 	/*! Codec preference for an outgoing offer */
 	struct ast_flags outgoing_call_offer_pref;
+	/*! Codec preference for an outgoing answer */
+	struct ast_flags outgoing_call_answer_pref;
+	/*! Codec preference for an incoming answer */
+	struct ast_flags incoming_call_answer_pref;
 };
 
 /*!
@@ -3260,12 +3264,12 @@
  *
  * \param pref A pointer to an ast_flags structure to receive the preference flags
  * \param pref_str The call codec preference setting string
- * \param is_outgoing Is for outgoing calls?
+ * \param allow_merge Allow the "local_merge" and "remote_merge" options?
  *
  * \retval 0 The string was parsed successfully
  * \retval -1 The string option was invalid
  */
-int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int is_outgoing);
+int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int allow_merge);
 
 /*!
  * \brief Transport shutdown monitor callback.
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index fd49a7b..5b1aa94 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -926,4 +926,13 @@
  */
 struct ast_sip_session_media *ast_sip_session_media_get_transport(struct ast_sip_session *session, struct ast_sip_session_media *session_media);
 
+/*!
+ * \brief Get the channel or endpoint name associated with the session
+ * \since 18.0.0
+ *
+ * @param session
+ * @retval Channel name or endpoint name or "unknown"
+ */
+const char *ast_sip_session_get_name(struct ast_sip_session *session);
+
 #endif /* _RES_PJSIP_SESSION_H */
diff --git a/include/asterisk/res_pjsip_session_caps.h b/include/asterisk/res_pjsip_session_caps.h
index 0d7020f..a7ec35b 100644
--- a/include/asterisk/res_pjsip_session_caps.h
+++ b/include/asterisk/res_pjsip_session_caps.h
@@ -38,7 +38,7 @@
  * \note Returned object's reference must be released at some point,
  */
 struct ast_format_cap *ast_sip_create_joint_call_cap(const struct ast_format_cap *remote,
-	struct ast_format_cap *local, enum ast_media_type media_type,
+	const struct ast_format_cap *local, enum ast_media_type media_type,
 	struct ast_flags codec_pref);
 
 /*!
@@ -79,4 +79,24 @@
 struct ast_format_cap *ast_sip_session_create_joint_call_cap(const struct ast_sip_session *session,
 	enum ast_media_type media_type, const struct ast_format_cap *remote);
 
+/*!
+ * \brief Create joint answer capabilities
+ * \since 18.0.0
+ *
+ * Creates a list of joint capabilities between the given stream
+ * and the remote capabilities.
+ *
+ * \param session The session
+ * \param remote Capabilities received in an SDP answer from the peer
+ * \param stream Stream from pending topology that was sent on the offer
+ * \param media_type The media type
+ *
+ * \retval A pointer to the joint capabilities (which may be empty).
+ *         NULL will be returned only if no memory was available to allocate the structure.
+ * \note Returned object's reference must be released at some point,
+ */
+struct ast_format_cap *ast_sip_session_create_joint_cap_from_stream(
+	const struct ast_sip_session *session, const struct ast_format_cap *remote,
+	const struct ast_stream *stream, enum ast_media_type media_type);
+
 #endif /* RES_PJSIP_SESSION_CAPS_H */
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 152d9e1..4acb6f3 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -952,11 +952,11 @@
 					</see-also>
 				</configOption>
 				<configOption name="incoming_call_offer_pref" default="local">
-					<synopsis>Preferences for selecting codecs for an incoming call.</synopsis>
+					<synopsis>Preferences for selecting codecs for an incoming call's SDP offer.</synopsis>
 					<description>
 						<para>Based on this setting, a joint list of preferred codecs between those
 						received in an incoming SDP offer (remote), and those specified in the
-						endpoint's "allow" parameter (local) es created and is passed to the Asterisk
+						endpoint's "allow" parameter (local) is created and is passed to the Asterisk
 						core. </para>
 						<note><para>This list will consist of only those codecs found in both lists.</para></note>
 						<enumlist>
@@ -978,7 +978,7 @@
 					</description>
 				</configOption>
 				<configOption name="outgoing_call_offer_pref" default="local">
-					<synopsis>Preferences for selecting codecs for an outgoing call.</synopsis>
+					<synopsis>Preferences for selecting codecs for an outgoing call's SDP offer.</synopsis>
 					<description>
 						<para>Based on this setting, a joint list of preferred codecs between
 						those received from the Asterisk core (remote), and those specified in
@@ -1012,6 +1012,65 @@
 						</enumlist>
 					</description>
 				</configOption>
+				<configOption name="outgoing_call_answer_pref" default="local">
+					<synopsis>Preferences for selecting codecs for an outgoing call's SDP answer.</synopsis>
+					<description>
+						<para>Based on this setting, a joint list of preferred codecs between those
+						received in an incoming SDP answer (remote), and those originally send in
+						the SDP offer (local) is created and passed to the Asterisk core. </para>
+						<note><para>This list will consist of only those codecs found in both lists.</para></note>
+						<enumlist>
+							<enum name="local"><para>
+								Include all codecs in the local list that are also in the remote list
+								preserving the local order.  (default).
+							</para></enum>
+							<enum name="local_first"><para>
+								Include only the first codec in the local list that is also in the remote list.
+							</para></enum>
+							<enum name="remote"><para>
+								Include all codecs in the remote list that are also in the local list
+								preserving the remote order.
+							</para></enum>
+							<enum name="remote_first"><para>
+								Include only the first codec in the remote list that is also in the local list.
+							</para></enum>
+						</enumlist>
+					</description>
+				</configOption>
+				<configOption name="incoming_call_answer_pref" default="remote">
+					<synopsis>Preferences for selecting codecs for an incoming call's SDP answer.</synopsis>
+					<description>
+						<para>Based on this setting, a joint list of preferred codecs between
+						those received from the Asterisk core (local), and those specified in
+						the original list send to the core when the SDP offer was received.</para>
+						<enumlist>
+							<enum name="local"><para>
+								Include all codecs in the local list that are also in the remote list
+								preserving the local order.
+							</para></enum>
+							<enum name="local_merge"><para>
+								Include all codecs in BOTH lists preserving the local order.
+								Remote codecs not in the local list will be placed at the end
+								of the joint list.
+							</para></enum>
+							<enum name="local_first"><para>
+								Include only the first codec in the local list.
+							</para></enum>
+							<enum name="remote"><para>
+								Include all codecs in the remote list that are also in the local list
+								preserving the remote order. (default)
+							</para></enum>
+							<enum name="remote_merge"><para>
+								Include all codecs in BOTH lists preserving the remote order.
+								Local codecs not in the remote list will be placed at the end
+								of the joint list.
+							</para></enum>
+							<enum name="remote_first"><para>
+								Include only the first codec in the remote list.
+							</para></enum>
+						</enumlist>
+					</description>
+				</configOption>
 				<configOption name="rtp_keepalive">
 					<synopsis>Number of seconds between RTP comfort noise keepalive packets.</synopsis>
 					<description><para>
@@ -5133,19 +5192,19 @@
 	return value;
 }
 
-int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int is_outgoing)
+int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int allow_merge)
 {
 	pref->flags = 0;
 
 	if (strcmp(pref_str, "local") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_LOCAL | AST_SIP_CALL_CODEC_PREF_INTERSECT | AST_SIP_CALL_CODEC_PREF_ALL);
-	} else if (is_outgoing && strcmp(pref_str, "local_merge") == 0) {
+	} else if (allow_merge && strcmp(pref_str, "local_merge") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_LOCAL | AST_SIP_CALL_CODEC_PREF_UNION | AST_SIP_CALL_CODEC_PREF_ALL);
 	} else if (strcmp(pref_str, "local_first") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_LOCAL | AST_SIP_CALL_CODEC_PREF_INTERSECT | AST_SIP_CALL_CODEC_PREF_FIRST);
 	} else if (strcmp(pref_str, "remote") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_REMOTE | AST_SIP_CALL_CODEC_PREF_INTERSECT | AST_SIP_CALL_CODEC_PREF_ALL);
-	} else if (is_outgoing && strcmp(pref_str, "remote_merge") == 0) {
+	} else if (allow_merge && strcmp(pref_str, "remote_merge") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_REMOTE | AST_SIP_CALL_CODEC_PREF_UNION | AST_SIP_CALL_CODEC_PREF_ALL);
 	} else if (strcmp(pref_str, "remote_first") == 0) {
 		ast_set_flag(pref, AST_SIP_CALL_CODEC_PREF_REMOTE | AST_SIP_CALL_CODEC_PREF_UNION | AST_SIP_CALL_CODEC_PREF_FIRST);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index f95ee9e..e588a48 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1128,6 +1128,7 @@
 	struct ast_flags pref = { 0, };
 	int outgoing = strcmp(var->name, "outgoing_call_offer_pref") == 0;
 
+	/* The "local_merge" and "remote_merge" options are only allowed if outgoing */
 	int res = ast_sip_call_codec_str_to_pref(&pref, var->value, outgoing);
 	if (res != 0) {
 		return -1;
@@ -1142,6 +1143,28 @@
 	return 0;
 }
 
+static int call_answer_pref_handler(const struct aco_option *opt,
+	struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+	struct ast_flags pref = { 0, };
+	int incoming = strcmp(var->name, "incoming_call_answer_pref") == 0;
+
+	/* The "local_merge" and "remote_merge" options are only allowed if incoming */
+	int res = ast_sip_call_codec_str_to_pref(&pref, var->value, incoming);
+	if (res != 0) {
+		return -1;
+	}
+
+	if (incoming) {
+		endpoint->media.incoming_call_answer_pref = pref;
+	} else {
+		endpoint->media.outgoing_call_answer_pref = pref;
+	}
+
+	return 0;
+}
+
 static int incoming_call_offer_pref_to_str(const void *obj, const intptr_t *args, char **buf)
 {
 	const struct ast_sip_endpoint *endpoint = obj;
@@ -1166,6 +1189,30 @@
 	return 0;
 }
 
+static int outgoing_call_answer_pref_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+	const struct ast_sip_endpoint *endpoint = obj;
+
+	*buf = ast_strdup(ast_sip_call_codec_pref_to_str(endpoint->media.outgoing_call_answer_pref));
+	if (!(*buf)) {
+		return -1;
+	}
+
+	return 0;
+}
+
+static int incoming_call_answer_pref_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+	const struct ast_sip_endpoint *endpoint = obj;
+
+	*buf = ast_strdup(ast_sip_call_codec_pref_to_str(endpoint->media.incoming_call_answer_pref));
+	if (!(*buf)) {
+		return -1;
+	}
+
+	return 0;
+}
+
 static void *sip_nat_hook_alloc(const char *name)
 {
 	return ast_sorcery_generic_alloc(sizeof(struct ast_sip_nat_hook), NULL);
@@ -2025,6 +2072,10 @@
 		call_offer_pref_handler, incoming_call_offer_pref_to_str, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outgoing_call_offer_pref", "remote",
 		call_offer_pref_handler, outgoing_call_offer_pref_to_str, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outgoing_call_answer_pref", "local",
+		call_answer_pref_handler, outgoing_call_answer_pref_to_str, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "incoming_call_answer_pref", "remote",
+		call_answer_pref_handler, incoming_call_answer_pref_to_str, NULL, 0, 0);
 
 	if (ast_sip_initialize_sorcery_transport()) {
 		ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 1bcb661..16c4bae 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -448,6 +448,7 @@
 	get_codecs(session, stream, &codecs, session_media);
 	ast_rtp_codecs_payload_formats(&codecs, remote, &fmts);
 
+	ast_debug(1, "%s: Creating incoming call offer caps.\n", ast_sip_session_get_name(session));
 	incoming_call_offer_cap = ast_sip_session_create_joint_call_cap(
 		session, session_media->type, remote);
 
@@ -490,8 +491,7 @@
 	int dsp_features = 0;
 
 	if (!(caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
-	    !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT)) ||
-	    !(joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
+	    !(peer = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n",
 			ast_codec_media_type2str(session_media->type));
 		return -1;
@@ -499,8 +499,10 @@
 
 	/* get the endpoint capabilities */
 	if (direct_media_enabled) {
+		ast_debug(1, "%s: Direct media enabled\n", ast_sip_session_get_name(session));
 		ast_format_cap_get_compatible(session->endpoint->media.codecs, session->direct_media_cap, caps);
 	} else {
+		ast_debug(1, "%s: Direct media not enabled\n", ast_sip_session_get_name(session));
 		ast_format_cap_append_from_cap(caps, session->endpoint->media.codecs, media_type);
 	}
 
@@ -508,8 +510,9 @@
 	get_codecs(session, stream, &codecs,  session_media);
 	ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
 
-	/* get the joint capabilities between peer and endpoint */
-	ast_format_cap_get_compatible(caps, peer, joint);
+	ast_debug(1, "%s: Creating joint caps\n", ast_sip_session_get_name(session));
+	joint = ast_sip_session_create_joint_cap_from_stream(session, peer, asterisk_stream, session_media->type);
+
 	if (!ast_format_cap_count(joint)) {
 		struct ast_str *usbuf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
 		struct ast_str *thembuf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
@@ -541,11 +544,7 @@
 			AST_MEDIA_TYPE_UNKNOWN);
 		ast_format_cap_remove_by_type(caps, media_type);
 
-		if (session->endpoint->preferred_codec_only){
-			struct ast_format *preferred_fmt = ast_format_cap_get_format(joint, 0);
-			ast_format_cap_append(caps, preferred_fmt, 0);
-			ao2_ref(preferred_fmt, -1);
-		} else if (!session->endpoint->asymmetric_rtp_codec) {
+		if (!session->endpoint->asymmetric_rtp_codec) {
 			struct ast_format *best;
 			/*
 			 * If we don't allow the sending codec to be changed on our side
@@ -2078,6 +2077,7 @@
 		enable_rtcp(session, session_media, remote_stream);
 	}
 
+	ast_debug(1, "%s: Setting call caps.\n", ast_sip_session_get_name(session));
 	if (set_caps(session, session_media, session_media_transport, remote_stream, 0, asterisk_stream)) {
 		return -1;
 	}
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 67899e4..1d9e3fd 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -186,6 +186,17 @@
 	ao2_callback_data(sdp_handlers, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, remove_handler, (void *)stream_type, handler);
 }
 
+const char *ast_sip_session_get_name(struct ast_sip_session *session)
+{
+	if (session->channel) {
+		return ast_channel_name(session->channel);
+	} else if (session->endpoint) {
+		return ast_sorcery_object_get_id(session->endpoint);
+	} else {
+		return "unknown";
+	}
+}
+
 static int media_stats_local_ssrc_cmp(
 		const struct ast_rtp_instance_stats *vec_elem, const struct ast_rtp_instance_stats *srch)
 {
@@ -789,7 +800,8 @@
 
 		/* If this stream is already declined mark it as such, or mark it as such if we've reached the limit */
 		if (!remote_stream->desc.port || is_stream_limitation_reached(type, session->endpoint, type_streams)) {
-			ast_debug(1, "Declining incoming SDP media stream '%s' at position '%d'\n",
+			ast_debug(1, "%s: Declining incoming SDP media stream '%s' at position '%d'\n",
+				ast_sip_session_get_name(session),
 				ast_codec_media_type2str(type), i);
 			remove_stream_from_bundle(session_media, stream);
 			continue;
@@ -800,7 +812,8 @@
 
 		if (session_media->handler) {
 			handler = session_media->handler;
-			ast_debug(1, "Negotiating incoming SDP media stream '%s' using %s SDP handler\n",
+			ast_debug(1, "%s: Negotiating incoming SDP media stream '%s' using %s SDP handler\n",
+				ast_sip_session_get_name(session),
 				ast_codec_media_type2str(session_media->type),
 				session_media->handler->id);
 			res = handler->negotiate_incoming_sdp_stream(session, session_media, sdp, i, stream);
@@ -808,12 +821,14 @@
 				/* Catastrophic failure. Abort! */
 				return -1;
 			} else if (res == 0) {
-				ast_debug(1, "Declining incoming SDP media stream '%s' at position '%d'\n",
+				ast_debug(1, "%s: Declining incoming SDP media stream '%s' at position '%d'\n",
+					ast_sip_session_get_name(session),
 					ast_codec_media_type2str(type), i);
 				remove_stream_from_bundle(session_media, stream);
 				continue;
 			} else if (res > 0) {
-				ast_debug(1, "Media stream '%s' handled by %s\n",
+				ast_debug(1, "%s: Media stream '%s' handled by %s\n",
+					ast_sip_session_get_name(session),
 					ast_codec_media_type2str(session_media->type),
 					session_media->handler->id);
 				/* Handled by this handler. Move to the next stream */
@@ -825,14 +840,17 @@
 
 		handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
 		if (!handler_list) {
-			ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);
+			ast_debug(1, "%s: No registered SDP handlers for media type '%s'\n",
+				ast_sip_session_get_name(session),
+				media);
 			continue;
 		}
 		AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
 			if (handler == session_media->handler) {
 				continue;
 			}
-			ast_debug(1, "Negotiating incoming SDP media stream '%s' using %s SDP handler\n",
+			ast_debug(1, "%s: Negotiating incoming SDP media stream '%s' using %s SDP handler\n",
+				ast_sip_session_get_name(session),
 				ast_codec_media_type2str(session_media->type),
 				handler->id);
 			res = handler->negotiate_incoming_sdp_stream(session, session_media, sdp, i, stream);
@@ -840,12 +858,14 @@
 				/* Catastrophic failure. Abort! */
 				return -1;
 			} else if (res == 0) {
-				ast_debug(1, "Declining incoming SDP media stream '%s' at position '%d'\n",
+				ast_debug(1, "%s: Declining incoming SDP media stream '%s' at position '%d'\n",
+					ast_sip_session_get_name(session),
 					ast_codec_media_type2str(type), i);
 				remove_stream_from_bundle(session_media, stream);
 				continue;
 			} else if (res > 0) {
-				ast_debug(1, "Media stream '%s' handled by %s\n",
+				ast_debug(1, "%s: Media stream '%s' handled by %s\n",
+					ast_sip_session_get_name(session),
 					ast_codec_media_type2str(session_media->type),
 					handler->id);
 				/* Handled by this handler. Move to the next stream */
@@ -902,12 +922,14 @@
 
 	handler = session_media->handler;
 	if (handler) {
-		ast_debug(1, "Applying negotiated SDP media stream '%s' using %s SDP handler\n",
+		ast_debug(1, "%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
+			ast_sip_session_get_name(session),
 			ast_codec_media_type2str(session_media->type),
 			handler->id);
 		res = handler->apply_negotiated_sdp_stream(session, session_media, local, remote, index, asterisk_stream);
 		if (res >= 0) {
-			ast_debug(1, "Applied negotiated SDP media stream '%s' using %s SDP handler\n",
+			ast_debug(1, "%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
+				ast_sip_session_get_name(session),
 				ast_codec_media_type2str(session_media->type),
 				handler->id);
 			return 0;
@@ -917,14 +939,17 @@
 
 	handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
 	if (!handler_list) {
-		ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);
+		ast_debug(1, "%s: No registered SDP handlers for media type '%s'\n",
+			ast_sip_session_get_name(session),
+			media);
 		return -1;
 	}
 	AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
 		if (handler == session_media->handler) {
 			continue;
 		}
-		ast_debug(1, "Applying negotiated SDP media stream '%s' using %s SDP handler\n",
+		ast_debug(1, "%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
+			ast_sip_session_get_name(session),
 			ast_codec_media_type2str(session_media->type),
 			handler->id);
 		res = handler->apply_negotiated_sdp_stream(session, session_media, local, remote, index, asterisk_stream);
@@ -933,7 +958,8 @@
 			return -1;
 		}
 		if (res > 0) {
-			ast_debug(1, "Applied negotiated SDP media stream '%s' using %s SDP handler\n",
+			ast_debug(1, "%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
+				ast_sip_session_get_name(session),
 				ast_codec_media_type2str(session_media->type),
 				handler->id);
 			/* Handled by this handler. Move to the next stream */
@@ -943,7 +969,8 @@
 	}
 
 	if (session_media->handler && session_media->handler->stream_stop) {
-		ast_debug(1, "Stopping SDP media stream '%s' as it is not currently negotiated\n",
+		ast_debug(1, "%s: Stopping SDP media stream '%s' as it is not currently negotiated\n",
+			ast_sip_session_get_name(session),
 			ast_codec_media_type2str(session_media->type));
 		session_media->handler->stream_stop(session_media);
 	}
@@ -2721,6 +2748,7 @@
 				continue;
 			}
 
+			ast_debug(1, "%s: Creating outgoing call offer caps.\n", ast_sip_session_get_name(session));
 			clone_stream = ast_sip_session_create_joint_call_stream(session, req_stream);
 			if (!clone_stream || ast_stream_get_format_count(clone_stream) == 0) {
 				ast_stream_free(clone_stream);
diff --git a/res/res_pjsip_session/pjsip_session_caps.c b/res/res_pjsip_session/pjsip_session_caps.c
index ca7ef44..dcb7e4a 100644
--- a/res/res_pjsip_session/pjsip_session_caps.c
+++ b/res/res_pjsip_session/pjsip_session_caps.c
@@ -63,7 +63,7 @@
 }
 
 struct ast_format_cap *ast_sip_create_joint_call_cap(const struct ast_format_cap *remote,
-	struct ast_format_cap *local, enum ast_media_type media_type,
+	const struct ast_format_cap *local, enum ast_media_type media_type,
 	struct ast_flags codec_pref)
 {
 	struct ast_format_cap *joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
@@ -153,3 +153,19 @@
 
 	return joint;
 }
+
+struct ast_format_cap *ast_sip_session_create_joint_cap_from_stream(
+	const struct ast_sip_session *session, const struct ast_format_cap *remote,
+	const struct ast_stream *stream, enum ast_media_type media_type)
+{
+	const struct ast_format_cap *local = ast_stream_get_formats(stream);
+	struct ast_format_cap *joint = ast_sip_create_joint_call_cap(remote,
+		local, media_type,
+		session->call_direction == AST_SIP_SESSION_OUTGOING_CALL
+				? session->endpoint->media.outgoing_call_answer_pref
+				: session->endpoint->media.incoming_call_answer_pref);
+
+	log_caps(LOG_DEBUG, session, media_type, local, remote, joint);
+
+	return joint;
+}

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

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Iad188ae997bdcb5c28e2eb12c6bb2b732538ad45
Gerrit-Change-Number: 14328
Gerrit-PatchSet: 1
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20200427/082a5101/attachment-0001.html>


More information about the asterisk-code-review mailing list