core,app_dial,pjsip: Implement Advanced Codec Negotiation (ACN) - #285
maximilianfridrich wants to merge 2 commits into
Conversation
|
testsuite-test-pr: 20 |
|
I haven't looked at the code, just the upgrade note, but the options can not be removed. They must continue to exist. |
|
This PR must be tested with the corresponding testsuite PR which adds 48 tests to test the codec negotiation: Further, 10 tests were adopted to reflect the new behavior. For those tests, |
@jcolp And they must continue to work? Or silently be ignored like the ACN settings were? I'm not sure if I see a way for both settings to co-exist without interfering with each other. |
|
Yes. We can not remove options in minor versions, or alter their behavior, unless there is a critical reason why - such as a security issue. This does not rise to that level. |
|
For example, if the options are kept but default to empty in the code we can determine that they are actually unset. Default behavior should remain the same in that case even if the options were removed. If they are set then those settings take priority. If unset then the other options take priority.
|
Makes sense, I probably should have checked with the maintainers first. So would it be an option for Asterisk 21? |
|
Asterisk 21, once branched, can no longer receive breaking changes. |
|
I'm sticking to the policy that breaking changes are for standard releases, which next would be 23. If this change can be altered to maintain backwards compatibility then it would be eligible for all. |
|
Ok, then I will look into your suggestion and try to find a way to not change the existing behavior and not remove any settings. Is it possible to mark this PR as a draft while I do that? |
|
I've converted it to a draft. |
Consider the case where neither the "old" options They must be set to |
|
Thanks for picking this up!!! |
|
@gtjoseph Thank you! I am now incorporating Joshua's remarks and I noticed that some fax/pjsip tests failed (which I didn't check). So this is still a WIP, but we have confirmed that the ACN is working as expected (e.g. see the linked testsuite PR and we have done manual testing as well). |
To be more precise, I think the logic should be: As soon as one of I think everything else would lead to maximum confusion. I will state this in the docs for the settings. |
|
Update: We can not really invest more time into making this patch also work with the old settings. @jcolp Is the removal of the We are confident that this patch implements ACN as it is supposed to, the only missing piece seems to be the failing fax tests. |
There is a waiting-for-standard-release-development-cycle label for this purpose, that could be applied. But I'm not sure contributors can add it themselves. |
|
I've added it. |
c6b7d4b to
31abe63
Compare
|
Thanks for the comment and for offering help! @eallovon You're right, this PR is a bit stuck, mostly because it is not really a priority on our side anymore, so I don't get to invest time in this currently. To move this PR forward, I would say the following must be done in this order (can be done by anyone):
If you can help with any of the above, that would be greatly appreciated. And we can also talk about how to correctly attribute the work. PS:
With the breaking changes that we have currently, yes. If we can make this PR backwards compatible and make it coexist with the existing options, then it can be merged anytime. If the maintainers allow the removal of the old options for Asterisk 23/24, then it would have to be merged into master by mid August. See the bottom of the Asterisk Versions page.
Not in detail, no.
I'm not sure I fully understood the scenario, but it seems like this scenario should work even without ACN. The way you described it that sounds more like a bug to me, but I'm not sure. |
|
Hi, Thanks a lot for your detailed answer.
In the end I focused mainly on your comment here trying to figure out if it could be a bug. tl;drit may be a bug, but it never really worked. Though, in the process of debugging it I found that setting FTR, the longer explanationGiven the following configuration As I said in my previous message, with current version of asterisk (20.11 for example), if caller sends an offer with g729>g722>alaw, asterisk correctly sends an offer to callee with g729>alaw (respecting caller order, filtered from codec unknown in caller/callee configuration). But then the communication fails to establish with the message What I found is that the option What I discovered when adding some log in the code Therefore in our case, adding As I said, I'm afraid that if we don't find another culprit our interest in this PR will fade. |
|
I had a crash today. #0 ast_stream_topology_get_first_stream_by_type (type=AST_MEDIA_TYPE_AUDIO, topology=0x7f9038a9d5a8) at stream.c:976 (gdb) bt |
|
Thanks for the report @khoegh! The hint about the 183 and 180 with SDP is very useful and likely has to do with it. Unfortunately, currently I won't have time to look into the details. |
|
REMINDER: If this PR applies to other branches, please add a comment with the appropriate "cherry-pick-to" headers as per the Create a Pull Request process. If you don't want it cherry-picked, please add a comment with If, after adding "cherry-pick-to" comments, you change your mind, please edit the comment to DELETE the header lines and add The currently active branches are now 20, 21, 22 and master. |
1 similar comment
|
REMINDER: If this PR applies to other branches, please add a comment with the appropriate "cherry-pick-to" headers as per the Create a Pull Request process. If you don't want it cherry-picked, please add a comment with If, after adding "cherry-pick-to" comments, you change your mind, please edit the comment to DELETE the header lines and add The currently active branches are now 20, 21, 22 and master. |
|
REMINDER: If this PR applies to other branches, please add a comment with the appropriate cherry-pick-to headers as per the Create a Pull Request process. If you don't want it cherry-picked, please add a comment with so we don't keep asking. If, after adding cherry-pick-to comments, you change your mind, please edit the comment to DELETE the header lines and add . The currently active branches are now 20, 21, 22 and master. |
|
I've had 7 crashes in as many weeks, handling several hundred thousand calls pr day. When 180/SDP is received, there is no channel lock, and it is using the "old"
|
|
I've used the following patch for a couple of weeks (~5M calls) without crashes and haven't noticed any side effects.
|
|
I'm back again on this PR.
In fact after more test the workaround I had found did not work for all cases so we had to add this ACN patch to our asterisk. After some discussion with our customer he is willing to help on this ACN work in order for this PR to - hopefully - be included in asterisk. So we have now some time to work on this. As you said last time :
We are going in the next couple of weeks to try to address the first point, namely Fix failing PJSIP + T.38 tests. Two questions:
looking forward to reading you |
|
@eallovon That sounds great, thank you for picking this up!
|
|
@eallovon I added some changes to master...btriller:asterisk:acn |
|
So we were able to take some time to work on the T.38 issue. Our analysis seem to indicate that there is some kind of desynchronization between the media session and the T.38 part which leads asterisk to refuse the re-INVITE. From what we understood this desynchronization seem to come from these modifications in the PR which pushes to the stream handling only a copy of the media_state. From our analysis this copy does not really seem necessary (?) and from our tests, going backward, on this media_state copy restores the T.38 scenarios without breaking the ACN as far as we tried. Regarding the asterisk testsuite it seems to pass all the T.38 related test (except the Here is the proposed patch. Please don't hesitate to put it in your PR (we don't really care of being mentioned etc.) so that the testsuite could be rerun and we could check everything's fine : Index: src/asterisk/res/res_pjsip_session.c
===================================================================
--- src.orig/asterisk/res/res_pjsip_session.c
+++ src/asterisk/res/res_pjsip_session.c
@@ -2870,11 +2870,7 @@ static int sdp_requires_deferral(struct
/* As this is only called on an incoming SDP offer before processing it is not possible
* for streams and their media sessions to exist.
*/
- media_state = ast_sip_session_media_state_clone(session->pending_media_state);
- if (!media_state) {
- return -1;
- }
- if (ast_stream_topology_set_stream(media_state->topology, i, stream)) {
+ if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) {
ast_stream_free(stream);
return -1;
}
@@ -2887,7 +2883,7 @@ static int sdp_requires_deferral(struct
}
}
- session_media = ast_sip_session_media_state_add(session, media_state, ast_media_type_from_str(media), i);
+ session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i);
if (!session_media) {
return -1;
}
@@ -3027,8 +3023,6 @@ static pj_bool_t session_reinvite_on_rx_
return PJ_FALSE;
}
- ast_sip_session_media_state_reset(session->pending_media_state);
-
pjsip_rx_data_clone(rdata, 0, &session->deferred_reinvite);
return PJ_TRUE;Any feedback would be appreciated, thanks |
|
We continued to look into the T.38 tests and specifically the In the end this second patch fix also the Index: asterisk/channels/chan_pjsip.c
===================================================================
--- asterisk.orig/channels/chan_pjsip.c
+++ asterisk/channels/chan_pjsip.c
@@ -208,10 +208,16 @@ static enum ast_rtp_glue_result chan_pjs
return AST_RTP_GLUE_RESULT_FORBID;
}
+ /*
+ * Forbid native RTP only when T.38 is actually in use or negotiating.
+ */
datastore = ast_sip_session_get_datastore(channel->session, "t38");
if (datastore) {
+ enum ast_sip_session_t38state t38state = channel->session->t38state;
ao2_ref(datastore, -1);
- return AST_RTP_GLUE_RESULT_FORBID;
+ if (t38state != T38_DISABLED) {
+ return AST_RTP_GLUE_RESULT_FORBID;
+ }
}
endpoint = channel->session->endpoint;So normally with these two patches it should fix the T.38 scenario and the first task we were trying to accomplish to move this PR forward. Did you have any time to look at the first patch we suggested ? Any comments ? Again don't hesitate to integrate it in your PR to see if it actually fixes the testsuite. Or do you prefer that I open a new PR ? |
|
Hi @eallovon. Sorry for the late response, I'm a little swamped these days. The patches look good! I just added them as a commit to this branch and triggered the CI testsuite runs here on GitHub. Let's see what they report. |
There was a problem hiding this comment.
Attention! This pull request may contain issues that could prevent it from being accepted. Please review the checklist below and take the recommended action. If you believe any of these are not applicable, just add a comment and let us know.
- An Alembic change was detected but a commit message UpgradeNote with at least one of the 'alembic', 'database' or 'schema' keywords wasn't found. Please add an UpgradeNote to the commit message that mentions one of those keywords notifying users that there's a database schema change. (alembic-upgrade)
Documentation:
|
Workflow PRCheck failed |
|
I had a quick look at the failure. I searched for This diff should do the trick (as pjsip_manager.xml already references the new options) : diff --git a/res/res_pjsip/pjsip_manager.xml b/res/res_pjsip/pjsip_manager.xml
index 9f2cf634c5..50861ade33 100644
--- a/res/res_pjsip/pjsip_manager.xml
+++ b/res/res_pjsip/pjsip_manager.xml
@@ -638,9 +638,6 @@
<parameter name="Ignore183WithoutSdp">
<para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='ignore_183_without_sdp']/synopsis/node())"/></para>
</parameter>
- <parameter name="IncomingCallOfferPref">
- <para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='incoming_call_offer_pref']/synopsis/node())"/></para>
- </parameter>
<parameter name="IncomingMwiMailbox">
<para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='incoming_mwi_mailbox']/synopsis/node())"/></para>
</parameter> |
Advanced Codec Negotiation is now implemented for the dial application, pjsip channels and local channels. Resolves: asterisk#223 UpgradeNote: The two pjsip.conf options "incoming_call_offer_pref" and "outgoing_call_offer_pref" have been removed. Instead, the new options "codec_prefs_incoming_answer", "codec_prefs_incoming_offer", "codec_prefs_outgoing_answer", "codec_prefs_outgoing_offer" must be used. Even if the old settings were not used, this could break existing deployments as the default ACN options are now in use and they might behave differently in some call flows (e.g. by default, pending codecs are always preferred, not the endpoint configuration). UserNote: The Advanced Codec Negotiation feature is now implemented.
|
multiple-commits: interim |
|
Thank you for your efforts @eallovon. Currently, I still don't have the capacity to work on this unfortunately. I wish I could be of more help. |
|
Workflow PRCheck failed |
|
hello Just for information we're still investigating why our suggested patches failed quite some tests in the testsuite.
Sorry for this and sorry for the "no news" since a few weeks. I hope to be able give more news in a not to far future ... 😅 |
|
hello, So I'm back with a new patch that should fix most of the failing tests. Attached is a new patch that should apply on top of your branch. It mainly fixes the re-INVITE scenario where it was needed to distinguish whether it was a T.38 scenario or not when refreshing the session. I re-ran the testsuite (but mostly on the tests that failed last time) and here are the results compared between your initial PR, your PR with our first patches (current state of your PR) and then with this new attached patch (see table at the end).
Could you please integrate this new patch in your PR so that we could see what the real testsuite says. I hope the real testsuite will give us the same results. Regards, AppendixTest result I had :
|
|
Thank you very much @eallovon! I applied your patch to this branch by amending the last commit (with minor restructuring of your patch to fix "ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]" errors). Let's see what the CI-run tests report. |
Co-authored-by: Etienne Allovon <eallovon@avencall.com>
|
Workflow PRCheck failed |
|
Thank you for the update @maximilianfridrich (and for the fix in our patch). In the end the test result looks even better than what I had on my side.
|
|
@maximilianfridrich Could you please also update testsuite, and re-run tests? |
|
Hi @maximilianfridrich, @eallovon, I dug into the remaining CI failures on this PR and I believe I have root causes for all of them, plus a patch (attached below) that I verified against the testsuite (current testsuite master, Debian 13, Root cause analysis of the failing gatesmaster-pjs1 (geolocation ×2, message_redirect ×2) — not caused by this PRThese are simply the branch being ~250 commits behind master. The testsuite tests were updated/added for features that landed in Asterisk master after this branch's base:
A rebase fixes these four. I test-merged current master: only master-pjs2 (dtmf_sdp ×6) and master-fax (t38_initial_offer) — default behavior regressionAll of these tests assert the pre-ACN default negotiation behavior:
This is exactly the backwards-compatibility point @jcolp raised back in 2023 ("default behavior with this change should match previous versions"), and matches @maximilianfridrich's own 2023 analysis that the incoming defaults would have to become
master-pjs5 (codec_mismatch, hold_declined) — real bugs in
|
| Test | baseline | patched |
|---|---|---|
sdp_offer_answer/.../audio-video/codec-mismatch |
❌ | ✅ |
sdp_offer_answer/.../audio-video/hold-declined |
❌ | ✅ |
fax/pjsip/t38_initial_offer |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_generation/dtmf_sdp_48k_audio_8k_digits_bob |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_generation/dtmf_sdp_48k_priority_diff |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_generation/dtmf_sdp_8k_priority_diff |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_negotiation_alice |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_negotiation_alice_asym |
❌ | ✅ |
dtmf_sdp/dtmf_sdp_negotiation_bob |
❌ | ✅ |
Regression sweep of previously-passing codec-sensitive tests, all still ✅ with the patch: apps/dial/preserve_top, all_codecs_on_empty_reinvite/early-offer, all_codecs_on_empty_reinvite/late-offer, dtmf_sdp_48k_priority_match, dtmf_sdp_48k_priority_match_8k_digits, dtmf_sdp_8k_priority_match, sdp_offer_answer/.../audio/basic, sdp_offer_answer/.../decline/basic, channels/pjsip/hold, fax/pjsip/t38.
Remaining work beyond this patch
- Rebase onto master (fixes the 4 pjs1 failures; one small conflict).
- The 2023 review blocker still stands:
incoming_call_offer_pref/outgoing_call_offer_prefare removed and the Alembic migration drops their columns. With the compat defaults above, restoring the old options (old options take priority when set, ACN options otherwise, as @jcolp suggested) becomes much more tractable, and the migration could be dropped entirely. - The PR checklist bot wants an UpgradeNote containing "alembic"/"database"/"schema" — moot if the migration is dropped.
- With these defaults, most of the pjsip.conf adaptations in the testsuite PR (pjsip: Add tests for Advanced Codec Negotiation (ACN) testsuite#20) to pre-existing tests should no longer be needed and could be reverted, which also addresses the "please update testsuite" request.
Patch (applies on top of d659d4c92c)
diff --git a/res/res_pjsip/pjsip_config.xml b/res/res_pjsip/pjsip_config.xml
index 960fed1f8b..df0817a46c 100644
--- a/res/res_pjsip/pjsip_config.xml
+++ b/res/res_pjsip/pjsip_config.xml
@@ -106,8 +106,8 @@
<para>
</para>
<enumlist>
- <enum name="pending"><para>The codec list from the caller. (default)</para></enum>
- <enum name="configured"><para>The codec list from the endpoint.</para></enum>
+ <enum name="pending"><para>The codec list from the caller.</para></enum>
+ <enum name="configured"><para>The codec list from the endpoint. (default)</para></enum>
</enumlist>
</enum>
<enum name="operation : < intersect | only_preferred | only_nonpreferred >">
@@ -170,17 +170,17 @@
<para>
</para>
<enumlist>
- <enum name="pending"><para>The codec list from the core. (default)</para></enum>
- <enum name="configured"><para>The codec list from the endpoint.</para></enum>
+ <enum name="pending"><para>The codec list from the core.</para></enum>
+ <enum name="configured"><para>The codec list from the endpoint. (default)</para></enum>
</enumlist>
</enum>
<enum name="operation : < union | intersect | only_preferred | only_nonpreferred >">
<para>
</para>
<enumlist>
- <enum name="union"><para>Merge the lists with the preferred codecs first. (default)</para></enum>
- <enum name="intersect"><para>Only common codecs with the preferred codecs first. (default)</para></enum>
- <enum name="only_preferred"><para>Use only the preferred codecs.</para></enum>
+ <enum name="union"><para>Merge the lists with the preferred codecs first.</para></enum>
+ <enum name="intersect"><para>Only common codecs with the preferred codecs first.</para></enum>
+ <enum name="only_preferred"><para>Use only the preferred codecs. (default)</para></enum>
<enum name="only_nonpreferred"><para>Use only the non-preferred codecs.</para></enum>
</enumlist>
</enum>
@@ -235,8 +235,8 @@
<para>
</para>
<enumlist>
- <enum name="pending"><para>The codec list in the received SDP answer. (default)</para></enum>
- <enum name="configured"><para>The codec list from the endpoint.</para></enum>
+ <enum name="pending"><para>The codec list in the received SDP answer.</para></enum>
+ <enum name="configured"><para>The codec list from the endpoint. (default)</para></enum>
</enumlist>
</enum>
<enum name="operation : < union | intersect | only_preferred | only_nonpreferred >">
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 5f6fa62b3f..7e45c11889 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1269,15 +1269,15 @@ static int codec_prefs_handler(const struct aco_option *opt,
return -1;
}
option_prefs = &endpoint->media.codec_prefs_incoming_offer;
- default_prefer = CODEC_NEGOTIATION_PREFER_PENDING;
+ default_prefer = CODEC_NEGOTIATION_PREFER_CONFIGURED;
default_operation = CODEC_NEGOTIATION_OPERATION_INTERSECT;
} else if (strcmp(var->name, "codec_prefs_outgoing_offer") == 0) {
option_prefs = &endpoint->media.codec_prefs_outgoing_offer;
- default_prefer = CODEC_NEGOTIATION_PREFER_PENDING;
- default_operation = CODEC_NEGOTIATION_OPERATION_UNION;
+ default_prefer = CODEC_NEGOTIATION_PREFER_CONFIGURED;
+ default_operation = CODEC_NEGOTIATION_OPERATION_ONLY_PREFERRED;
} else if (strcmp(var->name, "codec_prefs_incoming_answer") == 0) {
option_prefs = &endpoint->media.codec_prefs_incoming_answer;
- default_prefer = CODEC_NEGOTIATION_PREFER_PENDING;
+ default_prefer = CODEC_NEGOTIATION_PREFER_CONFIGURED;
default_operation = CODEC_NEGOTIATION_OPERATION_INTERSECT;
} else if (strcmp(var->name, "codec_prefs_outgoing_answer") == 0) {
option_prefs = &endpoint->media.codec_prefs_outgoing_answer;
@@ -2226,13 +2226,13 @@ int ast_res_pjsip_initialize_configuration(void)
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "suppress_q850_reason_headers", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, suppress_q850_reason_headers));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ignore_183_without_sdp", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ignore_183_without_sdp));
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "codec_prefs_incoming_offer",
- "prefer: pending, operation: intersect, keep: all, transcode: allow",
+ "prefer: configured, operation: intersect, keep: all, transcode: allow",
codec_prefs_handler, incoming_offer_codec_prefs_to_str, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "codec_prefs_outgoing_offer",
- "prefer: pending, operation: union, keep: all, transcode: allow",
+ "prefer: configured, operation: only_preferred, keep: all, transcode: allow",
codec_prefs_handler, outgoing_offer_codec_prefs_to_str, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "codec_prefs_incoming_answer",
- "prefer: pending, operation: intersect, keep: all",
+ "prefer: configured, operation: intersect, keep: all",
codec_prefs_handler, incoming_answer_codec_prefs_to_str, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "codec_prefs_outgoing_answer",
"prefer: pending, operation: intersect, keep: all",
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index da0bfe3d69..bcc8cf80b3 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -877,6 +877,7 @@ static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sd
RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
struct ast_sip_session_media *session_media = NULL;
int res;
+ int no_common_codecs = 0;
enum ast_media_type type;
struct ast_stream *stream = NULL;
pjmedia_sdp_media *remote_stream = sdp->media[i];
@@ -939,16 +940,19 @@ static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sd
}
remote_ast_stream = ast_stream_topology_get_first_stream_by_type(remote_topology, type);
- if (remote_ast_stream) {
+ if (remote_ast_stream && remote_stream->desc.port) {
/* Here we always have a remote offer, so we create a resolved stream using the remote SDP offer
* and the configured endpoint settings codec_prefs_incoming_offer. */
configured_stream = ast_stream_topology_get_first_stream_by_type(session->endpoint->media.topology, type);
resolved_stream = ast_stream_create_resolved(remote_ast_stream, configured_stream, &session->endpoint->media.codec_prefs_incoming_offer, NULL);
if (!resolved_stream || ast_format_cap_empty(ast_stream_get_formats(resolved_stream))) {
- ast_stream_free(resolved_stream); /* Can handle NULL */
+ /* Decline just this stream below instead of failing the whole
+ * negotiation. If no stream ends up accepted, the negotiation
+ * still fails as a whole. resolved_stream is freed by RAII_VAR. */
stream = ast_stream_alloc(stream_name, type);
- handled = 0;
- SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "No common codecs between incoming SDP offer and endpoint configuration.\n");
+ no_common_codecs = 1;
+ ast_trace(-1, "%s: No common codecs between incoming SDP offer and endpoint configuration, declining stream\n",
+ ast_sip_session_get_name(session));
} else {
stream = ast_stream_clone(resolved_stream, stream_name);
}
@@ -1007,8 +1011,9 @@ static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sd
ast_sip_session_get_name(session));
}
- /* 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)) {
+ /* If this stream is already declined mark it as such, or mark it as such if we've reached
+ * the limit or no codecs were in common with the endpoint configuration */
+ if (no_common_codecs || !remote_stream->desc.port || is_stream_limitation_reached(type, session->endpoint, type_streams)) {
remove_stream_from_bundle(session_media, stream);
SCOPE_EXIT_EXPR(continue, "%s: Declining incoming SDP media stream %s'\n",
ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
Advanced Codec Negotiation is now implemented for the dial application, pjsip channels and local channels.
Resolves: #223
UpgradeNote: The two pjsip.conf options "incoming_call_offer_pref" and "outgoing_call_offer_pref" have been removed. Instead, the new options "codec_prefs_incoming_answer", "codec_prefs_incoming_offer", "codec_prefs_outgoing_answer", "codec_prefs_outgoing_offer" must be used. Even if the old settings were not used, this could break existing deployments as the default ACN options are now in use and they might behave differently in some call flows (e.g. by default, pending codecs are always preferred, not the endpoint configuration).
UserNote: The Advanced Codec Negotiation feature is now implemented.