Commit f918be96 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2024_w01' into 'develop'

Integration: 2024.w01

See merge request oai/openairinterface5g!2502

* !2482 Trigger UL Failure if Ack of Msg4 not received and implement RA Contention Resolution timer in gNB
* !2484 function to harmonize handling of NAS registraction accept
* !2487 Rework PUCCH codec with c16_t type and functions to make readable code
* !2491 improvements for NR UE detaching
* !2499 Update L1sim and RFsim documentation
* !2500 Fix FAPI CoreSetType enumeration options after the fix on the description made by SCF
* !2489 NR UE improvements RRCSetup
parents c37974ca 898473d6
...@@ -12,23 +12,29 @@ ...@@ -12,23 +12,29 @@
</tr> </tr>
</table> </table>
This page is valid for the develop branch **Note: unless you know what you are doing, you likely do not need this!
Rather, you are probably looking for the
[RFsimulator](../radio/rfsimulator/README.md)!**
**Table of Contents** oaisim has been scraped and replaced by the same programs that are used for the
real-time operation, `lte-softmodem` and `lte-uesoftmodem`. This uses the IF4p5
fronthaul protocol to achieve the communication.
[[_TOC_]] Context: oaisim used to be a simulation mode inside OAI to emulate an eNB and
multiple UEs.
The old oaisim is dead! Long live oaisim! :)
If you are looking for a description of the old oaisim (which is still available in some branches/tags), please see [here](OpenAirLTEEmulation) and [here](how-to-run-oaisim-with-multiple-ue). [[_TOC_]]
oaisim has been scraped and replaced by the same programs that are used for the real-time operation, `lte-softmodem` and `lte-uesoftmodem`. The latter also now includes an optional channel model, just like oaisim did. # Build
# <a name="build">[How to build the eNB and the UE](BUILD.md)</a> Build eNB/UE as normal, as also described in [How to build the eNB and the UE](./BUILD.md):
```bash
./build_oai -c --ninja --eNB --UE
```
The following paragraph explains how to run the L1 simulator in noS1 mode and using the oai kernel modules. # How to run an eNB with the noS1 option
# <a name="run-noS1-eNB">How to run an eNB with the noS1 option</a> The following paragraph(s) explains how to run the L1 simulator in noS1 mode and using the oai kernel modules.
Modify the configuration file for IF4p5 fronthaul, `/openairinterface5g/ci-scripts/conf_files/rcc.band7.nos1.simulator.conf`, and replace the loopback interface with a physical ethernet interface and the IP addresses to work on your network. Copy your modifications to a new file, let's call YYY.conf the resulting configuration file. Modify the configuration file for IF4p5 fronthaul, `/openairinterface5g/ci-scripts/conf_files/rcc.band7.nos1.simulator.conf`, and replace the loopback interface with a physical ethernet interface and the IP addresses to work on your network. Copy your modifications to a new file, let's call YYY.conf the resulting configuration file.
...@@ -42,7 +48,7 @@ $ cd ../ran_build/build ...@@ -42,7 +48,7 @@ $ cd ../ran_build/build
$ sudo -E ./lte-softmodem -O YYY.conf --noS1 --nokrnmod 0 $ sudo -E ./lte-softmodem -O YYY.conf --noS1 --nokrnmod 0
``` ```
# <a name="run-noS1-UE">How to run a UE with the noS1 option</a> # How to run a UE with the noS1 option
Similarly modify the example configuration file in `/openairinterface5g/ci-scripts/conf_files/rru.band7.nos1.simulator.conf` and replace loopback interface and IP addresses. Copy your modifications to a new file, let's call XXX.conf the resulting configuration file. Similarly modify the example configuration file in `/openairinterface5g/ci-scripts/conf_files/rru.band7.nos1.simulator.conf` and replace loopback interface and IP addresses. Copy your modifications to a new file, let's call XXX.conf the resulting configuration file.
...@@ -58,38 +64,17 @@ $ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1 --nokrnmod 0 ...@@ -58,38 +64,17 @@ $ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1 --nokrnmod 0
That should give you equivalent functionality to what you had with oaisim including noise and RF channel emulation (path loss / fading, etc.). You should also be able to run multiple UEs. That should give you equivalent functionality to what you had with oaisim including noise and RF channel emulation (path loss / fading, etc.). You should also be able to run multiple UEs.
# <a name="CInote">Continuous Integration notes</a> # How to ping an eNB from a UE and vice versa (with the noS1 option)
The CI currently tests the noS1 build option with one eNB and one UE in the following scenarios:
* pinging one UE from one eNB
* pinging one eNB from one UE
* iperf download between one eNB and one UE
* iperf upload between one eNB and one UE
* all the above tests are done in FDD 5Mhz mode.
# <a name="noS1-pinging">How to ping an eNB from a UE and vice versa (with the noS1 option)</a>
Once your eNB and UE (built with the noS1 option) are running and synchronised, you can ping the eNB from the UE with the following command: Once your eNB and UE (built with the noS1 option) are running and synchronised, you can ping the eNB from the UE with the following command:
```bash ```bash
ping -I oai0 -c 20 $eNB_ip_addr ping -I oai0 -c 20 $eNB_ip_addr
``` ```
where $eNB_ip_addr is the IP address of your eNB. where `$eNB_ip_addr` is the IP address of your eNB.
Similarly, you can ping the UE from the eNB. Similarly, you can ping the UE from the eNB.
The IP adresses of the eNB and the UE are set up by the init_nas_nos1 program and should have the following values: The IP adresses of the eNB and the UE are set up by the `init_nas_nos1` program and should have the following values:
* eNB_ip_addr set to 20 10.0.1.1 * `$eNB_ip_addr` set to 10.0.1.1
* ue_ip_addr set to 20 10.0.1.2 * `ue_ip_addr` set to 10.0.1.2
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
[oai softmodem features](FEATURE_SET.md)
[oai softmodem build procedure](BUILD.md)
...@@ -7,12 +7,18 @@ ...@@ -7,12 +7,18 @@
</a> </a>
</td> </td>
<td style="border-collapse: collapse; border: none; vertical-align: center;"> <td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">Running OAI Softmodems</font></b> <b><font size = "5">Running OAI 5G Softmodems</font></b>
</td> </td>
</tr> </tr>
</table> </table>
After you have [built the softmodem executables](BUILD.md) you can set your default directory to the build directory `cmake_targets/ran_build/build/` and start testing some use cases. Below, the description of the different oai functionalities should help you choose the oai configuration that suits your need. This document explains some options for running 5G executables.
After you have [built the softmodem executables](BUILD.md) you can set your
default directory to the build directory `cmake_targets/ran_build/build/` and
start testing some use cases. Below, the description of the different OAI
functionalities should help you choose the OAI configuration that suits your
need.
[[_TOC_]] [[_TOC_]]
...@@ -20,28 +26,27 @@ After you have [built the softmodem executables](BUILD.md) you can set your defa ...@@ -20,28 +26,27 @@ After you have [built the softmodem executables](BUILD.md) you can set your defa
## RFsimulator ## RFsimulator
The RF simulator is an OAI device replacing the radio heads (for example the USRP device). It allows connecting the oai UE (LTE or 5G) and respectively the oai eNodeB or gNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation. The rf simulator has some preliminary support for channel modeling. The RFsimulator is an OAI device replacing the radio heads (for example the
USRP device). It allows connecting the oai UE (LTE or 5G) and respectively the
oai eNodeB or gNodeB through a network interface carrying the time-domain
samples, getting rid of over the air unpredictable perturbations. This is the
ideal tool to check signal processing algorithms and protocols implementation.
The RFsimulator has some preliminary support for channel modeling.
It is planned to enhance this simulator with the following functionalities: It is planned to enhance this simulator with the following functionalities:
- Support for multiple eNodeB's or gNodeB's for hand-over tests - Support for multiple eNodeB's or gNodeB's for hand-over tests
This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../radio/rfsimulator/README.md ) contains the detailed documentation. This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../radio/rfsimulator/README.md) contains the detailed documentation.
## L2 nFAPI Simulator ## L2 nFAPI Simulator
This simulator connects a eNodeB and UEs through a nfapi interface, short-cutting the L1 layer. The objective of this simulator is to allow multi UEs simulation, with a large number of UEs (ideally up to 255 ) .Here to ease the platform setup, UEs are simulated via a single `lte-uesoftmodem` instance. Today the CI tests just with one UE and architecture has to be reviewed to allow a number of UE above about 16. This work is on-going. This simulator connects an eNodeB and UEs through an nFAPI interface,
short-cutting the L1 layer. The objective of this simulator is to allow multi
As for the rf simulator, no specific hardware is required. The [L2 nfapi simulator page](L2NFAPI.md) contains the detailed documentation. UEs simulation, with a large number of UEs (ideally up to 255).
## L1 Simulator
**This information might be outdated. We recommend to use the RFsimulator as
shown above.**
The L1 simulator is using the ethernet fronthaul protocol, as used to connect a RRU and a RAU to connect UEs and a eNodeB. UEs are simulated in a single `lte-uesoftmodem` process, as for the nfapi simulator. As for the RFsimulator, no specific hardware is required. The [L2 nfapi
simulator page](./L2NFAPI.md) contains the detailed documentation.
The [L1 simulator page](L1SIM.md) contains the detailed documentation.
# Running with a true radio head # Running with a true radio head
...@@ -89,7 +94,7 @@ At the UE the --sa flag will: ...@@ -89,7 +94,7 @@ At the UE the --sa flag will:
4) 5G-NR RRC Reconfiguration 4) 5G-NR RRC Reconfiguration
5) Start Downlink and Uplink Data Transfer 5) Start Downlink and Uplink Data Transfer
Command line parameters for UE in --sa mode: Command line parameters for UE in `--sa` mode:
- `-C` : downlink carrier frequency in Hz (default value 0) - `-C` : downlink carrier frequency in Hz (default value 0)
- `--CO` : uplink frequency offset for FDD in Hz (default value 0) - `--CO` : uplink frequency offset for FDD in Hz (default value 0)
- `--numerology` : numerology index (default value 1) - `--numerology` : numerology index (default value 1)
...@@ -104,7 +109,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band ...@@ -104,7 +109,7 @@ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --sa sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --sa
``` ```
With the RF simulator (on the same machine): With the RFsimulator (on the same machine):
```bash ```bash
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa
...@@ -117,11 +122,15 @@ Additionally, at UE side `--uecap_file` option can be used to pass the UE Capabi ...@@ -117,11 +122,15 @@ Additionally, at UE side `--uecap_file` option can be used to pass the UE Capabi
Some other useful paramters of the UE are Some other useful paramters of the UE are
- --ue-fo-compensation: enables the frequency offset compenstation at the UE. This is useful when running over the air and/or without an external clock/time source - `--ue-fo-compensation`: enables the frequency offset compenstation at the UE. This is useful when running over the air and/or without an external clock/time source
- --usrp-args: this is the equivalend paramter of sdr_addrs field in the gNB config file and can be used to identify the USRP and set some basic paramters (like the clock source) - `--usrp-args`: this is the equivalend paramter of `sdr_addrs` field in the gNB config file and can be used to identify the USRP and set some basic paramters (like the clock source)
- --clock-source: sets the clock-source (internal or external). - `--clock-source`: sets the clock-source (internal or external).
- --time-source: sets the time-source (internal or external). - `--time-source`: sets the time-source (internal or external).
You can see all options by typing
```
./nr-uesoftmodem --help
```
# Specific OAI modes # Specific OAI modes
...@@ -154,9 +163,31 @@ In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB ...@@ -154,9 +163,31 @@ In phy-test mode it is possible to mimic the reception of UE Capabilities at gNB
## noS1 setup with OAI UE ## noS1 setup with OAI UE
Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode. Instead of randomly generated payload, in the phy-test mode we can also
inject/receive user-plane traffic over a TUN interface. This is the so-called
noS1 mode.
This setup is described in the [rfsimulator page](../radio/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested. The noS1 mode is applicable to both gNB/UE, and enabled by passing `--noS1` as
an option. The gNB/UE will open a TUN interface which the interface names and
IP addresses `oaitun_enb1`/10.0.1.1, and `oaitun_ue1`/10.0.1.2, respectively.
You can then use these interfaces to send traffic, e.g.,
```bash
iperf -sui1 -B 10.0.1.2
```
to open an iperf server on the UE side, and
```bash
iperf -uc 10.0.1.2 -B 10.0.1.1 -i1 -t10 -b1M
```
to send data from the gNB down to the UE.
Note that this does not work if both interfaces are on the same host. We
recommend to use two different hosts, or at least network namespaces, to route
traffic through the gNB/UE tunnel.
This option is only really helpful for phy-test/do-ra (see below) modes, in
which the UE does not connect to a core network. If the UE connects to a core
network, it receives an IP address for which it automatically opens a network
interface.
## do-ra setup with OAI ## do-ra setup with OAI
...@@ -244,7 +275,3 @@ The DL logical antenna port configuration can be selected through configuration ...@@ -244,7 +275,3 @@ The DL logical antenna port configuration can be selected through configuration
Finally the number of TX physical antenna in the RU part of the configuration file, `nb_tx`, should be equal or larger than the total number of PDSCH logical antenna ports. Finally the number of TX physical antenna in the RU part of the configuration file, `nb_tx`, should be equal or larger than the total number of PDSCH logical antenna ports.
[Example of configuration file with parameters for 2-layer MIMO](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf) [Example of configuration file with parameters for 2-layer MIMO](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf)
# Additional links
[Selecting an alternative ldpc implementation at run time](../openair1/PHY/CODING/DOC/LDPCImplementation.md)
...@@ -286,7 +286,6 @@ typedef enum { ...@@ -286,7 +286,6 @@ typedef enum {
typedef enum { typedef enum {
NFAPI_NR_CSET_CONFIG_MIB_SIB1=0, NFAPI_NR_CSET_CONFIG_MIB_SIB1=0,
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0 NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0
} nfapi_nr_coreset_config_type_e; } nfapi_nr_coreset_config_type_e;
typedef enum { typedef enum {
......
...@@ -8,144 +8,152 @@ ...@@ -8,144 +8,152 @@
configmodule_interface_t *uniqCfg = NULL; configmodule_interface_t *uniqCfg = NULL;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
time_stats_t timeEncoder,timeDecoder; time_stats_t timeEncoder, timeDecoder;
opp_enabled=1; opp_enabled = 1;
reset_meas(&timeEncoder); reset_meas(&timeEncoder);
reset_meas(&timeDecoder); reset_meas(&timeDecoder);
randominit(0); randominit(0);
int arguments, iterations = 1000, messageLength = 11; int arguments, iterations = 1000, messageLength = 11;
//int matlabDebug = 0; // int matlabDebug = 0;
uint32_t testInput, encoderOutput, codingDifference, nBitError=0, blockErrorState = 0, blockErrorCumulative=0, bitErrorCumulative=0; uint32_t testInput, encoderOutput, codingDifference, nBitError = 0, blockErrorState = 0, blockErrorCumulative = 0,
uint16_t estimatedOutput; bitErrorCumulative = 0;
double SNRstart = -20.0, SNRstop = 5.0, SNRinc= 0.5; //dB uint16_t estimatedOutput;
double SNR, SNR_lin, sigma; double SNRstart = -20.0, SNRstop = 5.0, SNRinc = 0.5; // dB
double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS]; double SNR, SNR_lin, sigma;
//int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS]; double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS];
int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS]; // int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
unsigned char qbits=8; int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS];
unsigned char qbits = 8;
while ((arguments = getopt (argc, argv, "s:d:f:l:i:mhg")) != -1)
switch (arguments) while ((arguments = getopt(argc, argv, "s:d:f:l:i:mhg")) != -1)
{ switch (arguments) {
case 's': case 's':
SNRstart = atof(optarg); SNRstart = atof(optarg);
break; break;
case 'd': case 'd':
SNRinc = atof(optarg); SNRinc = atof(optarg);
break; break;
case 'f': case 'f':
SNRstop = atof(optarg); SNRstop = atof(optarg);
break; break;
case 'l': case 'l':
messageLength = atoi(optarg); messageLength = atoi(optarg);
break; break;
case 'i': case 'i':
iterations = atoi(optarg); iterations = atoi(optarg);
break; break;
/*case 'm': /*case 'm':
matlabDebug = 1; matlabDebug = 1;
//#define DEBUG_POLAR_MATLAB //#define DEBUG_POLAR_MATLAB
break;*/ break;*/
case 'g': case 'g':
iterations = 1; iterations = 1;
SNRstart = -6.0; SNRstart = -6.0;
SNRstop = -6.0; SNRstop = -6.0;
messageLength = 11; messageLength = 11;
break; break;
case 'h': case 'h':
//printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n"); // printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n");
printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n"); printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n");
exit(-1); exit(-1);
default: default:
perror("[smallblocktest.c] Problem at argument parsing with getopt"); perror("[smallblocktest.c] Problem at argument parsing with getopt");
exit(-1); exit(-1);
} }
uint16_t mask = 0x07ff >> (11 - messageLength);
uint16_t mask = 0x07ff >> (11-messageLength); for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { printf("SNR %f\n", SNR);
printf("SNR %f\n",SNR); SNR_lin = pow(10, SNR / 10.0);
SNR_lin = pow(10, SNR/10.0); sigma = 1.0 / sqrt(SNR_lin);
sigma = 1.0/sqrt(SNR_lin);
for (int itr = 1; itr <= iterations; itr++) {
for (int itr = 1; itr <= iterations; itr++) { // Generate random test input of length "messageLength"
testInput = 0;
//Generate random test input of length "messageLength" for (int i = 1; i < messageLength; i++) {
testInput = 0; testInput |= (((uint32_t)(rand() % 2)) & 1);
for (int i = 1; i < messageLength; i++) { testInput <<= 1;
testInput |= ( ((uint32_t) (rand()%2)) &1); }
testInput<<=1; testInput |= (((uint32_t)(rand() % 2)) & 1);
} // Encoding
testInput |= ( ((uint32_t) (rand()%2)) &1); start_meas(&timeEncoder);
//Encoding encoderOutput = encodeSmallBlock(testInput, messageLength);
start_meas(&timeEncoder); stop_meas(&timeEncoder);
encoderOutput = encodeSmallBlock((uint16_t*)&testInput, (uint8_t)messageLength);
stop_meas(&timeEncoder); for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; i++) {
// BPSK modulation
for (int i=0; i<NR_SMALL_BLOCK_CODED_BITS; i++) { if ((encoderOutput >> i) & 1) {
//BPSK modulation modulatedInput[i] = -1;
if ((encoderOutput>>i) & 1 ) { } else {
modulatedInput[i]=-1; modulatedInput[i] = 1;
} else { }
modulatedInput[i]=1;
} // AWGN
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(SNR_lin)));
//AWGN
channelOutput[i] = modulatedInput[i] + ( gaussdouble(0.0,1.0) * ( 1/sqrt(SNR_lin) ) ); // Quantization
channelOutput_int8[i] = quantize(sigma / 16.0, channelOutput[i], qbits);
//Quantization }
channelOutput_int8[i] = quantize(sigma/16.0, channelOutput[i], qbits);
} // Decoding
start_meas(&timeDecoder);
//Decoding estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength);
start_meas(&timeDecoder); stop_meas(&timeDecoder);
estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength);
stop_meas(&timeDecoder);
#ifdef DEBUG_SMALLBLOCKTEST #ifdef DEBUG_SMALLBLOCKTEST
printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput); printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput);
for (int i=0;i<32;i++) for (int i = 0; i < 32; i++)
printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n", i, (testInput>>i)&1, i, (estimatedOutput>>i)&1, i, (codingDifference>>i)&1, i, (mask>>i)&1); printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n",
i,
(testInput >> i) & 1,
i,
(estimatedOutput >> i) & 1,
i,
(codingDifference >> i) & 1,
i,
(mask >> i) & 1);
#endif #endif
//Error Calculation // Error Calculation
estimatedOutput &= mask; estimatedOutput &= mask;
codingDifference = ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm. codingDifference =
((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm.
for (nBitError = 0; codingDifference; nBitError++) for (nBitError = 0; codingDifference; nBitError++)
codingDifference &= codingDifference - 1; codingDifference &= codingDifference - 1;
blockErrorState = (nBitError > 0) ? 1 : 0; blockErrorState = (nBitError > 0) ? 1 : 0;
blockErrorCumulative+=blockErrorState; blockErrorCumulative += blockErrorState;
bitErrorCumulative+=nBitError; bitErrorCumulative += nBitError;
nBitError = 0; blockErrorState = 0; nBitError = 0;
} blockErrorState = 0;
}
//Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively. // Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively.
printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n", printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n",
SNR, SNR,
((double)bitErrorCumulative / (iterations*messageLength)), ((double)bitErrorCumulative / (iterations * messageLength)),
((double)blockErrorCumulative/iterations), ((double)blockErrorCumulative / iterations),
((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()), ((double)timeEncoder.diff / timeEncoder.trials) / (get_cpu_freq_GHz()),
((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0)); ((double)timeDecoder.diff / timeDecoder.trials) / (get_cpu_freq_GHz() * 1000.0));
blockErrorCumulative=0; blockErrorCumulative = 0;
bitErrorCumulative=0; bitErrorCumulative = 0;
} }
print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL); print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL); print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);
return (0); return (0);
} }
...@@ -34,11 +34,12 @@ ...@@ -34,11 +34,12 @@
//input = [0 ... 0 c_K-1 ... c_2 c_1 c_0] //input = [0 ... 0 c_K-1 ... c_2 c_1 c_0]
//output = [d_31 d_30 ... d_2 d_1 d_0] //output = [d_31 d_30 ... d_2 d_1 d_0]
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len){ uint32_t encodeSmallBlock(int in, int len)
uint32_t out = 0; {
for (uint16_t i=0; i<len; i++) uint32_t out = 0;
if ((*in & (1<<i)) > 0) for (int i = 0; i < len; i++)
out^=nrSmallBlockBasis[i]; if ((in & (1 << i)) > 0)
out ^= nrSmallBlockBasis[i];
return out; return out;
} }
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#define L1d_CLS 64 #define L1d_CLS 64
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len); uint32_t encodeSmallBlock(int in, int len);
uint16_t decodeSmallBlock(int8_t *in, uint8_t len); uint16_t decodeSmallBlock(int8_t *in, uint8_t len);
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
uint32_t n_id, uint32_t n_id,
uint8_t n_hop, int n_hop,
int nr_slot_tx, int nr_slot_tx,
uint8_t *u, uint8_t *u,
uint8_t *v); uint8_t *v);
......
...@@ -32,12 +32,13 @@ ...@@ -32,12 +32,13 @@
#include "nr_dci.h" #include "nr_dci.h"
void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
uint32_t n_id, uint32_t n_id,
uint8_t n_hop, int n_hop,
int nr_slot_tx, int nr_slot_tx,
uint8_t *u, uint8_t *u,
uint8_t *v) { uint8_t *v)
{
/* /*
* Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping
* The following variables are set by higher layers: * The following variables are set by higher layers:
......
This diff is collapsed.
This diff is collapsed.
...@@ -215,7 +215,8 @@ extern "C" { ...@@ -215,7 +215,8 @@ extern "C" {
{ {
return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)}; return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
} }
__attribute__((always_inline)) inline c16_t c16divShift(const c16_t a, const c16_t b, const int Shift) { __attribute__((always_inline)) inline c16_t c16MulConjShift(const c16_t a, const c16_t b, const int Shift)
{
return (c16_t) { return (c16_t) {
.r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift), .r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift),
.i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift) .i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift)
......
...@@ -83,64 +83,7 @@ binary_search_float_nr( ...@@ -83,64 +83,7 @@ binary_search_float_nr(
return first; return first;
} }
/*
void nr_generate_pucch0(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
int16_t amp,
int nr_slot_tx,
uint8_t mcs,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB);
void nr_generate_pucch1(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t timeDomainOCC,
uint8_t nr_bit);
void nr_generate_pucch2(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit);
void nr_generate_pucch3_4(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
pucch_format_nr_t fmt,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_slot_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit,
uint8_t occ_length_format4,
uint8_t occ_index_format4);
*/
/**************** variables **************************************/
/**************** functions **************************************/
//extern uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
//extern uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
/******************************************************************* /*******************************************************************
* *
* NAME : pucch_procedures_ue_nr * NAME : pucch_procedures_ue_nr
......
...@@ -401,6 +401,10 @@ typedef struct nas_deregistration_req_s { ...@@ -401,6 +401,10 @@ typedef struct nas_deregistration_req_s {
release_cause_t cause; release_cause_t cause;
} nas_deregistration_req_t; } nas_deregistration_req_t;
typedef struct nas_detach_req_s {
bool wait_release;
} nas_detach_req_t;
/* /*
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* NAS information transfer * NAS information transfer
......
...@@ -61,6 +61,7 @@ MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefre ...@@ -61,6 +61,7 @@ MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefre
MESSAGE_DEF(NAS_CELL_SELECTION_REQ, MESSAGE_PRIORITY_MED, NasCellSelectionReq, nas_cell_selection_req) MESSAGE_DEF(NAS_CELL_SELECTION_REQ, MESSAGE_PRIORITY_MED, NasCellSelectionReq, nas_cell_selection_req)
MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, NasConnEstabliReq, nas_conn_establi_req) MESSAGE_DEF(NAS_CONN_ESTABLI_REQ, MESSAGE_PRIORITY_MED, NasConnEstabliReq, nas_conn_establi_req)
MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req) MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq, nas_ul_data_req)
MESSAGE_DEF(NAS_DETACH_REQ, MESSAGE_PRIORITY_MED, NasDetachReq, nas_detach_req)
MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, NasDeregistrationReq, nas_deregistration_req) MESSAGE_DEF(NAS_DEREGISTRATION_REQ, MESSAGE_PRIORITY_MED, NasDeregistrationReq, nas_deregistration_req)
MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp) MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp)
......
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
#define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req #define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req
#define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req #define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req
#define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req #define NAS_UPLINK_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_req
#define NAS_DETACH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_detach_req
#define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req #define NAS_DEREGISTRATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_deregistration_req
#define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp #define NAS_RAB_ESTABLI_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_rab_est_rsp
...@@ -429,6 +430,7 @@ typedef cell_info_req_t NasCellSelectionReq; ...@@ -429,6 +430,7 @@ typedef cell_info_req_t NasCellSelectionReq;
typedef nas_establish_req_t NasConnEstabliReq; typedef nas_establish_req_t NasConnEstabliReq;
typedef ul_info_transfer_req_t NasUlDataReq; typedef ul_info_transfer_req_t NasUlDataReq;
typedef nas_deregistration_req_t NasDeregistrationReq; typedef nas_deregistration_req_t NasDeregistrationReq;
typedef nas_detach_req_t NasDetachReq;
typedef rab_establish_rsp_t NasRabEstRsp; typedef rab_establish_rsp_t NasRabEstRsp;
......
...@@ -4431,20 +4431,18 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD ...@@ -4431,20 +4431,18 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
} }
void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
{
int32_t duration;
if (coreset0 == NULL) if (coreset0 == NULL)
coreset0 = calloc(1,sizeof(*coreset0)); coreset0 = calloc(1,sizeof(*coreset0));
coreset0->controlResourceSetId = 0;
AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n"); AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n");
duration = type0_PDCCH_CSS_config->num_symbols; coreset0->controlResourceSetId = 0;
int duration = type0_PDCCH_CSS_config->num_symbols;
if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6); if(coreset0->frequencyDomainResources.buf == NULL)
coreset0->frequencyDomainResources.buf = calloc(1,6);
switch(type0_PDCCH_CSS_config->num_rbs){ switch(type0_PDCCH_CSS_config->num_rbs){
case 24: case 24:
...@@ -4470,8 +4468,9 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf ...@@ -4470,8 +4468,9 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf
coreset0->frequencyDomainResources.bits_unused = 3; coreset0->frequencyDomainResources.bits_unused = 3;
coreset0->duration = duration; coreset0->duration = duration;
coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved)); if (!coreset0->cce_REG_MappingType.choice.interleaved)
coreset0->cce_REG_MappingType.choice.interleaved = calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved));
coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6; coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2; coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL; // -> use cell_id coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL; // -> use cell_id
...@@ -4481,23 +4480,28 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf ...@@ -4481,23 +4480,28 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf
coreset0->tci_StatesPDCCH_ToReleaseList = NULL; coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
coreset0->tci_PresentInDCI = NULL; coreset0->tci_PresentInDCI = NULL;
coreset0->pdcch_DMRS_ScramblingID = NULL; coreset0->pdcch_DMRS_ScramblingID = NULL;
} }
void fill_searchSpaceZero(NR_SearchSpace_t *ss0, void fill_searchSpaceZero(NR_SearchSpace_t *ss0,
int slots_per_frame, int slots_per_frame,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
{ {
if(ss0 == NULL)
if(ss0 == NULL) ss0=calloc(1,sizeof(*ss0)); ss0 = calloc(1, sizeof(*ss0));
if(ss0->controlResourceSetId == NULL) ss0->controlResourceSetId=calloc(1,sizeof(*ss0->controlResourceSetId)); if(ss0->controlResourceSetId == NULL)
if(ss0->monitoringSymbolsWithinSlot == NULL) ss0->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss0->monitoringSymbolsWithinSlot)); ss0->controlResourceSetId = calloc(1, sizeof(*ss0->controlResourceSetId));
if(ss0->monitoringSymbolsWithinSlot->buf == NULL) ss0->monitoringSymbolsWithinSlot->buf = calloc(1,2); if(ss0->monitoringSymbolsWithinSlot == NULL)
if(ss0->nrofCandidates == NULL) ss0->nrofCandidates = calloc(1,sizeof(*ss0->nrofCandidates)); ss0->monitoringSymbolsWithinSlot = calloc(1, sizeof(*ss0->monitoringSymbolsWithinSlot));
if(ss0->searchSpaceType == NULL) ss0->searchSpaceType = calloc(1,sizeof(*ss0->searchSpaceType)); if(ss0->monitoringSymbolsWithinSlot->buf == NULL)
if(ss0->searchSpaceType->choice.common == NULL) ss0->searchSpaceType->choice.common=calloc(1,sizeof(*ss0->searchSpaceType->choice.common)); ss0->monitoringSymbolsWithinSlot->buf = calloc(1, 2);
if(ss0->nrofCandidates == NULL)
ss0->nrofCandidates = calloc(1, sizeof(*ss0->nrofCandidates));
if(ss0->searchSpaceType == NULL)
ss0->searchSpaceType = calloc(1, sizeof(*ss0->searchSpaceType));
if(ss0->searchSpaceType->choice.common == NULL)
ss0->searchSpaceType->choice.common = calloc(1, sizeof(*ss0->searchSpaceType->choice.common));
if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL)
ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1, sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n"); AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n");
...@@ -4508,13 +4512,15 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, ...@@ -4508,13 +4512,15 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0,
ss0->searchSpaceId = 0; ss0->searchSpaceId = 0;
*ss0->controlResourceSetId = 0; *ss0->controlResourceSetId = 0;
ss0->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss0->monitoringSlotPeriodicityAndOffset)); if(ss0->monitoringSlotPeriodicityAndOffset == NULL)
ss0->monitoringSlotPeriodicityAndOffset = calloc(1, sizeof(*ss0->monitoringSlotPeriodicityAndOffset));
set_monitoring_periodicity_offset(ss0,periodicity,offset); set_monitoring_periodicity_offset(ss0,periodicity,offset);
const uint32_t duration = type0_PDCCH_CSS_config->search_space_duration; const uint32_t duration = type0_PDCCH_CSS_config->search_space_duration;
if (duration==1) if (duration==1)
ss0->duration = NULL; ss0->duration = NULL;
else{ else{
ss0->duration = calloc(1,sizeof(*ss0->duration)); if (!ss0->duration)
ss0->duration = calloc(1, sizeof(*ss0->duration));
*ss0->duration = duration; *ss0->duration = duration;
} }
......
...@@ -795,6 +795,22 @@ void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs) ...@@ -795,6 +795,22 @@ void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs)
pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL); pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
} }
static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source)
{
target->systemFrameNumber.size = source->systemFrameNumber.size;
target->systemFrameNumber.bits_unused = source->systemFrameNumber.bits_unused;
if (!target->systemFrameNumber.buf)
target->systemFrameNumber.buf = calloc(target->systemFrameNumber.size, sizeof(*target->systemFrameNumber.buf));
for (int i = 0; i < target->systemFrameNumber.size; i++)
target->systemFrameNumber.buf[i] = source->systemFrameNumber.buf[i];
target->subCarrierSpacingCommon = source->subCarrierSpacingCommon;
target->ssb_SubcarrierOffset = source->ssb_SubcarrierOffset;
target->dmrs_TypeA_Position = source->dmrs_TypeA_Position;
target->pdcch_ConfigSIB1 = source->pdcch_ConfigSIB1;
target->cellBarred = source->cellBarred;
target->intraFreqReselection = source->intraFreqReselection;
}
void nr_rrc_mac_config_req_mib(module_id_t module_id, void nr_rrc_mac_config_req_mib(module_id_t module_id,
int cc_idP, int cc_idP,
NR_MIB_t *mib, NR_MIB_t *mib,
...@@ -802,16 +818,16 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, ...@@ -802,16 +818,16 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
{ {
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
AssertFatal(mib, "MIB should not be NULL\n"); AssertFatal(mib, "MIB should not be NULL\n");
// initialize dl and ul config_request upon first reception of MIB if (!mac->mib)
mac->mib = mib; // update by every reception mac->mib = calloc(1, sizeof(*mac->mib));
update_mib_conf(mac->mib, mib);
mac->phy_config.Mod_id = module_id; mac->phy_config.Mod_id = module_id;
mac->phy_config.CC_id = cc_idP; mac->phy_config.CC_id = cc_idP;
if (sched_sib == 1) if (sched_sib == 1)
mac->get_sib1 = true; mac->get_sib1 = true;
else if (sched_sib == 2) else if (sched_sib == 2)
mac->get_otherSI = true; mac->get_otherSI = true;
nr_ue_decode_mib(module_id, nr_ue_decode_mib(module_id, cc_idP);
cc_idP);
} }
static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target) static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
...@@ -1365,11 +1381,12 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, ...@@ -1365,11 +1381,12 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
// Sending to PHY a request to resync // Sending to PHY a request to resync
// with no target cell ID // with no target cell ID
mac->synch_request.Mod_id = module_id; if (reset_cause != DETACH) {
mac->synch_request.CC_id = 0; mac->synch_request.Mod_id = module_id;
mac->synch_request.synch_req.target_Nid_cell = -1; mac->synch_request.CC_id = 0;
mac->if_module->synch_request(&mac->synch_request); mac->synch_request.synch_req.target_Nid_cell = -1;
mac->if_module->synch_request(&mac->synch_request);
}
} }
void nr_rrc_mac_config_req_sib1(module_id_t module_id, void nr_rrc_mac_config_req_sib1(module_id_t module_id,
......
...@@ -167,6 +167,8 @@ typedef enum { ...@@ -167,6 +167,8 @@ typedef enum {
typedef enum { typedef enum {
GO_TO_IDLE, GO_TO_IDLE,
DETACH,
T300_EXPIRY,
RE_ESTABLISHMENT RE_ESTABLISHMENT
} NR_UE_MAC_reset_cause_t; } NR_UE_MAC_reset_cause_t;
......
...@@ -198,6 +198,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac) ...@@ -198,6 +198,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac)
free(sc->nrofHARQ_ProcessesForPDSCH); free(sc->nrofHARQ_ProcessesForPDSCH);
free(sc->rateMatching_PUSCH); free(sc->rateMatching_PUSCH);
free(sc->xOverhead_PUSCH); free(sc->xOverhead_PUSCH);
free(sc->maxMIMO_Layers_PDSCH);
free(sc->maxMIMO_Layers_PUSCH); free(sc->maxMIMO_Layers_PUSCH);
memset(&mac->sc_info, 0, sizeof(mac->sc_info)); memset(&mac->sc_info, 0, sizeof(mac->sc_info));
......
...@@ -263,7 +263,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, ...@@ -263,7 +263,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
case NR_RNTI_SP_CSI: case NR_RNTI_SP_CSI:
break; break;
case NR_RNTI_SI: case NR_RNTI_SI:
sps=14; sps = 14;
// for SPS=14 8 MSBs in positions 13 down to 6 // for SPS=14 8 MSBs in positions 13 down to 6
monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values
......
...@@ -2352,8 +2352,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche ...@@ -2352,8 +2352,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot) bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot)
{ {
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config; NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL;
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
if(!pucch_Config || if(!pucch_Config ||
!pucch_Config->schedulingRequestResourceToAddModList || !pucch_Config->schedulingRequestResourceToAddModList ||
...@@ -2366,6 +2365,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p ...@@ -2366,6 +2365,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
int SR_period; int SR_offset; int SR_period; int SR_offset;
find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset); find_period_offset_SR(SchedulingRequestResourceConfig,&SR_period,&SR_offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
int sfn_sf = frame * n_slots_frame + slot; int sfn_sf = frame * n_slots_frame + slot;
if ((sfn_sf - SR_offset) % SR_period == 0) { if ((sfn_sf - SR_offset) % SR_period == 0) {
...@@ -2454,8 +2454,7 @@ int compute_csi_priority(NR_UE_MAC_INST_t *mac, NR_CSI_ReportConfig_t *csirep) ...@@ -2454,8 +2454,7 @@ int compute_csi_priority(NR_UE_MAC_INST_t *mac, NR_CSI_ReportConfig_t *csirep)
int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch) int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch)
{ {
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_BWP_Id_t bwp_id = current_UL_BWP->bwp_id; NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL;
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config;
int num_csi = 0; int num_csi = 0;
if (mac->sc_info.csi_MeasConfig) { if (mac->sc_info.csi_MeasConfig) {
...@@ -2476,7 +2475,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC ...@@ -2476,7 +2475,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) { for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) {
const NR_PUCCH_CSI_Resource_t *pucchcsires = const NR_PUCCH_CSI_Resource_t *pucchcsires =
csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[i]; csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[i];
if (pucchcsires->uplinkBandwidthPartId == bwp_id) { if (pucchcsires->uplinkBandwidthPartId == current_UL_BWP->bwp_id) {
csi_res_id = pucchcsires->pucch_Resource; csi_res_id = pucchcsires->pucch_Resource;
break; break;
} }
......
...@@ -885,7 +885,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo ...@@ -885,7 +885,7 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; NR_SRS_Config_t *srs_config = current_UL_BWP ? current_UL_BWP->srs_Config : NULL;
if (!srs_config) { if (!srs_config) {
return false; return false;
......
...@@ -693,6 +693,21 @@ void nr_initiate_ra_proc(module_id_t module_idP, ...@@ -693,6 +693,21 @@ void nr_initiate_ra_proc(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
} }
static void start_ra_contention_resolution_timer(NR_RA_t *ra, const long ra_ContentionResolutionTimer, const int K2, const int scs)
{
// 3GPP TS 38.331 Section 6.3.2 Radio resource control information elements
// ra-ContentionResolutionTimer ENUMERATED {sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64}
// The initial value for the contention resolution timer.
// Value sf8 corresponds to 8 subframes, value sf16 corresponds to 16 subframes, and so on.
// We add K2 because we start the timer in the DL slot that schedules Msg3/Msg3 retransmission
ra->contention_resolution_timer = ((((int)ra_ContentionResolutionTimer + 1) * 8) << scs) + K2;
LOG_D(NR_MAC,
"Starting RA Contention Resolution timer with %d ms + %d K2 (%d slots) duration\n",
((int)ra_ContentionResolutionTimer + 1) * 8,
K2,
ra->contention_resolution_timer);
}
static void nr_generate_Msg3_retransmission(module_id_t module_idP, static void nr_generate_Msg3_retransmission(module_id_t module_idP,
int CC_id, int CC_id,
frame_t frame, frame_t frame,
...@@ -796,7 +811,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ...@@ -796,7 +811,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1; ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
} }
...@@ -861,6 +876,14 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, ...@@ -861,6 +876,14 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
vrb_map_UL[rbStart + BWPStart + rb] |= SL_to_bitmap(StartSymbolIndex, NrOfSymbols); vrb_map_UL[rbStart + BWPStart + rb] |= SL_to_bitmap(StartSymbolIndex, NrOfSymbols);
} }
// Restart RA contention resolution timer in Msg3 retransmission slot (current slot + K2)
// 3GPP TS 38.321 Section 5.1.5 Contention Resolution
start_ra_contention_resolution_timer(
ra,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
K2,
ra->UL_BWP.scs);
// reset state to wait msg3 // reset state to wait msg3
ra->state = WAIT_Msg3; ra->state = WAIT_Msg3;
ra->Msg3_frame = sched_frame; ra->Msg3_frame = sched_frame;
...@@ -1241,7 +1264,7 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1241,7 +1264,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_req->nPDUs += 1; dl_req->nPDUs += 1;
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
} }
...@@ -1383,6 +1406,14 @@ static void nr_generate_Msg2(module_id_t module_idP, ...@@ -1383,6 +1406,14 @@ static void nr_generate_Msg2(module_id_t module_idP,
nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association);
nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
// Start RA contention resolution timer in Msg3 transmission slot (current slot + K2)
// 3GPP TS 38.321 Section 5.1.5 Contention Resolution
start_ra_contention_resolution_timer(
ra,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
*ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2,
ra->UL_BWP.scs);
if (ra->cfra) { if (ra->cfra) {
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_idP]->UE_info, ra->rnti);
if (UE) { if (UE) {
...@@ -1458,7 +1489,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, ...@@ -1458,7 +1489,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_req->nPDUs += 1; dl_req->nPDUs += 1;
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_configure_pdcch(pdcch_pdu_rel15, coreset, &ra->sched_pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
} }
...@@ -1884,9 +1915,9 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s ...@@ -1884,9 +1915,9 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s
if (harq->round == 0) { if (harq->round == 0) {
if (UE->Msg4_ACKed) { if (UE->Msg4_ACKed) {
LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
UE->ra_timer = 0;
} else { } else {
LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti); LOG_I(NR_MAC, "%4d.%2d UE %04x: RA Procedure failed at Msg4!\n", frame, slot, ra->rnti);
nr_mac_trigger_ul_failure(sched_ctrl, UE->current_DL_BWP.scs);
} }
// Pause scheduling according to: // Pause scheduling according to:
...@@ -2062,6 +2093,18 @@ void nr_schedule_RA(module_id_t module_idP, ...@@ -2062,6 +2093,18 @@ void nr_schedule_RA(module_id_t module_idP,
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &cc->ra[i]; NR_RA_t *ra = &cc->ra[i];
LOG_D(NR_MAC, "RA[state:%d]\n", ra->state); LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
// Check RA Contention Resolution timer
if (ra->state >= WAIT_Msg3) {
ra->contention_resolution_timer--;
if (ra->contention_resolution_timer < 0) {
LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti);
nr_mac_release_ue(mac, ra->rnti);
nr_clear_ra_proc(module_idP, CC_id, frameP, ra);
continue;
}
}
switch (ra->state) { switch (ra->state) {
case Msg2: case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req);
......
...@@ -405,7 +405,6 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, ...@@ -405,7 +405,6 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nr_configure_pdcch(pdcch_pdu_rel15, nr_configure_pdcch(pdcch_pdu_rel15,
gNB_mac->sched_ctrlCommon->coreset, gNB_mac->sched_ctrlCommon->coreset,
true, // sib1
&gNB_mac->sched_ctrlCommon->sched_pdcch); &gNB_mac->sched_ctrlCommon->sched_pdcch);
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
......
...@@ -1023,7 +1023,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1023,7 +1023,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid);
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch);
gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu;
} }
......
...@@ -770,7 +770,6 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { ...@@ -770,7 +770,6 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
NR_ControlResourceSet_t *coreset, NR_ControlResourceSet_t *coreset,
bool is_sib1,
NR_sched_pdcch_t *pdcch) { NR_sched_pdcch_t *pdcch) {
...@@ -794,10 +793,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, ...@@ -794,10 +793,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
pdcch_pdu->ShiftIndex = pdcch->ShiftIndex; pdcch_pdu->ShiftIndex = pdcch->ShiftIndex;
if(coreset->controlResourceSetId == 0) { if(coreset->controlResourceSetId == 0) {
if(is_sib1) pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
else
pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0;
} else{ } else{
pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
} }
...@@ -2401,10 +2397,6 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf ...@@ -2401,10 +2397,6 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
/* Set default BWPs */ /* Set default BWPs */
AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp); AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp);
if (get_softmodem_params()->phy_test == 0) {
UE->ra_timer = 12000 << UE->current_DL_BWP.scs; // 12000 ms is arbitrary and found to be a good timeout from experiments
}
/* get Number of HARQ processes for this UE */ /* get Number of HARQ processes for this UE */
// pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes // pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes
create_dl_harq_list(sched_ctrl, &UE->sc_info); create_dl_harq_list(sched_ctrl, &UE->sc_info);
...@@ -2959,24 +2951,6 @@ void nr_mac_update_timers(module_id_t module_id, ...@@ -2959,24 +2951,6 @@ void nr_mac_update_timers(module_id_t module_id,
if (sched_ctrl->rrc_processing_timer == 0) if (sched_ctrl->rrc_processing_timer == 0)
nr_mac_apply_cellgroup(mac, UE, frame, slot); nr_mac_apply_cellgroup(mac, UE, frame, slot);
} }
// RA timer
if (UE->ra_timer > 0) {
UE->ra_timer--;
if (UE->ra_timer == 0) {
const rnti_t rnti = UE->rnti;
LOG_W(NR_MAC, "Removing UE %04x because RA timer expired\n", rnti);
mac_remove_nr_ue(mac, rnti);
NR_COMMON_channels_t *cc = &mac->common_channels[0];
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
if (cc->ra[i].rnti == rnti) {
nr_clear_ra_proc(module_id, 0, frame, &cc->ra[i]);
}
}
// don't skip a UE, current UE does not exist anymore
UE--;
}
}
} }
} }
......
...@@ -765,7 +765,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -765,7 +765,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
nr_mac_reset_ul_failure(UE_scheduling_control); nr_mac_reset_ul_failure(UE_scheduling_control);
reset_dl_harq_list(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control);
reset_ul_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control);
UE_msg3_stage->ra_timer = 0;
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
process_CellGroup(ra->CellGroup, UE_msg3_stage); process_CellGroup(ra->CellGroup, UE_msg3_stage);
...@@ -2345,7 +2344,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n ...@@ -2345,7 +2344,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1; ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch);
pdcch_pdu_coreset[coresetid] = pdcch_pdu; pdcch_pdu_coreset[coresetid] = pdcch_pdu;
} }
......
...@@ -199,7 +199,6 @@ void find_search_space(int ss_type, ...@@ -199,7 +199,6 @@ void find_search_space(int ss_type,
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
NR_ControlResourceSet_t *coreset, NR_ControlResourceSet_t *coreset,
bool is_sib1,
NR_sched_pdcch_t *pdcch); NR_sched_pdcch_t *pdcch);
NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
......
...@@ -223,6 +223,7 @@ typedef struct { ...@@ -223,6 +223,7 @@ typedef struct {
NR_CellGroupConfig_t *CellGroup; NR_CellGroupConfig_t *CellGroup;
/// Preambles for contention-free access /// Preambles for contention-free access
NR_preamble_ue_t preambles; NR_preamble_ue_t preambles;
int contention_resolution_timer;
/// CFRA flag /// CFRA flag
bool cfra; bool cfra;
// BWP for RA // BWP for RA
...@@ -712,7 +713,6 @@ typedef struct { ...@@ -712,7 +713,6 @@ typedef struct {
// UE selected beam index // UE selected beam index
uint8_t UE_beam_index; uint8_t UE_beam_index;
bool Msg4_ACKed; bool Msg4_ACKed;
uint32_t ra_timer;
float ul_thr_ue; float ul_thr_ue;
float dl_thr_ue; float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook; long pdsch_HARQ_ACK_Codebook;
......
...@@ -877,55 +877,57 @@ uint8_t do_NR_RRCReconfigurationComplete(uint8_t *buffer, size_t buffer_size, co ...@@ -877,55 +877,57 @@ uint8_t do_NR_RRCReconfigurationComplete(uint8_t *buffer, size_t buffer_size, co
return((enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8);
} }
uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t do_RRCSetupComplete(uint8_t Mod_id,
const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){ uint8_t *buffer,
asn_enc_rval_t enc_rval; size_t buffer_size,
const uint8_t Transaction_id,
NR_UL_DCCH_Message_t ul_dcch_msg; uint8_t sel_plmn_id,
NR_RRCSetupComplete_t *RrcSetupComplete; const int dedicatedInfoNASLength,
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); const char *dedicatedInfoNAS)
{
uint8_t buf[6]; NR_UL_DCCH_Message_t ul_dcch_msg = {0};
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1)); ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete; ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t)); ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t));
RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete; NR_RRCSetupComplete_t *RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete;
RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id; RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id;
RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete; RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t)); RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t));
// RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension = CALLOC(1, NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete;
// sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension)); ies->selectedPLMN_Identity = sel_plmn_id;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id; ies->registeredAMF = NULL;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL;
ies->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value));
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; NR_NG_5G_S_TMSI_t *stmsi = &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6; stmsi->size = 6;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf = buf; stmsi->buf = calloc(stmsi->size, sizeof(*stmsi->buf));
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[0] = 0x12; AssertFatal(stmsi->buf != NULL, "out of memory\n");
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[1] = 0x34; stmsi->buf[0] = 0x12;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[2] = 0x56; stmsi->buf[1] = 0x34;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78; stmsi->buf[2] = 0x56;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A; stmsi->buf[3] = 0x78;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC; stmsi->buf[4] = 0x9A;
stmsi->buf[5] = 0xBC;
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength); memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
} }
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL, NULL,
(void *)&ul_dcch_msg, (void *)&ul_dcch_msg,
buffer, buffer,
buffer_size); buffer_size);
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name,enc_rval.encoded); enc_rval.failed_type->name,enc_rval.encoded);
LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UL_DCCH_Message, &ul_dcch_msg);
return((enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8);
} }
......
This diff is collapsed.
...@@ -83,7 +83,7 @@ typedef enum Rrc_State_NR_e { ...@@ -83,7 +83,7 @@ typedef enum Rrc_State_NR_e {
RRC_STATE_IDLE_NR = 0, RRC_STATE_IDLE_NR = 0,
RRC_STATE_INACTIVE_NR, RRC_STATE_INACTIVE_NR,
RRC_STATE_CONNECTED_NR, RRC_STATE_CONNECTED_NR,
RRC_STATE_DETACH_NR,
RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR,
RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR,
} Rrc_State_NR_t; } Rrc_State_NR_t;
...@@ -206,8 +206,6 @@ typedef struct rrcPerNB { ...@@ -206,8 +206,6 @@ typedef struct rrcPerNB {
} rrcPerNB_t; } rrcPerNB_t;
typedef struct NR_UE_RRC_INST_s { typedef struct NR_UE_RRC_INST_s {
NR_MeasConfig_t *meas_config;
rrcPerNB_t perNB[NB_CNX_UE]; rrcPerNB_t perNB[NB_CNX_UE];
char *uecap_file; char *uecap_file;
......
...@@ -105,7 +105,7 @@ void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti); ...@@ -105,7 +105,7 @@ void nr_mac_rrc_msg3_ind(const module_id_t mod_id, int rnti);
void *rrc_nrue_task(void *args_p); void *rrc_nrue_task(void *args_p);
void *rrc_nrue(void *args_p); void *rrc_nrue(void *args_p);
void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers); void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc, instance_t instance);
/**\brief RRC NSA UE task. /**\brief RRC NSA UE task.
\param void *args_p Pointer on arguments to start the task. */ \param void *args_p Pointer on arguments to start the task. */
...@@ -122,6 +122,7 @@ int get_from_lte_ue_fd(); ...@@ -122,6 +122,7 @@ int get_from_lte_ue_fd();
void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo); void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo);
void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id); void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id);
void handle_t300_expiry(instance_t instance);
void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac); void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac); void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac);
......
...@@ -98,9 +98,18 @@ void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo) ...@@ -98,9 +98,18 @@ void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo)
} }
} }
void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers) void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc, instance_t instance)
{ {
// T304 NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
if (timers->T300_active == true) {
timers->T300_cnt += 10;
if(timers->T300_cnt >= timers->T300_k) {
timers->T300_active = false;
timers->T300_cnt = 0;
handle_t300_expiry(instance);
}
}
if (timers->T304_active == true) { if (timers->T304_active == true) {
timers->T304_cnt += 10; timers->T304_cnt += 10;
if(timers->T304_cnt >= timers->T304_k) { if(timers->T304_cnt >= timers->T304_k) {
...@@ -120,6 +129,14 @@ void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers) ...@@ -120,6 +129,14 @@ void nr_rrc_handle_timers(NR_UE_Timers_Constants_t *timers)
AssertFatal(false, "Radio link failure! Not handled yet!\n"); AssertFatal(false, "Radio link failure! Not handled yet!\n");
} }
} }
if (timers->T311_active == true) {
timers->T311_cnt += 10;
if(timers->T311_cnt >= timers->T311_k) {
// Upon T311 expiry, the UE shall perform the actions upon going to RRC_IDLE
// with release cause 'RRC connection failure'
nr_rrc_going_to_IDLE(instance, RRC_CONNECTION_FAILURE, NULL);
}
}
} }
void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync) void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync)
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "RegistrationAccept.h" #include "RegistrationAccept.h"
#include "assertions.h" #include "assertions.h"
int decode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len) int decode_registration_accept(registration_accept_msg *registration_accept, const uint8_t *buffer, uint32_t len)
{ {
uint32_t decoded = 0; uint32_t decoded = 0;
int decoded_result = 0; int decoded_result = 0;
......
...@@ -62,7 +62,7 @@ typedef struct registration_accept_msg_tag { ...@@ -62,7 +62,7 @@ typedef struct registration_accept_msg_tag {
FGSMobileIdentity *guti; FGSMobileIdentity *guti;
} registration_accept_msg; } registration_accept_msg;
int decode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); int decode_registration_accept(registration_accept_msg *registrationaccept, const uint8_t *buffer, uint32_t len);
int encode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); int encode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
......
...@@ -37,13 +37,13 @@ ...@@ -37,13 +37,13 @@
#include "TLVDecoder.h" #include "TLVDecoder.h"
#include "FGSMobileIdentity.h" #include "FGSMobileIdentity.h"
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, const uint8_t *buffer);
static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer); static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer);
static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer); static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer);
int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, const uint8_t *buffer, uint32_t len)
{ {
int decoded_rc = TLV_DECODE_VALUE_DOESNT_MATCH; int decoded_rc = TLV_DECODE_VALUE_DOESNT_MATCH;
int decoded = 0; int decoded = 0;
...@@ -117,7 +117,7 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei ...@@ -117,7 +117,7 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei
return (encoded + encoded_rc); return (encoded + encoded_rc);
} }
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer) static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, const uint8_t *buffer)
{ {
int decoded = 0; int decoded = 0;
uint16_t temp; uint16_t temp;
......
...@@ -149,7 +149,7 @@ typedef union FGSMobileIdentity_tag { ...@@ -149,7 +149,7 @@ typedef union FGSMobileIdentity_tag {
int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len); int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len); int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, const uint8_t *buffer, uint32_t len);
#endif /* FGS MOBILE IDENTITY_H_ */ #endif /* FGS MOBILE IDENTITY_H_ */
...@@ -617,7 +617,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia ...@@ -617,7 +617,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
} }
} }
static void decodeRegistrationAccept(uint8_t *buf, int len, nr_ue_nas_t *nas) static void decodeRegistrationAccept(const uint8_t *buf, int len, nr_ue_nas_t *nas)
{ {
registration_accept_msg reg_acc = {0}; registration_accept_msg reg_acc = {0};
/* it seems there is no 5G corresponding emm_msg_decode() function, so here /* it seems there is no 5G corresponding emm_msg_decode() function, so here
...@@ -911,6 +911,14 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i ...@@ -911,6 +911,14 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg);
} }
static void send_nas_detach_req(instance_t instance, bool wait_release)
{
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DETACH_REQ);
nas_detach_req_t *req = &NAS_DETACH_REQ(msg);
req->wait_release = wait_release;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg);
}
static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len) static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len)
{ {
int nssai_cnt = 0; int nssai_cnt = 0;
...@@ -1033,6 +1041,29 @@ void *nas_nrue_task(void *args_p) ...@@ -1033,6 +1041,29 @@ void *nas_nrue_task(void *args_p)
} }
} }
static void handle_registration_accept(instance_t instance,
nr_ue_nas_t *nas,
const uint8_t *pdu_buffer,
uint32_t msg_length)
{
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
decodeRegistrationAccept(pdu_buffer, msg_length, nas);
get_allowed_nssai(nas_allowed_nssai, pdu_buffer, msg_length);
as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) {
send_nas_uplink_data_req(instance, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas);
if (nssai_idx < 0) {
LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n");
} else {
request_default_pdusession(instance, nssai_idx);
}
}
void *nas_nrue(void *args_p) void *nas_nrue(void *args_p)
{ {
// Wait for a message or an event // Wait for a message or an event
...@@ -1112,24 +1143,8 @@ void *nas_nrue(void *args_p) ...@@ -1112,24 +1143,8 @@ void *nas_nrue(void *args_p)
int msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); int msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
if (msg_type == REGISTRATION_ACCEPT) { if (msg_type == REGISTRATION_ACCEPT) {
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
nr_ue_nas_t *nas = get_ue_nas_info(0); nr_ue_nas_t *nas = get_ue_nas_info(0);
decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); handle_registration_accept(instance, nas, pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
get_allowed_nssai(nas_allowed_nssai, pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) {
send_nas_uplink_data_req(instance, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas);
if (nssai_idx < 0) {
LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n");
} else {
request_default_pdusession(instance, nssai_idx);
}
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
} }
...@@ -1165,15 +1180,19 @@ void *nas_nrue(void *args_p) ...@@ -1165,15 +1180,19 @@ void *nas_nrue(void *args_p)
case NAS_DEREGISTRATION_REQ: { case NAS_DEREGISTRATION_REQ: {
LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p)); LOG_I(NAS, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p));
nr_ue_nas_t *nas = get_ue_nas_info(0); nr_ue_nas_t *nas = get_ue_nas_info(0);
nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p);
if (nas->guti) { if (nas->guti) {
nas_deregistration_req_t *req = &NAS_DEREGISTRATION_REQ(msg_p); if (req->cause == AS_DETACH) {
if (req->cause == AS_DETACH)
nas->termination_procedure = true; nas->termination_procedure = true;
send_nas_detach_req(instance, true);
}
as_nas_info_t initialNasMsg = {0}; as_nas_info_t initialNasMsg = {0};
generateDeregistrationRequest(nas, &initialNasMsg, req); generateDeregistrationRequest(nas, &initialNasMsg, req);
send_nas_uplink_data_req(instance, &initialNasMsg); send_nas_uplink_data_req(instance, &initialNasMsg);
} else { } else {
LOG_E(NAS, "no GUTI, cannot trigger deregistration request\n"); LOG_W(NAS, "No GUTI, cannot trigger deregistration request.\n");
if (req->cause == AS_DETACH)
send_nas_detach_req(instance, false);
} }
} break; } break;
...@@ -1205,21 +1224,7 @@ void *nas_nrue(void *args_p) ...@@ -1205,21 +1224,7 @@ void *nas_nrue(void *args_p)
decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer);
break; break;
case REGISTRATION_ACCEPT: case REGISTRATION_ACCEPT:
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); handle_registration_accept(instance, nas, pdu_buffer, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length);
decodeRegistrationAccept(pdu_buffer, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length, nas);
as_nas_info_t initialNasMsg = {0};
generateRegistrationComplete(nas, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) {
send_nas_uplink_data_req(instance, &initialNasMsg);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas);
if (nssai_idx < 0) {
LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n");
} else {
request_default_pdusession(instance, nssai_idx);
}
break; break;
case FGS_DEREGISTRATION_ACCEPT: case FGS_DEREGISTRATION_ACCEPT:
LOG_I(NAS, "received deregistration accept\n"); LOG_I(NAS, "received deregistration accept\n");
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment