This commit introduces a new RTP transport model,
based on the AmRtpTransport abstraction, providing a more modular and
efficient approach to RTP handling compared to the legacy model.
General things:
- Introduction of new RTP receiver and transport abstractions
- The new model coexists with the legacy RTP handling
to preserve backward compatibility
Architecture overview:
- A new AmRtpTransport layer is introduced to encapsulate RTP transport logic
and decouple it from AmRtpStream and session-level code
- Transport-specific functionality is implemented via dedicated classes:
- AmRtpTransport: base abstraction responsible for RTP/RTCP packet flow,
lifecycle management, and interaction with streams
- AmRtpUdpSocket: UDP-based RTP socket implementation
- AmRtpSocketPair: manages RTP/RTCP socket pairs and their coordination
- AmRtpStream is refactored to rely on the transport interface
instead of directly managing sockets and low-level I/O
Integration details:
- SIP session and dialog logic (AmSession, AmSipDialog) is updated to work with
the new transport model
- SBC call legs and call profiles are extended to support transport selection
and lifecycle handling
- SDP processing (AmSdp) is updated to reflect transport capabilities and
address handling changes
This refactoring improves separation of concerns, reduces coupling between RTP
streaming and transport mechanics, and provides a cleaner foundation for future
RTP extensions and optimizations.
Code provenance and license:
- part of the code was written by Fokus GmbH
- part of the code was written by Sipwise GmbH
- part of the code base copyrighted by Fokus GmbH was provided by them in
the form of backports under the GPL license.
- these changes are covered by the GPL, matching the existing project license
Change-Id: I313c4abd9b54f805c1e668c019cf6fb8c4a9e46d
Rework the payload to be a string instead of the raw char array.
This eliminates cases when we actually need to track that this char array
is indeed null-terminated and deprives us from doing other tricks to
properly maintain this char array.
Also no need to return const of payload anymore, because simply copied
during return. Data protection ensured by not giving a reference to the payload,
modifiable still during the first time setting this payload.
Rework also other users, such as nested call into AmSdp provided `parse()`.
Now `parse()` takes a string, and already in a local scope handles a char array
copy of this given string. This is only because the `parse_sdp_line_ex()` still
requires a refactor to be working with strings instead of char array.
Additionally: move parser helpers of AmSdp to const char pointers,
instead of working on a plain char pointer. This is because the SDP body
parser has been moved from the referenced pointer `char *&`
to the `const char *` pointer. This allows to not have additionally
heap allocated SDP body C-string for parsing purposes.
No functional change.
Change-Id: Ic3ee6c349b62e7e5e0cd4de722f9ed923862a7cb
Preamble: no functional changes.
AmSdp::parse() mixes int values with bool,
what makes the behavior not really clear, not defined
and can lead to the unpredicted result (even though the
compiler *should* actually fix that, but one ought to
not rely on this).
Hence make the parse method only be working with bool values.
Then, reverse the return value so that it's clear
that wrongly parsed is `false`, and good parsed is `true`.
Refactor all users accordingly.
Also rework those users, who indeed need `int` value
be returned, e.g. when having -1.
Do the same thing with the `parse_sdp_line_ex()` helper,
whereas parse() is the only user of it. And also reverse
the interpretation of true/false.
Then, make `parse()` working with a plain `char*`, so not a const.
Because doing a tricks like:
cast `char*` to const (user level) -> cast `const char*` to non-const
in a function (in a old C-like manner), has really no sense.
Refactor everything accordingly.
Other than that, refactor AmMimeBody:
Refactor it to work with a plain `char *` pointer instead of working
with `unsigned char *`, which nowadays has really no sense and
rather is a rudiment of C-like code base coming from the past.
Convert `payload` from `unsigned char*` to `char *` accordingly.
Refactor everything in AmMimeBody implementation accordingly.
Remove rudiment C-like casting everywhere, where possible.
Update `parseMultipart()` to work with a plain `const char *`
instead of `const unsigned char*`
P.S.: leave a list of TODO's for further rework, which
is not directly related to this scope of rework.
Change-Id: Ie1e132429245e0d2cc740d5b1c1fc17cf037a820
A a mechanism to get the AmSession object
stored polymorphically on the EvQueueMap.
Follow the classes hierarchy:
AmEventQueueInterface -> AmEventQueue -> AmSession
to retrieve AmSession by down casting it from base class.
When retrieved, acquire the snapshot dedicated lock
to prevent other thread destroying this gotten AmSession.
As soon as AmSessionSnapshot is ready,
release the lock and let other (real owner) thread do anything with it.
Left corner cases:
- by the time the AmEventQueueInterface is retrieved and down-casted
into the AmSession, returned to the user and the snapshot lock
is acquired, this thread can simply destroy the AmSession object
- this is an undefined behavior
Change-Id: Ia62b5cb27618e2c077ae5a247bb914be74e17fa9
Otherwise we can end up with:
Program terminated with signal SIGSEGV, Segmentation fault.
104 ./core/AmSession.cpp: No such file or directory.
[Current thread is 1 (Thread 0x7fc7dd677e40 (LWP 176249))]
Change-Id: Ia61de0caa9b1764839c740e62bc3f463da4ed4dc
Make the way we get call-id when calling ILOG_DLG()
file specific, which allows to define locally
(within a target file) how to get the call-id value.
Change-Id: I4af87edf9d1ea52d9678b3354bc797cf1f5f0b54
If the dlg object is freed, then don't try to log
things based on the call-id value taken from it.
Just do slightly before.
Change-Id: I09e865ca77d64c6c398cf8dc35c189e076fdb26d
Volatile increments/decrements are deprecated by C++20,
use a full operation instead.
Fixes:
18: 57:47 AmSession.cpp: In static member function 'static void AmSession::session_started()':
18: 57:47 AmSession.cpp:607:3: warning: '++' expression of 'volatile'-qualified type is deprecated [-Wvolatile]
18: 57:47 607 | session_num++;
18: 57:47 | ^~~~~~~~~~~
18: 57:47 AmSession.cpp: In static member function 'static void AmSession::session_stopped()':
18: 57:47 AmSession.cpp:624:3: warning: '--' expression of 'volatile'-qualified type is deprecated [-Wvolatile]
18: 57:47 624 | session_num--;
18: 57:47 | ^~~~~~~~~~~
Change-Id: I68ad2cee9396765b0df1ba5b583435c326154dde
* 1.4:
b/f: fix incorrect parsing of keys with semicolon at the beginning in get_header_keyvalue
[systemd] Restart in case of failure
[init-script] Fix diractory for Pid-file
b/f: fix false positive matching keys with prefixes in get_header_keyvalue
Added missing /etc/sysconfig/sems file to the pkg/rpm
1.4 branch build version
updated changelog for 1.4.3 release
SEMS 1.4.3 release
c/f: revert a83b8e1 as it can cause some issues with the linker
c/f: make it possible to pass CXX / CC from env vars
c/f: make callgen compile using proper IP for From host
core: name default interface as "default"
core: handle exceptions in out-of-dlg messages gracefully
b/f: stopping failed outbound calls
b/f: AmCondition::wait_for_to nsec overflow
Add [Install] directive for systemd
applications which are doing outbound calls should implement
onFailedOutboundCall if the behavior should be different than
setting stopped.
Reported by Andrei Samusenko
* remotes/origin/1.4: (27 commits)
b/f: getHeader: find correct hdr also if it's substring of another hdr
b/f: support values at end of SDP without CR (master 8ec8a910a2)
b/f: T38 streams in SBC/B2B (udptl transport); proper media direction passthrough
click2dial: b/f: fix crash when using without credentials
Add systemd-related files to the pkg/rpm dir
Add libzrtp support to the CMakeFile
Fix c/p typo in cmake-files
Missing include for close(FILE *)
Drop privileges for SEMS process
b/f: in webconference app, handle session timer timeout and RTP timeout
b/f: on RTP timeout, end dialog with sending BYE
b/f: make listRooms return only non-expired rooms
b/f: B2BUA: fixed replies for error handling
b/f: fixing b6d5f726 (fix SBC SDP filter)
b/f: fix SBC SDP filter with connection per media only
add Retry-After: 0 to NOTIFY 500 response on low CSeq
b/f: click2dial: save content_type, cseq to connect callee
b/f: use proper empty string value
b/f: use proper failure return value
b/f: reset RTP-received timestamp when (re)starting process RTP stream
...
If NAT flag (P-MsgFlags: 2) is passed only in the initial INVITE,
re-INVITE will set up the RTP stream to the private address, but not
enable symmetric RTP (comedia style send-to-where-i-get-rtp-from)
again. this fix remembers passive_mode for the call.
If an INVITE has been forked and more than one branch is aimed at SEMS,
then the branch parameter of the top-via is necessary to distinguish the
different sessions.
By default, SEMS will now accept forked INVITEs.
This behavior can be switched off by setting "accept_forked_dialogs" to "no" (default=yes).
Conflicts:
core/AmSipDispatcher.cpp
If NAT flag (P-MsgFlags: 2) is passed only in the initial INVITE,
re-INVITE will set up the RTP stream to the private address, but not
enable symmetric RTP (comedia style send-to-where-i-get-rtp-from)
again. this fix remembers passive_mode for the call.
In case 100rel is disabled on SEMS' side, but UAC requires it, SEMS
would reject the INVITE, drop further processing on the session, but
still keep it. If INVITE is first in session, UAC would clear the
dialog, but SEMS would still keep it.
But spotted and explained by Stefan S.
max/avg calls and calls/s values, can be accessed via
get_callsmax/get_callsavg/get_cpsmax/get_cpsavg from
- stats server
- XMLRPC through xmlrpc2di
based on a patch by Robert Szokovacs rsokovacs gammatelecom hu
In the context of multihomed servers, the signaling interface can be selecetd by the application. By default, the signaling interface is determined automatically. The media interface can also be set manually, there is however no automatic selection. In the case it is not set by the application, the default interface (the first one defined) is used instead.
SIP message processing and Session event processing are now
enclosed in blocks with the form
vv <type> [<callid>|<ltag>] ... vv
^^ <type> [<callid>|<ltag>] ... ^^
where
<type> = M SIP message processing
<type> = S Session event processing
app level timers can now be used easily with the AmSession functions:
setTimer(int id, unsigned timeout)
removeTimer(int id)
removeTimers()
timersSupported()
- change the way RSeq accounting is done: changed signed data type to
unsigned, at expense of adding two more vars to AmSipDialog; this
should make AmSipDialog more replication friendly.
- b/f: if 100rel is disabled and an inbound request asks support for it,
reply with 420.