MIB, SIB1, random access and regular scheduling are traced.
At the beginning of a connection (rrc setup request and rrc setup), the
RNTI is reported as 0. Might be fixed, somehow, if absolutely needed (not
sure).
./run_tests.sh was not functional anymore because of the introduction
of AssertFatal() in nr_rlc_entity.c
Including the .h and providing exit_function() solves the problem.
Some people needed that.
Let's stop to 19 for the time being. It's tricky enough.
We can increase later if needed. (A previous commit
made the tracers to accept up to 32 variables.)
T_MAX_ARGS was 16 and some people start to use the T machinery with
more than 16 values. So be it. Let tracers be friendly and accept 32.
(More commits to follow for full support.)
Also why is T_MAX_ARGS in T_defs.h when it's only used by event.h?
Hum?
It is very possible that the operating system returns a file
descriptor bigger than the size of bridge->buf (MAX_FD_RFSIMU, which
is 250 as of now). As a minimum, let's fail if the socket file
descriptor is out of bounds.
A proper solution may be implemented later, if needed.
Integration: `2024.w33`
See merge request oai/openairinterface5g!2911
- !2784 Reworking beam structures at NR MAC gNB
- !2889 Fix delta for PUSCH DMRS type 2
- !2908 NR MAC UE CSI improvements
- !2896 Fix for llr functions reading/writing outside buffers
- !2902 nr rlc: reduce "SDU rejected" logging
- !2884 NR UE: Cleanup global variables used for command line parameter storage
- !2910 NR gNB DMRS symbol race
- CI: Update phytest-timing test threshold
- make it work for SRB or DRB
- adapt callers of this function
- cleanup key derivation: the User Plane keys are generated at some places
but are not used, remove the generation
Compiling the nrUE with -fsanitize=undefined leads to a crash
because the function nas_stream_encrypt_eia1() accesses the data
as uint32_t but the data is not aligned.
Actually this function wants 64 bits (big-endian) of data, so let's
introduce a simple function to read a big-endian 64 bits value.
It may seem bad (unoptimized), but looking at the output of gcc
without -fsanitize=undefined this will be translated as just one
movbeq instruction (on the machine where I did the test), which is
actually less instructions than the previous version which was doing
too movbel plus orq.
Moreover, after the main loop we need to process the last remaining
bytes (so less than 8). The code was wrong, reading past the input
data (and also not caring about alignment). It may work, it may fail,
it depends on many things. But it's plain wrong. So this was replaced
for something better, simpler. No need for mask32bit() anymore, only
one call to U64() is needed.
And now -fsanitize=undefined is happy, so all is good.
We also restrict the input length to be multiple of 8 bits. I don't
think it's a problem. To be refined if I'm wrong. (I think RRC and
NAS messages are 8-bits aligned, so it shouldn't be a problem.)
It should not be > 0xffffff.
Normally the core network would prevent this case from happening.
Plus to reach this value means to send a lot of NAS messages, which
is very doubtful in practice.
Anyway, it's better to deal with the case.
We exit if that happens. To be refined if needed (very doubtful).
This function was very wrong, now it's just wrong.
(It does not sanitize the input properly. Some bad input may have
unexpected effects on the nrUE.)
It needs a serious rewrite.
I just wanted to "fix" it so that it processes correctly some
correct input data.
OAI core network is sending Deregistation Accept in clear, even
after security context activation.
The standards is not clear to me, so let's accept it.
To be removed if incorrect with respect to the standards.
(The core network will need to be fixed then.)
The version before this commit is wrong, taking wrong byte for msg_type
in some cases.
I don't have much time to implement a proper NAS PDU parser, so let's go
with hardcoded values.
Some later work will be done to have a cleaner solution. As of now, it's
too much work.
Get the security algorithms from SecurityModeCommand.
Restructure the code a bit: add the function handle_security_mode_command()
and adapt the code to use it.
Derive also knas_enc (not used yet).
Do the derivation for knas_enc and knas_int only after reception
of SecurityModeCommand. We need the algorithms configured by core
network to derive those keys.
The starting point was the function do_NR_DLInformationTransfer() which
may deal with more than 256 bytes.
Then why not cleanup all the functions in the same file.
(And do a bit of formattting fixing while we're here.)
Then cleanup the callers of those functions.
Then, because of do_SIB23_NR() let's also cleanup in some
structures.
Not all the codebase was cleaned up, there surely remain some uint8_t
(and char/short/uint16_t) which are wrong.
By using a struct we may have warnings at compilation time in some
cases if the type is not used properly.
The type definition becomes a bit weird, so we need to properly
comment.
If too strange, we can revert to the classical "void" definition.
- rename "lib_ctx" to "mac_implementation" which is what is stored because
of previous commit
- rename "mac" to "mac_context" to be clearer with what is stored in this
variable too
The main work of this commit is to rewrite cipher_aes_128_cbc_cmac()
which was too slow and created issues when running the 4G eNB on some
machines (LLL when using a b210).
Instead of creating the security context, use it, and delete it, all in
cipher_aes_128_cbc_cmac(), we introduce the function init_aes_128_cbc_cmac()
to create it, and we change cipher_aes_128_cbc_cmac() to just use it,
and we also adapt free_aes_128_cbc_cmac(). The function aes_128_cbc_cmac()
is removed, it does not follow the new init/use/free API.
Doing so, on the primary test machine used to do this work (a powerful
and fast machine where it is possible to set the CPUs' frequencies)
it was possible to limit the CPUs' frequencies to 500 MHz (it was not
possible to go lower) without any LLL (using a b210, quectel UE in
idle, no data traffic, only periodic measurement reports). Before this
commit, it was necessary to set a frequency of at least 1.8 GHz
otherwise some LLL would appear.
Then we need to adapt the rest of the code to take into account those
changes.
A notion of security container (stream_security_container_t) containing
ciphering and integrity contexts is introduced.
And the code is harmonized for, hopefully, better readability.
The (opaque) type stream_security_context_t is introduced, used by
both integrity and ciphering contexts. The idea is to use a
init()/use()/free() API for all the security procedures, identical for
all the ciphering and integrity procedures.
Introduce the structure nr_pdcp_integrity_data_t and adapt code to use it.
Note: in nr_pdcp_sdu_t we keep the 'count' variable (which is also present
in nr_pdcp_integrity_data_t). They represent the same value, but 'count'
in nr_pdcp_integrity_data_t is to be specifically used for integrity while
the other one has other uses, so it's better to keep it.
The case securityModeFailure didn't seem to be implemented
properly, so I just removed it entirely.
The variable 'securityMode' did not make much sense, removed as well.
Plus for integrity, there was: securityMode |= 1 << 5 for nea1
and << 6 for nea2, which does not seem correct (I would expect << 4
and << 5 respectively), so it was properly incorrect.
'securityModeCommand->criticalExtensions.choice.securityModeCommand'
was accessed before checking that
'securityModeCommand->criticalExtensions.present'
is 'NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand',
which is wrong.
The tests 'securityMode >= NO_SECURITY_MODE' and 'securityMode != 0xff'
don't make sense/are unclear, so removed too.
So let's simplify this function, wrong in several places. And put
some AssertFatal() so that the code won't do weird things. The
AssertFatal() can be removed later and the function improved later
if needed. The case securityModeFailure can also be handled later,
but I think there is more work to do than just encoding the message
and send it to the gNB, so it's not bad to remove it for the moment.
The use of security_mode_completed in the PDCP entity was a hack.
Plus it was not working at all with the deregistration request
when nea2 is used, sent when doing ctrl+c in the nrUE.
So let's remove it.
And let's handle activation of integrity and ciphering more in
accordance with what 38.331 says. SecurityModeComplete has to
be sent integrity protected, but not ciphered. Only after should
the ciphering be activated. (See 38.331 5.3.4.3.)
A COTS UE is sending UE capabilities with accessStratumRelease "rel16"
which is not decoded by our RRC. Switching to RRC 16.13.0 lets our RRC
accept these capabilities (and as a positive side effect lets this
particular UE work nicely in NSA fr1).
cleanup means:
- typo: susbend -> suspend
- call nr_pdcp_manager_unlock() where needed
- simplify LOG_XX (remove __FILE__, __LINE__, __FUNCTION__)
note:
nr_pdcp_release_srb() and nr_pdcp_release_drb() don't use
nr_pdcp_release_drb() because they modify the arrays, so
it does not make sense to "abstract" the accesses to
->srb and ->drb.
Security part needs to be checked, may fail to work.
But if it fails, it was probably not working before either.
This commit also contains adding 'static' to nr_pdcp_entity_release()
and nr_pdcp_entity_delete() (it was too complicated to do a separate
commit for this).
We also update stats in free_rx_list() (again, too complicated for
a separate commit).
openair2/RRC/NR/rrc_gNB.c probably needs some more work, it is a
bit ugly to reestablish all the drbs without checking if they
exit. It will generate warnings at runtime. I didn't do it because
I don't know the proper way.
The function generateDRB() sets the value to 100ms but the function
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() sets it to 0ms.
So what happens is that the UE gets the value 100ms in the
RRC Reconfiguration but the gNB creates the PDCP entity with 0ms.
Let's create it with 100ms instead, to be aligned with how we configure
the UE.
And also avoid some PDCP warnings at runtime when some packets
are retransmitted but rejected because of the 0ms timer. This is
the warning:
[PDCP] discard NR PDU rcvd_count=68469, entity->rx_deliv 68481,sdu_in_list 0
This is just a hotfix. A real solution is to have the RB creation in
only one place. And we should also have those parameters configurable.
Work for later.
This commit follows the previous one and adds a dependancy for the
generated .h files so that when we change T_messages.txt to add a
T trace, the compilation succeeds when using ninja in
cmake_targets/ran_build/build.
When using the make system to generate T files, if you change
T_messages.txt you may have problems compiling the gnb with ninja.
If you want to see the problem:
First run: cd cmake_targets; ./build_oai --ninja --gNB
Then: cd common/utils/T
edit T_messages.txt, add a trace, for example:
---
ID = ENB_PHY_UL_TOCK
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
GROUP = ALL:PHY:GRAPHIC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe
---
then run: make
then: cd cmake_targets/ran_build/build; ninja nr-softmodem
You should have an error looking like this:
---
[3/81] Checking validity of VCD files
FAILED: common/utils/T/CMakeFiles/check_vcd /tmp/develop/cmake_targets/ran_build/build/common/utils/T/CMakeFiles/check_vcd
cd /tmp/develop/cmake_targets/ran_build/build/common/utils/T && /tmp/develop/cmake_targets/ran_build/build/common/utils/T/_check_vcd /tmp/develop/common/utils/T/T_messages.txt /tmp/develop/common/utils/T/../LOG/vcd_signal_dumper.h
error: VCD_FIRST_VARIABLE is not correct in T_defs.h
You probably added a VCD trace (variable or function) but you did not
update T_messages.txt and/or T_defs.h in common/utils/T/
[...]
---
Let's first isolate the generated T .h files when using make because
we have two versions of T_IDs.h and T_messages.txt.h when mixing
make/cmake.
A next commit will regenerate T_IDs.h and T_messages.txt.h when
T_messages.txt chages for the cmake system, because this commit
does not solve the problem.
tx_next was increased only when all segments of an SDU were sent to
lower layers. This may lead to a situation where the receive entity
transmits a control PDU that is rejected because it sets its ACK to
tx_next+1 (if all segments were not transmitted when the control PDU
is sent).
What is done now is to increase tx_next as soon as we send the first
segment of an SDU to lower layers. A control PDU received from the
receive entity is now accepted and processed.
Specifications (38.322 5.2.3.1.1) say to increase tx_next when the
RLC entity receives an SDU from upper layers. But for us, since the
buffering of SDUs is done in the RLC layer and since the buffer size
may be big, we may increase tx_next too much. The choice has been
made to increase it only when we transmit an SDU to lower layers.
We may change this logic if needed. (But it won't be simple.)
When t_poll_retransmit expires we need to consider an SDU for
retransmission.
We used to take the first SDU (which could be a segment, not a full SDU)
of the wait list and put it in the retransmit list.
When testing with some UE (Amarisoft UE) a bad behavior was detected.
This is what happens for the SDU with SN 6 (for illustration purpose).
The gNB is sending an SDU in several pieces (it is segmented).
slot n: rlc sn 6 [1 .. 119[ p=0 RECEIVED
slot n+x: rlc sn 6 ]120 .. 180[ p=0 RECEIVED
slot n+x+y: rlc sn 6 ]181 .. 210] p=1 not RECEIVED
Then when t_poll_retransmit expires rlc retransmits only the PDU of
slot n (with p=1 this time) and the UE replies with ack 6. So nothing
happens on the gnb side.
(We would have expected ack 7 + nack 6 181..end.)
Then after t_poll_retransmit expires again rlc retransmits only PDU
of slot n and the UE still replies with ack 6.
This goes on forever (or some other timeout occurs.)
The logic is now changed.
When t_poll_retransmit expires we transfer all the SDUs in the wait list
having the same SN as the head of the wait list into the retransmit list.
Testing with Amarisoft UE, it seems to work properly.
The RLC tests were not compiling because of the include of
openair2/RRC/NR/rrc_gNB_radio_bearers.h
by
openair2/LAYER2/nr_rlc/nr_rlc_entity.h
which does not seem correct/necessary to start with.
The only thing needed by nr_rlc_entity.h from rrc_gNB_radio_bearers.h
is MAX_DRBS_PER_UE which can be defined in common/platform_constants.h
like NGAP_MAX_PDU_SESSION.