Compare commits

...

5 Commits

Author SHA1 Message Date
Asterisk Development Team
3bb594c9ca Update for 23.0.0 2025-10-15 17:01:28 +00:00
Asterisk Development Team
6249324f40 Update for 23.0.0-rc2 2025-09-25 13:49:56 +00:00
George Joseph
86e3ed9620 res_rtp_asterisk.c: Use rtp->dtls in __rtp_sendto when rtcp mux is used.
In __rtp_sendto(), the check for DTLS negotiation completion for rtcp packets
needs to use the rtp->dtls structure instead of rtp->rtcp->dtls when
AST_RTP_INSTANCE_RTCP_MUX is set.

Resolves: #1474
2025-09-25 07:09:22 -06:00
George Joseph
546cefb305 chan_websocket: Fix codec validation and add passthrough option.
* Fixed an issue in webchan_write() where we weren't detecting equivalent
  codecs properly.
* Added the "p" dialstring option that puts the channel driver in
  "passthrough" mode where it will not attempt to re-frame or re-time
  media coming in over the websocket from the remote app.  This can be used
  for any codec but MUST be used for codecs that use packet headers or whose
  data stream can't be broken up on arbitrary byte boundaries. In this case,
  the remote app is fully responsible for correctly framing and timing media
  sent to Asterisk and the MEDIA text commands that could be sent over the
  websocket are disabled.  Currently, passthrough mode is automatically set
  for the opus, speex and g729 codecs.
* Now calling ast_set_read_format() after ast_channel_set_rawreadformat() to
  ensure proper translation paths are set up when switching between native
  frames and slin silence frames.  This fixes an issue with codec errors
  when transcode_via_sln=yes.

Resolves: #1462
2025-09-25 07:09:22 -06:00
George Joseph
2b562c9531 res_ari: Ensure outbound websocket config has a websocket_client_id.
Added a check to outbound_websocket_apply() that makes sure an outbound
websocket config object in ari.conf has a websocket_client_id parameter.

Resolves: #1457
2025-09-25 07:09:22 -06:00
10 changed files with 263 additions and 41 deletions

View File

@@ -1 +1 @@
23.0.0-rc1
23.0.0

View File

@@ -1 +1 @@
ChangeLogs/ChangeLog-23.0.0-rc1.html
ChangeLogs/ChangeLog-23.0.0.html

View File

@@ -1 +1 @@
ChangeLogs/ChangeLog-23.0.0-rc1.md
ChangeLogs/ChangeLog-23.0.0.md

View File

