If "streams" is given, it contains one entry per media stream.
Media-specific subscriptions aren't currently supported, so we expect
only one entry per call party, which includes a subscription to all
media streams. Crudely work around this with a feed ID uniqueness test
until proper multi-stream support is available.
Change-Id: Iaf6f8e63fb2dc20880fe807b118cc574942d53eb
We can determine the feed ID from the handle and the API does not
mandate the feed ID to be present.
Change-Id: I25b6c84b7cd8fb816d95db13d30aef41d943cafe
The "configure" message can be used without SDP to update an existing
publisher. In this use case we simply use the "audio" and "video" flags
to update the respective RECV flags of the media streams. This supports
muting and unmuting.
Change-Id: Icc77c4720124616b8b8acae3419d4d3aa200ae81
Put the code to print the details of a publisher into a JSON into a
separate function so that it can be reused.
Change-Id: I6530f2450c971663e4000fcbdc63716f631385c4
Use a callback function to populate the internal JSON fields. This makes
it possible to reuse this function for other, similar notifications.
Change-Id: I0127379b26502d88e9af38cc89f77f6b88358018
We want to send the notification to each publisher's own session, and
not to the session of the originating event.
Change-Id: I46a7c9b6adf796b076da03fac62c77ddc1d2f214
Distinguish between two cases: Sending a message to one particular WS or
HTTP connection directly as a response to a request, and sending an
asynchronous message or event to a session. Introduce
janus_send_json_sync_response() to do the format, and update all event
notifications to use janus_send_json_async().
Change-Id: I3b5a05e8c3c61d046bcaec29006698625a2570fa
We only support websocket-connected Janus sessions for now, and don't
support the HTTP polling mechanism.
Change-Id: Ia4160deeb02db20ed819864fe35f45de14c47ed8
As multiple handles from multiple different sessions can participate in
the same room, we need a way to look up handles from different sessions.
We therefore transfer ownership of all janus_handle objects to global
level. As these are currently not reference-counted, this necessitates
holding the global lock for the entirety of the signalling process.
Change-Id: Ibe27cb28407d1c8d7290faaaf5b6ae7c7f71679a
Janus rooms are not necessarily tied to just a single session. Make it
possible for one room to be used from multiple sessions.
Change-Id: Id35db2ada66a5bf392ce577cb5f2a970ca13b9dc
There's a mixture of RTPengine and RTPEngine, though we lowercase it
entirely most of the time, so let's stick to this and unify its style.
While at it remove the "the" article for rtpengine as well,
where applicable.
Change-Id: Idbad9313499942ad12ade2c9ce76fe3ec4cd2762
If a subscribe answer says that it doesn't want to receive any media
(i.e. `inactive` - `recv` flag unset), clear our corresponding `send`
flag so that we actually don't send media there.
Change-Id: I8862cc6f4121a82c723a8303ba70345d064cd243
... which is the more direct way to copy a bit flag in a mirror fashion,
instead of doing an if/else.
Change-Id: I7283d31f7a44e6bf1ee15ea1c14cb3b8fe0293b9
We're supposed to use the remote password for sending STUN error
responses (same as for sending STUN success responses), not the local
one.
Fixes a bug from 2015.
Closes#1626
Change-Id: I975178405dcd41661bdc5e0c1208295f9db70006
While LWS explicitly allows usage of lws_callback_on_writable() from
other threads, for some reason there is no internal locking in place,
and so a concurrently running lws_service() can interfere with internal
structures, in particular if lws_service() is closing connections at the
same time as lws_callback_on_writable() is invoked.
The suggested approach of using lws_cancel_service() in combination with
the LWS_CALLBACK_EVENT_WAIT_CANCELLED callback and a user-kept queue is
not feasible, as we need to support LWS 2.x, which doesn't have
LWS_CALLBACK_EVENT_WAIT_CANCELLED.
Closes#1624
Change-Id: Ia3ddeda66fd553c87f99404e0816d97ecbd4cdfe
Avoid calling lws_write() from threads other than the service thread, as
this might not be thread-safe. Instead store the values used for the
HTTP response headers in the websocket_output, then trigger a "writable"
callback, and finally do all the lws_write() calls from the service
thread.
Reported in #1624
Change-Id: Ifcb050193044e5543f750a12fb44f5e16d4c0a08
In order to support a per-call toggle for DTMF logging without having
the global config option set, we always open the socket just in case.
Change-Id: Ibb62672afa21e41623e74603214b4d9d8b94443c
Improve an efficiency of the code in terms of not checking anything
inside the function, if the `sdp_manipulation` flags are absent.
Change-Id: I2a5d8cf675a73ec7a2b4af94d5c7fe2f18fc1772
Do not use the `g_queue_is_empty()` to check the emptiness
of the `add_commands_*` GQueue. It's enough to check the pointer
and the first `->head` value.
Change-Id: Ie01f45d5f8bbaa5af3a09594cce145a0e83943c2
Do not proceed to the `g_hash_table_lookup()` if the `attr_name`
is empty.
Additonally: improve slightly the same check for the CMD_SUBST.
Change-Id: I39e34c34b458150ebae38dff5e6a46f6e8f17c66
It substitutes a specified `a=` line taken from the concerned
media attributes list. If such line has been not found,
the attributes list remains untouched.
It subsitutes one attribute at a time, so one attribute into
another attribute.
Change-Id: Ie0a48ba46a1b196fbe33b09dedc40e4498640e34
Since the function has been swapped to the 'bool' return value,
we must comply with it.
media_player.c: In function ‘media_player_read_decoded_packet’:
media_player.c:374:17: warning: ‘return’ with no value,
in function returning non-void
374 | return;
| ^~~~~~
media_player.c:371:13: note: declared here
371 | static bool media_player_read_decoded_packet(struct media_player *mp) {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Change-Id: If4034164de1325b780dcb1792c6a1674ec7b55b4
Track audio writes in the mix buffer to set the `active` flag to true
whenever a write occurs, which makes it possible to create the buffer in
an inactivate state and implicitly set it active on demand.
Handle the mix buffer not returning any data in the RTP sending logic
(which is what happens for an inactive buffer) by simply not sending any
packets.
Change-Id: Iaeb0f6deadb3d90020c8c62872735cc94db80504
Similar to the existing media_player, but instead of simply producing
its own standalone output media stream, the audio_player takes over the
entire media stream flowing to the receiver, including media forwarded
from the opposite side of the call, as well as media produced by the
media_player.
Change-Id: Ic34ecf08fc73b04210cfffb1a7d795b462ece5ea
We use next_run.tv_sec as flag to signal shut down of the media player
timer. Don't even call the run function when the timer has already been
shut down.
Change-Id: I68248ce05e368bd17ed1a6d346f125c035d0da07
Return true/false from media player run functions to signal whether
playback is finished and whether codec handlers should be reset.
Change-Id: Ieb2e0861190ad2851d986bae28becc5548e215ce
Extend __make_transcoder_full with a custom callback function to create
the SSRC handlers.
Functional no-op.
Change-Id: I79cfabf6e9758b105a89908f9023bd773b838d9e
Support creating transcoders with different "packet decoded" callback
functions.
Functional no-op.
Change-Id: I49ba720841161999dc0ae166ea0841dc094e8bc7
Split out the parts of __ssrc_handler_transcode_new that are related to
the decoder only, leaving the encoder-related code in a separate
function. Allow re-use of the decoder setup code.
Functional no-op.
Change-Id: Ifb91c388a872a4ca14c0cc4571f4d0578271407f
A simple circular audio buffer that allows mixing multiple sources of
audio. Sources are tracked by SSRC and all sources are expected to
provide audio in the same format (same clock rate, channels, sample
format).
Only one consumer per buffer is supported, which is expected to retrieve
buffered audio at regular intervals (ptime) and so continuously empty
the buffer.
The first audio source to write into the buffer at the leading edge of
the circular buffer has its audio simply copied into the buffer, with
the leading edge advanced, while other later sources writing into the
buffer mixed into the existing buffered audio at their respective write
positions.
Change-Id: I0f6642b036944508f2a33420359de488ef8b991c
Convenience function to check whether any formats have changed, which
would indicate that a restart of the media player is needed.
Functional no-op.
Change-Id: I2bc9b57b95bb229bc4f8cfc49ca662fa724d3642
In order to improve the efficieny of the code (make lookups
faster) use GQueues for CMD_ADD manipulations and
GHashTable for CMD_REM manipulations.
This gives the following benefits:
- faster lookup (check), if any SDP command is to be applied
(no need to iterate through all values of commands, as it used to be)
- keep a sequence for CMD_ADD values given by option flag(s)
In order to keep the code more lightweight and clear,
add a separate struct ptr to queues and hash tables into
the call_interfaces header.
Change-Id: I7e45aca4062750c7b8959473edb410ed76cc04e7
Don't change to a new port for sendonly streams as this causes problems
with NAT. A device receiving a sendonly SDP with a new port won't send
any RTP to the new port, leading to a closed (non existent) NAT mapping.
Change-Id: I2ea2163eb9f1203226bd781b53f421c790a86f0a
The old port latching logic was simply to use the last (newest)
allocated endpoint_map. This turned out to be wrong, because the last
used socket on the monologue could have been one that was allocated
earlier (and older endpoint_map), as it can happen during repeated
re-invites. Add a new function to actually look for the correct
endpoint_map, matching the currently used socket, to make sure the port
doesn't change.
Change-Id: Iae768fe48539264575aed67cbbb6b08ac745130f
New section of option flags has been introduced for SDP body
attributes manipulations.
Three levels of the SDP session are concerned:
- session level (global one)
- media level - audio
- media level - video
Three different actions are supported for now:
- add
- remove
The value of the command has a wildcard matching approach.
Other attributes apart `a=` can not be edited by this functionality.
So such headers as: `c=`, `s=`, `o=` cannot be touched.
Change-Id: I939d4582839096b2399f7ded865e91ff6eb960a4
(cherry picked from commit 3f06c18793fe95e5b070044a0291a3e1528ac6e4)
Because of the repeating code snippets, which insert attributes
into the SDP chop->output GString, it's just better to introduce
a separate function for that.
This will give one additional advantage — there will be only one
place, where we can control (for example, depending on manipulation
rules) whether to print this attribute or not.
Change-Id: I1b12f2dd2fda8475a783352678ac939267b64080
To better organizea code and not duplicate same functionality
in the future, it's better to handle an insertion of
the sdp_attribute object using a dedicated hanlder.
New handler:
attr_insert(struct sdp_attributes *attrs, struct sdp_attribute *attr)
Change-Id: I24236d81257b95ef98e0886d3ba362cc1e50dfbe
Defined in RFC 8842. If a tls-id was previously given and a the new SDP
shows a different tls-id or none at all, we must restart DTLS.
Relevant to #1585
Change-Id: I554234dfcacbd330c7a0c6aea68f24d0449cba21
Only parse out a codec type if the codec is given with any parameters
set (and not just by name). Parsing out a codec type when just its name
is given leads to a codec type with default parameters set (such as the
number of channels) which can lead to a stricter matching than desired.
When a codec is given just by name we want to match all codecs of that
type, not just the ones with the same parameters as the default ones.
Change-Id: I583bf4045dbd55291d8dc596310730024853d386
There's no point in sampling Graphite-specific stats, nor in reporting
them out, if Graphite is not enabled.
Change-Id: If8014513832485f38d81b478c695391129c21dff
Distinguish between two different types of "gauge" type metrics: Actual
gauges which (at least conceptually) have a single continuous value, and
metrics which are comprised of discretely sampled values, possibly from
multiple sources.
Real gauges with continuous values don't have mean/average/deviation
values directly associated with them, as calculating these requires
sampling or some other analysis.
Sampled metrics on the other hand do have these associated values.
Clarify which function does what and where each value comes from.
Change-Id: Iff5dd844b70ff70979b1b8c84dc7734d44b3da20
Rename structs and variables to make it clear that these min/max values
are min/max per-sec rate values.
Carry mins and maxes separately from averages. This changes the meaning
of $command_ps_avg away from an "average of averages" to an actual
average, which is more accurate.
Calculate this average based on per-interval differences and interval
duration (stats_rate_min_max_avg_sample).
Side effect: As rtpe_latest_graphite_interval_start is now set in
print_graphite_data instead of in graphite_loop_run, the test now
reports a different "interval calls duration".
Change-Id: I67b1118c18ca2464a48c4836fca3cfdb4d53c898
Perform accumulation of stats only once (i.e. increasing an actual
counter) and report stats based on differences to previous values,
instead of carrying multiple stats counters for each metric and
resetting each counter to zero whenever stats are reported.
`rtpe_stats` is the global master accumulator.
`_intv` variables are intermediate and local storage for values sampled
from `rtpe_stats` at regular intervals.
`_rate` and `_diff` variables hold stats calculated from `rtpe_stats`
and the respective `_intv` variable whenever the sampling and reporting
occurs.
`stats_counters_calc_diff` is used to calculate stats as differences
between `rtpe_stats` and the last sampled `_intv`
`stats_counters_calc_rate` does the same but calculates a per-second
rate, based on a microsecond duration.
Eliminate now-useless struct global_stats_ax
Change-Id: Ic4ca630161787025219b67e49b41995204d60573
Use dedicated functions and different code paths for the different use
cases, instead of just a single function which does if/else all the
time.
Change-Id: Ic3ab928c3605cfe4a2f48889e95a3a1ddccdbbec
In order to rewrite certain session-level SDP lines, we need to
reference a packet_stream which contains the correct information. But we
cannot simply rely on the first media section having a usable packet
stream, as the first media section could have been rejected. Iterate
media sections until we find a usable one.
Change-Id: I36594e80981fc0645a7747399bd9951fbc2e5676
This fixes the payload counts not being tracked correctly when payload
types repeat after the tracker rolls over.
Change-Id: I16208ef73f3af3b051b96541a4c145b323cef7b2
The SRTP decryption context is associated with the local socket. Use the
socket that a packet was actually received on for the decryption context
instead of using the one that it was expected to be received on.
Change-Id: Iddf400a440fc51b4afb370ec827f75e9626b2cfd
(cherry picked from commit 8c3452e50b7aa4f5b7122dbd7221e34143467885)
When a receiving socket doesn't match the socket we were expecting, make
sure that the receiving socket is actually one of the sockets we want to
use at this point before blindly switching the socket.
This fixes a race condition after a re-invite: A new set of sockets has
been opened, but an old/delayed RTP packet still arrives on one of the
old ports. In this case we don't want to switch the local socket.
Change-Id: I4e2b87ad608b1a9c6a0bb2eae5c305fd79be70d5
(cherry picked from commit 304a1b11ef6679b4ab133c1c44bb0f180903d948)
As Redis updates must be triggered with the call unlocked, use a
convenience wrapper function to unlock, update, unref.
fixes#1602
Change-Id: I67095f31fb605b6977c88d9e9b3db581dd71a0d9
... so that the publishing session gets notified about "webrtcup" and
not the session which created the room.
Change-Id: If7b308df4afa7afb19ecaca1f743f87c3c736007
Our own Janus WS client would create a single WS session and then create
all rooms under this one session and run all publishes and subscribers
under the same session. This is not a restiction imposed by Janus
though, which allows participation in one room by multiple sessions.
Remove this restriction to more closely mirror Janus behaviour.
Change-Id: Ic11f961369ce5ded599a7a22cd730236460a8c61
To allow supplying the handle ID and session ID separately without
requiring it to be in the JSON.
Change-Id: I4a6f18410084add2a37cdf1ea3375072a8e192ca
According to:
{
"request" : "join",
"ptype" : "subscriber",
"room" : <unique ID of the room to subscribe in>,
"use_msid" : <whether subscriptions should include an msid that references the publisher; false by default>,
"autoupdate" : <whether a new SDP offer is sent automatically when a subscribed publisher leaves; true by default>,
"private_id" : <unique ID of the publisher that originated this request; optional, unless mandated by the room configuration>,
"streams" : [
{
"feed" : <unique ID of publisher owning the stream to subscribe to>,
"mid" : "<unique mid of the publisher stream to subscribe to; optional>"
"crossrefid" : "<id to map this subscription with entries in streams list; optional>"
// Optionally, simulcast or SVC targets (defaults if missing)
},
// Other streams to subscribe to
]
}
{
"videoroom" : "attached",
"room" : <room ID>,
"streams" : [
{
"mindex" : <unique m-index of this stream>,
"mid" : "<unique mid of this stream>",
"type" : "<type of this stream's media (audio|video|data)>",
"feed_id" : <unique ID of the publisher originating this stream>,
"feed_mid" : "<unique mid of this publisher's stream>",
"feed_display" : "<display name of this publisher, if any>",
"send" : <true|false; whether we configured the stream to relay media>,
"ready" : <true|false; whether this stream is ready to start sending media (will be false at the beginning)>
},
// Other streams in the subscription, if any
]
}
Change-Id: Ieb38d4f562686283457a963334056b27927be974
Apparently Janus allows a single handle to be both controller and
publisher, and possibly also both publisher and subscriber. Remove the
limitation that forces one handle to only take one role.
Change-Id: I22c20981a213b84d06dad07b1ff634bfd024fd91
This is a new option flag, which provides a possiblity
to select specific crypto suite(s) for the offerer from
the given list of crypto suites received in the offer.
This will be used later on, when processing an answer from
the recipient and generating an answer to be sent out towards offerer.
Furthermore, this is being decided not when the answer is processed,
but already when the offer is processed.
Flag usage example:
`SDES-offerer_pref:AES_256_CM_HMAC_SHA;AES_256_CM_HMAC_SHA1_32;`
Change-Id: I2b22b38347d24f27331482e18b92305fbadb2520
We're already determining the destination media section in
media_player_play_init() (looking for audio media), so it makes sense to
determine the payload type there as well.
Change-Id: I33d4a15005c2146864f74663fe8de2893454345b
Split out the logic to determine the destination payload type into a
separate functions. This makes it possible to supply a different, or
pre-determined, payload type instead.
Change-Id: I9b67b29cafc0c6ce4e18eede64dea3d1973f8b63
It makes more sense to set up the codec handler from the init function
rather than from the function reading the media packet.
Change-Id: I0bea3d0fc0669a54f93b2598251df69274950365
Provide the targets for the two /bin/ components.
Adapt .install debhelper files.
Adapt iptables module install location to use the environment variable.
Change-Id: I963feba5f60f53773e497121d8947e7b4997d687
… if it does not exist. Likewise in iptables-extension/Makefile .
daemon/rtpengine.pod: spell what MOS means
MAX_SESSIONS in config file does not work, it must be max-sessions.
https://github.com/sipwise/rtpengine/pull/1589
1872 /* first add those mentioned in the order list,
1873 * but only, if they were previously generated/added to the sdes_out */
>>> CID 1530346: Control flow issues (DEADCODE)
>>> Execution cannot reach the expression "NULL" inside this statement: "l = (cpq_order ? cpq_order-...".
1874 for (GList *l = cpq_order ? cpq_order->head : NULL; l; l = l->next)
Change-Id: I58f84ba82d215a9eb6cbd97548e8e9e8a954bdc6
This is a new option flag, which provides the ordered list,
in which to add crypto suites into the SDP body.
Right now they're always added in the order given in the source code.
Flag usage example:
`SDES-order:AES_256_CM_HMAC_SHA;AES_256_CM_HMAC_SHA1_32;AES_192_CM_HMAC_SHA1_80;`
This means — those listed SDES crypto suites will be added
into the generated SDP body at the top of crypto suites list, in the given order.
But, each of them is added, only if it is about to be added/generated.
In other words, the `SDES-order:` flag itself doesn't add crypto suites,
it just affects the order of those suites to be added.
And the rest of non-mentioned suites, which are also to be added,
will be appended after those given, in the free manner of ordering.
Important thing to remember - it doesn't change the crypto suite tag
for the recipient, even though changing the order of them.
Additionally.
This flag does not contradict with `SDES-nonew`, `SDES-only-` and `SDES-no-` flags.
It just orders the list of crypto suites already prepared to be sent out.
Change-Id: I0fec54f9e2f3cd4913e905e8afe825712f82d1ae
A new function dedicated to SDES crypto suites comparison.
It compares the crypto suites using a name in 'str' format.
Recommended to be used in combination with:
g_queue_find_custom() or g_list_find_custom()
Change-Id: I08ff6d3304f74d29154110caa472618478ca1837
New helper func: call_ng_flags_str_q_multi()
It parses given flags delimited by a separator, and stores
each of them in the given GQueue.
By default delimiter is assumed as: ';'.
Change-Id: I1e29bf3d852868e2bc4d98b1775f70b38f61054a
This type is used as const everywhere except internally, so make it part
of the typedef for brevity.
Change-Id: Ic4afe037b392239a991d5380c6708903011da29e
A new function dedicated to SDES crypto suites policy checks
has been introduced: 'crypto_params_sdes_check_limitations()'.
Use it to decrease an amount of repeating code blocks
related to SDES checks.
Change-Id: I0ac242a63107a9f3a41f95a57e3d3675645ac18d
Add a new flag to only accept these individual crypto suites
and none of the others.
For example, `SDES-only-NULL_HMAC_SHA1_32`
would only accept the crypto suite `NULL_HMAC_SHA1_32` for
the offer being generated.
This also takes precedence over the `SDES-no-` flag(s),
if used together, so the `SDES-no` will be not taken into account.
This has two effects:
- if a given crypto suite was present in a received offer,
it will be kept, so will be present in the outgoing offer; and
- if a given crypto suite was not present in the received offer,
it will be added to it. The rest, which is not mentioned,
will be dropped/not added.
Flag name: 'SDES-only-<crypto name>'
Additionally: add another new flag 'SDES-nonew'.
It will not add any new crypto suites into the offer.
It takes precedence over the `SDES-no` and `SDES-only` flags,
if used in combination.
Change-Id: Ic4fa03957ee3d4d24b0c4f3fd003eada05f49b0b
1) Read dtxb->start while the lock is held (not strictly necessary as
the read should be atomic anyway)
2) Expect that dtxb->start can be larger than rtpe_now.tv
The latter can happen as `rtpe_now` in a timer thread is faked to be
exactly the time when the timer was supposed to run, and not the actual
current time, which means that a newly added packet can have a later
time stamp than the "now" the timer thread is using.
Change-Id: I48fd7f78af97c6d5b802e5151d69855a90f4032d
Instead of going through ffmpeg to en/decode Opus, use libopus directly,
which allows us to benefit from additional features that aren't
available when going through ffmpeg.
Change-Id: I017c276cfa9755cefe95c8da26691446b718d4c8
Some codecs (e.g. Opus) can natively encode audio with various clock
rates without producing an output that is locked to that clock rate and
without requiring resampling the input. Add an appropriate callback
function and adapt tests.
Change-Id: Id788c4d4c05e20f93cce7e910f9f265b381cbe34
This makes it possible to have codecs running at variable clock rates
that differ from their RTP clock rates.
Change-Id: Ia2f5effb82eefe8c3028573ba0a6697da28473b1
Instead of just having an integer multiplier, support a fractional
factor. This allows us to have the RTP clock rate run faster than the
audio clock rate, and not just slower by an integer factor.
Change-Id: I7681cf369c43d8424ca2d2ebeffe932595d271ec
Unmark a monologue that has been scheduled for deletion when it's
associated with another one, which happens during offer/answer.
Fixes a regression from 53dbef7e1 which removed this logic from
__monologue_unkernelize with re-adding it elsewhere.
Change-Id: I037162e91fec42631680f7767f58b172fd6e04db
Add a flag to force increasing the SDP version,
even if the SDP hasn't been changed.
And cover it with tests.
Flag name: 'force-increment-sdp-ver'
Additionally fix the name of the 'sdp-version' flag
in the 'rtpengine-ng-client' tool.
Change-Id: I466792668b0cd313b5e21b248dd14cd599333cbd
`call_get_monologue_new` is supposed to always return a full dialogue,
but an error in invocation (using a from-tag that doesn't belong to an
offer/answer) can lead to the second half being unset. Return an error
in this case.
Change-Id: I84b21ff5e5c0403fc07cae83fee206705ecff8b3