When a frame is provided to ast_write ensure that a multistream
capable channel has a stream for it before attempting to give it
to the channel driver. In some cases (such as a deferred SDP
negotiation) the stream may not yet exist.
ASTERISK-27364
Change-Id: Icf84ca982a67cdd6e9a71851eb7eb1bd0e865276
Some endpoints do not like a stream being reused for a new
media stream. The frame/jitterbuffer can rely on underlying
attributes of the media stream in order to order the packets.
When a new stream takes its place without any notice the
buffer can get confused and the media ends up getting dropped.
This change uses the SSRC change to determine that a new source
is reusing an existing stream and then bridge_softmix renegotiates
each participant such that they see a new media stream. This
causes the frame/jitterbuffer to start fresh and work as expected.
ASTERISK-27277
Change-Id: I30ccbdba16ca073d7f31e0e59ab778c153afae07
* ast_channel_request_stream_topology_change() must not be called with any
channel locks held.
* ast_channel_stream_topology_changed() must be called with only the
passed channel lock held.
ASTERISK-27212
Change-Id: I843de7956d9f1cc7cc02025aea3463d8fe19c691
joint_cap needs to be released unconditionally as chan->tech->requester
does not steal the reference even on success.
ASTERISK-27180 #close
Change-Id: I647728992559bdb0a9c7357c20be1b36400d68b6
This adds a parameter to ast_waitfordigit_full which can be used to only
stop waiting when certain expected digits are received. Any unexpected
DTMF digits are simply ignored.
This also creates a new dialplan application WaitDigit.
ASTERISK-27129 #close
Change-Id: Id233935ea3d13e71c75a0861834c5936c3700ef9
This change fixes a few things uncovered during SFU testing.
1. Unreal channels incorrectly forwarded video frames when
no video stream was present on them. This caused a crash when
they were read as the core requires a stream to exist for the
underlying media type. The Unreal channel will now ensure a
stream exists for the media type before forwarding the frame
and if no stream exists then the frame is dropped.
2. Mapping of frames during bridging from the stream number of
the underlying channel to the stream number of the bridge was
done in the wrong location. This resulted in the frame getting
dropped. This mapping now occurs on reading of the frame from
the channel.
3. Bridging was using the wrong ast_read function resulting in
it living in a non-multistream world.
4. In bridge_softmix when adding new streams to existing channels
the wrong stream topology was copied resulting in no streams
being added.
Change-Id: Ib7445722c3219951d6740802a0feddf2908c18c8
This API was not actively maintained, was not added to new modules
(such as res_pjsip), and there exist better alternatives to acquire the
same information, such as the ARI.
Change-Id: I4b2185a83aeb74798b4ad43ff8f89f971096aa83
Clear channel flag AST_FLAG_END_DTMF_ONLY in ast_waitfordigit_full when
ast_read returns NULL.
ASTERISK-27100 #close
Change-Id: Id3039e9a4e74e0cb359f636c9fd0c9740ebf7d9d
The stream topology (list of streams and order) is now stored with the
configured PJSIP endpoints and used during the negotiation process.
Media negotiation state information has been changed to be stored
in a separate object. Two of these objects exist at any one time
on a session. The active media state information is what was previously
negotiated and the pending media state information is what the
media state will become if negotiation succeeds. Streams and other
state information is stored in this object using the index (or
position) of each individual stream for easy lookup.
The ability for a media type handler to specify a callback for
writing has been added as well as the ability to add file
descriptors with a callback which is invoked when data is available
to be read on them. This allows media logic to live outside of
the chan_pjsip module.
Direct media has been changed so that only the first audio and
video stream are directly connected. In the future once the RTP
engine glue API has been updated to know about streams each individual
stream can be directly connected as appropriate.
Media negotiation itself will currently answer all the provided streams
on an offer within configured limits and on an offer will use the
topology created as a result of the disallow/allow codec lines.
If a stream has been removed or declined we will now mark it as such
within the resulting SDP.
Applications can now also request that the stream topology change.
If we are told to do so we will limit any provided formats to the ones
configured on the endpoint and send a re-invite with the new topology.
Two new configuration options have also been added to PJSIP endpoints:
max_audio_streams: determines the maximum number of audio streams to
offer/accept from an endpoint. Defaults to 1.
max_video_streams: determines the maximum number of video streams to
offer/accept from an endpoint. Defaults to 1.
ASTERISK-27076
Change-Id: I8afd8dd2eb538806a39b887af0abd046266e14c7
When a stasis channel is stolen by another app, the control
structure is unreffed but never unlinked from the app_controls
container. This causes the channel reference to leak.
Added OBJ_UNLINK to the callback in channel_stolen_cb.
Also added some additional channel lifecycle debug messages to
channel.c.
ASTERISK-27059 #close
Repoorted-by: George Joseph
Change-Id: Ib820936cd49453f20156971785e7f4f182c56e14
The ast_channel_suppress function wrongly decremented the
reference count of the underlying structure used to keep
track of what should be suppressed on a channel if the
function was called multiple times on the same channel.
This change cleans up the reference counting a bit so
this no longer occurs.
ASTERISK-27016
Change-Id: I2eed4077cb4916e6626f9f120b63b963acc5c136
ASTERISK-26419 introduced a bug when calling ast_audiohook_write_list in
ast_write. It would free the frame given to ast_write if the frame returned
by ast_audiohook_write_list was different than the given one. The frame give
to ast_write should never be freed within that function. It is the caller's
resposibility to free the frame after writing (or when it its done with it).
By freeing it within ast_write this of course led to some memory corruption
problems.
This patch makes it so the frame given to ast_write is no longer freed within
the function. The frame returned by ast_audiohook_write_list is now subsequently
used in ast_write and is freed later. It is freed either after translate if the
frame returned by translate is different, or near the end of ast_write prior to
function exit.
ASTERISK-26973 #close
Change-Id: Ic9085ba5f555eeed12f6e565a638c3649695988b
When manipulating flags on a channel the channel has to be
locked to guarantee that nothing else is also manipulating
the flags. This change introduces locking where necessary to
guarantee this. It also adds helper functions that manipulate
channel flags and lock to reduce repeated code.
ASTERISK-26789
Change-Id: I489280662dba0f4c50981bfc5b5a7073fef2db10
When using the Bridge AMI action on the same channel multiple times
it was possible for the channel to return to the wrong location in
the dialplan if the other party hung up. This happened because the
priority of the channel was not preserved across each action
invocation and it would fail to move on to the next priority in
other cases.
This change makes it so that the priority of a channel is preserved
when taking control of it from another thread and it is incremented
as appropriate such that the priority reflects where the channel
should next be executed in the dialplan, not where it may or may not
currently be.
The Bridge AMI action was also changed to ensure that it too
starts the channels at the next location in the dialplan.
ASTERISK-24529
Change-Id: I52406669cf64208aef7252a65b63ade31fbf7a5a
This patch is the first cut at adding stream support to the bridging framework.
Changes were made to the framework that allows mapping of stream topologies to
a bridge's supported media types.
The first channel to enter a bridge initially defines the media types for a
bridge (i.e. a one to one mapping is created between the bridge and the first
channel). Subsequently added channels merge their media types into the bridge's
adding to it when necessary. This allows channels with different sized
topologies to map correctly to each other according to media type. The bridge
drops any frame that does not have a matching index into a given write stream.
For now though, bridge_simple will align its two channels according to size or
first to join. Once both channels join the bridge the one with the most streams
will indicate to the other channel to update its streams to be the same as that
of the other. If both channels have the same number of streams then the first
channel to join is chosen as the stream base.
A topology change source was also added to a channel when a stream toplogy
change request is made. This allows subsystems to know whether or not they
initiated a change request. Thus avoiding potential recursive situations.
ASTERISK-26966 #close
Change-Id: I1eb5987921dd80c3cdcf52accc136393ca2d4163
This change extends the ast_request functionality by adding another
function and callback to create an outgoing channel with a requested
stream topology. Fallback is provided by either converting the
requested stream topology into a format capabilities structure if
the channel driver does not support streams or by converting the
requested format capabilities into a stream topology if the channel
driver does support streams.
The Dial application has also been updated to request an outgoing
channel with the stream topology of the calling channel.
ASTERISK-26959
Change-Id: Ifa9037a672ac21d42dd7125aa09816dc879a70e6
This change removes the old epoll support which has not been used or
maintained in quite some time.
The fixed number of file descriptors on a channel has also been removed.
File descriptors are now contained in a growable vector. This can be
used like before by specifying a specific position to store a file
descriptor at or using a new API call, ast_channel_fd_add, which adds
a file descriptor to the channel and returns its position.
Tests have been added which cover the growing behavior of the vector
and the new API call.
ASTERISK-26885
Change-Id: I1a754b506c009b83dfdeeb08c2d2815db30ef928
This change adds a few things to facilitate stream topology changing:
1. Control frame types have been added for use by the channel driver
to notify the application that the channel wants to change the stream
topology or that a stream topology change has been accepted. They are
also used by the indicate interface to the channel that the application
uses to indicate it wants to do the same.
2. Legacy behavior has been adopted in ast_read() such that if a
channel requests a stream topology change it is denied automatically
and the current stream topology is preserved if the application is
not capable of handling streams.
Tests have also been written which confirm the multistream and
non-multistream behavior.
ASTERISK-26839
Change-Id: Ia68ef22bca8e8457265ca4f0f9de600cbcc10bc9
* Removed the AST_CHAN_TP_MULTISTREAM tech property. We now rely
on read_stream being set to indicate a multi stream channel.
* Added ast_channel_is_multistream convenience function.
* Fixed issue where stream and default_stream weren't being set on
a frame retrieved from the queue.
* Now testing for NULL being returned from the driver's read or
read_stream callback.
* Fixed issue where the dropnondefault code was crashing on a
NULL f.
* Now enforcing that if either read_stream or write_stream are
set when ast_channel_tech_set is called that BOTH are set.
* Added the unit tests.
ASTERISK-26816
Change-Id: If7792b20d782e71e823dabd3124572cf0a4caab2
This change introduces an ast_read_stream function and callback in
the channel technology which allows reading frames from all streams
and not just the default streams.
The stream number has also been added to frames. This is to allow the
case where frames are queued onto the channel instead of being read
directly from the driver.
This change does impose a restriction on reading though: a chain of
frames can only contain frames from the same stream.
ASTERISK-26816
Change-Id: I5d7dc35e86694df91fd025126f6cfe0453aa38ce
This change adds an ast_write_stream function which allows
writing a frame to a specific media stream. It also moves
ast_write() to using this underneath by writing media
frames provided to it to the default streams of the channel.
Existing functionality (such as audiohooks, framehooks, etc)
are limited to being applied to the default stream only.
Unit tests have also been added which test the behavior of
both non-multistream and multistream channels to confirm that
the write() and write_stream() callbacks are invoked
appropriately.
ASTERISK-26793
Change-Id: I4df20d1b65bd4d787fce0b4b478e19d2dfea245c
The ast_waitfor_nandfds operation will manipulate the flags
of channels passed in. This was previously done without
the channel lock being held. This could result in incorrect
values existing for the flags if another thread manipulated
the flags at the same time.
This change locks the channel during flag manipulation.
ASTERISK-26788
Change-Id: I2c5c8edec17c9bdad4a93291576838cb552ca5ed
We shouldn't unlock the channel after starting a snapshot staging because
another thread may interfere and do its own snapshot staging.
* app_dial.c:dial_exec_full() made hold the channel lock while setting up
the outgoing channel staging. Made hold the channel lock after the called
party answers while updating the caller channel staging.
* chan_sip.c:sip_new() completed the channel staging on off-nominal exit.
Also we need to use ast_hangup() instead of ast_channel_unref() at that
location.
* channel.c:__ast_channel_alloc_ap() added a comment about not needing to
complete the channel snapshot staging on off-nominal exit paths.
* rtp_engine.c:ast_rtp_instance_set_stats_vars() made hold the channel
locks while staging the channels for the stats channel variables.
Change-Id: Iefb6336893163f6447bad65568722ad5d5d8212a
Using the timerfd timing module can cause channel freezing, lingering, or
deadlock issues. The problem is because this is the only timing module
that uses an associated alert-pipe. When the alert-pipe becomes
unbalanced with respect to the number of frames in the read queue bad
things can happen. If the alert-pipe has fewer alerts queued than the
read queue then nothing might wake up the thread to handle received frames
from the channel driver. For local channels this is the only way to wake
up the thread to handle received frames. Being unbalanced in the other
direction is less of an issue as it will cause unnecessary reads into the
channel driver.
ASTERISK-26716 is an example of this deadlock which was indirectly fixed
by the change that found the need for this patch.
* In channel.c:__ast_queue_frame(): Adding frame lists to the read queue
did not add the same number of alerts to the alert-pipe. Correspondingly,
when there is an exceptionally long queue event, any removed frames did
not also remove the corresponding number of alerts from the alert-pipe.
ASTERISK-26632 #close
Change-Id: Ia98137c5bf6e9d6d202ce0eb36441851875863f6
A dialplan intercept routine is equivalent to an interrupt routine. As
such, the routine must be done quickly and you do not have access to the
media stream. These restrictions are necessary because the media stream
is the responsibility of some other code and interfering with or delaying
that processing is bad. A possible future dialplan processing
architecture change may allow the interception routine to run in a
different thread from the main thread handling the media and remove the
execution time restriction.
* Made res_agi.c:run_agi() running an AGI in an interception routine run
in DeadAGI mode. No touchy channel frames.
ASTERISK-25951
ASTERISK-26343
ASTERISK-26716
Change-Id: I638f147ca7a7f2590d7194a8ef4090eb191e4e43
There are several issues with deferring frames that are caused by the
refactoring.
1) The code deferring frames mishandles adding a deferred frame to the
deferred queue. As a result the deferred queue can only be one frame
long.
2) Deferrable frames can come directly from the channel driver as well as
the read queue. These frames need to be added to the deferred queue.
3) Whoever is deferring frames is really only doing the __ast_read() to
collect deferred frames and doesn't care about the returned frames except
to detect a hangup event. When frame deferral is completed we must make
the normal frame processing see the hangup as a frame anyway. As such,
there is no need to have varying hangup frame deferral methods. We also
need to be aware of the AST_SOFTHANGUP_ASYNCGOTO hangup that isn't real.
That fake hangup is to cause the PBX thread to break out of loops to go
execute a new dialplan location.
4) To properly deal with deferrable frames from the channel driver as
pointed out by (2) above, means that it is possible to process a dialplan
interception routine while frames are deferred because of the
AST_CONTROL_READ_ACTION control frame. Deferring frames is not
implemented as a re-entrant operation so you could have the unsupported
case of two sections of code thinking they have control of the media
stream.
A worse problem is because of the bad implementation of the AMI PlayDTMF
action. It can cause two threads to be deferring frames on the same
channel at the same time. (ASTERISK_25940)
* Rather than fix all these problems simply revert the API refactoring as
there is going to be only autoservice and safe_sleep deferring frames
anyway.
ASTERISK-26343
ASTERISK-26716 #close
Change-Id: I45069c779aa3a35b6c863f65245a6df2c7865496
* channel.c:ast_sendtext(): Fix T.140 SendText memory leak.
* format_compatibility.c: T.140 RED and T.140 were swapped.
* res_rtp_asterisk.c:rtp_red_init(): Fix ast_format_t140_red ref leak.
* res_rtp_asterisk.c:rtp_red_init(): Fix data race after starting periodic
scheduled red_write().
* res_rtp_asterisk.c: Some other minor misc tweaks.
Change-Id: Ifa27a2e0f8a966b1cf628607c86fc4374b0b88cb
This change adds experimental support for providing RTCP
feedback information to codec modules so they can dynamically
change themselves based on conditions.
ASTERISK-26584
Change-Id: Ifd6aa77fb4a7ff546c6025900fc2baf332c31857
It was possible for a frame to be re-inserted into a jitter buffer after it
had been removed from it. A case when this happened was if a frame was read
out of the jitterbuffer, passed to the translation core, and then multiple
frames were returned from said translation core. Upon multiple frames being
returned the first is passed on, but sebsequently "chained" frames are put
back into the read queue. Thus it was possible for a frame to go back into
the jitter buffer where this would cause problems.
This patch adds a flag to frames that are inserted into the channel's read
queue after translation. The abstract jitter buffer code then checks for this
flag and ignores any frames marked as such.
Change-Id: I276c44edc9dcff61e606242f71274265c7779587
The recent change that made frame deferral into an API had a behavior
change to it. When frame deferral was completed, we would take all of
the deferred frames and queue them all onto the channel in one call to
ast_queue_frame_head(). Before frame deferral was API-ized, places that
performed manual frame deferral would actually take each deferred frame
and queue them onto the channel.
This change in behavior caused the confbridge_recording test to start
failing consistently. Without going too crazily deep into the details,
a channel was getting "stuck" in an ast_safe_sleep(). An AMI redirect
was attempting to break it out of the sleep, but because there were more
frames in the channel read queue than expected, the channel ended up
being unable to break from its sleep loop.
By restoring the behavior of individual frame queuing after deferral,
the test starts passing again.
Note, this points to a potential underlying issue pointing to an
"unbalance" that can occur when queuing multiple frames at once,
and so a follow-up issue is being created to investigate that
possibility.
Change-Id: Ied5dacacda06d343dea751ed5814a03364fe5a7d
The sending codec is switched to the receiving codec and then
is switched back to the best native codec on EVERY receiving RTP packets.
This is because after call of ast_channel_set_rawwriteformat there is call
of ast_set_write_format which calls set_format which sets rawwriteformat
to the best native format.
This patch adds a new function ast_set_write_format_path which set
specific write path on channel and uses this function to switch
the sending codec.
ASTERISK-26603 #close
Change-Id: I5b7d098f8b254ce8f45546e6c36e5d324737f71d
This works the same as for AMI manager variables. Set
"channelvars=foo,bar" in your ari.conf general section, and then the
channel variables "foo" and "bar" (along with their values), will
appear in every Stasis websocket channel event.
ASTERISK-26492 #close
patches:
ari_vars.diff submitted by Mark Michelson
Change-Id: I5609ba239259577c0948645df776d7f3bc864229