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
If the Content-Length is empty, then it makes no sense
to parse and filter application/sdp body.
Otherwise a parser is going to fail and answer with 488.
Change-Id: I92cdd19319c6f4a4edcfbaeec7bad1be12c8a0b0
Add parsing of Content-Length, for cases
were this length matters (e.g. ct length > 0,
but suddenly there is no SDP body).
Also add a getter for the AmContentType's length.
Change-Id: I92cdd19319c6f4a4edcfbaeec7bad1be12c8a0b1
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
When using that, the return value must always
be checked, because the parsing itself can indeed fail.
Fixes such things as:
** CID 583412: Error handling issues (CHECKED_RETURN)
/core/AmB2BSession.cpp: 340 in AmB2BSession::acceptPendingInvite(AmSipRequest *, const AmMimeBody *)()
_____________________________________________________________________________________________
*** CID 583412: Error handling issues (CHECKED_RETURN)
/core/AmB2BSession.cpp: 340 in AmB2BSession::acceptPendingInvite(AmSipRequest *, const AmMimeBody *)()
334 return;
335 }
336
337 /* port must reflect actual port in SDP offer coming in */
338 if (sdp) {
339 AmSdp fake_sdp;
>>> CID 583412: Error handling issues (CHECKED_RETURN)
>>> Calling "parse" without checking return value (as is done elsewhere 12 out of 15 times).
340 fake_sdp.parse((const char *)sdp->getPayload());
341 desired_port = getMediaPort(fake_sdp);
342 }
343
344 if (desired_port) {
345 ILOG_DLG(L_DBG, "Desired port for fake 200OK is '%d'\n", desired_port);
Change-Id: I7bd177a624ebe2df2629863eb31f97f99bd921bb
Make the AmOfferAnswer model actual and introduce
according class API updates.
Accordingly update CallLeg, SBCCallLeg and AmSipDialog.
Change-Id: Iab26f4a7577af56df68ffe693859eaac08913b7f
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
Introduce `ILOG_DLG()` call-id logging based on `dlg`.
This commit only introduces a usage of it for
CallLeg and SBCCallLeg classes.
Later commits will spread this usage over all
AmB2BSession based classes.
Change-Id: I18ad8ba5129cb8912f401bb089ad82dbf9909a18
Move it to the dlg level, because of complex visibility.
In other words, when working on the dialog level and e.g.
generating new SDP body using `dlg.oa`, there is no way
to save it.
Moving it to the dlg level, gives a control over it on
the whole amount of inheritance levels plus dlg.
Change-Id: Iebb13e3e58f2558dc060e23270d99d690fa54572
SDP session origin id and version are limited by it's size
to 64 bits (8 bytes), that is because we are using `unsigned long long`
type for both id and version. Hence the maximum value it can hold
is two sixty-forth power, so equals: 18,446,744,073,709,551,615
In case one intentionally sets it to something like:
"o=- 18446744073709551615 18446744073709551615 IN IP4 192.168.0.1"
SEMS gets overwhelmed with that conversion inside the code make
it just to a string literal 'F'.
To overcome it, just use __uint128 (which is of 128bits size)
for the session origin id and version.
Change-Id: I2ad9659aa81dad79969749053dc3fd0d69e2cbd2
Use `unsigned long long` for SDP session id and version
instead of unsigned int.
Refactor all usage of them accordingly.
Additionally intrdouce new utils functions for conversion:
- `ulonglong2str()` - converts `unsigned long long` to `string`
- `str2ull()` - converts `string` to `unsigned long long`
Change-Id: I4210349a5442d4173b14227497f4a01d68cad7a4
Save SDP origin after a call leg is held.
Successive reinvites in the session version must be incremented
based on hold/resume reinvite and not based on the original SDP origin.
Change-Id: I771778dbc26f329561fd928ec70e17ab644b19be
Increment the sessV each time,
when creating new hold request.
Instead of blindly using `established_body` AmMimeBody,
properly treat the sessV, and keep it updated.
`updateLocalSdp()` stores updated body then as `CallLeg::non_hold_sdp`
Which will be later on used to resume held.
During resume keep sessV incremented, because each time new
SDP offer is sent out, sessV has to be updated.
Change-Id: Ifaa6ead0a36f9fe77e032e64547a490d856c44d6