@@ -1,17 +1,17 @@
<html><head><title>ChangeLog for asterisk-23.0.0-rc1</title></head><body>
<h2>Change Log for Release asterisk-23.0.0-rc1</h2>
<html><head><title>ChangeLog for asterisk-23.0.0</title></head><body>
<h2>Change Log for Release asterisk-23.0.0</h2>
<h3>Links:</h3>
<ul>
<li><a href="https://downloads.asterisk.org/pub/telephony/asterisk/releases/ChangeLog-23.0.0-rc1.html">Full ChangeLog</a> </li>
<li><a href="https://github.com/asterisk/asterisk/compare/23.0.0-pre1...23.0.0-rc1">GitHub Diff</a> </li>
<li><a href="https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-23.0.0-rc1.tar.gz">Tarball</a> </li>
<li><a href="https://downloads.asterisk.org/pub/telephony/asterisk/releases/ChangeLog-23.0.0.html">Full ChangeLog</a> </li>
<li><a href="https://github.com/asterisk/asterisk/compare/23.0.0-pre1...23.0.0">GitHub Diff</a> </li>
<li><a href="https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-23.0.0.tar.gz">Tarball</a> </li>
<li><a href="https://downloads.asterisk.org/pub/telephony/asterisk">Downloads</a> </li>
</ul>
<h3>Summary:</h3>
<ul>
<li>Commits: 41</li>
<li>Commit Authors: 13</li>
<li>Issues Resolved: 32</li>
<li>Commits: 45</li>
<li>Commit Authors: 14</li>
<li>Issues Resolved: 36</li>
<li>Security Advisories Resolved: 1</li>
<li><a href="https://github.com/asterisk/asterisk/security/advisories/GHSA-64qc-9x89-rx5j">GHSA-64qc-9x89-rx5j</a>: A specifically malformed Authorization header in an incoming SIP request can cause Asterisk to crash</li>
</ul>
@@ -130,9 +130,10 @@
<ul>
<li>Alexei Gradinari: (1)</li>
<li>Alexey Khabulyak: (1)</li>
<li>Allan Nathanson: (1)</li>
<li>Artem Umerov: (1)</li>
<li>Ben Ford: (2)</li>
<li>George Joseph: (4)</li>
<li>George Joseph: (7)</li>
<li>Igor Goncharovsky: (2)</li>
<li>Joe Garlick: (1)</li>
<li>Jose Lopes: (1)</li>
@@ -177,6 +178,10 @@
<li>1394: [improvement]: sig_analog: Skip Caller ID spill if Caller ID is disabled</li>
<li>1396: [new-feature]: pbx_builtins: Make tone option for WaitExten configurable</li>
<li>1401: [bug]: app_waitfornoise timeout is always less then configured because of time() usage</li>
<li>1451: [bug]: ast_config_text_file_save2(): incorrect handling of deep/wide template inheritance</li>
<li>1457: [bug]: segmentation fault because of a wrong ari config</li>
<li>1462: [bug]: chan_websocket isn't handling the "opus" codec correctly.</li>
<li>1474: [bug]: Media doesn't flow for video conference after res_rtp_asterisk change to stop media flow before DTLS completes</li>
<li>ASTERISK-30370: config: Template inheritance is incorrect for ast_variable_retrieve</li>
</ul>
<h3>Commits By Author:</h3>
@@ -206,13 +211,16 @@
<p>res_rtp_asterisk: Don't send RTP before DTLS has negotiated.</p>
</li>
<li>
<h4>George Joseph (4):</h4>
<h4>George Joseph (7):</h4>
</li>
<li>xmldoc.c: Fix rendering of CLI output.</li>
<li>chan_websocket: Fix buffer overrun when processing TEXT websocket frames.</li>
<li>chan_websocket: Allow additional URI parameters to be added to the outgoing URI.</li>
<li>res_pjsip_authenticator_digest: Fix SEGV if get_authorization_hdr returns NULL.</li>
<li>res_ari: Ensure outbound websocket config has a websocket_client_id.</li>
<li>chan_websocket: Fix codec validation and add passthrough option.</li>
<li>
<p>res_pjsip_authenticator_digest: Fix SEGV if get_authorization_hdr returns NULL.</p>
<p>res_rtp_asterisk.c: Use rtp-&gt;dtls in __rtp_sendto when rtcp mux is used.</p>
</li>
<li>
<h4>Igor Goncharovsky (2):</h4>
@@ -278,6 +286,10 @@
<li>logger.c: Remove deprecated/redundant configuration option.</li>
<li>func_dialplan: Remove deprecated/redundant function.</li>
<li>Update version for Asterisk 23</li>
<li>config.c: fix saving of deep/wide template configurations</li>
<li>res_rtp_asterisk.c: Use rtp-&gt;dtls in __rtp_sendto when rtcp mux is used.</li>
<li>chan_websocket: Fix codec validation and add passthrough option.</li>
<li>res_ari: Ensure outbound websocket config has a websocket_client_id.</li>
<li>chan_websocket.c: Add DTMF messages</li>
<li>app_queue.c: Add new global 'log_unpause_on_reason_change'</li>
<li>app_waitforsilence.c: Use milliseconds to calculate timeout time</li>
@@ -465,6 +477,54 @@
<h4>Update version for Asterisk 23</h4>
<p>Author: Ben Ford
Date: 2025-08-13</p>
<h4>config.c: fix saving of deep/wide template configurations</h4>
<p>Author: Allan Nathanson
Date: 2025-09-10</p>
<p>Follow-on to #244 and #960 regarding how the ast_config_XXX APIs
handle template inheritance.</p>
<p>ast_config_text_file_save2() incorrectly suppressed variables if they
matched any ancestor template. This broke deep chains (dropping values
based on distant parents) and wide inheritance (ignoring last-wins order
across multiple parents).</p>
<p>The function now inspects the full template hierarchy to find the nearest
effective parent (last occurrence wins). Earlier inherited duplicates are
collapsed, explicit overrides are kept unless they exactly match the parent,
and PreserveEffectiveContext avoids writing redundant lines.</p>
<p>Resolves: #1451</p>
<h4>res_rtp_asterisk.c: Use rtp-&gt;dtls in __rtp_sendto when rtcp mux is used.</h4>
<p>Author: George Joseph
Date: 2025-09-23</p>
<p>In __rtp_sendto(), the check for DTLS negotiation completion for rtcp packets
needs to use the rtp-&gt;dtls structure instead of rtp-&gt;rtcp-&gt;dtls when
AST_RTP_INSTANCE_RTCP_MUX is set.</p>
<p>Resolves: #1474</p>
<h4>chan_websocket: Fix codec validation and add passthrough option.</h4>
<p>Author: George Joseph
Date: 2025-09-17</p>
<ul>
<li>Fixed an issue in webchan_write() where we weren't detecting equivalent
codecs properly.</li>
<li>Added the "p" dialstring option that puts the channel driver in
"passthrough" mode where it will not attempt to re-frame or re-time
media coming in over the websocket from the remote app. This can be used
for any codec but MUST be used for codecs that use packet headers or whose
data stream can't be broken up on arbitrary byte boundaries. In this case,
the remote app is fully responsible for correctly framing and timing media
sent to Asterisk and the MEDIA text commands that could be sent over the
websocket are disabled. Currently, passthrough mode is automatically set
for the opus, speex and g729 codecs.</li>
<li>Now calling ast_set_read_format() after ast_channel_set_rawreadformat() to
ensure proper translation paths are set up when switching between native
frames and slin silence frames. This fixes an issue with codec errors
when transcode_via_sln=yes.</li>
</ul>
<p>Resolves: #1462</p>
<h4>res_ari: Ensure outbound websocket config has a websocket_client_id.</h4>
<p>Author: George Joseph
Date: 2025-09-12</p>
<p>Added a check to outbound_websocket_apply() that makes sure an outbound
websocket config object in ari.conf has a websocket_client_id parameter.</p>
<p>Resolves: #1457</p>
<h4>chan_websocket.c: Add DTMF messages</h4>
<p>Author: Joe Garlick
Date: 2025-09-04</p>

