When replying with 200OK generated by SEMS to INVITE requests,
which have no SDP body included, just answer with empty 200OK.
This sets the `OAState` of the call leg to `OA_None`.
Change-Id: Ic28e80d670ba4ce98be6abac9d17689688f99f71
Re-use previously offered SDP body, when processing
a call session with an involvement of DSM, and getting
newer SIP invite having no SDP offer.
This affects applications using the B2B `connectCollee()`
functionality and doesn't actually touch the B2B core itself.
(Which would be wrong if changed in a usual core SDP
processing, whereas original request can be empty and
an offer/answer is postponed to 200OK/ACK exchange)
(Re)invites towards DSM applications technically must
not be empty, because DSMs don't support late offering.
In order to overcome that just pretend that empty
re-INVITEs are using previous body version.
Change-Id: I252eb9f32e7dc073454a2258b176f77bf15d35c9
Introduce getters for headers in requests
and replies:
- `B2B.getHeaderRequest()`
- `B2B.getHeaderReply()`
Change-Id: I1dfc24658a9e044407f95de9507032f1b041b451
Don't store the `st` variable in a processor register
but store as usually in memory.
Resolves:
AmUriParser.cpp:97:16: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
97 | register int st = ST1;
|
Change-Id: Ia38feab1e58aeab20e2f7319bee268feca919a82
Don't store variables in a processor register
but store as usually in memory.
Resolves:
10: 32:12 AmSdp.cpp: In function 'bool parse_sdp_line_ex(AmSdp*, char*&)':
10: 32:12 AmSdp.cpp:571:21: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 571 | register parse_st state;
10: 32:12 | ^~~~~
10: 32:12 AmSdp.cpp: In function 'char* parse_sdp_connection(AmSdp*, char*, char)':
10: 32:12 AmSdp.cpp:757:30: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 757 | register sdp_connection_st state;
10: 32:12 | ^~~~~
10: 32:12 AmSdp.cpp: In function 'void parse_sdp_media(AmSdp*, char*)':
10: 32:12 AmSdp.cpp:838:25: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 838 | register sdp_media_st state;
10: 32:12 | ^~~~~
10: 32:12 AmSdp.cpp: In function 'char* parse_sdp_attr(AmSdp*, char*)':
10: 32:12 AmSdp.cpp:1038:31: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 1038 | register sdp_attr_rtpmap_st rtpmap_st;
10: 32:12 | ^~~~~~~~~
10: 32:12 AmSdp.cpp:1039:29: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 1039 | register sdp_attr_fmtp_st fmtp_st;
10: 32:12 | ^~~~~~~
10: 32:12 AmSdp.cpp: In function 'void parse_sdp_origin(AmSdp*, char*)':
10: 32:12 AmSdp.cpp:1253:26: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
10: 32:12 1253 | register sdp_origin_st origin_st;
10: 32:12 |
Change-Id: Ice87c3659816003c94359f891a490db0910ff74a
Explicitly set port and nports to 0 when initializing
a brand new instance of SdpMedia.
This resolves warnings:
../../core/AmSdp.h:168:8: warning: '*(__vector(2) unsigned int*)((char*)&<unnamed> + offsetof(SdpMedia, SdpMedia::port))' may be used uninitialized [-Wmaybe-uninitialized]
168 | struct SdpMedia
| ^~~~~~~~
../../core/AmSdp.h:168:8: warning: '<unnamed>.SdpMedia::nports' may be used uninitialized [-Wmaybe-uninitialized]
168 | struct SdpMedia
Change-Id: Ifa2838ba0ef2f1a48b4fdc07b7bfaf8c5aefcfaa
Don't store `fin` variable in a processor register
but store as usually in memory.
Resolves:
parse_100rel.cpp: In function 'bool parse_rseq(unsigned int*, const char*, int)':
parse_100rel.cpp:19:19: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
19 | register bool fin; \
| ^~~
parse_100rel.cpp:55:3: note: in expansion of macro 'READ_NUMBER'
55 | READ_NUMBER(rseq, pos, end);
| ^~~~~~~~~~~
parse_100rel.cpp: In function 'bool parse_rack(sip_rack*, const char*, int)':
parse_100rel.cpp:19:19: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
19 | register bool fin; \
| ^~~
parse_100rel.cpp:84:3: note: in expansion of macro 'READ_NUMBER'
84 | READ_NUMBER(rseq, pos, end);
| ^~~~~~~~~~~
parse_100rel.cpp:19:19: warning: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
19 | register bool fin; \
| ^~~
parse_100rel.cpp:91:3: note: in expansion of macro 'READ_NUMBER'
91 | READ_NUMBER(cseq, pos, end);
| ^~~~~~~~~~~
Change-Id: I9030a5ac8b7ebb0dd1b932296f73a7987639fc26
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
Add a function to the AmSipDialog class interface,
to be able to check whether the OA currently expects an offer.
Use it then in the `CallLeg::updateLocalSdp(AmSdp &sdp)`
Change-Id: I1c4f4364ce13c7b03e22e0f037d19b99245a0be8
Do not take into account `send_491_on_pending_session_leg`
when processing pending updates for call-pick call scenario.
This is required to let the A side (so caller) be updated,
which in a cascading manner later triggers 200OK sending
towards the call pick-up'er, and further media updates
via re-invite.
`send_491_on_pending_session_leg` is used to prevent
overlapping updates towards the same other leg.
In this situation however, two updates towards the caller
is a proper way to finish the call-pickup, so the media update.
A new header for interaction between SBC<->B2B introduced:
`P-Force-491`, which takes either of values '1' or '0'.
If set to '0' the `send_491_on_pending_session_leg` will always
be ignored by SBC, and hence re-invite will reach the target,
regardless if there has been anyone shortly before.
Change-Id: Iee7d2c6ef38e568e7c57a89358b22be0b1cb0438
We need to take care of cases, when one leg has pending
transaction(s), and an opposite leg triggers media re-negotiations,
which assumes we have to update the first leg as well (the one which
has a pending transaction).
Perviously we used to only support sending a fake 200OK to the one,
who triggered a media attributes re-negotiation, and scheduling
an update for the opposite leg for a later time (as soon as its done
with its own transaction(s) ).
For now we can optionally decide whether:
- to send 200OK to the one who triggers re-INVITE
- to send 491 Pending to the one who triggers re-INVITE
Using the approach with 491, gives a solution to the problem,
when a fake 200OK is sent to the remote side, and ACK after a while
is not matched to any of the existing local transactions.
This can happen in case, we have sent a fake 200OK, but SBC triggers
one more transaction towards the same side (over already existing one).
This behavior leads to a failure when trying to match coming ACK to the fake 200OK.
By default, enabled behavior - generate fake 200OK.
Optionally it's now possible to enable 491 Pending response,
by setting sems.conf option:
- send_491_on_pending_session_leg = 'yes'
Change-Id: I17f41833651eb006666315c1f9a7cfd4c0441f8a
Core in CE is missing currently functions to accept
pending invitations, introduce them from PRO version:
- `acceptPendingInviteB2B()`
- `acceptPendingInvite()`
Additionally:
- add a helper to create fake replies `createFakeReply()`
Change-Id: Icc5be22051f68f269d4b93637f2b3b59498dbd25
Sync the `CallLeg::onB2BReconnect()` with PRO code version,
and add second part of SDP origin manipulation fix.
Change-Id: I7d7558bc88ab91d00bac72a22e1f713afd218233
If there are no timers then it makes no senes to process ticks in real
time. Sleep up to 0.5 seconds in that case. When timers are added we
are immediately woken up through the conditional variable. Only setting
the shutdown flag would not wake up the thread, but a sleep time of half
a second should be an acceptable delay for shutdowns.
Analogous to 695d902841
Change-Id: I37adf078825470af99e6a7755df3d8786d3eeaa6
Signal the sleeping thread through a condition variable whenever a new
event has been added to the queue. We can then process these events
immediately instead of having to wait for the timer to expire.
(The decision to use a separate private mutex and an extra bool value
for the AmCondition class of course is highly questionable, but that's
what we have in the code base for now.)
Change-Id: I78b74f1152e36aa106906e962bc133f15093ea02
Use one method for wheel turning and another separate method for events
processing. This logically separates two indepenent processes.
In the event of the actual sleep time being different from the requested
sleep time, we do the wheel turning based on the number of required
ticks, but run the events processing only once, after the wall clock has
been brought up to date.
Change-Id: Ibbc6571a5a569050647efd1ba595c1fd08918409
We may end up sleeping shorter or longer than the desired sleep time. If
we ended up sleeping shorter, don't advance a tick, and if we ended up
sleeping significantly longer (more than one tick), advance multiple
ticks.
Change-Id: I0be20104e6243c89006367430a3663cc304486b9
Go to sleep even if the sleep time is less than 2 ms. This makes the
math a lot easier and shouldn't have a noticeable impact as this is
a somewhat unnecessary attempt at optimization.
Analogous to 292eb8cf1c
Change-Id: I6d936a4450967dcd76b4647f189aa3f71e5ed7ae
By making the wall_clock private to the timer thread, we force all
externally used timers to use relative timeout values. Amend the timer
class to keep both timeout values for clarity.
The previously existing member `expires` is the absolute timeout, but is
now initially left unset (zero). Instead the given timeout value is put
into the new member `expires_rel` and the absolute timeout is calculated
only once the timer is inserted into the wheel by adding the current
wall clock.
We add an extra getter function for the current wall clock only for
debugging and logging purposes.
This also turns the two expiry timestamps kept in the timer class
protected and private, delegating maintenance to getter and setter
methods.
Change-Id: Ia6baf552a1de94ba64f314e9123df172b45eed85
Change it into a wrapper that directly calls time() to eliminate the
need of the timer thread to continuously set unix_clock to the current
time. With vDSO the call to time() is sufficiently cheap.
Move constructor to header and remove default empty destructor.
Change-Id: Ib812a993da9340b9ded4fd97c81d762d9452c3ea
If there are no sessions then it makes no senes to process ticks in real
time. Sleep up to 0.5 seconds in that case. When sessions are added we
are immediately woken up through the conditional variable. Only setting
the shutdown flag would not wake up the thread, but a sleep time of half
a second should be an acceptable delay for shutdowns.
Change-Id: I5aa43382248754ff8dec811038998cf636579734
Calculate how many ticks have passed since we were last awake, and
advance next_tick based on the actual time, but in multiples of tick.
Change-Id: I50f9804b1002780fc55358f00ff41d3a73ab854e
Go to sleep even if the sleep time is less than 2 ms. This makes the
math a lot easier and shouldn't have a noticeable impact as this is
a somewhat unnecessary attempt at optimization.
Change-Id: Ibd97c216e529b4e0b2110f81200b649db6ff2764
Extend logging in the `AmSipSubscription::makeSubscription()`
and also refactor code for better readability.
Change-Id: Ibbeb9f8cb7b808bf24685af46ed31c00040913a0
If the leg during the `B2BEvent::B2BTerminateLeg` event
handling turns out to be in the 183/200 faked state,
then handle the leg termination with CANCEL, instead of BYE.
This is because this leg has never seen the real 200OK
response, and hence remains indeed in the early stage.
Change-Id: I4a9d4197a6ea42f1cfbbcdc5fb306c48684e64bf
When outbound PRACK is challanged, SEMS is regenerating
the PRACK to proxy duplicating the proxy socket in the
Route header, with the result of:
Route: <sip:127.0.0.1:5062;lr>,
<sip:127.0.0.1:5062;lr=on;ftag=xyz;leg_b=1;did=f85.d281>,
<sip:127.0.0.1;r2=on;lr=on;ftag=xyz;ngcplb=yes>,
<sip:192.168.178.104;r2=on;lr=on;ftag=xyz;ngcplb=yes>
the duplicate "127.0.0.1:5062" is causing routing
issue on proxy, cause loose_route() function removes
only the first element. Then proxy sends PRACK to
itself.
To avoid that, we make sure is SEMS to do not add
the 'outbound_socket' value in the Route header
if that value already exist in the first position.
Change-Id: Id310144d8e77a99111e199358462496c9dd0495c
For the PRACK transcations (e.g. PRACK/401) update the
remote tag as well as route set.
Scope: `AmSipDialog::onRxReplyStatus()`
Additionally: do not reset remote tag during the authentication
process for PRACK methods, in: `UACAuth::onSipReply()`.
Change-Id: Ibd4e4ee737287bab3883b74a32ded6a966ec62ab
During refreshing of the media for the call leg in the
`CallLeg::adjustOffer()`, when the resume is required,
but the `on_hold` wasn't set before (so is false),
then additionally check, whether the SDP body
(media sessions of `MT_AUDIO` type) has state like:
- sendonly
- recvonly
- inactive
This will properly fix the attributes (like: `a=sendonly`)
in the re-INVITE, which is supposed to resume the session.
Change-Id: I1c45b7db55d2a5174f3fd96f3fcd0201b48345f2
This is a partial rework of b67428d.
The patch was always saving the Allow header
from the initial INVITE and replacing the Allow
header in the 200 OK with that.
This fixed an issue with AA, where Allow
header in the 200 OK, generated by the AA, was
empty. But it causes an issue in case of normal
calls between A and B.
In general we want to keep the Allow header in
the 200 OK, if exist.
Instead, we want to add the Allow header in the 200 OK
response in case the 200 OK does not contain
the Allow header. In this case we won't set the
original Allow from the INVITE but instead we will
set a default Allow header (SIP_REPLY_DEFAULT_ALLOW)
containing all the major SIP method.
Change-Id: I6bf5a2cc7e0228f7b99d28963d16c14c463be695
Backport from the upstream to add `lock(mutex)` calls
in order to avoid crash.
Upstream commit: 0af0c924a8fc9638c5b18a4d5799a085ea8132bc
Change-Id: I022b09d2827b41f0785a9c0568c334b8a2af108f
Backport from the upstream to fix parsing of sip uri,
when display name contains uri scheme characters:
's', 'i', 'p', and ':'
Upstream commit: fe760b5afdb455707ad2ed3ada7f7fbda6b2fd0e
Change-Id: Idf0236ae9ef2be958693d589894d52ea1ed70848
Backport from the upstream to support looking up aliased
interface names.
Upstream commit: a84509091031331159abb199e21701cb6d7e79b1
Change-Id: I557dee742351268737fe69df8991aede531bb57b
Backport from the upstream to handle responses to SIP_METH_CANCEL
in Cancelling state, preventing dialog and session leaks i.e. on timeouts.
Upstream commit: 54025209301bd111d56ffcb6540473c4f5057779
Change-Id: Iab1d5797f1f5bcd70a27c805d96dab7e67bb1749
Backport from the upstream to add support for body content type
application/csta+xml in INVITE and INFO requests/responses.
Upstream commit: 6f67d15c3857c1f8ed5b33615b7f5ff0e12d3a92
Change-Id: I085eda4a10e73139bd4dce4d75def82bf6da1e8d
Fix instances of make rules not being parallel execution safe, where the
targets declare a list of dependencies which depend on the order they
have been declared to be executed serially, otherwise these can cause
race conditions.
Either move some of the dependencies down into their transitive
dependencies, or rearrange them to call $(MAKE) to force a serial
point. In other instances add missing dependencies to make sure the
objects to install have previously been built.
Change-Id: I21b499557ac5e9faa603841fa1882b58239ee650
Fix for:
fft.c: In function 'WebRtcIsac_Fftradix':
fft.c:338:22: warning: the comparison will always evaluate as 'false' for the address of 'Tmp0' will never be NULL [-Waddress]
338 | if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL
| ^~
In file included from fft.h:34,
from fft.c:126:
structs.h:250:10: note: 'Tmp0' declared here
250 | double Tmp0[MAXFFTSIZE];
| ^~~~
fft.c:338:48: warning: the comparison will always evaluate as 'false' for the address of 'Tmp1' will never be NULL [-Waddress]
338 | if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL
| ^~
structs.h:251:10: note: 'Tmp1' declared here
251 | double Tmp1[MAXFFTSIZE];
| ^~~~
fft.c:338:74: warning: the comparison will always evaluate as 'false' for the address of 'Tmp2' will never be NULL [-Waddress]
338 | if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL
| ^~
structs.h:252:10: note: 'Tmp2' declared here
252 | double Tmp2[MAXFFTSIZE];
| ^~~~
fft.c:338:100: warning: the comparison will always evaluate as 'false' for the address of 'Tmp3' will never be NULL [-Waddress]
338 | if (fftstate->Tmp0 == NULL || fftstate->Tmp1 == NULL || fftstate->Tmp2 == NULL || fftstate->Tmp3 == NULL
| ^~
structs.h:253:10: note: 'Tmp3' declared here
253 | double Tmp3[MAXFFTSIZE];
| ^~~~
fft.c:339:25: warning: the comparison will always evaluate as 'false' for the address of 'Perm' will never be NULL [-Waddress]
339 | || fftstate->Perm == NULL) {
| ^~
structs.h:254:7: note: 'Perm' declared here
254 | int Perm[MAXFFTSIZE];
| ^~~~
Change-Id: I7060e20d532e80f2ec78c04999676c86136ae34a