When openr2 is installed mfcr2_show_links_of() is no longer ifdeffed out
which makes gcc-16 complain with 'variable ‘x’ set but not used'.
Resolves: #1947
When a PJSIP endpoint is configured with set_var invoking a dialplan
function (e.g. PJSIP_HEADER(add,...)), chan_pjsip_new() calls
pbx_builtin_setvar_helper() while holding the channel lock.
For function-style variables, this dispatches to ast_func_write()
which, in the case of PJSIP_HEADER, calls
ast_sip_push_task_wait_serializer() -- blocking synchronously while
the channel lock is held.
If a concurrent operation (ARI, AMI, rtp_check_timeout) traverses
the channels container via ast_channel_get_by_name(), it acquires
the container lock then tries to lock individual channels in the
iteration callback (by_uniqueid_cb/by_name_cb). When the serializer
thread also needs the container lock, a circular dependency forms:
channel_lock -> serializer_wait -> container_lock -> channel_lock
This causes a complete Asterisk freeze. In the observed case, 36
threads were blocked on the container lock until res_freeze_check
triggered SIGABRT after its 30-second timeout.
Unlock the channel before iterating endpoint channel_vars so that
dialplan functions can block without holding the channel lock. Re-lock
the channel for ast_channel_stage_snapshot_done() so the batched
snapshot is published under lock and captures the full channel state
including the variables set during the loop.
Fixes: #1872
Add a property to the CHANNEL method to retrieve the auth method,
which can be used to retrieve the specific auth method actually
negotiated for a call (e.g. RSA, MD5, etc.).
Also clean up some of the documentation for the secure properties
to clarify how these relate to call encryption.
Resolves: #1878
UserNote: CHANNEL(auth_method) can now be used to retrieve the
auth method negotiated for a call on IAX2 channels.
Commit 2da221e217 added a missing abort
if datalen < 0 check on a code path and an assertion inside
iax_frame_wrap if we ever encountered a frame with a negative frame
length (which will eventually cause a crash).
Add another missing abort check for negative datalen, exposed by this
assertion. (Similar to the previous commit, this is a video frame with
a datalen of -1).
Resolves: #1865
Redirects initiated by 302 response codes weren't handled correctly
when setting the hangup cause code and tech cause code on the responding
channel. They're now set to 23 (REDIRECTED_TO_NEW_DESTINATION) and
302 (Moved permanently). Other non-2XX response codes also had issues.
A new API ast_channel_dialed_causes_iterator() was added to retrieve
the hangup cause codes for a channel.
chan_pjsip_session_end() in chan_pjsip has been refactored to set the
correct cause codes on a channel based on the cause codes added by
chan_pjsip_incoming_response_update_cause(). Copious amounts of
debugging and comments were also added.
Resolves: #1819
The original chan_websocket implementation attempted to improve the
call quality experience by generating silence frames to send to the core
when no media was being read from the websocket and padding frames with
silence when short frames were read from the websocket. Both of these
required switching the formats on the channel to slin for short periods
of time then switching them back to whatever format the websocket channel
was configured for. Unfortunately, the format switching caused issues
when transcoding was required and the transcode_via_sln option was enabled
in asterisk.conf (which it is by default). The switch would cause the
transcoding path to be incorrectly set resulting in malformed RTP packets
being sent back out to the caller on the other end which the caller heard
as loud noise.
After looking through the code and performing multiple listening tests,
the best solution to this problem was to just remove the code that was
attempting to generate the silence. There was no decrease in call quality
whatsoever and the code is a bit simpler. None of the other channel drivers
nor res_rtp_asterisk generate silence frames or pad short frames which
backed up decision.
Resolves: #1785
Currently, WebSockets both accept and send media without the option to
disable one or the other. This commit adds the ability to set the media
direction for a WebSocket, making it unidirectional or bidirectional
(the default). Direction is done from the point of view of the
application, NOT Asterisk. The allowed values are 'both', 'in', and
'out'. If media direction is 'both' (the default), Asterisk accepts and
sends media to the application. If it is 'in', Asterisk will drop any
media received from the application. If it is 'out', Asterisk will not
write any media frames to the application.
UserNote: WebSocket now supports media direction, allowing for
unidirectional media. This is done from the perspective of the
application and can be set via channel origination, external media, or
commands sent from the application. Check out
https://docs.asterisk.org/Configuration/Channel-Drivers/WebSocket/ for
more.
Fix discarded-qualifiers errors to compile successfully with gcc 15.2.1.
Associated changes have also been made to libss7; however, for compatibility
we cast const char* values to char*. In the future, these casts could be
removed.
Resolves: #1786
chan_iax2 has several code paths where a frame's data length
is calculated by subtraction. On some paths, there is a check
for negative length. One of these paths is missing this check,
and on this path, it is possible for the result to be negative,
leading to a crash as a result of memory operations using the
bogus length.
Add a check to capture this off-nominal case. This will log
the appropriate warnings as in other cases and prevent a crash.
Also update the log messages to be clearer.
Resolves: #1707
GCC 15.2.1 pays attention to the discarding of the const
qualifier when strchr, strrchr, memchr, or memrchr are now
used. This change fixes numerous errors with this throughout
the tree. The fixes can be broken down into the following:
1. The return value should be considered const.
2. The value passed to strchr or strrchr can be cast as it is
expected and allowed to be modified.
3. The pointer passed to strchr or strrchr is not meant to be
modified and so the contents must be duplicated.
4. It was declared const and never should have been.
This change adds an API call to allow direct access to the latest
snapshot of an ast_endpoint. This is then used by chan_pjsip when
calculating device state, eliminating the need to access the cache
which would incur a container find and access.
When chan_websocket received a Ping or a Pong opcode it would cause the channel to hangup. This change allows Ping/Pong opcodes and allows them to silently pass
From the original report* on ASTERISK-24915:
> The problem occurs because the handle_incoming function updates
p->method to req->method (p being a struct sip_pvt *) before
checking if the CSeq makes sense, and if the CSeq is unexpected, it
does not reset p->method to its old value before returning. Then,
when asterisk sends the 200 OK response for the original INVITE,
since p->method is now equal to SIP_ACK (instead of SIP_INVITE), the
resp_need_contact function (called from respprep) says "its a SIP
ACK, no need to add a Contact header for the response", which is
wrong, since it's not a SIP ACK but a SIP INVITE dialog.
I have confirmed that the analysis is correct and that the patch fixes
the behavior.
*: https://issues-archive.asterisk.org/ASTERISK-24915Resolves: #1711
We now add the websocket's file descriptor to the channel's fd array and let
it poll for data availability instead if having a dedicated thread that
does the polling. This eliminates the thread and allows removal of most
explicit locking since the core channel code will lock the channel to prevent
simultaneous calls to webchan_read, webchan_hangup, etc.
While we were here, the hangup code was refactored to use ast_hangup_with_cause
instead of directly queueing an AST_CONTROL_HANGUP frame. This allows us
to set hangup causes and generate snapshots.
For a bit of extra debugging, a table of websocket close codes was added
to http_websocket.h with an accompanying "to string" function added to
res_http_websocket.c
Resolves: #1683
This change moves the PJSIP module from the threadpool API
to the taskpool API. PJSIP-specific implementations for
task usage have been removed and replaced with calls to
the optimized taskpool implementations instead. The need
for a pool of serializers has also been removed as
taskpool inherently provides this. The default settings
have also been changed to be more realistic for common
usage.
UpgradeNote: The threadpool_* options in pjsip.conf have now
been deprecated though they continue to be read and used.
They have been replaced with taskpool options that give greater
control over the underlying taskpool used for PJSIP. An alembic
upgrade script has been added to add these options to realtime
as well.
On an outbound websocket connection, when the triggering caller hangs up,
webchan_hangup() closes the outbound websocket session and sets the websocket
session handle to NULL. If the hangup happened in the tiny window between
opening the outbound websocket connection and before read_thread_handler()
was able to send the MEDIA_START message, it could segfault because the
websocket session handle was NULL. If it didn't actually segfault, there was
also the possibility that the websocket instance wouldn't get cleaned up which
could also cause the channel snapshot to not get cleaned up. That could
cause memory leaks and `core show channels` to list phantom WebSocket
channels.
To prevent the race, the send_event() macro now locks the websocket_pvt
instance and checks the websocket session handle before attempting to send
the MEDIA_START message.
Resolves: #1643Resolves: #1645
Currently, if chan_websocket receives an un supported frame like comfort noise it will exit the websocket. The proposed change is to tolerate the other frames by not sending them down the websocket but instead just ignoring them.
Resolves: #1587
Also cleaned up a few unused #if blocks, and started sending a few ERROR
events back to the apps.
Resolves: #1574
DeveloperNote: Apps can now send a `MARK_MEDIA` command with an optional
`correlation_id` parameter to chan_websocket which will be placed in the
media frame queue. When that frame is dequeued after all intervening media
has been played to the core, chan_websocket will send a
`MEDIA_MARK_PROCESSED` event to the app with the same correlation_id
(if any).
With recent enhancements to chan_websocket, the original plain-text
implementation of control messages and events is now too limiting. We
probably should have used JSON initially but better late than never. Going
forward, enhancements that require control message or event changes will
only be done to the JSON variants and the plain-text variants are now
deprecated but not yet removed.
* Added the chan_websocket.conf config file that allows setting which control
message format to use globally: "json" or "plain-text". "plain-text" is the
default for now to preserve existing behavior.
* Added a dialstring option `f(json|plain-text)` to allow the format to be
overridden on a call-by-call basis. Again, 'plain-text' is the default for
now to preserve existing behavior.
The JSON for commands sent by the app to Asterisk must be...
`{ "command": "<command>" ... }` where `<command>` is one of `ANSWER`, `HANGUP`,
`START_MEDIA_BUFFERING`, etc. The `STOP_MEDIA_BUFFERING` command takes an
additional, optional parameter to be returned in the corresponding
`MEDIA_BUFFERING_COMPLETED` event:
`{ "command": "STOP_MEDIA_BUFFERING", "correlation_id": "<correlation id>" }`.
The JSON for events sent from Asterisk to the app will be...
`{ "event": "<event>", "channel_id": "<channel_id>" ... }`.
The `MEDIA_START` event will now look like...
```
{
"event": "MEDIA_START",
"connection_id": "media_connection1",
"channel": "WebSocket/media_connection1/0x5140001a0040",
"channel_id": "1761245643.1",
"format": "ulaw",
"optimal_frame_size": 160,
"ptime": 20,
"channel_variables": {
"DIALEDPEERNUMBER": "media_connection1/c(ulaw)",
"MEDIA_WEBSOCKET_CONNECTION_ID": "media_connection1",
"MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE": "160"
}
}
```
Note the addition of the channel variables which can't be supported
with the plain-text formatting.
The documentation will be updated with the exact formats for all commands
and events.
Resolves: #1546Resolves: #1563
DeveloperNote: The chan_websocket plain-text control and event messages are now
deprecated (but remain the default) in favor of JSON formatted messages.
See https://docs.asterisk.org/Configuration/Channel-Drivers/WebSocket for
more information.
DeveloperNote: A "transport_data" parameter has been added to the
channels/externalMedia ARI endpoint which, for websocket, allows the caller
to specify parameters to be added to the dialstring for the channel. For
instance, `"transport_data": "f(json)"`.
Commit b333ee3b introduced a fix to chan_pjsip that addressed RTP issues with
blind transfers and some SBCs. Unfortunately, the fix broke some WebRTC
clients that are sensitive to SSRC changes and non-monotonic timestamps so
the fix is now disabled for endpoints with the "bundle" parameter set to true.
Resolves: #1535
This change moves the PJSIP module from the threadpool API
to the taskpool API. PJSIP-specific implementations for
task usage have been removed and replaced with calls to
the optimized taskpool implementations instead. The need
for a pool of serializers has also been removed as
taskpool inherently provides this. The default settings
have also been changed to be more realistic for common
usage.
UpgradeNote: The threadpool_* options in pjsip.conf have now
been deprecated though they continue to be read and used.
They have been replaced with taskpool options that give greater
control over the underlying taskpool used for PJSIP. An alembic
upgrade script has been added to add these options to realtime
as well.
Although the ISDN/Q.850/Q.931 hangup cause code is already part of the ARI
and AMI hangup and channel destroyed events, it can be helpful to know what
the actual channel technology code was if the call was unsuccessful.
For PJSIP, it's the SIP response code.
* A new "tech_hangupcause" field was added to the ast_channel structure along
with ast_channel_tech_hangupcause() and ast_channel_tech_hangupcause_set()
functions. It should only be set for off-nominal terminations.
* chan_pjsip was modified to set the tech hangup cause in the
chan_pjsip_hangup() and chan_pjsip_session_end() functions. This is a bit
tricky because these two functions aren't always called in the same order.
The channel that hangs up first will get chan_pjsip_session_end() called
first which will trigger the core to call chan_pjsip_hangup() on itself,
then call chan_pjsip_hangup() on the other channel. The other channel's
chan_pjsip_session_end() function will get called last. Unfortunately,
the other channel's HangupRequest events are sent before chan_pjsip has had a
chance to set the tech hangupcause code so the HangupRequest events for that
channel won't have the cause code set. The ChannelDestroyed and Hangup
events however will have the code set for both channels.
* A new "tech_cause" field was added to the ast_channel_snapshot_hangup
structure. This is a public structure so a bit of refactoring was needed to
preserve ABI compatibility.
* The ARI ChannelHangupRequest and ChannelDestroyed events were modified to
include the "tech_cause" parameter in the JSON for off-nominal terminations.
The parameter is suppressed for nominal termination.
* The AMI SoftHangupRequest, HangupRequest and Hangup events were modified to
include the "TechCause" parameter for off-nominal terminations. Like their ARI
counterparts, the parameter is suppressed for nominal termination.
DeveloperNote: A "tech_cause" parameter has been added to the
ChannelHangupRequest and ChannelDestroyed ARI event messages and a "TechCause"
parameter has been added to the HangupRequest, SoftHangupRequest and Hangup
AMI event messages. For chan_pjsip, these will be set to the last SIP
response status code for off-nominally terminated calls. The parameter is
suppressed for nominal termination.
It is customary to allow # to terminate digit collection immediately
when there would normally be a timeout. However, currently, users are
forced to wait for the timeout to expire when dialing numbers that
are prefixes of other valid matches, and there is no way to end the
timeout early. Customarily, # terminates the timeout, but at the moment,
this is just rejected unless there happens to be a matching extension
ending in #.
Allow # to terminate the timeout in cases where there is no dialplan
match. This ensures that the dialplan is always respected, but if a
valid extension has been dialed that happens to prefix other valid
matches, # can be used to dial it immediately.
Resolves: #1510
If Last Number Redial is used to redial, ensure that we do not wait
for further digits. This was possible if the number that was last
dialed is a prefix of another possible dialplan match. Since all we
did is copy the number into the extension buffer, if other matches
are now possible, there would thus be a timeout before the call went
through. We now complete redialed calls immediaetly in all cases.
Resolves: #1483
* 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
Add a dialplan function that can be used to get/set properties of
DAHDI channels (as opposed to Asterisk channels). This exposes
properties that were not previously available, allowing for certain
operations to now be performed in the dialplan.
Resolves: #1455
UserNote: The DAHDI_CHANNEL function allows for getting/setting
certain properties about DAHDI channels from the dialplan.
If Caller ID is disabled for an FXS port, then we should not send any
Caller ID spill on the line, as we have no Caller ID information that
we can/should be sending.
Resolves: #1394
It is possible to modify the dialmode setting in the chan_dahdi/sig_analog
private using the CHANNEL function, to modify it during calls. However,
it was not being reset between calls, meaning that if, for example, tone
dialing was disabled, it would never work again unless explicitly enabled.
This fixes the setting by pairing it with a "perm" version of the setting,
as a few other features have, so that it can be reset to the permanent
setting between calls. The documentation is also clarified to explain
the interaction of this setting and the digitdetect setting more clearly.
Resolves: #1378
* Added a new option to the WebSocket dial string to capture the additional
URI parameters.
* Added a new API ast_uri_verify_encoded() that verifies that a string
either doesn't need URI encoding or that it has already been encoded.
* Added a new API ast_websocket_client_add_uri_params() to add the params
to the client websocket session.
* Added XML documentation that will show up with `core show application Dial`
that shows how to use it.
Resolves: #1352
UserNote: A new WebSocket channel driver option `v` has been added to the
Dial application that allows you to specify additional URI parameters on
outgoing connections. Run `core show application Dial` from the Asterisk CLI
to see how to use it.
ast_websocket_read() receives data into a fixed 64K buffer then continually
reallocates a final buffer that, after all continuation frames have been
received, is the exact length of the data received and returns that to the
caller. process_text_message() in chan_websocket was attempting to set a
NULL terminator on the received payload assuming the payload buffer it
received was the large 64K buffer. The assumption was incorrect so when it
tried to set a NULL terminator on the payload, it could, depending on the
state of the heap at the time, cause heap corruption.
process_text_message() now allocates its own payload_len + 1 sized buffer,
copies the payload received from ast_websocket_read() into it then NULL
terminates it prevent the possibility of the overrun and corruption.
Resolves: #1384
Previously, we were only using # (ST) as a terminator, and not handling
A (STP), B (ST2P), or C (ST3P), which erroneously led to it being
treated as part of the dialed number. Parse any of these as the start
digit.
Resolves: #1301
In the WebSocket channel driver, the FLUSH_MEDIA command clears all frames from
the queue but does not reset the frame_queue_length counter.
As a result, the driver incorrectly thinks the queue is full after flushing,
which prevents new multimedia frames from being sent, especially after multiple
flush commands.
This fix sets frame_queue_length to 0 after flushing, ensuring the queue state
is consistent with its actual content.
Fixes: #1304
When the RTP media source changes, such as after a blind transfer, the new source introduces a discontinuous timestamp. According to RFC 3550, Section 5.1, an RTP stream's timestamp for a given SSRC must increment monotonically and linearly.
To comply with the standard and avoid a large timestamp jump on the existing SSRC, a new SSRC is generated for the new media stream.
This change resolves known interoperability issues with certain SBCs (like Sonus/Ribbon) that stop forwarding media when they detect such a timestamp violation. This code uses the existing implementation from chan_sip.
Resolves: #927
* Created chan_websocket which can exchange media over both inbound and
outbound websockets which the driver will frame and time.
See http://s.asterisk.net/mow for more information.
* res_http_websocket: Made defines for max message size public and converted
a few nuisance verbose messages to debugs.
* main/channel.c: Changed an obsolete nuisance error to a debug.
* ARI channels: Updated externalMedia to include chan_websocket as a supported
transport.
UserNote: A new channel driver "chan_websocket" is now available. It can
exchange media over both inbound and outbound websockets and will both frame
and re-time the media it receives.
See http://s.asterisk.net/mow for more information.
UserNote: The ARI channels/externalMedia API now includes support for the
WebSocket transport provided by chan_websocket.
When a call is transfered via DTMF feature code, the Transfer Target and
Transferer are bridged immediately. This opens the possibilty of a race
condition between the creation of an INVITE and the bridge induced colp
update that can result in the set caller ID being over-written with the
transferer's default info.
Fixes: #1234
Adds support for Call Waiting Deluxe options to enhance
the current call waiting feature.
As part of this change, a mechanism is also added that
allows a channel driver to queue an audio file for Dial()
to play, which is necessary for the announcement function.
ASTERISK-30373 #close
Resolves: #271
UserNote: Call Waiting Deluxe can now be enabled for FXS channels
by enabling its corresponding option.
* Update Dial() documentation for IAX2 to include syntax for RSA
public key names.
* Add additional details to a couple warnings to provide more context
when an undecodable frame is received.
Resolves: #1206
Updated the AudioSocket protocol to allow sending DTMF frames.
AST_FRAME_DTMF frames are now forwarded to the server, in addition to
AST_FRAME_AUDIO frames. A new payload type AST_AUDIOSOCKET_KIND_DTMF
with value 0x03 was added to the protocol. The payload is a 1-byte
ascii representing the DTMF digit (0-9,*,#...).
UserNote: The AudioSocket protocol now forwards DTMF frames with
payload type 0x03. The payload is a 1-byte ascii representing the DTMF
digit (0-9,*,#...).
- Correct wait timeout logic in the dialplan application.
- Include server address in log messages for better traceability.
- Allow dialplan app to exit gracefully on hangup messages and socket closure.
- Optimize I/O by reducing redundant read()/write() operations.
Co-authored-by: Florent CHAUVEAU <florentch@pm.me>