View File

@@ -1,18 +1,18 @@
## Change Log for Release asterisk-23.0.0-rc1
## Change Log for Release asterisk-23.0.0
### Links:
- [Full ChangeLog](https://downloads.asterisk.org/pub/telephony/asterisk/releases/ChangeLog-23.0.0-rc1.html)
- [GitHub Diff](https://github.com/asterisk/asterisk/compare/23.0.0-pre1...23.0.0-rc1)
- [Tarball](https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-23.0.0-rc1.tar.gz)
- [Full ChangeLog](https://downloads.asterisk.org/pub/telephony/asterisk/releases/ChangeLog-23.0.0.html)
- [GitHub Diff](https://github.com/asterisk/asterisk/compare/23.0.0-pre1...23.0.0)
- [Tarball](https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-23.0.0.tar.gz)
- [Downloads](https://downloads.asterisk.org/pub/telephony/asterisk)
### Summary:
- Commits: 41
- Commit Authors: 13
- Issues Resolved: 32
- Commits: 45
- Commit Authors: 14
- Issues Resolved: 36
- Security Advisories Resolved: 1
- [GHSA-64qc-9x89-rx5j](https://github.com/asterisk/asterisk/security/advisories/GHSA-64qc-9x89-rx5j): A specifically malformed Authorization header in an incoming SIP request can cause Asterisk to crash
@@ -115,9 +115,10 @@
- Alexei Gradinari: (1)
- Alexey Khabulyak: (1)
- Allan Nathanson: (1)
- Artem Umerov: (1)
- Ben Ford: (2)
- George Joseph: (4)
- George Joseph: (7)
- Igor Goncharovsky: (2)
- Joe Garlick: (1)
- Jose Lopes: (1)
@@ -163,6 +164,10 @@
- 1394: [improvement]: sig_analog: Skip Caller ID spill if Caller ID is disabled
- 1396: [new-feature]: pbx_builtins: Make tone option for WaitExten configurable
- 1401: [bug]: app_waitfornoise timeout is always less then configured because of time() usage
- 1451: [bug]: ast_config_text_file_save2(): incorrect handling of deep/wide template inheritance
- 1457: [bug]: segmentation fault because of a wrong ari config
- 1462: [bug]: chan_websocket isn't handling the "opus" codec correctly.
- 1474: [bug]: Media doesn't flow for video conference after res_rtp_asterisk change to stop media flow before DTLS completes
- ASTERISK-30370: config: Template inheritance is incorrect for ast_variable_retrieve
### Commits By Author:
@@ -179,11 +184,14 @@
- #### Ben Ford (1):
- res_rtp_asterisk: Don't send RTP before DTLS has negotiated.
- #### George Joseph (4):
- #### George Joseph (7):
- xmldoc.c: Fix rendering of CLI output.
- chan_websocket: Fix buffer overrun when processing TEXT websocket frames.
- chan_websocket: Allow additional URI parameters to be added to the outgoing URI.
- res_pjsip_authenticator_digest: Fix SEGV if get_authorization_hdr returns NULL.
- res_ari: Ensure outbound websocket config has a websocket_client_id.
- chan_websocket: Fix codec validation and add passthrough option.
- res_rtp_asterisk.c: Use rtp->dtls in __rtp_sendto when rtcp mux is used.
- #### Igor Goncharovsky (2):
- app_waitforsilence.c: Use milliseconds to calculate timeout time
@@ -233,6 +241,10 @@
- logger.c: Remove deprecated/redundant configuration option.
- func_dialplan: Remove deprecated/redundant function.
- Update version for Asterisk 23
- config.c: fix saving of deep/wide template configurations
- res_rtp_asterisk.c: Use rtp->dtls in __rtp_sendto when rtcp mux is used.
- chan_websocket: Fix codec validation and add passthrough option.
- res_ari: Ensure outbound websocket config has a websocket_client_id.
- chan_websocket.c: Add DTMF messages
- app_queue.c: Add new global 'log_unpause_on_reason_change'
- app_waitforsilence.c: Use milliseconds to calculate timeout time
@@ -481,6 +493,66 @@
Date: 2025-08-13
#### config.c: fix saving of deep/wide template configurations
Author: Allan Nathanson
Date: 2025-09-10
Follow-on to #244 and #960 regarding how the ast_config_XXX APIs
handle template inheritance.
ast_config_text_file_save2() incorrectly suppressed variables if they
matched any ancestor template. This broke deep chains (dropping values
based on distant parents) and wide inheritance (ignoring last-wins order
across multiple parents).
The function now inspects the full template hierarchy to find the nearest
effective parent (last occurrence wins). Earlier inherited duplicates are
collapsed, explicit overrides are kept unless they exactly match the parent,
and PreserveEffectiveContext avoids writing redundant lines.
Resolves: #1451
#### res_rtp_asterisk.c: Use rtp->dtls in __rtp_sendto when rtcp mux is used.
Author: George Joseph
Date: 2025-09-23
In __rtp_sendto(), the check for DTLS negotiation completion for rtcp packets
needs to use the rtp->dtls structure instead of rtp->rtcp->dtls when
AST_RTP_INSTANCE_RTCP_MUX is set.
Resolves: #1474
#### chan_websocket: Fix codec validation and add passthrough option.
Author: George Joseph
Date: 2025-09-17
* Fixed an issue in webchan_write() where we weren't detecting equivalent
codecs properly.
* Added the "p" dialstring option that puts the channel driver in
"passthrough" mode where it will not attempt to re-frame or re-time
media coming in over the websocket from the remote app. This can be used
for any codec but MUST be used for codecs that use packet headers or whose
data stream can't be broken up on arbitrary byte boundaries. In this case,
the remote app is fully responsible for correctly framing and timing media
sent to Asterisk and the MEDIA text commands that could be sent over the
websocket are disabled. Currently, passthrough mode is automatically set
for the opus, speex and g729 codecs.
* Now calling ast_set_read_format() after ast_channel_set_rawreadformat() to
ensure proper translation paths are set up when switching between native
frames and slin silence frames. This fixes an issue with codec errors
when transcode_via_sln=yes.
Resolves: #1462
#### res_ari: Ensure outbound websocket config has a websocket_client_id.
Author: George Joseph
Date: 2025-09-12
Added a check to outbound_websocket_apply() that makes sure an outbound
websocket config object in ari.conf has a websocket_client_id parameter.
Resolves: #1457
#### chan_websocket.c: Add DTMF messages
Author: Joe Garlick
Date: 2025-09-04

View File

@@ -1,4 +1,4 @@
<html><head><title>Readme for asterisk-23.0.0-rc1</title></head><body>
<html><head><title>Readme for asterisk-23.0.0</title></head><body>
<h1>The Asterisk(R) Open Source PBX</h1>
<pre><code>By Mark Spencer &lt;markster@digium.com&gt; and the Asterisk.org developer community.
Copyright (C) 2001-2025 Sangoma Technologies Corporation and other copyright holders.
@@ -37,7 +37,7 @@ hardware.</p>
<p>If you are updating from a previous version of Asterisk, make sure you
read the Change Logs.</p>
<!-- CHANGELOGS (the URL will change based on the location of this README) -->
<p><a href="ChangeLogs/ChangeLog-23.0.0-rc1.html">Change Logs</a></p>
<p><a href="ChangeLogs/ChangeLog-23.0.0.html">Change Logs</a></p>
<!-- END-CHANGELOGS -->
<h3>NEW INSTALLATIONS</h3>

View File

@@ -55,7 +55,7 @@ If you are updating from a previous version of Asterisk, make sure you
read the Change Logs.
<!-- CHANGELOGS (the URL will change based on the location of this README) -->
[Change Logs](ChangeLogs/ChangeLog-23.0.0-rc1.html)
[Change Logs](ChangeLogs/ChangeLog-23.0.0.html)
<!-- END-CHANGELOGS -->
### NEW INSTALLATIONS

View File

@@ -59,6 +59,18 @@
/channels/answer ARI endpoint.
</para>
</enum>
<enum name="p - Passthrough mode">
<para>In passthrough mode, the channel driver won't attempt
to re-frame or re-time media coming in over the websocket from
the remote app. This can be used for any codec but MUST be used
for codecs that use packet headers or whose data stream can't be
broken up on arbitrary byte boundaries. In this case, the remote
app is fully responsible for correctly framing and timing media
sent to Asterisk and the MEDIA text commands that could be sent
over the websocket are disabled. Currently, passthrough mode is
automatically set for the opus, speex and g729 codecs.
</para>
</enum>
<enum name="v(uri_parameters) - Add parameters to the outbound URI">
<para>This option allows you to add additional parameters to the
outbound URI. The format is:
@@ -78,6 +90,9 @@
<example title="Make an outbound WebSocket connection using connection 'connection1' and the 'sln16' codec.">
same => n,Dial(WebSocket/connection1/c(sln16))
</example>
<example title="Make an outbound WebSocket connection using connection 'connection1' and the 'opus' codec. Passthrough mode will automatically be set.">
same => n,Dial(WebSocket/connection1/c(opus))
</example>
<example title="Listen for an incoming WebSocket connection and don't auto-answer it.">
same => n,Dial(WebSocket/INCOMING/n)
</example>
@@ -127,6 +142,7 @@ struct websocket_pvt {
char *uri_params;
char *leftover_data;
int no_auto_answer;
int passthrough;
int optimal_frame_size;
int bulk_media_in_progress;
int report_queue_drained;
@@ -188,6 +204,7 @@ static void set_channel_format(struct websocket_pvt * instance,
if (ast_format_cmp(ast_channel_rawreadformat(instance->channel), fmt)
== AST_FORMAT_CMP_NOT_EQUAL) {
ast_channel_set_rawreadformat(instance->channel, fmt);
ast_set_read_format(instance->channel, ast_channel_readformat(instance->channel));
ast_debug(4, "Switching readformat to %s\n", ast_format_get_name(fmt));
}
}
@@ -332,10 +349,10 @@ static struct ast_frame *webchan_read(struct ast_channel *ast)
}
/*
* If the frame length is already optimal_frame_size, we can just
* return it.
* If we're in passthrough mode or the frame length is already optimal_frame_size,
* we can just return it.
*/
if (native_frame->datalen == instance->optimal_frame_size) {
if (instance->passthrough || native_frame->datalen == instance->optimal_frame_size) {
set_channel_format(instance, instance->native_format);
return native_frame;
}
@@ -499,6 +516,11 @@ static int process_text_message(struct websocket_pvt *instance,
ast_queue_control(instance->channel, AST_CONTROL_HANGUP);
} else if (ast_strings_equal(command, START_MEDIA_BUFFERING)) {
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
AST_LIST_LOCK(&instance->frame_queue);
instance->bulk_media_in_progress = 1;
AST_LIST_UNLOCK(&instance->frame_queue);
@@ -511,6 +533,12 @@ static int process_text_message(struct websocket_pvt *instance,
id = ast_strip(command + strlen(STOP_MEDIA_BUFFERING));
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
ast_debug(4, "%s: WebSocket %s '%s' with %d bytes in leftover_data.\n",
ast_channel_name(instance->channel), STOP_MEDIA_BUFFERING, id,
(int)instance->leftover_len);
@@ -533,6 +561,13 @@ static int process_text_message(struct websocket_pvt *instance,
} else if (ast_strings_equal(command, FLUSH_MEDIA)) {
struct ast_frame *frame = NULL;
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
AST_LIST_LOCK(&instance->frame_queue);
while ((frame = AST_LIST_REMOVE_HEAD(&instance->frame_queue, frame_list))) {
ast_frfree(frame);
@@ -543,6 +578,12 @@ static int process_text_message(struct websocket_pvt *instance,
AST_LIST_UNLOCK(&instance->frame_queue);
} else if (ast_strings_equal(payload, REPORT_QUEUE_DRAINED)) {
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
AST_LIST_LOCK(&instance->frame_queue);
instance->report_queue_drained = 1;
AST_LIST_UNLOCK(&instance->frame_queue);
@@ -569,11 +610,21 @@ static int process_text_message(struct websocket_pvt *instance,
}
} else if (ast_strings_equal(payload, PAUSE_MEDIA)) {
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
AST_LIST_LOCK(&instance->frame_queue);
instance->queue_paused = 1;
AST_LIST_UNLOCK(&instance->frame_queue);
} else if (ast_strings_equal(payload, CONTINUE_MEDIA)) {
if (instance->passthrough) {
ast_debug(4, "%s: WebSocket in passthrough mode. Ignoring %s command.\n",
ast_channel_name(instance->channel), command);
return 0;
}
AST_LIST_LOCK(&instance->frame_queue);
instance->queue_paused = 0;
AST_LIST_UNLOCK(&instance->frame_queue);
@@ -607,6 +658,11 @@ static int process_binary_message(struct websocket_pvt *instance,
next_frame_ptr = payload;
instance->bytes_read += payload_len;
if (instance->passthrough) {
res = queue_frame_from_buffer(instance, payload, payload_len);
return res;
}
if (instance->bulk_media_in_progress && instance->leftover_len > 0) {
/*
* We have leftover data from a previous websocket message.
@@ -791,10 +847,10 @@ static void *read_thread_handler(void *obj)
* This is especially important for outbound connections otherwise
* the app won't know who the media is for.
*/
res = ast_asprintf(&command, "%s connection_id:%s channel:%s format:%s optimal_frame_size:%d", MEDIA_START,
res = ast_asprintf(&command, "%s connection_id:%s channel:%s format:%s optimal_frame_size:%d ptime:%d", MEDIA_START,
instance->connection_id, ast_channel_name(instance->channel),
ast_format_get_name(instance->native_format),
instance->optimal_frame_size);
instance->optimal_frame_size, instance->native_codec->default_ms);
if (res <= 0 || !command) {
ast_queue_control(instance->channel, AST_CONTROL_HANGUP);
ast_log(LOG_ERROR, "%s: Failed to create MEDIA_START\n", ast_channel_name(instance->channel));
@@ -843,9 +899,11 @@ static int webchan_write(struct ast_channel *ast, struct ast_frame *f)
ast_channel_name(ast));
return -1;
}
if (f->subclass.format != instance->native_format) {
ast_log(LOG_WARNING, "%s: This WebSocket channel only supports the '%s' format\n",
ast_channel_name(ast), ast_format_get_name(instance->native_format));
if (ast_format_cmp(f->subclass.format, instance->native_format) == AST_FORMAT_CMP_NOT_EQUAL) {
ast_log(LOG_WARNING, "%s: This WebSocket channel only supports the '%s' format, not '%s'\n",
ast_channel_name(ast), ast_format_get_name(instance->native_format),
ast_format_get_name(f->subclass.format));
return -1;
}
@@ -1044,15 +1102,36 @@ static struct websocket_pvt* websocket_new(const char *chan_name,
* References for native_format and native_codec are now held by the
* instance and will be released when the instance is destroyed.
*/
instance->optimal_frame_size =
(instance->native_codec->default_ms * instance->native_codec->minimum_bytes)
/ instance->native_codec->minimum_ms;
instance->leftover_data = ast_calloc(1, instance->optimal_frame_size);
if (!instance->leftover_data) {
return NULL;
/*
* It's not possible for us to re-time or re-frame media if the data
* stream can't be broken up on arbitrary byte boundaries. This is usually
* indicated by the codec's minimum_bytes being small (10 bytes or less).
* We need to force passthrough mode in this case.
*/
if (instance->native_codec->minimum_bytes <= 10) {
instance->passthrough = 1;
instance->optimal_frame_size = 0;
} else {
instance->optimal_frame_size =
(instance->native_codec->default_ms * instance->native_codec->minimum_bytes)
/ instance->native_codec->minimum_ms;
instance->leftover_data = ast_calloc(1, instance->optimal_frame_size);
if (!instance->leftover_data) {
return NULL;
}
}
ast_debug(3,
"%s: WebSocket channel native format '%s' Sample rate: %d ptime: %dms minms: %u minbytes: %u passthrough: %d optimal_frame_size: %d\n",
chan_name, ast_format_get_name(instance->native_format),
ast_format_get_sample_rate(instance->native_format),
ast_format_get_default_ms(instance->native_format),
ast_format_get_minimum_ms(instance->native_format),
ast_format_get_minimum_bytes(instance->native_format),
instance->passthrough,
instance->optimal_frame_size);
/* We have exclusive access to proxy and sorcery, no need for locking here. */
if (ao2_weakproxy_set_object(proxy, instance, OBJ_NOLOCK)) {
return NULL;
@@ -1195,12 +1274,14 @@ enum {
OPT_WS_CODEC = (1 << 0),
OPT_WS_NO_AUTO_ANSWER = (1 << 1),
OPT_WS_URI_PARAM = (1 << 2),
OPT_WS_PASSTHROUGH = (1 << 3),
};
enum {
OPT_ARG_WS_CODEC,
OPT_ARG_WS_NO_AUTO_ANSWER,
OPT_ARG_WS_URI_PARAM,
OPT_ARG_WS_PASSTHROUGH,
OPT_ARG_ARRAY_SIZE
};
@@ -1208,6 +1289,7 @@ AST_APP_OPTIONS(websocket_options, BEGIN_OPTIONS
AST_APP_OPTION_ARG('c', OPT_WS_CODEC, OPT_ARG_WS_CODEC),
AST_APP_OPTION('n', OPT_WS_NO_AUTO_ANSWER),
AST_APP_OPTION_ARG('v', OPT_WS_URI_PARAM, OPT_ARG_WS_URI_PARAM),
AST_APP_OPTION('p', OPT_WS_PASSTHROUGH),
END_OPTIONS );
static struct ast_channel *webchan_request(const char *type,
@@ -1281,6 +1363,9 @@ static struct ast_channel *webchan_request(const char *type,
}
instance->no_auto_answer = ast_test_flag(&opts, OPT_WS_NO_AUTO_ANSWER);
if (!instance->passthrough) {
instance->passthrough = ast_test_flag(&opts, OPT_WS_PASSTHROUGH);
}
if (ast_test_flag(&opts, OPT_WS_URI_PARAM)
&& !ast_strlen_zero(opt_args[OPT_ARG_WS_URI_PARAM])) {

View File

@@ -119,6 +119,11 @@ static int outbound_websocket_apply(const struct ast_sorcery *sorcery, void *obj
ast_debug(3, "%s: Initializing outbound websocket\n", id);
if (!owc->websocket_client) {
ast_log(LOG_WARNING, "%s: Outbound websocket missing websocket_client_id\n", id);
res = -1;
}
if (ast_strlen_zero(owc->apps)) {
ast_log(LOG_WARNING, "%s: Outbound websocket missing apps\n", id);
res = -1;

View File

@@ -3453,7 +3453,7 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz
int res;
#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
char *out = buf;
struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
struct dtls_details *dtls = (!rtcp || rtp->rtcp->type == AST_RTP_INSTANCE_RTCP_MUX) ? &rtp->dtls : &rtp->rtcp->dtls;
/* Don't send RTP if DTLS hasn't finished yet */
if (dtls->ssl && ((*out < 20) || (*out > 63)) && dtls->connection == AST_RTP_DTLS_CONNECTION_NEW) {