Merge branch 'integration_2023_w47' into 'develop'

See merge request oai/openairinterface5g!2450

* !2440 hotfix: set PDCP t-reordering to 100ms
* !2439 rfsimulator: ignore PIPE signal
* !2441 minor: documentation: advertise correct default value for --ssb
* !2446 chore(ci): displaying the ASN1C commit
* !2443 CI documentation: updates and how to reproduce
* !2355 NR UE improve handling of MSG4 feedback in default PUCCH
* !2408 NR UE MAC config improvements
* !2431 T: isolate generated .h files when using make
* !2442 nr pdcp: rework reestablishment
* !2448 lte: switch to RRC release 16.13.0
* !2088 Implementation of logical channel prioritization at UE
* correctly read timing advance option `-A` in gNB
* set sample advance for OAIUE test to make it more stable
* set gain for OAIUE test to make it more stable
* !2445 Correctly allocate SCC n_TimingAdvanceOffset
* !2454 bugfix: fix NSA CI test
This commit is contained in:
Robert Schmidt
2023-11-28 06:38:49 +00:00
63 changed files with 28098 additions and 888 deletions
@@ -63,6 +63,7 @@ gNBs =
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
initialDLBWPcontrolResourceSetZero = 0;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
@@ -220,7 +220,7 @@ RUs = (
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
max_rxgain = 65;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
@@ -7,7 +7,7 @@ services:
container_name: oai-gnb
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --sa --tune-offset 20000000 --log_config.global_log_options level,nocolor,time
USE_ADDITIONAL_OPTIONS: --sa --tune-offset 20000000 -A 45 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
@@ -8,7 +8,7 @@ services:
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.20.2 -r 106 --numerology 1 --band 78 -C 3511200000 --sa --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 --log_config.global_log_options level,nocolor,time --uicc0.imsi 208970000000111 --uicc0.nssai_sd 16777215
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.20.2 -r 106 --numerology 1 --band 78 -C 3511200000 --sa --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 45 --log_config.global_log_options level,nocolor,time --uicc0.imsi 208970000000111 --uicc0.nssai_sd 16777215
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
+2
View File
@@ -667,6 +667,8 @@ install_asn1c_from_source(){
git clone https://github.com/mouse07410/asn1c /tmp/asn1c
cd /tmp/asn1c
git checkout vlm_master
# Showing which version is used
git log -n1
autoreconf -iv
./configure --prefix /opt/asn1c/
make -j`nproc`
+1 -2
View File
@@ -1,7 +1,5 @@
*.o
*.a
T_IDs.h
T_messages.txt.h
genids
tracer/enb
tracer/gnb
@@ -18,3 +16,4 @@ tracer/extract_output_subframe
tracer/extract
tracer/multi
tracee/tracee
incgen
+2 -1
View File
@@ -8,11 +8,12 @@ else()
endif()
add_custom_command(OUTPUT T_IDs.h
COMMAND genids ${CMAKE_CURRENT_SOURCE_DIR}/T_messages.txt T_IDs.h
DEPENDS genids
DEPENDS genids T_messages.txt
COMMENT "Generating T_IDs.h from T_messages.txt"
)
add_custom_command(OUTPUT T_messages.txt.h
COMMAND xxd -i T_messages.txt ${CMAKE_CURRENT_BINARY_DIR}/T_messages.txt.h
DEPENDS T_messages.txt
COMMENT "Generating T_messages.txt.h from T_messages.txt"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
+12 -9
View File
@@ -1,10 +1,10 @@
CC=gcc
CFLAGS=-Wall -g
CFLAGS=-Wall -g -Iincgen
GENIDS=genids
GENIDS_OBJS=genids.o
all : $(GENIDS) T_messages.txt.h T_IDs.h
all : $(GENIDS) incgen/T_messages.txt.h incgen/T_IDs.h
$(GENIDS): $(GENIDS_OBJS)
$(CC) $(CFLAGS) -o $(GENIDS) $(GENIDS_OBJS)
@@ -12,21 +12,24 @@ $(GENIDS): $(GENIDS_OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
T_messages.txt.h: T_messages.txt
xxd -i T_messages.txt T_messages.txt.h
incgen/T_messages.txt.h: T_messages.txt
mkdir -p incgen
xxd -i T_messages.txt incgen/T_messages.txt.h
T_IDs.h: $(GENIDS) T_messages.txt
./$(GENIDS) T_messages.txt T_IDs.h
incgen/T_IDs.h: $(GENIDS) T_messages.txt
mkdir -p incgen
./$(GENIDS) T_messages.txt incgen/T_IDs.h
check_vcd: T_IDs.h T_messages.txt.h
check_vcd: incgen/T_IDs.h incgen/T_messages.txt.h
gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread
./_check_vcd T_messages.txt ../LOG/vcd_signal_dumper.h || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false)
./_check_vcd T_messages.txt ../LOG/vcd_signal_dumper.h || (rm -rf ./_check_vcd ./incgen && false)
rm -f ./_check_vcd
.PHONY: check_vcd
clean:
rm -f *.o $(GENIDS) core T_IDs.h T_messages.txt.h _check_vcd
rm -f *.o $(GENIDS) core _check_vcd
rm -rf incgen
cleanall: clean
cd tracer && $(MAKE) clean
+10 -2
View File
@@ -1,8 +1,10 @@
CC=gcc
CFLAGS=-Wall -g -pthread -DT_TRACER -I.
CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen
PROG=tracee
OBJS=tracee.o ../T.o ../local_tracer.o
OBJS=tracee.o T.o ../local_tracer.o
all: T_dep $(PROG)
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) -lrt
@@ -10,5 +12,11 @@ $(PROG): $(OBJS)
tracee.o: tracee.c
$(CC) $(CFLAGS) -c -o $@ $<
T.o: ../T.c
$(CC) $(CFLAGS) -c -o $@ $<
T_dep:
cd .. && make
clean:
rm -f *.o $(PROG) core
@@ -0,0 +1,14 @@
#ifndef _CONFIG_USERAPI_H_
#define _CONFIG_USERAPI_H_
typedef int paramdef_t;
#ifdef CMDLINE_TTRACEPARAMS_DESC
#undef CMDLINE_TTRACEPARAMS_DESC
#endif
#define CMDLINE_TTRACEPARAMS_DESC {}
#define config_get(dummy, ...) (void)(dummy)
#define config_process_cmdline(...) /**/
#endif /* _CONFIG_USERAPI_H_ */
+2 -1
View File
@@ -6,7 +6,8 @@
int main(void)
{
int frame = 0;
T_init(2021, 1, 0);
T_init(2021, 1);
T_stdout = 0;
while (1) {
getchar();
T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(0), T_INT(0), T_INT(frame), T_INT(0), T_INT(0), T_INT(0));
+3 -3
View File
@@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-Wall -g -pthread -DT_TRACER -I.
CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen
#CFLAGS += -O3 -ffast-math -fomit-frame-pointer
@@ -66,9 +66,9 @@ gnb: utils.o gnb.o database.o event.o handler.o configuration.o \
filter/filter.a
$(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
multi.o: ../T_IDs.h
multi.o: ../incgen/T_IDs.h
../T_IDs.h:
../incgen/T_IDs.h: ../T_messages.txt
cd .. && $(MAKE)
.PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a
+1
View File
@@ -305,6 +305,7 @@ Furthermore, the gNB and UE support
- HARQ procedures
* ULSCH scheduler
- Configuration of fapi PDU according to DCI
- Logical channel prioritization of 'data from any logical channel'
* NR-CSIRS scheduler
- Scheduling of NR-CSIRS reception
- Fill UCI for CSI measurement reporting
+1 -1
View File
@@ -95,7 +95,7 @@ Command line parameters for UE in --sa mode:
- `--numerology` : numerology index (default value 1)
- `-r` : bandwidth in terms of RBs (default value 106)
- `--band` : NR band number (default value 78)
- `--ssb` : SSB start subcarrier (default value 512)
- `--ssb` : SSB start subcarrier (default value 516)
You can run this, using USRPs, on two separate machines:
+117 -21
View File
@@ -6,7 +6,7 @@
| Machine | IP address | Lockable Resource | Function | Connected devices |
| ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- |
| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB (n78) | 172.21.19.14 |
| asterix | 172.21.16.127 | CI-Asterix-Usage | *unused* | 172.21.19.14 |
| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2) |
| porcepix | 172.21.16.136 | CI-Porcepix | Executor, EPC, 5GC | -- |
| nrmodule2 | 172.21.16.139 | CI-NrModule2 | Quectel | Quectel module |
@@ -15,25 +15,19 @@
| idefix | 172.21.16.135 | CI-Idefix | Quectel | Quectel module |
| caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) |
| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator |
| manarola | 172.21.8.116 | _None_ | gNB | AW2S |
| nano | 172.21.18.48 | CI-Nano-Legacy-EPC | Executor, EPC, adb | 2x COTS (adb) |
| hutch | 172.21.18.46 | CI-Hutch-Legacy-FDD-eNB | eNB (B7) | B200mini (30C5239) |
| starsky | 172.21.18.45 | CI-Starsky-Legacy-TDD-eNB | eNB (B40) | b200mini (30A3E3C) |
| carabe | 172.21.18.47 | CI-Carabe-Legacy-FDD-OAI-LTE-UE | UE (B7UE) | B200mini (30AE8C9) |
| nokiabox | 172.21.19.39 | _None_ | gNB (Nokia), 5GC | _Nokia RF integrated_ |
| avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) |
| orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | |
| bellatrix | 172.21.16.104 | CI-Bellatrix-RAN-Docker | Static Code Analysis | -- |
Note: The available resources, and their current usage, is indicated here:
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
"New" Jenkins, i.e., with RAN-Container-Parent
## Networked devices
| Type | IP address (mgmt) |
| ------------- | ----------------- |
| USRP N310 | 172.21.19.14 |
| USRP N310 | 172.21.19.13 |
## Testbenches
### 5G OTA Testbench
@@ -82,61 +76,116 @@ Note: The available resources, and their current usage, is indicated here:
### [RAN-Container-Parent](https://jenkins-oai.eurecom.fr/job/RAN-Container-Parent/)
**Purpose**: automatically triggered tests on MR creation or push, from Gitlab
Webhook
Webhook ~documentation ~BUILD-ONLY ~4G-LTE ~5G-NR
- [RAN-cppcheck](https://jenkins-oai.eurecom.fr/job/RAN-cppcheck/1664/)
- obelix
This pipeline has basically two main stages, as follows. For the image build,
please also refer to the [dedicated documentation](../docker/README.md) for
information on how the images are built.
#### Image Build pipelines
- [RAN-ARM-Cross-Compile-Builder](https://jenkins-oai.eurecom.fr/job/RAN-ARM-Cross-Compile-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR
- orion: Cross-compilation from Intel to ARM
- base image from `Dockerfile.base.ubuntu20.cross-arm64`
- build image from `Dockerfile.build.ubuntu20.cross-arm64` (no target images)
- [RAN-cppcheck](https://jenkins-oai.eurecom.fr/job/RAN-cppcheck/)
~BUILD-ONLY ~4G-LTE ~5G-NR
- bellatrix
- performs static code analysis, currently not actively enforced
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL image build using the OpenShift Cluster (using gcc/clang)
- base image from `Dockerfile.build.rhel9`
- build image from `Dockerfile.build.rhel9`, followed by
- target image from `Dockerfile.eNB.rhel9`
- target image from `Dockerfile.gNB.rhel9`,
- target image from `Dockerfile.gNB.aw2s.rhel9`
- target image from `Dockerfile.nr-cuup.rhel9`
- target image from `Dockerfile.lteUE.rhel9`
- target image from `Dockerfile.nrUE.rhel9`
- build image from `Dockerfile.phySim.rhel9` (creates as direct target physical simulator
image)
- build image from `Dockerfile.clang.rhel9` (compilation only, artifacts not used currently)
- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR
- obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!)
- base image from `Dockerfile.base.ubuntu20`
- build image from `Dockerfile.build.ubuntu20`, followed by
- target image from `Dockerfile.eNB.ubuntu20`
- target image from `Dockerfile.gNB.ubuntu20`
- target image from `Dockerfile.nr-cuup.ubuntu20`
- target image from `Dockerfile.nrUE.ubuntu20`
- target image from `Dockerfile.lteUE.ubuntu20`
- target image from `Dockerfile.lteRU.ubuntu20`
#### Image Test pipelines
- [OAI-CN5G-COTS-UE-Test](https://jenkins-oai.eurecom.fr/job/OAI-CN5G-COTS-UE-Test/)
~5G-NR
- using 5GC bench (resources `CI-Cetautomatix-OC-oaicicd-session`, `CI-Dogmatix-CN5G-gNB`): Attach/Detach of UE with multiple PDU sessions
- [RAN-gNB-N300-Timing-Phytest-LDPC](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-gNB-N300-Timing-Phytest-LDPC/)
~5G-NR
- caracal + N310
- pure performance test through phy-test scheduler, see command line for more details
- [RAN-Interop-F1](https://jenkins-oai.eurecom.fr/job/RAN-Interop-F1/)
~5G-NR
- ofqot (DU, 1x UE)
- F1 interoperability testing: sets up connection to Accelleran CU, UE connection and connectivity test
- F1 interoperability: set up connection between Accelleran CU and OAI DU and pass all traffic over F1
- 3rd-party gNB/CU interoperability: set up connection between Accelleran CU and OAI UE and test connectivity
- [RAN-L2-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
~4G-LTE
- obelix (eNB, 1x UE, OAI EPC)
- L2simulator: skips physical layer and uses proxy between eNB and UE
- [RAN-L2-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-5G/)
~5G-NR
- obelix (gNB, 1x UE, OAI 5GC)
- L2simulator: skips physical layer and uses proxy between gNB and UE, currently only ping
- [RAN-LTE-FDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-LTEBOX-Container/)
~4G-LTE
- hutch + B210, nano w/ ltebox + 2x UE
- tests RRC inactivity timers, different bandwidths, IF4p5 fronthaul
- [RAN-LTE-FDD-OAIUE-OAICN4G-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-OAIUE-OAICN4G-Container/)
~4G-LTE
- hutch + B210 (eNB), carabe + B210 (4G UE), nano w/ OAI 4GC
- tests OAI 4G for 10 MHz/TM1; known to be unstable
- [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/)
~4G-LTE
- obelix + N310, porcepix, nrmodule2 + Quectel
- TM1 and TM2 test, IF4p5 fronthaul
- [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/)
~4G-LTE
- starsky + B210, nano w/ ltebox + 2x UE
- TM1 over bandwidths 5, 10, 20 MHz in Band 40, default scheduler for 20 MHz
- [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/)
~4G-LTE ~5G-NR
- nepes + B200 (eNB), ofqot + B200 (gNB), idefix + Quectel, nepes w/ ltebox
- basic NSA test
- [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/)
~4G-LTE ~5G-NR
- cluster (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster
- unitary simulators (`nr_dlsim`, etc.)
- [RAN-RF-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-4G/)
~4G-LTE
- obelix (eNB, lteUE, OAI EPC)
- uses RFsimulator, for FDD 5, 10, 20MHz with core, 5MHz noS1
- [RAN-RF-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-5G/)
~5G-NR
- obelix (gNB, nrUE, OAI 5GC)
- uses RFsimulator, TDD 40MHz, FDD 40MHz, F1 split
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL 8 image build using the OpenShift Cluster
- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/)
~5G-NR
- 5G-NR SA test setup: avra(RHEL9.1) + AW2S, amariue, OAI CN5G
- uses OpenShift cluster for CN deployment and container images for gNB deployment
- multi UE testing
- multi UE testing using Amarisoft UE simulator
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
~5G-NR
- ofqot + B200, idefix + Quectel, nepes w/ sabox
- basic SA test (20 MHz TDD), F1, reestablishment, ...
- [RAN-SA-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-OAIUE-CN5G/)
~5G-NR
- 5G-NR SA test setup: gNB on avra(RHEL9.2) + N310, OAIUE on caracal(RHEL9.1) + N310, OAI CN5G
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
- obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!)
### RAN-CI-NSA-Trigger
@@ -148,6 +197,53 @@ Webhook
- [RAN-SA-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G/)
- asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ OAI 5GC
- NR 2x2 (standalone)
- [RAN-SA-AmariS-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-AmariS-CN5G/)
- asterix + N310, amariue (1x UE), porcepix w/ OAI 5GC
- Amarisoft UE simulator: expected to be increased to more UEs
## How to reproduce CI results
The CI builds docker images at the beginning of every test run. To see the
exact command line steps, please refer to the `docker/Dockerfile.build.*`
files. Note that the console log of each pipeline run also lists the used
docker files.
The CI uses these images for *most* of the pipelines. It uses docker-compose to
orchestrate the images. To identify the docker-compose file, follow these
steps:
1. Each CI test run HTML lists the XML file used for a particular test run.
Open the corresponding XML file under `ci-scripts/xml_files/`.
2. The XML file has a "test case" that refers to deployment of the image; it
will reference a directory containing a YAML file (the docker-compose file)
using option `yaml_path`, which will be under `ci-scripts/yaml_files/`. Go
to this directory and open the docker-compose file.
3. The docker-compose file can be used to run images locally, or you can infer
the used configuration file and possible additional options that are to be
passed to the executable to run from source.
For instance, to see how the CI runs the multi-UE 5G RFsim test case, the above
steps look like this:
1. The first tab in the 5G RFsim test mentions
`xml_files/container_5g_rfsim.xml`, so open
`ci-scripts/xml_files/container_5g_rfsim.xml`.
2. This XML file has a `DeployGenObject` test case, referencing the directory
`yaml_files/5g_rfsimulator`. The corresponding docker-compose file path is
`ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml`.
3. To know how to run the gNB, realize that there is a section `oai-gnb`. It
mounts the configuration
`ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf` (note that the path
is relative to the directory in which the docker-compose file is located).
Further, an environment variable `USE_ADDITIONAL_OPTIONS` is declared,
referencing the relevant options `--sa -E --rfsim` (you can ignore logging
options). You would therefore run the gNB from source like this:
```
sudo ./cmake_targets/ran_build/build/nr-softmodem -O ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf --sa -E --rfsim
```
To run this on your local machine, assuming you have a 5GC installed, you
might need to change IP information in the config to match your core.
If you wish, you can rebuild CI images locally following [these
steps](../docker/README.md) and then use the docker-compose file directly.
Some tests are run from source (e.g.
`ci-scripts/xml_files/gnb_phytest_usrp_run.xml`), which directly give the
options they are run with.
+4 -3
View File
@@ -102,6 +102,7 @@ int attach_rru(RU_t *ru);
int connect_rau(RU_t *ru);
static void NRRCconfig_RU(configmodule_interface_t *cfg);
extern uint32_t timing_advance;
extern int emulate_rf;
extern int numerology;
@@ -846,11 +847,11 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot, fp, 0)] - sf_extension * sizeof(int32_t);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance) & 0xffffffff);
(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance) & 0xffffffff);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1);
// prepare tx buffer pointers
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - sf_extension,
timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance - sf_extension,
txp,
siglen + sf_extension,
ru->nb_tx,
@@ -860,7 +861,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
"returned %d, E %f\n",
ru->idx,
i,
(long long unsigned int)(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - sf_extension),
(long long unsigned int)(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - timing_advance - sf_extension),
frame,
slot,
proc->frame_tx_unwrap,
+30 -4
View File
@@ -34,6 +34,8 @@
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "radio/COMMON/common_lib.h"
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
/*
* NR SLOT PROCESSING SEQUENCE
@@ -944,14 +946,38 @@ void *UE_thread(void *arg)
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
{
int inst;
NR_UE_MAC_INST_t *mac_inst;
NR_UE_RRC_INST_t* rrc_inst;
for (inst=0; inst < nb_inst; inst++) {
AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file, reconfig_file, rbconfig_file)) != NULL, "can not initialize RRC module\n");
AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
for (int inst = 0; inst < nb_inst; inst++) {
AssertFatal((rrc_inst = nr_l3_init_ue(uecap_file)) != NULL, "can not initialize RRC module\n");
AssertFatal((mac_inst = nr_l2_init_ue()) != NULL, "can not initialize L2 module\n");
AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
if (!get_softmodem_params()->sa) {
init_nsa_message(rrc_inst, reconfig_file, rbconfig_file);
// TODO why do we need noS1 configuration?
// temporarily moved here to understand why not using the one provided by gNB
nr_rlc_activate_srb0(mac_inst->crnti, NULL, send_srb0_rrc);
if (IS_SOFTMODEM_NOS1) {
// get default noS1 configuration
NR_RadioBearerConfig_t *rbconfig = NULL;
NR_RLC_BearerConfig_t *rlc_rbconfig = NULL;
fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
// set up PDCP, RLC, MAC
nr_pdcp_layer_init(false);
nr_pdcp_add_drbs(ENB_FLAG_NO, mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_rlc_add_drb(mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_toadd_list;
rlc_toadd_list.list.count = 1;
rlc_toadd_list.list.array = calloc(1, sizeof(NR_RLC_BearerConfig_t));
rlc_toadd_list.list.array[0] = rlc_rbconfig;
nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL);
// free memory
free_nr_noS1_bearer_config(&rbconfig, NULL);
}
}
}
}
+9 -7
View File
@@ -437,8 +437,6 @@ int main( int argc, char **argv ) {
if (set_exe_prio)
set_priority(79);
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
PHY_VARS_NR_UE *UE[MAX_NUM_CCs];
start_background_system();
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) {
@@ -478,6 +476,13 @@ int main( int argc, char **argv ) {
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g));
PHY_vars_UE_g[0] = malloc(sizeof(*PHY_vars_UE_g[0]) * MAX_NUM_CCs);
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[0][CC_id] = malloc(sizeof(*PHY_vars_UE_g[0][CC_id]));
memset(PHY_vars_UE_g[0][CC_id], 0, sizeof(*PHY_vars_UE_g[0][CC_id]));
}
init_NR_UE(1, uecap_file, reconfig_file, rbconfig_file);
int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1;
@@ -493,8 +498,6 @@ int main( int argc, char **argv ) {
}
}
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
if (get_softmodem_params()->emulate_l1) {
RCconfig_nr_ue_macrlc();
get_channel_model_mode(uniqCfg);
@@ -510,10 +513,9 @@ int main( int argc, char **argv ) {
start_oai_nrue_threads();
if (!get_softmodem_params()->emulate_l1) {
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
PHY_VARS_NR_UE *UE[MAX_NUM_CCs];
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
UE[CC_id] = PHY_vars_UE_g[0][CC_id];
memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
set_options(CC_id, UE[CC_id]);
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+1 -1
View File
@@ -638,7 +638,7 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config)
{
fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
if(phy_config != NULL) {
memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
memcpy(nrUE_config, &phy_config->config_req, sizeof(fapi_nr_config_request_t));
pushNotifiedFIFO(&PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->phy_config_ind, newNotifiedFIFO_elt(1,0,NULL,NULL));
}
return 0;
+5 -3
View File
@@ -822,7 +822,7 @@ int main(int argc, char **argv)
nr_gold_pdsch(UE, i, UE->scramblingID_dlsch[i]);
}
nr_l2_init_ue(NULL);
nr_l2_init_ue();
UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu);
@@ -835,7 +835,6 @@ int main(int argc, char **argv)
UE->chest_time = chest_type[1];
UE_mac->if_module = nr_ue_if_module_init(0);
UE_mac->state = UE_CONNECTED;
unsigned int available_bits=0;
unsigned char *estimated_output_bit;
@@ -853,7 +852,10 @@ int main(int argc, char **argv)
//Configure UE
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
nr_rrc_mac_config_req_scg(0, 0, secondaryCellGroup);
nr_rrc_mac_config_req_cg(0, 0, secondaryCellGroup);
UE_mac->state = UE_CONNECTED;
UE_mac->ra.ra_state = RA_SUCCEEDED;
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
+3 -3
View File
@@ -690,11 +690,11 @@ int main(int argc, char *argv[])
}
//Configure UE
NR_UE_RRC_INST_t rrcue = {0};
rrcue.scell_group_config = secondaryCellGroup;
nr_l2_init_ue(&rrcue);
nr_l2_init_ue();
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu);
UE->if_inst = nr_ue_if_module_init(0);
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
+1 -1
View File
@@ -174,7 +174,7 @@
#define SCCPARAMS_DESC(scc) { \
{GNB_CONFIG_STRING_PHYSCELLID,NULL,0,.i64ptr=scc->physCellId,.defint64val=0,TYPE_INT64,0/*0*/}, \
{GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET,NULL,0,.i64ptr=scc->n_TimingAdvanceOffset,.defint64val=NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0,TYPE_INT64,0/*1*/},\
{GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET,NULL,0,.i64ptr=scc->n_TimingAdvanceOffset,.defint64val=-1,TYPE_INT64,0/*1*/},\
{GNB_CONFIG_STRING_SSBPERIODICITYSERVINGCELL,NULL,0,.i64ptr=scc->ssb_periodicityServingCell,.defint64val=NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20,TYPE_INT64,0/*2*/},\
{GNB_CONFIG_STRING_DMRSTYPEAPOSITION,NULL,0,.i64ptr=&scc->dmrs_TypeA_Position,.defint64val=NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2,TYPE_INT64,0/*3*/},\
{GNB_CONFIG_STRING_SUBCARRIERSPACING,NULL,0,.i64ptr=scc->ssbSubcarrierSpacing,.defint64val=NR_SubcarrierSpacing_kHz30,TYPE_INT64,0/*4*/},\
+7 -1
View File
@@ -159,7 +159,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
scc->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
scc->uplinkConfigCommon->frequencyInfoUL = CALLOC(1,sizeof(struct NR_FrequencyInfoUL));
scc->uplinkConfigCommon->initialUplinkBWP = CALLOC(1,sizeof(struct NR_BWP_UplinkCommon));
//scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
//scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon));
scc->n_TimingAdvanceOffset = CALLOC(1, sizeof(long));
scc->ssb_PositionsInBurst = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__ssb_PositionsInBurst));
scc->ssb_periodicityServingCell = CALLOC(1,sizeof(long));
// scc->rateMatchPatternToAddModList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToAddModList));
@@ -439,6 +440,11 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL;
}
if ((int)*scc->n_TimingAdvanceOffset == -1) {
free(scc->n_TimingAdvanceOffset);
scc->n_TimingAdvanceOffset = NULL;
}
// check pucch_ResourceConfig
AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2,
"pucch_ResourceConfig should be 0 or 1 for now\n");
+3 -2
View File
@@ -570,9 +570,9 @@ typedef struct NR_UE_DL_BWP {
NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList_Common;
NR_PDSCH_Config_t *pdsch_Config;
NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig;
long *pdsch_HARQ_ACK_Codebook;
uint8_t mcsTableIdx;
nr_dci_format_t dci_format;
int bw_tbslbrm;
} NR_UE_DL_BWP_t;
typedef struct NR_UE_UL_BWP {
@@ -591,13 +591,14 @@ typedef struct NR_UE_UL_BWP {
NR_PUSCH_Config_t *pusch_Config;
NR_PUCCH_Config_t *pucch_Config;
NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon;
long *harq_ACK_SpatialBundlingPUCCH;
NR_UplinkConfig_t *supplementaryUplink;
NR_CSI_MeasConfig_t *csi_MeasConfig;
NR_SRS_Config_t *srs_Config;
long *msg3_DeltaPreamble;
long transform_precoding;
uint8_t mcs_table;
nr_dci_format_t dci_format;
int bw_tbslbrm;
int max_fb_time;
} NR_UE_UL_BWP_t;
+15 -16
View File
@@ -3278,7 +3278,8 @@ uint16_t get_rb_bwp_dci(nr_dci_format_t format,
uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
const NR_UE_UL_BWP_t *UL_BWP,
const NR_CellGroupConfig_t *cg,
const NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig,
long pdsch_HARQ_ACK_Codebook,
dci_pdu_rel15_t *dci_pdu,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
@@ -3328,12 +3329,12 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
/// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16
size += 16;
// Carrier indicator
if (cg->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
if (crossCarrierSchedulingConfig != NULL) {
dci_pdu->carrier_indicator.nbits=3;
size += dci_pdu->carrier_indicator.nbits;
}
// UL/SUL indicator
if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink != NULL) {
if (UL_BWP->supplementaryUplink != NULL) {
dci_pdu->carrier_indicator.nbits=1;
size += dci_pdu->ul_sul_indicator.nbits;
}
@@ -3376,7 +3377,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
size += 1;
}
// 1st DAI
if (DL_BWP->pdsch_HARQ_ACK_Codebook && *DL_BWP->pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic)
if (pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic)
dci_pdu->dai[0].nbits = 2;
else
dci_pdu->dai[0].nbits = 1;
@@ -3416,7 +3417,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
size += dci_pdu->antenna_ports.nbits;
LOG_D(NR_MAC,"dci_pdu->antenna_ports.nbits = %d\n",dci_pdu->antenna_ports.nbits);
// SRS request
if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
if (UL_BWP->supplementaryUplink == NULL)
dci_pdu->srs_request.nbits = 2;
else
dci_pdu->srs_request.nbits = 3;
@@ -3481,7 +3482,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
// Format identifier
size = 1;
// Carrier indicator
if (cg->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig != NULL) {
if (crossCarrierSchedulingConfig != NULL) {
dci_pdu->carrier_indicator.nbits=3;
size += dci_pdu->carrier_indicator.nbits;
}
@@ -3548,7 +3549,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
// HARQ PID
size += 4;
// DAI
if (DL_BWP->pdsch_HARQ_ACK_Codebook && *DL_BWP->pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) { // FIXME in case of more than one serving cell
if (pdsch_HARQ_ACK_Codebook == NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) { // FIXME in case of more than one serving cell
dci_pdu->dai[0].nbits = 2;
size += dci_pdu->dai[0].nbits;
}
@@ -3575,7 +3576,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
size += dci_pdu->transmission_configuration_indication.nbits;
}
// SRS request
if (cg->spCellConfig->spCellConfigDedicated->supplementaryUplink==NULL)
if (UL_BWP->supplementaryUplink == NULL)
dci_pdu->srs_request.nbits = 2;
else
dci_pdu->srs_request.nbits = 3;
@@ -4734,11 +4735,10 @@ uint16_t compute_pucch_prb_size(uint8_t format,
}
int get_dlbw_tbslbrm(int scc_bwpsize,
NR_CellGroupConfig_t *cg) {
const NR_ServingCellConfig_t *servingCellConfig)
{
int bw = scc_bwpsize;
if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) {
const NR_ServingCellConfig_t *servingCellConfig = cg->spCellConfig->spCellConfigDedicated;
if (servingCellConfig) {
if(servingCellConfig->downlinkBWP_ToAddModList) {
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = servingCellConfig->downlinkBWP_ToAddModList;
for (int i=0; i<BWP_list->list.count; i++) {
@@ -4753,11 +4753,10 @@ int get_dlbw_tbslbrm(int scc_bwpsize,
}
int get_ulbw_tbslbrm(int scc_bwpsize,
NR_CellGroupConfig_t *cg) {
const NR_ServingCellConfig_t *servingCellConfig)
{
int bw = scc_bwpsize;
if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) {
const NR_ServingCellConfig_t *servingCellConfig = cg->spCellConfig->spCellConfigDedicated;
if (servingCellConfig) {
if (servingCellConfig->uplinkConfig &&
servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList) {
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *BWP_list = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
@@ -95,7 +95,8 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP, int ss_type, int tda
uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
const NR_UE_UL_BWP_t *UL_BWP,
const NR_CellGroupConfig_t *cg,
const NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig,
long pdsch_HARQ_ACK_Codebook,
dci_pdu_rel15_t *dci_pdu,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
@@ -196,10 +197,10 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset);
int get_dlbw_tbslbrm(int scc_bwpsize,
NR_CellGroupConfig_t *cg);
const NR_ServingCellConfig_t *servingCellConfig);
int get_ulbw_tbslbrm(int scc_bwpsize,
NR_CellGroupConfig_t *cg);
const NR_ServingCellConfig_t *servingCellConfig);
uint32_t nr_compute_tbslbrm(uint16_t table,
uint16_t nb_rb,
+331 -167
View File
@@ -30,6 +30,8 @@
* \warning
*/
#define _GNU_SOURCE
//#include "mac_defs.h"
#include <NR_MAC_gNB/mac_proto.h>
#include "NR_MAC_UE/mac_proto.h"
@@ -39,6 +41,32 @@
#include "executables/softmodem-common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
const long logicalChannelGroup0_NR = 0;
typedef struct NR_LogicalChannelConfig__ul_SpecificParameters LcConfig_UlParamas_t;
const LcConfig_UlParamas_t NR_LCSRB1 = {
.priority = 1,
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
const LcConfig_UlParamas_t NR_LCSRB2 = {
.priority = 3,
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
const LcConfig_UlParamas_t NR_LCSRB3 = {
.priority = 1,
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
// these are the default values for SRB configurations(SRB1 and SRB2) as mentioned in 36.331 pg 258-259
const NR_LogicalChannelConfig_t NR_SRB1_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
(LcConfig_UlParamas_t *)&NR_LCSRB1};
const NR_LogicalChannelConfig_t NR_SRB2_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
(LcConfig_UlParamas_t *)&NR_LCSRB2};
const NR_LogicalChannelConfig_t NR_SRB3_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
(LcConfig_UlParamas_t *)&NR_LCSRB3};
void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
int mu,
NR_TDD_UL_DL_Pattern_t *pattern)
@@ -511,51 +539,193 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac,
mac->BWP_coresets[i] = NULL;
}
static int lcid_cmp(const void *lc1, const void *lc2, void *mac_inst)
{
uint8_t id1 = ((nr_lcordered_info_t *)lc1)->lcids_ordered;
uint8_t id2 = ((nr_lcordered_info_t *)lc2)->lcids_ordered;
NR_UE_MAC_INST_t *mac = (NR_UE_MAC_INST_t *)mac_inst;
NR_LogicalChannelConfig_t **lc_config = &mac->logicalChannelConfig[0];
AssertFatal(id1 > 0 && id2 > 0, "undefined logical channel identity\n");
AssertFatal(lc_config[id1 - 1] != NULL || lc_config[id2 - 1] != NULL, "logical channel configuration should be available\n");
return (lc_config[id1 - 1]->ul_SpecificParameters->priority - lc_config[id2 - 1]->ul_SpecificParameters->priority);
}
void nr_release_mac_config_logicalChannelBearer(module_id_t module_id, long channel_identity)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
if (mac->logicalChannelConfig[channel_identity - 1] != NULL) {
mac->logicalChannelConfig[channel_identity - 1] = NULL;
memset(&mac->scheduling_info.lc_sched_info[channel_identity - 1], 0, sizeof(NR_LC_SCHEDULING_INFO));
} else {
LOG_E(NR_MAC, "Trying to release a non configured logical channel bearer %li\n", channel_identity);
}
}
static uint16_t nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration)
{
switch (bucketsizeduration) {
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50:
return 50;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100:
return 100;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150:
return 150;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300:
return 300;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500:
return 500;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000:
return 1000;
default:
return 0;
}
}
void nr_configure_mac_config_logicalChannelBearer(module_id_t module_id,
long channel_identity,
NR_LogicalChannelConfig_t *lc_config)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
LOG_I(NR_MAC, "[MACLogicalChannelConfig]Applying RRC Logical Channel Config %d to lcid %li\n", module_id, channel_identity);
mac->logicalChannelConfig[channel_identity - 1] = lc_config;
// initialize the variable Bj for every LCID
mac->scheduling_info.lc_sched_info[channel_identity - 1].Bj = 0;
// store the bucket size
int pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
int bsd = nr_get_ms_bucketsizeduration(lc_config->ul_SpecificParameters->bucketSizeDuration);
// in infinite pbr, the bucket is saturated by pbr
if (lc_config->ul_SpecificParameters->prioritisedBitRate
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
bsd = 1;
}
mac->scheduling_info.lc_sched_info[channel_identity - 1].bucket_size = pbr * bsd;
if (lc_config->ul_SpecificParameters->logicalChannelGroup != NULL)
mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = *lc_config->ul_SpecificParameters->logicalChannelGroup;
else
mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = 0;
}
void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
if (rlc_toadd_list) {
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
int id = rlc_bearer->logicalChannelIdentity - 1;
mac->active_RLC_bearer[id] = true;
}
}
if (rlc_torelease_list) {
for (int i = 0; i < rlc_torelease_list->list.count; i++) {
if (rlc_torelease_list->list.array[i]) {
int id = *rlc_torelease_list->list.array[i] - 1;
mac->active_RLC_bearer[id] = false;
int lc_identity = *rlc_torelease_list->list.array[i];
nr_release_mac_config_logicalChannelBearer(module_id, lc_identity);
}
}
}
if (rlc_toadd_list) {
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
int lc_identity = rlc_bearer->logicalChannelIdentity;
mac->lc_ordered_info[i].lcids_ordered = lc_identity;
NR_LogicalChannelConfig_t *mac_lc_config;
if (mac->logicalChannelConfig[lc_identity - 1] == NULL) {
/* setup of new LCID*/
LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity);
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer should be present for LCID establishment\n");
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
if (rlc_bearer->mac_LogicalChannelConfig != NULL) {
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
} else {
LOG_I(NR_RRC, "Applying the default logicalChannelConfig for SRB\n");
if (srb_id == 1)
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB1_logicalChannelConfig_defaultValue;
else if (srb_id == 2)
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB2_logicalChannelConfig_defaultValue;
else if (srb_id == 3)
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB3_logicalChannelConfig_defaultValue;
else
AssertFatal(1 == 0, "The logical id %d is not a valid SRB id %li\n", lc_identity, srb_id);
}
} else { /* DRB */
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
AssertFatal(mac_lc_config != NULL, "For DRB, it should be mandatorily present\n");
}
} else {
/* LC is already established, reconfiguring the LC */
LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity);
if (rlc_bearer->mac_LogicalChannelConfig != NULL) {
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
} else {
/* Need M - Maintains current value */
continue;
}
}
mac->lc_ordered_info[i].logicalChannelConfig_ordered = mac_lc_config;
nr_configure_mac_config_logicalChannelBearer(module_id, lc_identity, mac_lc_config);
}
// reorder the logical channels as per its priority
qsort_r(mac->lc_ordered_info, rlc_toadd_list->list.count, sizeof(nr_lcordered_info_t), lcid_cmp, mac);
}
}
void configure_scc(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommonSIB_t *scc_sib,
NR_ServingCellConfigCommon_t *scc)
{
// SCC is provided when receiving reconfigurationWithSync
// SCC_SIB is provided when receiving SIB1
// So never at the same time
if (scc) {
if (scc->physCellId)
mac->physCellId = *scc->physCellId;
mac->bwp_dlcommon = scc->downlinkConfigCommon->initialDownlinkBWP;
mac->bwp_ulcommon = scc->uplinkConfigCommon->initialUplinkBWP;
mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position;
mac->tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon;
mac->p_Max = scc->uplinkConfigCommon->frequencyInfoUL->p_Max ?
*scc->uplinkConfigCommon->frequencyInfoUL->p_Max :
INT_MIN;
mac->nr_band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
}
if (scc_sib) {
mac->bwp_dlcommon = &scc_sib->downlinkConfigCommon.initialDownlinkBWP;
mac->bwp_ulcommon = &scc_sib->uplinkConfigCommon->initialUplinkBWP;
mac->tdd_UL_DL_ConfigurationCommon = scc_sib->tdd_UL_DL_ConfigurationCommon;
mac->p_Max = scc_sib->uplinkConfigCommon->frequencyInfoUL.p_Max ?
*scc_sib->uplinkConfigCommon->frequencyInfoUL.p_Max :
INT_MIN;
mac->nr_band = *scc_sib->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
}
}
void configure_current_BWP(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommonSIB_t *scc,
NR_CellGroupConfig_t *cell_group_config)
const NR_ServingCellConfig_t *spCellConfigDedicated)
{
NR_UE_DL_BWP_t *DL_BWP = &mac->current_DL_BWP;
NR_UE_UL_BWP_t *UL_BWP = &mac->current_UL_BWP;
NR_BWP_t dl_genericParameters = {0};
NR_BWP_t ul_genericParameters = {0};
DL_BWP->n_dl_bwp = 0;
UL_BWP->n_ul_bwp = 0;
if(scc) {
DL_BWP->bwp_id = 0;
UL_BWP->bwp_id = 0;
mac->bwp_dlcommon = &scc->downlinkConfigCommon.initialDownlinkBWP;
mac->bwp_ulcommon = &scc->uplinkConfigCommon->initialUplinkBWP;
dl_genericParameters = mac->bwp_dlcommon->genericParameters;
if(scc->uplinkConfigCommon)
ul_genericParameters = scc->uplinkConfigCommon->initialUplinkBWP.genericParameters;
if(mac->bwp_ulcommon)
ul_genericParameters = mac->bwp_ulcommon->genericParameters;
else
ul_genericParameters = mac->bwp_dlcommon->genericParameters;
DL_BWP->pdsch_Config = NULL;
if (mac->bwp_dlcommon->pdsch_ConfigCommon)
DL_BWP->tdaList_Common = mac->bwp_dlcommon->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
if (mac->bwp_ulcommon->pusch_ConfigCommon) {
@@ -564,99 +734,95 @@ void configure_current_BWP(NR_UE_MAC_INST_t *mac,
}
if (mac->bwp_ulcommon->pucch_ConfigCommon)
UL_BWP->pucch_ConfigCommon = mac->bwp_ulcommon->pucch_ConfigCommon->choice.setup;
if (mac->bwp_ulcommon->rach_ConfigCommon)
if (mac->bwp_ulcommon->rach_ConfigCommon) {
UL_BWP->rach_ConfigCommon = mac->bwp_ulcommon->rach_ConfigCommon->choice.setup;
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);
}
if (mac->bwp_dlcommon->pdcch_ConfigCommon)
configure_ss_coreset(mac, mac->bwp_dlcommon->pdcch_ConfigCommon->choice.setup, NULL);
}
if(cell_group_config) {
if (cell_group_config->physicalCellGroupConfig) {
DL_BWP->pdsch_HARQ_ACK_Codebook = &cell_group_config->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook;
UL_BWP->harq_ACK_SpatialBundlingPUCCH = cell_group_config->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH;
if(spCellConfigDedicated) {
UL_BWP->supplementaryUplink = spCellConfigDedicated->supplementaryUplink;
UL_BWP->csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig ? spCellConfigDedicated->csi_MeasConfig->choice.setup : NULL;
UL_BWP->pusch_servingcellconfig =
spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig ? spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL;
DL_BWP->pdsch_servingcellconfig = spCellConfigDedicated->pdsch_ServingCellConfig ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL;
if (spCellConfigDedicated->firstActiveDownlinkBWP_Id)
DL_BWP->bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id;
if (spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)
UL_BWP->bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id;
NR_BWP_Downlink_t *bwp_downlink = NULL;
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = spCellConfigDedicated->downlinkBWP_ToAddModList;
if (bwpList)
DL_BWP->n_dl_bwp = bwpList->list.count;
if (bwpList && DL_BWP->bwp_id > 0) {
for (int i = 0; i < bwpList->list.count; i++) {
bwp_downlink = bwpList->list.array[i];
if(bwp_downlink->bwp_Id == DL_BWP->bwp_id)
break;
}
AssertFatal(bwp_downlink != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id);
dl_genericParameters = bwp_downlink->bwp_Common->genericParameters;
DL_BWP->pdsch_Config = bwp_downlink->bwp_Dedicated->pdsch_Config->choice.setup;
DL_BWP->tdaList_Common = bwp_downlink->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
configure_ss_coreset(mac,
bwp_downlink->bwp_Common->pdcch_ConfigCommon ? bwp_downlink->bwp_Common->pdcch_ConfigCommon->choice.setup : NULL,
bwp_downlink->bwp_Dedicated->pdcch_Config ? bwp_downlink->bwp_Dedicated->pdcch_Config->choice.setup : NULL);
}
else {
dl_genericParameters = mac->bwp_dlcommon->genericParameters;
DL_BWP->pdsch_Config = spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup;
DL_BWP->tdaList_Common = mac->bwp_dlcommon->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
configure_ss_coreset(mac,
mac->bwp_dlcommon->pdcch_ConfigCommon ? mac->bwp_dlcommon->pdcch_ConfigCommon->choice.setup : NULL,
spCellConfigDedicated->initialDownlinkBWP->pdcch_Config ? spCellConfigDedicated->initialDownlinkBWP->pdcch_Config->choice.setup : NULL);
}
if (cell_group_config->spCellConfig &&
cell_group_config->spCellConfig->spCellConfigDedicated) {
struct NR_ServingCellConfig *spCellConfigDedicated = cell_group_config->spCellConfig->spCellConfigDedicated;
UL_BWP->csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig ? spCellConfigDedicated->csi_MeasConfig->choice.setup : NULL;
UL_BWP->pusch_servingcellconfig =
spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig ? spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL;
DL_BWP->pdsch_servingcellconfig = spCellConfigDedicated->pdsch_ServingCellConfig ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL;
if (spCellConfigDedicated->firstActiveDownlinkBWP_Id)
DL_BWP->bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id;
if (spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)
UL_BWP->bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id;
NR_BWP_Downlink_t *bwp_downlink = NULL;
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = spCellConfigDedicated->downlinkBWP_ToAddModList;
if (bwpList)
DL_BWP->n_dl_bwp = bwpList->list.count;
if (bwpList && DL_BWP->bwp_id > 0) {
for (int i = 0; i < bwpList->list.count; i++) {
bwp_downlink = bwpList->list.array[i];
if(bwp_downlink->bwp_Id == DL_BWP->bwp_id)
break;
}
AssertFatal(bwp_downlink != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id);
dl_genericParameters = bwp_downlink->bwp_Common->genericParameters;
DL_BWP->pdsch_Config = bwp_downlink->bwp_Dedicated->pdsch_Config->choice.setup;
DL_BWP->tdaList_Common = bwp_downlink->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
configure_ss_coreset(mac,
bwp_downlink->bwp_Common->pdcch_ConfigCommon ? bwp_downlink->bwp_Common->pdcch_ConfigCommon->choice.setup : NULL,
bwp_downlink->bwp_Dedicated->pdcch_Config ? bwp_downlink->bwp_Dedicated->pdcch_Config->choice.setup : NULL);
UL_BWP->msg3_DeltaPreamble = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble;
NR_BWP_Uplink_t *bwp_uplink = NULL;
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
if (ubwpList)
UL_BWP->n_ul_bwp = ubwpList->list.count;
if (ubwpList && UL_BWP->bwp_id > 0) {
for (int i = 0; i < ubwpList->list.count; i++) {
bwp_uplink = ubwpList->list.array[i];
if(bwp_uplink->bwp_Id == UL_BWP->bwp_id)
break;
}
else {
dl_genericParameters = mac->bwp_dlcommon->genericParameters;
DL_BWP->pdsch_Config = spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup;
DL_BWP->tdaList_Common = mac->bwp_dlcommon->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
configure_ss_coreset(mac,
mac->bwp_dlcommon->pdcch_ConfigCommon ? mac->bwp_dlcommon->pdcch_ConfigCommon->choice.setup : NULL,
spCellConfigDedicated->initialDownlinkBWP->pdcch_Config ? spCellConfigDedicated->initialDownlinkBWP->pdcch_Config->choice.setup : NULL);
}
UL_BWP->msg3_DeltaPreamble = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble;
NR_BWP_Uplink_t *bwp_uplink = NULL;
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
if (ubwpList)
UL_BWP->n_ul_bwp = ubwpList->list.count;
if (ubwpList && UL_BWP->bwp_id > 0) {
for (int i = 0; i < ubwpList->list.count; i++) {
bwp_uplink = ubwpList->list.array[i];
if(bwp_uplink->bwp_Id == UL_BWP->bwp_id)
break;
}
AssertFatal(bwp_uplink != NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id);
ul_genericParameters = bwp_uplink->bwp_Common->genericParameters;
UL_BWP->tdaList_Common = bwp_uplink->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
UL_BWP->pusch_Config = bwp_uplink->bwp_Dedicated->pusch_Config->choice.setup;
UL_BWP->pucch_Config = bwp_uplink->bwp_Dedicated->pucch_Config->choice.setup;
UL_BWP->srs_Config = bwp_uplink->bwp_Dedicated->srs_Config->choice.setup;
UL_BWP->configuredGrantConfig = bwp_uplink->bwp_Dedicated->configuredGrantConfig ? bwp_uplink->bwp_Dedicated->configuredGrantConfig->choice.setup : NULL;
if (bwp_uplink->bwp_Common->pucch_ConfigCommon)
UL_BWP->pucch_ConfigCommon = bwp_uplink->bwp_Common->pucch_ConfigCommon->choice.setup;
if (bwp_uplink->bwp_Common->rach_ConfigCommon)
UL_BWP->rach_ConfigCommon = bwp_uplink->bwp_Common->rach_ConfigCommon->choice.setup;
}
else {
UL_BWP->tdaList_Common = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
UL_BWP->pusch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup;
UL_BWP->pucch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
UL_BWP->srs_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
UL_BWP->configuredGrantConfig =
spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig ? spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig->choice.setup : NULL;
ul_genericParameters = mac->bwp_ulcommon->genericParameters;
if (mac->bwp_ulcommon->pucch_ConfigCommon)
UL_BWP->pucch_ConfigCommon = mac->bwp_ulcommon->pucch_ConfigCommon->choice.setup;
if (mac->bwp_ulcommon->rach_ConfigCommon)
UL_BWP->rach_ConfigCommon = mac->bwp_ulcommon->rach_ConfigCommon->choice.setup;
AssertFatal(bwp_uplink != NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id);
ul_genericParameters = bwp_uplink->bwp_Common->genericParameters;
UL_BWP->tdaList_Common = bwp_uplink->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
UL_BWP->pusch_Config = bwp_uplink->bwp_Dedicated->pusch_Config->choice.setup;
UL_BWP->pucch_Config = bwp_uplink->bwp_Dedicated->pucch_Config->choice.setup;
UL_BWP->srs_Config = bwp_uplink->bwp_Dedicated->srs_Config->choice.setup;
UL_BWP->configuredGrantConfig = bwp_uplink->bwp_Dedicated->configuredGrantConfig ? bwp_uplink->bwp_Dedicated->configuredGrantConfig->choice.setup : NULL;
if (bwp_uplink->bwp_Common->pucch_ConfigCommon)
UL_BWP->pucch_ConfigCommon = bwp_uplink->bwp_Common->pucch_ConfigCommon->choice.setup;
if (bwp_uplink->bwp_Common->rach_ConfigCommon) {
UL_BWP->rach_ConfigCommon = bwp_uplink->bwp_Common->rach_ConfigCommon->choice.setup;
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);
}
}
else
AssertFatal(1==0,"We shouldn't end here in configuring BWP\n");
else {
UL_BWP->tdaList_Common = mac->bwp_ulcommon->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
UL_BWP->pusch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pusch_Config->choice.setup;
UL_BWP->pucch_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
UL_BWP->srs_Config = spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup;
UL_BWP->configuredGrantConfig =
spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig ? spCellConfigDedicated->uplinkConfig->initialUplinkBWP->configuredGrantConfig->choice.setup : NULL;
ul_genericParameters = mac->bwp_ulcommon->genericParameters;
if (mac->bwp_ulcommon->pucch_ConfigCommon)
UL_BWP->pucch_ConfigCommon = mac->bwp_ulcommon->pucch_ConfigCommon->choice.setup;
if (mac->bwp_ulcommon->rach_ConfigCommon)
UL_BWP->rach_ConfigCommon = mac->bwp_ulcommon->rach_ConfigCommon->choice.setup;
}
}
DL_BWP->scs = dl_genericParameters.subcarrierSpacing;
@@ -673,6 +839,8 @@ void configure_current_BWP(NR_UE_MAC_INST_t *mac,
DL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(mac->bwp_dlcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
UL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(mac->bwp_ulcommon->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
DL_BWP->bw_tbslbrm = get_dlbw_tbslbrm(DL_BWP->initial_BWPSize, spCellConfigDedicated);
UL_BWP->bw_tbslbrm = get_ulbw_tbslbrm(UL_BWP->initial_BWPSize, spCellConfigDedicated);
}
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs)
@@ -706,23 +874,21 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
void nr_rrc_mac_config_req_sib1(module_id_t module_id,
int cc_idP,
struct NR_SI_SchedulingInfo *si_SchedulingInfo,
NR_SI_SchedulingInfo_t *si_SchedulingInfo,
NR_ServingCellConfigCommonSIB_t *scc)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
AssertFatal(scc, "SIB1 SCC should not be NULL\n");
mac->tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon;
mac->p_Max = scc->uplinkConfigCommon->frequencyInfoUL.p_Max;
configure_scc(mac, scc, NULL);
mac->si_SchedulingInfo = si_SchedulingInfo;
mac->nr_band = *scc->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
config_common_ue_sa(mac, scc, module_id, cc_idP);
// configure BWP only if it is a SIB1 detection in non connected state (after sync)
// not if it is a periodical update of SIB1 (no change of BWP in that case)
if(mac->state < UE_CONNECTED)
configure_current_BWP(mac, scc, NULL);
// Setup the SSB to Rach Occasionsif (cell_group_config->spCellConfig) { mapping according to the config
build_ssb_to_ro_map(mac);
if (!get_softmodem_params()->emulate_l1)
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
@@ -731,81 +897,79 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id,
void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
module_id_t module_id,
int cc_idP,
struct NR_ReconfigurationWithSync *reconfigurationWithSync)
const NR_ReconfigurationWithSync_t *reconfigurationWithSync)
{
RA_config_t *ra = &mac->ra;
if (reconfigurationWithSync->rach_ConfigDedicated) {
ra->rach_ConfigDedicated = reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
}
NR_ServingCellConfigCommon_t *scc = reconfigurationWithSync->spCellConfigCommon;
mac->bwp_dlcommon = scc->downlinkConfigCommon->initialDownlinkBWP;
mac->bwp_ulcommon = scc->uplinkConfigCommon->initialUplinkBWP;
mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position;
mac->tdd_UL_DL_ConfigurationCommon = scc->tdd_UL_DL_ConfigurationCommon;
mac->p_Max = scc->uplinkConfigCommon->frequencyInfoUL->p_Max;
mac->nr_band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
mac->physCellId = *scc->physCellId;
configure_scc(mac, NULL, reconfigurationWithSync->spCellConfigCommon);
mac->crnti = reconfigurationWithSync->newUE_Identity;
LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti);
config_common_ue(mac, scc, module_id, cc_idP);
config_common_ue(mac, reconfigurationWithSync->spCellConfigCommon, module_id, cc_idP);
mac->state = UE_NOT_SYNC;
ra->ra_state = RA_UE_IDLE;
nr_ue_mac_default_configs(mac);
if (!get_softmodem_params()->emulate_l1) {
mac->synch_request.Mod_id = module_id;
mac->synch_request.CC_id = cc_idP;
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
mac->if_module->synch_request(&mac->synch_request);
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
}
}
void nr_rrc_mac_config_req_mcg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *cell_group_config)
void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac,
const NR_PhysicalCellGroupConfig_t *phyConfig)
{
mac->pdsch_HARQ_ACK_Codebook = phyConfig->pdsch_HARQ_ACK_Codebook;
mac->harq_ACK_SpatialBundlingPUCCH = phyConfig->harq_ACK_SpatialBundlingPUCCH ? true : false;
mac->harq_ACK_SpatialBundlingPUSCH = phyConfig->harq_ACK_SpatialBundlingPUSCH ? true : false;
NR_P_Max_t *p_NR_FR1 = phyConfig->p_NR_FR1;
NR_P_Max_t *p_UE_FR1 = phyConfig->ext1 ?
phyConfig->ext1->p_UE_FR1 :
NULL;
if (p_NR_FR1 == NULL)
mac->p_Max_alt = p_UE_FR1 == NULL ? INT_MIN : *p_UE_FR1;
else
mac->p_Max_alt = p_UE_FR1 == NULL ? *p_NR_FR1 :
(*p_UE_FR1 < *p_NR_FR1 ?
*p_UE_FR1 : *p_NR_FR1);
}
void nr_rrc_mac_config_req_cg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *cell_group_config)
{
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
mac->cg = cell_group_config;
if (cell_group_config->spCellConfig)
mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0;
else
mac->servCellIndex = 0;
mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING;
mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE;
LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n",
module_id,
mac->scheduling_info.periodicBSR_SF,
mac->scheduling_info.retxBSR_SF);
if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) {
LOG_A(NR_MAC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
handle_reconfiguration_with_sync(mac, module_id, cc_idP, cell_group_config->spCellConfig->reconfigurationWithSync);
mac->state = UE_NOT_SYNC;
mac->ra.ra_state = RA_UE_IDLE;
nr_ue_mac_default_configs(mac);
if (!get_softmodem_params()->emulate_l1) {
mac->synch_request.Mod_id = module_id;
mac->synch_request.CC_id = cc_idP;
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
mac->if_module->synch_request(&mac->synch_request);
mac->if_module->phy_config_request(&mac->phy_config);
mac->phy_config_request_sent = true;
}
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);
if (cell_group_config->mac_CellGroupConfig) {
// TODO handle MAC-CellGroupConfig
}
configure_current_BWP(mac, NULL, cell_group_config);
}
void nr_rrc_mac_config_req_scg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *scell_group_config)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
AssertFatal(scell_group_config, "scell_group_config cannot be NULL\n");
if (cell_group_config->physicalCellGroupConfig)
configure_physicalcellgroup(mac, cell_group_config->physicalCellGroupConfig);
mac->cg = scell_group_config;
mac->servCellIndex = *scell_group_config->spCellConfig->servCellIndex;
if (scell_group_config->spCellConfig->reconfigurationWithSync)
handle_reconfiguration_with_sync(mac, module_id, cc_idP, scell_group_config->spCellConfig->reconfigurationWithSync);
configure_current_BWP(mac, NULL, scell_group_config);
// Setup the SSB to Rach Occasions mapping according to the config
build_ssb_to_ro_map(mac);
if (cell_group_config->spCellConfig) {
NR_SpCellConfig_t *spCellConfig = cell_group_config->spCellConfig;
mac->servCellIndex = spCellConfig->servCellIndex ? *spCellConfig->servCellIndex : 0;
if (spCellConfig->reconfigurationWithSync) {
LOG_A(NR_MAC, "Received reconfigurationWithSync\n");
handle_reconfiguration_with_sync(mac, module_id, cc_idP, spCellConfig->reconfigurationWithSync);
}
if (spCellConfig->spCellConfigDedicated) {
mac->crossCarrierSchedulingConfig = spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig;
configure_current_BWP(mac, NULL, spCellConfig->spCellConfigDedicated);
}
}
if (!mac->dl_config_request || !mac->ul_config_request)
ue_init_config_request(mac, mac->current_DL_BWP.scs);
}
+46 -28
View File
@@ -162,7 +162,6 @@ typedef enum {
UE_NOT_SYNC = 0,
UE_SYNC,
UE_PERFORMING_RA,
UE_WAIT_TX_ACK_MSG4,
UE_CONNECTED
} NR_UE_L2_STATE_t;
@@ -171,24 +170,38 @@ typedef enum {
RA_4STEP
} nr_ra_type_e;
typedef struct {
// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain;
// buffer status for each lcid
uint8_t LCID_status;
// Bj bucket usage per lcid
int32_t Bj;
// Bucket size per lcid
int32_t bucket_size;
// logical channel group id for each LCID
uint8_t LCGID;
} NR_LC_SCHEDULING_INFO;
typedef struct {
// buffer status for each lcgid
uint8_t BSR; // should be more for mesh topology
// keep the number of bytes in rlc buffer for each lcgid
int32_t BSR_bytes;
} NR_LCG_SCHEDULING_INFO;
// LTE structure, might need to be adapted for NR
typedef struct {
/// buffer status for each lcgid
uint8_t BSR[NR_MAX_NUM_LCGID]; // should be more for mesh topology
/// keep the number of bytes in rlc buffer for each lcgid
int32_t BSR_bytes[NR_MAX_NUM_LCGID];
/// after multiplexing buffer remain for each lcid
int32_t LCID_buffer_remain[NR_MAX_NUM_LCID];
// lcs scheduling info
NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID];
// lcg scheduling info
NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID];
/// sum of all lcid buffer size
uint16_t All_lcid_buffer_size_lastTTI;
/// buffer status for each lcid
uint8_t LCID_status[NR_MAX_NUM_LCID];
uint16_t All_lcid_buffer_size_lastTTI;
/// SR pending as defined in 38.321
uint8_t SR_pending;
/// SR_COUNTER as defined in 38.321
uint16_t SR_COUNTER;
/// logical channel group ide for each LCID
uint8_t LCGID[NR_MAX_NUM_LCID];
/// retxBSR-Timer, default value is sf2560
uint16_t retxBSR_Timer;
/// retxBSR_SF, number of subframe before triggering a regular BSR
@@ -226,11 +239,6 @@ typedef struct {
uint16_t extendedBSR_Sizes_r10;
/// default value is false
uint16_t extendedPHR_r10;
//Bj bucket usage per lcid
int16_t Bj[NR_MAX_NUM_LCID];
// Bucket size per lcid
int16_t bucket_size[NR_MAX_NUM_LCID];
} NR_UE_SCHEDULING_INFO;
typedef enum {
@@ -424,23 +432,23 @@ typedef struct ssb_list_info {
uint8_t nb_tx_ssb;
} ssb_list_info_t;
typedef struct nr_lcordered_info_s {
// logical channels ids ordered as per priority
int lcids_ordered;
// logical channel configurations reordered as per priority
NR_LogicalChannelConfig_t *logicalChannelConfig_ordered;
} nr_lcordered_info_t;
/*!\brief Top level UE MAC structure */
typedef struct {
NR_UE_L2_STATE_t state;
NR_CellGroupConfig_t *cg;
int servCellIndex;
NR_CSI_ReportConfig_t *csirc;
long physCellId;
//// MAC config
int first_sync_frame;
bool get_sib1;
bool get_otherSI;
NR_DRX_Config_t *drx_Config;
NR_SchedulingRequestConfig_t *schedulingRequestConfig;
NR_BSR_Config_t *bsr_Config;
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
NR_MIB_t *mib;
struct NR_SI_SchedulingInfo *si_SchedulingInfo;
int si_window_start;
@@ -451,6 +459,9 @@ typedef struct {
NR_BWP_DownlinkCommon_t *bwp_dlcommon;
NR_BWP_UplinkCommon_t *bwp_ulcommon;
bool harq_ACK_SpatialBundlingPUCCH;
bool harq_ACK_SpatialBundlingPUSCH;
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
NR_SearchSpace_t *otherSI_SS;
@@ -462,6 +473,7 @@ typedef struct {
NR_SearchSpace_t *search_space_zero;
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig;
bool phy_config_request_sent;
frame_type_t frame_type;
@@ -508,15 +520,21 @@ typedef struct {
/// BSR report flag management
uint8_t BSR_reporting_active;
/// LogicalChannelConfig has bearer.
bool active_RLC_bearer[NR_MAX_NUM_LCID];
// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive.
NR_LogicalChannelConfig_t *logicalChannelConfig[NR_MAX_NUM_LCID];
// order lc info
nr_lcordered_info_t lc_ordered_info[NR_MAX_NUM_LCID];
NR_UE_SCHEDULING_INFO scheduling_info;
/// PHR
uint8_t PHR_reporting_active;
int dmrs_TypeA_Position;
NR_P_Max_t *p_Max;
int p_Max;
int p_Max_alt;
long pdsch_HARQ_ACK_Codebook;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
frequency_range_t frequency_range;
+18 -11
View File
@@ -43,6 +43,8 @@
\param module_id module id */
void nr_ue_init_mac(module_id_t module_idP);
void send_srb0_rrc(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data);
/**\brief apply default configuration values in nr_mac instance
\param mac mac instance */
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac);
@@ -67,13 +69,9 @@ void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list);
void nr_rrc_mac_config_req_scg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *scell_group_config);
void nr_rrc_mac_config_req_mcg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *scell_group_config);
void nr_rrc_mac_config_req_cg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *cell_group_config);
void nr_rrc_mac_config_req_mib(module_id_t module_id,
int cc_idP,
@@ -82,16 +80,15 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id,
void nr_rrc_mac_config_req_sib1(module_id_t module_id,
int cc_idP,
struct NR_SI_SchedulingInfo *si_SchedulingInfo,
NR_SI_SchedulingInfo_t *si_SchedulingInfo,
NR_ServingCellConfigCommonSIB_t *scc);
/**\brief initialization NR UE MAC instance(s), total number of MAC instance based on NB_NR_UE_MAC_INST*/
NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst);
NR_UE_MAC_INST_t * nr_l2_init_ue();
/**\brief fetch MAC instance by module_id, within 0 - (NB_NR_UE_MAC_INST-1)
\param module_id index of MAC instance(s)*/
NR_UE_MAC_INST_t *get_mac_inst(
module_id_t module_id);
NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id);
/**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms
performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures.
@@ -148,6 +145,13 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
int value);
/*! \fn int nr_get_pbr(uint8_t prioritizedbitrate)
\brief get the rate in kbps from the rate configured by the higher layer
\param[in] prioritizedbitrate
\return the rate in kbps
*/
uint32_t nr_get_pbr(uint8_t prioritizedbitrate);
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
\param[in] periodicBSR_Timer timer for periodic BSR
@@ -364,6 +368,9 @@ void nr_get_prach_resources(module_id_t mod_id,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
void init_RA(module_id_t mod_id,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon,
+8 -50
View File
@@ -36,16 +36,13 @@
//#undef MALLOC
#include "assertions.h"
#include "executables/softmodem-common.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
#include "nr_rlc/nr_rlc_oai_api.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "RRC/NR_UE/rrc_proto.h"
#include <pthread.h>
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
static void send_srb0_rrc(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data)
void send_srb0_rrc(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data)
{
AssertFatal(sdu_len > 0 && sdu_len < CCCH_SDU_SIZE, "invalid CCCH SDU size %d\n", sdu_len);
@@ -63,59 +60,20 @@ void send_msg3_rrc_request(module_id_t mod_id, int rnti)
nr_mac_rrc_msg3_ind(mod_id, rnti);
}
NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
//LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
//LOG_I(MAC, "[MAIN] init UE MAC functions \n");
NR_UE_MAC_INST_t * nr_l2_init_ue()
{
LOG_I(NR_MAC, "MAIN: init UE MAC functions \n");
//init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(NB_NR_UE_MAC_INST, sizeof(NR_UE_MAC_INST_t));
for (int j = 0; j < NB_NR_UE_MAC_INST; j++)
nr_ue_init_mac(j);
int scs = get_softmodem_params()->sa ?
get_softmodem_params()->numerology :
rrc_inst ?
*rrc_inst->scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon->ssbSubcarrierSpacing :
- 1;
if (scs > -1)
ue_init_config_request(nr_ue_mac_inst, scs);
if (get_softmodem_params()->sa)
ue_init_config_request(nr_ue_mac_inst, get_softmodem_params()->numerology);
if (rrc_inst && rrc_inst->scell_group_config) {
nr_rrc_mac_config_req_scg(0, 0, rrc_inst->scell_group_config);
int rc = rlc_module_init(0);
AssertFatal(rc == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
nr_rlc_activate_srb0(nr_ue_mac_inst->crnti, NULL, send_srb0_rrc);
if (IS_SOFTMODEM_NOS1){
// get default noS1 configuration
NR_RadioBearerConfig_t *rbconfig = NULL;
NR_RLC_BearerConfig_t *rlc_rbconfig = NULL;
fill_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
// set up PDCP, RLC, MAC
nr_pdcp_layer_init(false);
nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig);
struct NR_CellGroupConfig__rlc_BearerToAddModList rlc_toadd_list;
rlc_toadd_list.list.count = 1;
rlc_toadd_list.list.array = calloc(1, sizeof(NR_RLC_BearerConfig_t));
rlc_toadd_list.list.array[0] = rlc_rbconfig;
nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL);
// free memory
free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
}
}
else {
LOG_I(MAC,"Running without CellGroupConfig\n");
if(get_softmodem_params()->sa == 1) {
int rc = rlc_module_init(0);
AssertFatal(rc == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
}
}
int rc = rlc_module_init(0);
AssertFatal(rc == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
return (nr_ue_mac_inst);
}
+36 -4
View File
@@ -894,7 +894,6 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr
if (ra->cfra) {
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot);
mac->state = UE_CONNECTED;
ra->RA_window_cnt = -1;
} else {
LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
@@ -902,12 +901,12 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);
mac->state = UE_WAIT_TX_ACK_MSG4;
}
LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
ra->RA_active = 0;
ra->ra_state = RA_SUCCEEDED;
mac->state = UE_CONNECTED;
nr_mac_rrc_ra_ind(mod_id, frame, true);
}
@@ -915,8 +914,8 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) {
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
// Random seed generation
@@ -950,5 +949,38 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
// Resetting RA window
nr_get_RA_window(mac);
}
}
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
int sched_slot = current_harq->ul_slot;
int sched_frame = current_harq->ul_frame;
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, 0);
pthread_mutex_lock(&ul_config->mutex_ul_config);
mac->nr_ue_emul_l1.num_harqs = 1;
AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM,
"ul_config->number_pdus %d out of bounds\n",
ul_config->number_pdus);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
PUCCH_sched_t pucch = {0};
pucch.n_CCE = current_harq->n_CCE;
pucch.N_CCE = current_harq->N_CCE;
pucch.delta_pucch = current_harq->delta_pucch;
pucch.ack_payload = ack_nack;
pucch.n_harq = 1;
current_harq->active = false;
current_harq->ack_received = false;
if (get_softmodem_params()->emulate_l1) {
mac->nr_ue_emul_l1.harq[pid].active = true;
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_sfn = sched_frame;
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_slot = sched_slot;
}
nr_ue_configure_pucch(mac,
sched_slot,
mac->ra.t_crnti,
&pucch,
pucch_pdu);
fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
}
@@ -186,15 +186,38 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15_t temp_pdu;
if(dci_format == NR_DL_DCI_FORMAT_1_0)
alt_size =
nr_dci_size(current_DL_BWP, current_UL_BWP, mac->cg, &temp_pdu, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0);
nr_dci_size(current_DL_BWP,
current_UL_BWP,
mac->crossCarrierSchedulingConfig,
mac->pdsch_HARQ_ACK_Codebook,
&temp_pdu,
NR_UL_DCI_FORMAT_0_0,
rnti_type,
coreset,
dl_bwp_id,
ss->searchSpaceType->present,
mac->type0_PDCCH_CSS_config.num_rbs,
0);
if(dci_format == NR_UL_DCI_FORMAT_0_0)
alt_size =
nr_dci_size(current_DL_BWP, current_UL_BWP, mac->cg, &temp_pdu, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0);
nr_dci_size(current_DL_BWP,
current_UL_BWP,
mac->crossCarrierSchedulingConfig,
mac->pdsch_HARQ_ACK_Codebook,
&temp_pdu,
NR_DL_DCI_FORMAT_1_0,
rnti_type,
coreset,
dl_bwp_id,
ss->searchSpaceType->present,
mac->type0_PDCCH_CSS_config.num_rbs,
0);
}
rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP,
current_UL_BWP,
mac->cg,
mac->crossCarrierSchedulingConfig,
mac->pdsch_HARQ_ACK_Codebook,
&mac->def_dci_pdu_rel15[dl_config->slot][dci_format],
dci_format,
rnti_type,
@@ -58,7 +58,7 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
//TODO configure P-MAX from the upper layers according to 38.331
int p_powerclass = 23; // dBm assuming poweclass 3 UE
int p_emax = mac->p_Max ? *mac->p_Max : 0;
int p_emax = mac->p_Max != INT_MIN ? mac->p_Max : p_powerclass;
int delta_P_powerclass = 0; // for powerclass 2 needs to be changed
if(mac->p_Max && Qm == 1 && powerBoostPi2BPSK && (nr_band == 40 || nr_band == 41 || nr_band == 77 || nr_band == 78 || nr_band == 79)) {
p_emax += 3;
+39 -34
View File
@@ -169,6 +169,9 @@ void nr_ue_init_mac(module_id_t module_idP)
mac->phy_config_request_sent = false;
mac->state = UE_NOT_SYNC;
mac->si_window_start = -1;
mac->servCellIndex = 0;
memset(&mac->current_DL_BWP, 0, sizeof(mac->current_DL_BWP));
memset(&mac->current_UL_BWP, 0, sizeof(mac->current_UL_BWP));
}
void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
@@ -188,17 +191,11 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i);
mac->scheduling_info.Bj[i] = -1;
mac->scheduling_info.bucket_size[i] = -1;
if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0
mac->scheduling_info.LCGID[i] = 0;
} else { // initialize all the data channels lcgid to 1
mac->scheduling_info.LCGID[i] = 1;
}
mac->scheduling_info.LCID_status[i] = LCID_EMPTY;
mac->scheduling_info.LCID_buffer_remain[i] = 0;
mac->scheduling_info.lc_sched_info[i].Bj = -1;
mac->scheduling_info.lc_sched_info[i].bucket_size = -1;
mac->scheduling_info.lc_sched_info[i].LCGID = 0; // defaults to 0 irrespective of SRB or DRB
mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY;
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
mac->first_ul_tx[k] = 1;
}
@@ -735,11 +732,9 @@ static int nr_ue_process_dci_dl_10(module_id_t module_id,
dlsch_pdu->TBS = current_harq->TBS;
}
int bw_tbslbrm;
if (current_DL_BWP->initial_BWPSize > 0)
bw_tbslbrm = get_dlbw_tbslbrm(current_DL_BWP->initial_BWPSize, mac->cg);
else
bw_tbslbrm = dlsch_pdu->BWPSize;
int bw_tbslbrm = current_DL_BWP->initial_BWPSize > 0 ?
current_DL_BWP->bw_tbslbrm :
dlsch_pdu->BWPSize;
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, bw_tbslbrm, 1);
/* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
@@ -1164,8 +1159,7 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
long *maxMIMO_Layers = current_DL_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers;
AssertFatal(maxMIMO_Layers != NULL, "Option with max MIMO layers not configured is not supported\n");
int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4;
int bw_tbslbrm = get_dlbw_tbslbrm(current_DL_BWP->initial_BWPSize, mac->cg);
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, bw_tbslbrm, nl_tbslbrm);
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, current_DL_BWP->bw_tbslbrm, nl_tbslbrm);
/*PTRS configuration */
dlsch_pdu->pduBitmap = 0;
if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) {
@@ -1262,7 +1256,6 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
int slot)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id];
current_harq->active = true;
current_harq->ack_received = false;
current_harq->pucch_resource_indicator = pucch_id;
@@ -1364,7 +1357,8 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource;
if (current_UL_BWP->harq_ACK_SpatialBundlingPUCCH != NULL || *current_DL_BWP->pdsch_HARQ_ACK_Codebook != 1) {
if (mac->harq_ACK_SpatialBundlingPUCCH ||
mac->pdsch_HARQ_ACK_Codebook != NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic) {
LOG_E(MAC,"PUCCH Unsupported cell group configuration\n");
return;
} else if (current_DL_BWP && current_DL_BWP->pdsch_servingcellconfig && current_DL_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) {
@@ -2172,6 +2166,19 @@ void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int n
}
}
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind)
{
/* see TS 38.213 9.2.1 PUCCH Resource Sets */
int delta_PRI = res_ind;
int n_CCE_0 = pucch->n_CCE;
int N_CCE_0 = pucch->N_CCE;
if (N_CCE_0 == 0)
AssertFatal(1 == 0, "PUCCH No compatible pucch format found\n");
int r_PUCCH = ((2 * n_CCE_0) / N_CCE_0) + (2 * delta_PRI);
pucch->initial_pucch_id = r_PUCCH;
pucch->pucch_resource = NULL;
}
/*******************************************************************
*
* NAME : get_downlink_ack
@@ -2356,18 +2363,10 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
}
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP->pucch_Config;
if (mac->state == UE_WAIT_TX_ACK_MSG4 || !pucch_Config || !pucch_Config->resourceSetToAddModList
|| pucch_Config->resourceSetToAddModList->list.array[0] == NULL) {
/* see TS 38.213 9.2.1 PUCCH Resource Sets */
int delta_PRI = res_ind;
int n_CCE_0 = pucch->n_CCE;
int N_CCE_0 = pucch->N_CCE;
if (N_CCE_0 == 0)
AssertFatal(1 == 0, "PUCCH No compatible pucch format found\n");
int r_PUCCH = ((2 * n_CCE_0) / N_CCE_0) + (2 * delta_PRI);
pucch->initial_pucch_id = r_PUCCH;
pucch->pucch_resource = NULL;
} else {
if (!pucch_Config || !pucch_Config->resourceSetToAddModList
|| pucch_Config->resourceSetToAddModList->list.array[0] == NULL)
configure_initial_pucch(pucch, res_ind);
else {
int resource_set_id = find_pucch_resource_set(mac, O_ACK);
int n_list = pucch_Config->resourceSetToAddModList->list.count;
AssertFatal(resource_set_id < n_list, "Invalid PUCCH resource set id %d\n", resource_set_id);
@@ -2381,7 +2380,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
pucch->pucch_resource = acknack_resource;
LOG_D(MAC, "frame %d slot %d pucch acknack payload %d\n", frame, slot, o_ACK);
}
reverse_n_bits(&o_ACK,number_harq_feedback);
reverse_n_bits(&o_ACK, number_harq_feedback);
pucch->ack_payload = o_ACK;
pucch->n_harq = number_harq_feedback;
@@ -2833,7 +2832,8 @@ void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, int pdu_id)
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot);
LOG_D(MAC, "In [%d.%d] Handling DLSCH PDU type %d\n",
dl_info->frame, dl_info->slot, dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type);
// Processing MAC PDU
// it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs
@@ -2879,6 +2879,11 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
else
N_RB = mac->type0_PDCCH_CSS_config.num_rbs;
if (N_RB == 0) {
LOG_E(MAC, "DCI configuration error! N_RB = 0\n");
return 1;
}
switch(dci_format) {
case NR_DL_DCI_FORMAT_1_0:
+487 -133
View File
@@ -60,8 +60,8 @@
static prach_association_pattern_t prach_assoc_pattern;
static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type)
{
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
// clear ul_config for new frame/slot
@@ -91,8 +91,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
int cc_id,
frame_t frame,
int slot,
void *phy_data){
void *phy_data)
{
scheduled_response->dl_config = dl_config;
scheduled_response->ul_config = ul_config;
scheduled_response->tx_request = tx_request;
@@ -667,9 +667,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
if (!maxMIMO_Layers)
maxMIMO_Layers = pusch_Config ? pusch_Config->maxRank : NULL;
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
int bw_tbslbrm = get_ulbw_tbslbrm(current_UL_BWP->initial_BWPSize, mac->cg);
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table,
bw_tbslbrm,
current_UL_BWP->bw_tbslbrm,
*maxMIMO_Layers);
} else
pusch_config_pdu->tbslbrm = 0;
@@ -1095,6 +1094,31 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info)
pthread_mutex_unlock(&ul_config->mutex_ul_config);
}
// update Bj for all active lcids before LCP procedure
LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx);
for (nr_lcordered_info_t *lc_bearer = mac->lc_ordered_info; lc_bearer->logicalChannelConfig_ordered != NULL; lc_bearer++) {
int lcid = lc_bearer->lcids_ordered;
NR_LogicalChannelConfig_t *lcconfig = mac->logicalChannelConfig[lcid - 1];
NR_LC_SCHEDULING_INFO *sched_lc = &mac->scheduling_info.lc_sched_info[lcid - 1];
int32_t bucketSize_max =
sched_lc->bucket_size; // max amount of data that can be buffered/accumulated in a logical channel buffer
/*
measure Bj
increment the value of Bj by product PBR * T
*/
int T = 1; // time elapsed since Bj was last incremented
int32_t bj = sched_lc->Bj;
bj += nr_get_pbr(lcconfig->ul_SpecificParameters->prioritisedBitRate) * T;
if (lcconfig->ul_SpecificParameters->prioritisedBitRate
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
bj = nr_get_pbr(lcconfig->ul_SpecificParameters->prioritisedBitRate);
}
// bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization
sched_lc->Bj = min(bj, bucketSize_max);
}
// Call BSR procedure as described in Section 5.4.5 in 38.321
// First check ReTxBSR Timer because it is always configured
@@ -1147,23 +1171,23 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
// Reset transmission status
lcid_bytes_in_buffer[lcid - 1] = 0;
mac->scheduling_info.LCID_status[lcid - 1] = LCID_EMPTY;
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_EMPTY;
}
for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
// Reset Buffer Info
mac->scheduling_info.BSR[lcgid] = 0;
mac->scheduling_info.BSR_bytes[lcgid] = 0;
mac->scheduling_info.lcg_sched_info[lcgid].BSR = 0;
mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes = 0;
}
//Get Buffer Occupancy and fill lcid_reordered_array
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
if (mac->active_RLC_bearer[lcid - 1]) { // todo
int lcgid = mac->scheduling_info.LCGID[lcid - 1];
if (mac->logicalChannelConfig[lcid - 1] != NULL) { // todo
int lcgid = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
// Store already available data to transmit per Group
if (lcgid < NR_MAX_NUM_LCGID) {
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid - 1];
lcgid_buffer_remain[lcgid] += mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain;
}
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
@@ -1173,13 +1197,13 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
mac->scheduling_info.LCID_status[lcid - 1] = LCID_NOT_EMPTY;
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_NOT_EMPTY;
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
if (lcgid < NR_MAX_NUM_LCGID) {
num_lcid_with_data ++;
// sum lcid buffer which has same lcgid
mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes += rlc_status.bytes_in_buffer;
//Fill in the array
array_index = 0;
@@ -1222,7 +1246,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
"[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
module_idP,
lcid,
mac->scheduling_info.LCGID[lcid - 1],
mac->scheduling_info.lc_sched_info[lcid - 1].LCGID,
frameP,
slotP);
break;
@@ -1242,7 +1266,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
//Store Buffer Occupancy in remain buffers for next TTI
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
mac->scheduling_info.LCID_buffer_remain[lcid - 1] = lcid_bytes_in_buffer[lcid - 1];
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain = lcid_bytes_in_buffer[lcid - 1];
}
return bsr_regular_triggered;
@@ -2137,8 +2161,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, vo
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, phy_data);
if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
if (mac->state == UE_WAIT_TX_ACK_MSG4)
mac->state = UE_CONNECTED;
}
}
}
@@ -2632,7 +2654,7 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
int lcg_id = 0;
while (lcg_id < NR_MAX_NUM_LCGID) {
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) {
num_lcg_id_with_data++;
}
@@ -2713,11 +2735,17 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
int lcg_id_bsr_trunc = 0;
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
mac->scheduling_info.lcg_sched_info[lcg_id].BSR =
nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE,
NR_SHORT_BSR_TABLE_SIZE,
mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes);
} else {
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
mac->scheduling_info.lcg_sched_info[lcg_id].BSR =
nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE,
NR_LONG_BSR_TABLE_SIZE,
mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes);
}
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) {
num_lcg_id_with_data++;
lcg_id_bsr_trunc = lcg_id;
}
@@ -2751,8 +2779,8 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
// REPORT SHORT TRUNCATED BSR
//Get LCGID of highest priority LCID with data (todo)
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
lcg_id = mac->scheduling_info.LCGID[lcid - 1];
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
lcg_id = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes)) {
lcg_id_bsr_trunc = lcg_id;
}
}
@@ -2778,25 +2806,29 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
mac_ce_p->bsr_s = NULL;
mac_ce_p->bsr_t = NULL;
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0];
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1];
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2];
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3];
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4];
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5];
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6];
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7];
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
module_idP, frameP, subframe,
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.lcg_sched_info[0].BSR;
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.lcg_sched_info[1].BSR;
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.lcg_sched_info[2].BSR;
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.lcg_sched_info[3].BSR;
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.lcg_sched_info[4].BSR;
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.lcg_sched_info[5].BSR;
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.lcg_sched_info[6].BSR;
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.lcg_sched_info[7].BSR;
LOG_D(NR_MAC,
"[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 "
"%d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
module_idP,
frameP,
subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[0],
mac->scheduling_info.BSR[1],
mac->scheduling_info.BSR[2],
mac->scheduling_info.BSR[3],
mac->scheduling_info.BSR[4],
mac->scheduling_info.BSR[5],
mac->scheduling_info.BSR[6],
mac->scheduling_info.BSR[7]);
mac->scheduling_info.lcg_sched_info[0].BSR,
mac->scheduling_info.lcg_sched_info[1].BSR,
mac->scheduling_info.lcg_sched_info[2].BSR,
mac->scheduling_info.lcg_sched_info[3].BSR,
mac->scheduling_info.lcg_sched_info[4].BSR,
mac->scheduling_info.lcg_sched_info[5].BSR,
mac->scheduling_info.lcg_sched_info[6].BSR,
mac->scheduling_info.lcg_sched_info[7].BSR);
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
mac_ce_p->bsr_l = NULL;
@@ -2804,19 +2836,27 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
//Truncated BSR
mac_ce_p->bsr_s = NULL;
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe,
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR;
LOG_D(NR_MAC,
"[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
module_idP,
frameP,
subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR,
lcg_id_bsr_trunc);
} else {
mac_ce_p->bsr_t = NULL;
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
module_idP, frameP, subframe,
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR;
LOG_D(NR_MAC,
"[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
module_idP,
frameP,
subframe,
mac->BSR_reporting_active,
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR,
lcg_id_bsr_trunc);
}
}
@@ -2845,6 +2885,237 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
}
}
uint32_t get_count_lcids_same_priority(NR_UE_MAC_INST_t *mac, uint8_t start, uint8_t total_active_lcids, int *lcid_ordered_array)
{
// count number of logical channels with same priority as curr_lcid
uint8_t same_priority_count = 0;
uint8_t curr_lcid = lcid_ordered_array[start];
NR_LogicalChannelConfig_t *lc_config_curr = mac->logicalChannelConfig[curr_lcid - 1];
for (uint8_t index = start; index < total_active_lcids; index++) {
uint8_t next_lcid = lcid_ordered_array[index];
NR_LogicalChannelConfig_t *lc_config_next = mac->logicalChannelConfig[next_lcid - 1];
if (lc_config_curr->ul_SpecificParameters->priority == lc_config_next->ul_SpecificParameters->priority) {
same_priority_count++;
}
}
LOG_D(NR_MAC, "Number of lcids with same priority as that of lcid %d is %d\n", curr_lcid, same_priority_count);
return same_priority_count;
}
long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
uint8_t same_priority_count,
uint8_t lc_num,
uint16_t buflen_remain_ep,
int16_t buflen_remain,
uint8_t round_id,
uint32_t *bytes_read_fromlc,
long *target)
{
/* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/
NR_LogicalChannelConfig_t *lc_config = mac->logicalChannelConfig[lc_num - 1];
long pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
int32_t lcid_remain_buffer = mac->scheduling_info.lc_sched_info[lc_num - 1].LCID_buffer_remain;
*target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr;
long num_remaining_bytes = 0;
long num_bytes_requested = 0;
if (round_id == 0) { // initial round
uint16_t pdu_remain = (same_priority_count > 1) ? buflen_remain_ep : buflen_remain;
num_bytes_requested = (pdu_remain < pbr) ? min(pdu_remain, lcid_remain_buffer) : min(pbr, lcid_remain_buffer);
num_remaining_bytes = *target - bytes_read_fromlc[lc_num - 1];
num_bytes_requested = min(num_bytes_requested, num_remaining_bytes);
} else { // from first round
if (same_priority_count > 1) {
num_bytes_requested = min(buflen_remain_ep, lcid_remain_buffer);
num_remaining_bytes = buflen_remain_ep - bytes_read_fromlc[lc_num - 1];
num_bytes_requested = min(num_bytes_requested, num_remaining_bytes);
} else {
num_bytes_requested = min(buflen_remain, lcid_remain_buffer);
}
}
AssertFatal(num_remaining_bytes >= 0, "the total number of bytes allocated until target length is greater than expected\n");
LOG_D(NR_MAC, "number of bytes requested for lcid %d is %li\n", lc_num, num_bytes_requested);
return num_bytes_requested;
}
bool get_dataavailability_buffers(uint8_t total_active_lcids, int *lcid_ordered_array, bool *data_status_lcbuffers)
{
// check whether there is any data in the rlc buffer corresponding to active lcs
for (uint8_t id = 0; id < total_active_lcids; id++) {
int lcid = lcid_ordered_array[id];
if (data_status_lcbuffers[lcid - 1]) {
return true;
}
}
return false;
}
uint8_t select_logical_channels(NR_UE_MAC_INST_t *mac, uint8_t *num_active_lcids, int *active_lcids)
{
// (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical
// channels, TS38.321)
// selection of logical channels with Bj > 0
for (nr_lcordered_info_t *lc_bearer = mac->lc_ordered_info; lc_bearer->logicalChannelConfig_ordered != NULL; lc_bearer++) {
uint8_t lcid = lc_bearer->lcids_ordered;
if (mac->scheduling_info.lc_sched_info[lcid - 1].Bj > 0) {
active_lcids[*num_active_lcids] = lcid;
(*num_active_lcids)++;
LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, *num_active_lcids);
}
}
return 0;
}
static bool fill_mac_sdu(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframe,
uint8_t gNB_index,
uint16_t buflen,
int16_t *buflen_remain,
int lcid,
uint8_t **pdu,
uint32_t *counter,
uint8_t count_same_priority_lcids,
uint16_t buflen_ep,
uint32_t *lcids_bytes_tot,
uint16_t *num_sdus,
NR_UE_MAC_CE_INFO *mac_ce_p,
bool *lcids_data_status,
uint8_t *num_lcids_same_priority)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
/* prepare the MAC sdu */
int32_t lcid_remain_buffer = sched_info->lc_sched_info[lcid - 1].LCID_buffer_remain;
LOG_D(NR_MAC,
"In %s: [UE %d] [%d.%d] lcp round = %d, remaining mac pdu length = %d, lcid buffer remaining = %d, lcid = %d \n",
__FUNCTION__,
module_idP,
frameP,
subframe,
*counter,
*buflen_remain,
lcid_remain_buffer,
lcid);
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *)(*pdu);
*pdu += sh_size;
// number of bytes requested from RLC for each LCID
long target = 0;
long bytes_requested =
get_num_bytes_to_reqlc(mac, count_same_priority_lcids, lcid, buflen_ep, *buflen_remain, *counter, lcids_bytes_tot, &target);
uint16_t sdu_length = mac_rlc_data_req(module_idP,
mac->crnti,
gNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
lcid,
bytes_requested,
(char *)(*pdu),
0,
0);
AssertFatal(bytes_requested >= sdu_length,
"In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %li remaining bytes\n",
__FUNCTION__,
lcid,
sdu_length,
bytes_requested);
// Decrement Bj by the total size of MAC SDUs(RLC PDU) served to logical channel
// currently the Bj is drecremented by size of MAC SDus everytime it is served to logical channel, so by this approach there
// will be more chance for lower priority logical channels to be served in the next TTI
// second approach can also be followed where Bj is decremented only in the first round but not in the subsequent rounds
sched_info->lc_sched_info[lcid - 1].Bj -= sdu_length;
LOG_D(NR_MAC,
"decrement Bj of the lcid %d by size of sdu length = %d and new Bj for lcid %d is %d\n",
lcid,
sdu_length,
lcid,
sched_info->lc_sched_info[lcid - 1].Bj);
if (sdu_length > 0) {
LOG_D(NR_MAC,
"In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID "
"0x%02x (buflen (TBS) %d bytes)\n",
__FUNCTION__,
module_idP,
frameP,
subframe,
(*num_sdus) + 1,
sdu_length,
lcid,
buflen);
header->R = 0;
header->F = 1;
header->LCID = lcid;
header->L = htons(sdu_length);
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n");
LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length);
log_dump(NR_MAC, *pdu, sdu_length, LOG_DUMP_CHAR, "\n");
#endif
*pdu += sdu_length;
mac_ce_p->sdu_length_total += sdu_length;
mac_ce_p->total_mac_pdu_header_len += sh_size;
(*num_sdus)++;
} else {
*pdu -= sh_size;
lcids_data_status[lcid - 1] = false;
(*num_lcids_same_priority)--;
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n and hence set to false", __FUNCTION__, lcid);
return 0;
}
*buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
// Update Buffer remain and BSR bytes after transmission
NR_LC_SCHEDULING_INFO *lc_info = &sched_info->lc_sched_info[0] + lcid - 1;
NR_LCG_SCHEDULING_INFO *lcg_info = &sched_info->lcg_sched_info[0];
lc_info->LCID_buffer_remain -= sdu_length;
(lcg_info + lc_info->LCGID)->BSR_bytes -= sdu_length;
LOG_D(NR_MAC,
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d = %d\n",
module_idP,
frameP,
subframe,
lc_info->LCGID,
(lcg_info + lc_info->LCGID)->BSR_bytes);
if ((lcg_info + lc_info->LCGID)->BSR_bytes < 0)
(lcg_info + lc_info->LCGID)->BSR_bytes = 0;
// update number of bytes served from the current lcid
lcids_bytes_tot[lcid - 1] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sh_size);
if ((*counter == 0 && lcids_bytes_tot[lcid - 1] >= target)
|| (count_same_priority_lcids > 1
&& lcids_bytes_tot[lcid - 1] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in
// the first lcp run except when infinity
LOG_D(NR_MAC,
"In %s: total number bytes read from rlc buffer for lcid %d are %d\n",
__FUNCTION__,
lcid,
lcids_bytes_tot[lcid - 1]);
(*num_lcids_same_priority)--;
return 0;
}
return 1;
}
/**
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321)
@@ -2875,7 +3146,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
//mac_ce_p->phr_ce_len = 0;
//mac_ce_p->phr_header_len = 0;
uint16_t sdu_length = 0;
uint16_t num_sdus = 0;
mac_ce_p->sdu_length_total = 0;
NR_BSR_SHORT bsr_short, bsr_truncated;
@@ -2886,113 +3156,120 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
//NR_POWER_HEADROOM_CMD phr;
//mac_ce_p->phr_p = &phr;
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
//int highest_priority = 16;
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
uint8_t *pdu = ulsch_buffer;
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
// variable used to build the lcids with positive Bj
int lcids_bj_pos[NR_MAX_NUM_LCID] = {0};
uint8_t avail_lcids_count = 0;
// variable used to store the lcid data status during lcp
bool lcids_data_status[NR_MAX_NUM_LCID] = {0};
memset(lcids_data_status, 1, NR_MAX_NUM_LCID);
uint32_t lcp_allocation_counter =
0; // in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider
// bj and prioritized bit rate but just consider priority
uint16_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present
// because as per standard(TS38.321), all equal priority channels should be served equally
// nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
// Check for DCCH first
// TO DO: Multiplex in the order defined by the logical channel prioritization
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
if (!mac->active_RLC_bearer[lcid - 1])
continue;
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
// selection of logical channels
select_logical_channels(mac, &avail_lcids_count, lcids_bj_pos);
LOG_D(NR_MAC,
"[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d "
"bytes, buflen_remain %d bytes)\n",
module_idP,
frameP,
subframe,
lcid,
buflen,
mac_ce_p->sdu_length_total,
mac_ce_p->tot_mac_ce_len,
buflen_remain);
// multiplex in the order of highest priority
do {
/*
go until there is space availabile in the MAC PDU and there is data available in RLC buffers of active logical channels
*/
uint8_t num_lcids_same_priority = 0;
uint8_t count_same_priority_lcids = 0;
while (buflen_remain > 0) {
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu;
// variable used to store the total bytes read from rlc for each lcid
uint32_t lcids_bytes_tot[NR_MAX_NUM_LCID] = {0};
pdu += sh_size;
for (uint8_t id = 0; id < avail_lcids_count; id++) {
/*
loop over all logical channels in the order of priority. As stated in TS138.321 Section 5.4.3.1, in the first run, only
prioritized number of bytes are taken out from the corresponding RLC buffers of all active logical channels and if there is
still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel
is placed in the MAC PDU before going on to next high priority logical channel
*/
int lcid = lcids_bj_pos[id];
sdu_length = mac_rlc_data_req(module_idP,
mac->crnti,
gNB_index,
frameP,
ENB_FLAG_NO,
MBMS_FLAG_NO,
lcid,
buflen_remain,
(char *)pdu,
0,
0);
// skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to
// MAC PDU
if (!sched_info->lc_sched_info[lcid - 1].LCID_status || !lcids_data_status[lcid - 1]) {
lcids_data_status[lcid - 1] = false;
continue;
}
AssertFatal(buflen_remain >= sdu_length,
"LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n",
lcid,
sdu_length,
buflen_remain);
if (sdu_length > 0) {
LOG_D(NR_MAC,
"[UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x "
"(buflen (TBS) %d bytes)\n",
module_idP,
frameP,
subframe,
num_sdus + 1,
sdu_length,
lcid,
buflen);
header->R = 0;
header->F = 1;
header->LCID = lcid;
header->L = htons(sdu_length);
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n");
LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length);
log_dump(NR_MAC, pdu, sdu_length, LOG_DUMP_CHAR, "\n");
#endif
pdu += sdu_length;
mac_ce_p->sdu_length_total += sdu_length;
mac_ce_p->total_mac_pdu_header_len += sh_size;
num_sdus++;
} else {
pdu -= sh_size;
LOG_D(NR_MAC, "no data to transmit for RB with LCID 0x%02x\n", lcid);
break;
// count number of lc with same priority as lcid
if (!num_lcids_same_priority) {
num_lcids_same_priority = count_same_priority_lcids =
get_count_lcids_same_priority(mac, id, avail_lcids_count, lcids_bj_pos);
}
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
//Update Buffer remain and BSR bytes after transmission
mac->scheduling_info.LCID_buffer_remain[lcid - 1] -= sdu_length;
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] -= sdu_length;
LOG_D(NR_MAC,
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
"In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header "
"len %d bytes,"
"buflen_remain %d bytes)\n",
__FUNCTION__,
module_idP,
frameP,
subframe,
mac->scheduling_info.LCGID[lcid - 1],
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]]);
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] < 0)
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] = 0;
lcid,
buflen,
mac_ce_p->sdu_length_total,
mac_ce_p->tot_mac_ce_len,
buflen_remain);
if (num_lcids_same_priority == count_same_priority_lcids) {
buflen_ep = (buflen_remain - (count_same_priority_lcids * sh_size)) / count_same_priority_lcids;
}
while (buflen_remain > 0) {
/*
loops until the requested number of bytes from MAC to RLC are placed in the MAC PDU. The number of requested bytes
depends on whether it is the first run or otherwise because in the first run only prioritited number of bytes of all
active logical channels in the order of priority are placed in the MAC PDU. The 'get_num_bytes_to_reqlc' calculates
the target number of bytes to request from RLC via 'mac_rlc_data_req'
*/
if (!fill_mac_sdu(module_idP,
frameP,
subframe,
gNB_index,
buflen,
&buflen_remain,
lcid,
&pdu,
&lcp_allocation_counter,
count_same_priority_lcids,
buflen_ep,
lcids_bytes_tot,
&num_sdus,
mac_ce_p,
lcids_data_status,
&num_lcids_same_priority)) {
break;
}
}
}
}
lcp_allocation_counter++;
} while (buflen_remain > 0 && get_dataavailability_buffers(avail_lcids_count, lcids_bj_pos, lcids_data_status));
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
@@ -3061,3 +3338,80 @@ void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIG
dl_config->number_pdus += 1;
ul_time_alignment->ta_apply = false;
}
uint32_t nr_get_pbr(uint8_t prioritizedbitrate)
{
int32_t pbr = -1;
switch (prioritizedbitrate) {
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps0:
pbr = 0;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8:
pbr = 8;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16:
pbr = 16;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32:
pbr = 32;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps64:
pbr = 64;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps128:
pbr = 128;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps256:
pbr = 256;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps512:
pbr = 512;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps1024:
pbr = 1024;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps2048:
pbr = 2048;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps4096:
pbr = 4096;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8192:
pbr = 8192;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16384:
pbr = 16384;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32768:
pbr = 32768;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps65536:
pbr = 65536;
break;
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity:
pbr = INT32_MAX;
break;
default:
pbr = -1;
}
AssertFatal(pbr >= 0, "The proritized bit rate value is not one of the enum values\n");
uint32_t pbr_bytes =
(prioritizedbitrate < NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) ? pbr * 1000 : pbr;
return pbr_bytes;
}
@@ -847,6 +847,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
ul_bwp->bwp_id,
ss,
coreset,
0, // parameter not needed for DCI 0_0
nr_mac->cset0_bwp_size);
// Mark the corresponding RBs as used
@@ -1312,9 +1313,8 @@ static void nr_generate_Msg2(module_id_t module_idP,
pdsch_pdu_rel15->TBSize[0] = TBS;
}
int bw_tbslbrm = get_dlbw_tbslbrm(dl_bwp->initial_BWPSize, ra->CellGroup);
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
bw_tbslbrm,
dl_bwp->bw_tbslbrm,
1);
pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R);
@@ -1374,6 +1374,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
dl_bwp->bwp_id,
ss,
coreset,
0, // parameter not needed for DCI 1_0
nr_mac->cset0_bwp_size);
// DL TX request
@@ -1522,9 +1523,8 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
int x_Overhead = 0;
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling);
int bw_tbslbrm = get_dlbw_tbslbrm(dl_bwp->initial_BWPSize, ra->CellGroup);
pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx,
bw_tbslbrm,
dl_bwp->bw_tbslbrm,
1);
pdsch_pdu_rel15->maintenance_parms_v3.ldpcBaseGraph = get_BG(tb_size<<3,R);
@@ -1597,6 +1597,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac,
dl_bwp->bwp_id,
ss,
coreset,
0, // parameter not needed for DCI 1_0
nr_mac->cset0_bwp_size);
LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
@@ -506,6 +506,7 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
0,
gNB_mac->sched_ctrlCommon->search_space,
gNB_mac->sched_ctrlCommon->coreset,
0, // parameter not needed for DCI 1_0
gNB_mac->cset0_bwp_size);
LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
@@ -1086,10 +1086,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
long maxMIMO_Layers = current_BWP->pdsch_servingcellconfig ? *current_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers : 1;
const int nl_tbslbrm = min(maxMIMO_Layers, 4);
// Maximum number of PRBs across all configured DL BWPs
int scc_bwpsize = current_BWP->initial_BWPSize;
int bw_tbslbrm = get_dlbw_tbslbrm(scc_bwpsize, cg);
pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx,
bw_tbslbrm,
current_BWP->bw_tbslbrm,
nl_tbslbrm);
pdsch_pdu->maintenance_parms_v3.ldpcBaseGraph = get_BG(TBS<<3,R);
@@ -1200,6 +1198,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
bwp_id,
sched_ctrl->search_space,
sched_ctrl->coreset,
UE->pdsch_HARQ_ACK_Codebook,
gNB_mac->cset0_bwp_size);
LOG_D(NR_MAC,
@@ -1138,9 +1138,10 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
long pdsch_HARQ_ACK_Codebook,
uint16_t cset0_bwp_size)
{
NR_CrossCarrierSchedulingConfig_t *crossCarrierSchedulingConfig = NULL; // TODO configure
uint8_t fsize = 0, pos = 0;
uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload;
*dci_pdu = 0;
@@ -1158,16 +1159,49 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
// computing alternative size for padding
dci_pdu_rel15_t temp_pdu;
if(dci_format == NR_DL_DCI_FORMAT_1_0)
alt_size = nr_dci_size(current_DL_BWP, current_UL_BWP, CellGroup, &temp_pdu, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0);
alt_size = nr_dci_size(current_DL_BWP,
current_UL_BWP,
crossCarrierSchedulingConfig,
pdsch_HARQ_ACK_Codebook,
&temp_pdu,
NR_UL_DCI_FORMAT_0_0,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
0);
if(dci_format == NR_UL_DCI_FORMAT_0_0)
alt_size = nr_dci_size(current_DL_BWP, current_UL_BWP, CellGroup, &temp_pdu, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0);
alt_size = nr_dci_size(current_DL_BWP,
current_UL_BWP,
crossCarrierSchedulingConfig,
pdsch_HARQ_ACK_Codebook,
&temp_pdu,
NR_DL_DCI_FORMAT_1_0,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
0);
}
else
N_RB = cset0_bwp_size;
int dci_size = nr_dci_size(current_DL_BWP, current_UL_BWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, coreset, bwp_id, ss->searchSpaceType->present, cset0_bwp_size, alt_size);
int dci_size = nr_dci_size(current_DL_BWP,
current_UL_BWP,
crossCarrierSchedulingConfig,
pdsch_HARQ_ACK_Codebook,
dci_pdu_rel15,
dci_format,
rnti_type,
coreset,
bwp_id,
ss->searchSpaceType->present,
cset0_bwp_size,
alt_size);
pdcch_dci_pdu->PayloadSizeBits = dci_size;
AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported");
if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1)
@@ -2024,14 +2058,13 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
int target_ss;
if (CellGroup && CellGroup->physicalCellGroupConfig)
DL_BWP->pdsch_HARQ_ACK_Codebook = &CellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook;
NR_ServingCellConfig_t *servingCellConfig = NULL;
if (CellGroup &&
CellGroup->spCellConfig &&
CellGroup->spCellConfig->spCellConfigDedicated) {
const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
UL_BWP->supplementaryUplink = servingCellConfig->supplementaryUplink;
DL_BWP->pdsch_servingcellconfig = servingCellConfig->pdsch_ServingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
UL_BWP->pusch_servingcellconfig = servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->pusch_ServingCellConfig ?
servingCellConfig->uplinkConfig->pusch_ServingCellConfig->choice.setup : NULL;
@@ -2144,6 +2177,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
UL_BWP->initial_BWPSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
UL_BWP->initial_BWPStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
DL_BWP->bw_tbslbrm = get_dlbw_tbslbrm(DL_BWP->initial_BWPSize, servingCellConfig);
UL_BWP->bw_tbslbrm = get_ulbw_tbslbrm(UL_BWP->initial_BWPSize, servingCellConfig);
if (UL_BWP->bwp_id > 0) {
UL_BWP->pucch_ConfigCommon = ul_bwp->bwp_Common->pucch_ConfigCommon ? ul_bwp->bwp_Common->pucch_ConfigCommon->choice.setup : NULL;
UL_BWP->rach_ConfigCommon = ul_bwp->bwp_Common->rach_ConfigCommon ? ul_bwp->bwp_Common->rach_ConfigCommon->choice.setup : NULL;
@@ -2154,6 +2190,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
if(UE) {
if (CellGroup && CellGroup->physicalCellGroupConfig)
UE->pdsch_HARQ_ACK_Codebook = CellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook;
// Reset required fields in sched_ctrl (e.g. ul_ri and tpmi)
reset_sched_ctrl(sched_ctrl);
@@ -2288,10 +2288,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
if (!maxMIMO_Layers)
maxMIMO_Layers = current_BWP->pusch_Config->maxRank;
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n");
const int scc_bwpsize = current_BWP->initial_BWPSize;
int bw_tbslbrm = get_ulbw_tbslbrm(scc_bwpsize, cg);
pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcs_table,
bw_tbslbrm,
current_BWP->bw_tbslbrm,
*maxMIMO_Layers);
}
else
@@ -2396,6 +2394,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
current_BWP->bwp_id,
ss,
coreset,
UE->pdsch_HARQ_ACK_Codebook,
nr_mac->cset0_bwp_size);
memset(sched_pusch, 0, sizeof(*sched_pusch));
+1
View File
@@ -236,6 +236,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
int bwp_id,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
long pdsch_HARQ_ACK_Codebook,
uint16_t cset0_bwp_size);
void prepare_dci(const NR_CellGroupConfig_t *CellGroup, const NR_UE_DL_BWP_t *current_BWP, const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format);
+1
View File
@@ -705,6 +705,7 @@ typedef struct {
uint32_t ra_timer;
float ul_thr_ue;
float dl_thr_ue;
long pdsch_HARQ_ACK_Codebook;
} NR_UE_info_t;
typedef struct {
+82 -18
View File
@@ -88,7 +88,6 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size;
return;
}
@@ -120,7 +119,7 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size;
return;
}
}
@@ -130,7 +129,6 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += size;
return;
}
@@ -158,7 +156,6 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
entity->stats.txsdu_pkts++;
entity->stats.txsdu_bytes += cur->size;
nr_pdcp_free_sdu(cur);
count++;
}
@@ -224,7 +221,7 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
memcpy(buf + header_size, buffer, size);
if (entity->has_integrity){
if (entity->has_integrity) {
uint8_t integrity[4] = {0};
entity->integrity(entity->integrity_context,
integrity,
@@ -232,13 +229,12 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
entity->rb_id, count, entity->is_gnb ? 1 : 0);
memcpy((unsigned char *)buf + header_size + size, integrity, 4);
} else if (integrity_size == 4) {
// set MAC-I to 0 for SRBs with integrity not active
memset(buf + header_size + size, 0, 4);
}
// set MAC-I to 0 for SRBs with integrity not active
else if (integrity_size == 4)
memset(buf + header_size + size, 0, 4);
if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)){
if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)) {
entity->cipher(entity->security_context,
(unsigned char *)buf + header_size, size + integrity_size,
entity->rb_id, count, entity->is_gnb ? 1 : 0);
@@ -339,6 +335,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
cur->buffer, cur->size);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++;
entity->stats.txsdu_bytes += cur->size;
nr_pdcp_free_sdu(cur);
}
@@ -350,6 +348,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
cur->buffer, cur->size);
entity->rx_list = cur->next;
entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++;
entity->stats.txsdu_bytes += cur->size;
nr_pdcp_free_sdu(cur);
count++;
}
@@ -362,7 +362,7 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
}
}
void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
static void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
{
entity->t_current = now;
@@ -384,7 +384,7 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity)
}
}
void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
{
entity->tx_next = 0;
if (entity->t_reordering_start != 0) {
@@ -395,19 +395,71 @@ void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
entity->rx_deliv = 0;
}
void nr_pdcp_entity_release(nr_pdcp_entity_t *entity)
{
deliver_all_sdus(entity);
}
void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
static void free_rx_list(nr_pdcp_entity_t *entity)
{
nr_pdcp_sdu_t *cur = entity->rx_list;
while (cur != NULL) {
nr_pdcp_sdu_t *next = cur->next;
entity->stats.rxpdu_dd_pkts++;
entity->stats.rxpdu_dd_bytes += cur->size;
nr_pdcp_free_sdu(cur);
cur = next;
}
entity->rx_list = NULL;
entity->rx_size = 0;
}
static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity)
{
/* transmitting entity procedures */
/* todo: deal with ciphering/integrity algos and keys */
/* receiving entity procedures */
/* todo: deal with ciphering/integrity algos and keys */
}
static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity)
{
/* transmitting entity procedures */
entity->tx_next = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* receiving entity procedures */
/* deliver all SDUs if t_reordering is running */
if (entity->t_reordering_start != 0)
deliver_all_sdus(entity);
/* stop t_reordering */
entity->t_reordering_start = 0;
/* set rx_next and rx_deliv to the initial value */
entity->rx_next = 0;
entity->rx_deliv = 0;
/* todo: deal with ciphering/integrity algos and keys */
}
static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity)
{
/* transmitting entity procedures */
entity->tx_next = 0;
/* todo: deal with ciphering/integrity algos and keys */
/* receiving entity procedures */
free_rx_list(entity);
/* stop t_reordering */
entity->t_reordering_start = 0;
/* set rx_next and rx_deliv to the initial value */
entity->rx_next = 0;
entity->rx_deliv = 0;
/* todo: deal with ciphering/integrity algos and keys */
}
static void nr_pdcp_entity_release(nr_pdcp_entity_t *entity)
{
deliver_all_sdus(entity);
}
static void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
{
free_rx_list(entity);
if (entity->free_security != NULL)
entity->free_security(entity->security_context);
if (entity->free_integrity != NULL)
@@ -461,6 +513,18 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
ret->delete_entity = nr_pdcp_entity_delete;
ret->release_entity = nr_pdcp_entity_release;
ret->suspend_entity = nr_pdcp_entity_suspend;
switch (type) {
case NR_PDCP_DRB_AM:
ret->reestablish_entity = nr_pdcp_entity_reestablish_drb_am;
break;
case NR_PDCP_DRB_UM:
ret->reestablish_entity = nr_pdcp_entity_reestablish_drb_um;
break;
case NR_PDCP_SRB:
ret->reestablish_entity = nr_pdcp_entity_reestablish_srb;
break;
}
ret->get_stats = nr_pdcp_entity_get_stats;
ret->deliver_sdu = deliver_sdu;
+2 -1
View File
@@ -78,6 +78,7 @@ typedef struct nr_pdcp_entity_t {
void (*delete_entity)(struct nr_pdcp_entity_t *entity);
void (*release_entity)(struct nr_pdcp_entity_t *entity);
void (*suspend_entity)(struct nr_pdcp_entity_t *entity);
void (*reestablish_entity)(struct nr_pdcp_entity_t *entity);
void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out);
/* set_security: pass -1 to integrity_algorithm / ciphering_algorithm
@@ -123,7 +124,7 @@ typedef struct nr_pdcp_entity_t {
uint64_t t_current;
/* timers (stores the ms of activation, 0 means not active) */
int t_reordering_start;
uint64_t t_reordering_start;
/* security */
int has_ciphering;
+70 -96
View File
@@ -64,6 +64,25 @@ uint8_t proto_agent_flag = 0;
static ngran_node_t node_type;
nr_pdcp_entity_t *nr_pdcp_get_rb(nr_pdcp_ue_t *ue, int rb_id, bool srb_flag)
{
nr_pdcp_entity_t *rb;
if (srb_flag) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > MAX_DRBS_PER_UE)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
return rb;
}
/****************************************************************************/
/* rlc_data_req queue - begin */
/****************************************************************************/
@@ -263,24 +282,12 @@ static void do_pdcp_data_ind(
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid);
if (srb_flagP == 1) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > MAX_DRBS_PER_UE)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
rb = nr_pdcp_get_rb(ue, rb_id, srb_flagP);
if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
} else {
LOG_E(PDCP, "%s:%d:%s: no RB found (rb_id %ld, srb_flag %d)\n",
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
LOG_E(PDCP, "pdcp_data_ind: no RB found (rb_id %ld, srb_flag %d)\n", rb_id, srb_flagP);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
@@ -776,14 +783,8 @@ void add_srb(int is_gnb,
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid);
if (ue->srb[srb_id-1] != NULL) {
LOG_E(PDCP,
"%s:%d:%s: warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n",
__FILE__,
__LINE__,
__FUNCTION__,
srb_id,
rntiMaybeUEid);
if (nr_pdcp_get_rb(ue, srb_id, true) != NULL) {
LOG_E(PDCP, "warning SRB %d already exist for UE ID/RNTI %ld, do nothing\n", srb_id, rntiMaybeUEid);
} else {
pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id,
0, false, false, // sdap parameters
@@ -878,8 +879,8 @@ void add_drb(int is_gnb,
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rntiMaybeUEid);
if (ue->drb[drb_id-1] != NULL) {
LOG_W(PDCP, "%s:%d:%s: warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid);
if (nr_pdcp_get_rb(ue, drb_id, false) != NULL) {
LOG_W(PDCP, "warning DRB %d already exist for UE ID/RNTI %ld, do nothing\n", drb_id, rntiMaybeUEid);
} else {
pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id,
has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue,
@@ -997,25 +998,20 @@ void nr_pdcp_config_set_security(ue_id_t ue_id,
/* TODO: proper handling of DRBs, for the moment only SRBs are handled */
if (rb_id >= 1 && rb_id <= 2) {
rb = ue->srb[rb_id - 1];
rb = nr_pdcp_get_rb(ue, rb_id, true);
if (rb == NULL) {
LOG_E(PDCP, "%s:%d:%s: no SRB found (ue_id %ld, rb_id %ld)\n", __FILE__, __LINE__, __FUNCTION__, ue_id, rb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
integrity_algorithm = (security_modeP>>4) & 0xf;
ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP);
rb->security_mode_completed = false;
} else {
LOG_E(PDCP, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
if (rb == NULL) {
LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %ld)\n", ue_id, rb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
integrity_algorithm = (security_modeP>>4) & 0xf;
ciphering_algorithm = security_modeP & 0x0f;
rb->set_security(rb, integrity_algorithm, (char *)kRRCint_pP,
ciphering_algorithm, (char *)kRRCenc_pP);
rb->security_mode_completed = false;
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
@@ -1034,14 +1030,10 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id,
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
rb = nr_pdcp_get_rb(ue, rb_id, true);
if (rb == NULL) {
LOG_E(PDCP, "%s:%d:%s: no SRB found (ue_id %ld, rb_id %ld)\n", __FILE__, __LINE__, __FUNCTION__, ue_id, rb_id);
LOG_E(PDCP, "no SRB found (ue_id %ld, rb_id %ld)\n", ue_id, rb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return 0;
}
@@ -1062,9 +1054,10 @@ void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *srb = ue->srb[srb_id - 1];
nr_pdcp_entity_t *srb = nr_pdcp_get_rb(ue, srb_id, true);
if (srb == NULL) {
LOG_E(PDCP, "Trying to susbend SRB with ID %d but it is not established\n", srb_id);
LOG_E(PDCP, "Trying to suspend SRB with ID %d but it is not established\n", srb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
srb->suspend_entity(srb);
@@ -1075,9 +1068,10 @@ void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *drb = ue->drb[drb_id - 1];
nr_pdcp_entity_t *drb = nr_pdcp_get_rb(ue, drb_id, false);
if (drb == NULL) {
LOG_E(PDCP, "Trying to susbend DRB with ID %d but it is not established\n", drb_id);
LOG_E(PDCP, "Trying to suspend DRB with ID %d but it is not established\n", drb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
drb->suspend_entity(drb);
@@ -1088,7 +1082,12 @@ void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering)
{
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *srb = ue->srb[srb_id - 1];
nr_pdcp_entity_t *srb = nr_pdcp_get_rb(ue, srb_id, true);
if (srb == NULL) {
LOG_E(PDCP, "Trying to reconfigure SRB with ID %d but it is not established\n", srb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
int decoded_t_reordering = decode_t_reordering(t_Reordering);
srb->t_reordering = decoded_t_reordering;
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
@@ -1102,7 +1101,12 @@ void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering)
*/
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
nr_pdcp_entity_t *drb = ue->drb[drb_id - 1];
nr_pdcp_entity_t *drb = nr_pdcp_get_rb(ue, drb_id, false);
if (drb == NULL) {
LOG_E(PDCP, "Trying to reconfigure DRB with ID %d but it is not established\n", drb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
}
int decoded_t_reordering = decode_t_reordering(t_Reordering);
drb->t_reordering = decoded_t_reordering;
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
@@ -1136,36 +1140,21 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
void nr_pdcp_reestablishment(ue_id_t ue_id)
void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag)
{
// TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2
nr_pdcp_ue_t *ue;
nr_pdcp_entity_t *rb;
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
if (ue == NULL) {
LOG_E(PDCP, "Cannot find PDCP entity for UE %lx\n", ue_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return;
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
rb = nr_pdcp_get_rb(ue, rb_id, srb_flag);
if (rb != NULL) {
rb->reestablish_entity(rb);
} else {
LOG_W(PDCP, "UE %4.4lx cannot re-establish RB %d (is_srb %d), RB not found\n", ue_id, rb_id, srb_flag);
}
for (int i = 0; i < 3; i++) {
nr_pdcp_entity_t *srb = ue->srb[i];
if (srb != NULL) {
srb->tx_next = 0;
srb->rx_next = 0;
srb->rx_deliv = 0;
srb->rx_reord = 0;
}
}
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
nr_pdcp_entity_t *drb = ue->drb[i];
if (drb != NULL) {
// drb->tx_next = 0; // Should continue from the previous value
drb->rx_next = 0;
//drb->rx_deliv = 0; // should continue from the previous value
drb->rx_reord = 0;
}
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
@@ -1200,14 +1189,10 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
if (rb_id < 1 || rb_id > MAX_DRBS_PER_UE)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
rb = nr_pdcp_get_rb(ue, rb_id, false);
if (rb == NULL) {
LOG_E(PDCP, "%s:%d:%s: no DRB found (ue_id %ld, rb_id %ld)\n", __FILE__, __LINE__, __FUNCTION__, ue_id, rb_id);
LOG_E(PDCP, "no DRB found (ue_id %lx, rb_id %ld)\n", ue_id, rb_id);
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
return 0;
}
@@ -1309,18 +1294,7 @@ bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_stat
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id);
if (srb_flag == 1) {
if (rb_id < 1 || rb_id > 2)
rb = NULL;
else
rb = ue->srb[rb_id - 1];
} else {
if (rb_id < 1 || rb_id > 5)
rb = NULL;
else
rb = ue->drb[rb_id - 1];
}
rb = nr_pdcp_get_rb(ue, rb_id, srb_flag);
if (rb != NULL) {
rb->get_stats(rb, out);
+1 -1
View File
@@ -64,7 +64,7 @@ void add_drb(int is_gnb,
void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid);
bool nr_pdcp_remove_UE(ue_id_t ue_id);
void nr_pdcp_reestablishment(ue_id_t ue_id);
void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag);
void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id);
void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id);
+10 -5
View File
@@ -1103,15 +1103,20 @@ int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot,
return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements);
}
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) {
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid];
if (current_harq->active) {
current_harq->ack = ack_nack;
current_harq->ack_received = true;
LOG_T(PHY,"Updating harq_status for harq_id %d,ack/nak %d\n",harq_pid,current_harq->ack);
LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack);
// we can prepare feedback for MSG4 in advance
if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION)
prepare_msg4_feedback(mac, harq_pid, ack_nack);
else {
current_harq->ack = ack_nack;
current_harq->ack_received = true;
}
}
else {
//shouldn't get here
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -1,8 +1,10 @@
set(LTE_RRC_VERSION 15 6 0)
set(LTE_RRC_VERSION 16 13 0)
make_version(LTE_RRC_cc ${LTE_RRC_VERSION})
string(REPLACE ";" "." LTE_RRC_RELEASE "${LTE_RRC_VERSION}")
if(LTE_RRC_RELEASE VERSION_EQUAL "15.6.0")
if(LTE_RRC_RELEASE VERSION_EQUAL "16.13.0")
include(ASN.1/lte-rrc-16.13.0.cmake)
elseif(LTE_RRC_RELEASE VERSION_EQUAL "15.6.0")
include(ASN.1/lte-rrc-15.6.0.cmake)
else()
message(FATAL_ERROR "unknown LTE_RRC_RELEASE ${LTE_RRC_RELEASE}")
+4 -4
View File
@@ -511,7 +511,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
(*sib1_MBMS)->cellAccessRelatedInfo_r14.cellIdentity_r14.bits_unused=4;
(*sib1_MBMS)->freqBandIndicator_r14 = configuration->eutra_band[CC_id];
schedulingInfo->si_Periodicity_r14=LTE_SchedulingInfo__si_Periodicity_rf16;
schedulingInfo->si_Periodicity_r14=LTE_SI_Periodicity_r12_rf16;
*sib_type = LTE_SIB_Type_MBMS_r14_sibType13_v920;
asn1cSeqAdd(&schedulingInfo->sib_MappingInfo_r14.list, sib_type);
asn1cSeqAdd(&(*sib1_MBMS)->schedulingInfoList_MBMS_r14.list, schedulingInfo);
@@ -549,7 +549,7 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier,
memset((MBSFN_Area1)->ext1,0,sizeof(*(MBSFN_Area1)->ext1));
MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14 = CALLOC(1,sizeof(*( MBSFN_Area1->ext1)->subcarrierSpacingMBMS_r14));
memset(MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14,0,sizeof(*((MBSFN_Area1)->ext1)->subcarrierSpacingMBMS_r14));
*(MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14) = LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_khz_1dot25;
*(MBSFN_Area1->ext1->subcarrierSpacingMBMS_r14) = LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_kHz1dot25;
asn1cSeqAdd(&MBSFNArea_list->list,MBSFN_Area1);
}
@@ -938,9 +938,9 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
//(*sib1)->p_Max = CALLOC(1, sizeof(P_Max_t));
// *((*sib1)->p_Max) = 23;
schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8;
schedulingInfo.si_Periodicity=LTE_SI_Periodicity_r12_rf8;
if(configuration->eMBMS_M2_configured){
schedulingInfo2.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8;
schedulingInfo2.si_Periodicity=LTE_SI_Periodicity_r12_rf8;
}
// This is for SIB2/3
sib_type=LTE_SIB_Type_sibType3;
+6 -1
View File
@@ -2538,9 +2538,14 @@ rrc_ue_decode_dcch(
case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10:
break;
case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionResume_r13:
break;
case LTE_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
break;
case LTE_DL_DCCH_MessageType__c1_PR_spare1:
case LTE_DL_DCCH_MessageType__c1_PR_spare2:
case LTE_DL_DCCH_MessageType__c1_PR_spare3:
break;
default:
+1 -1
View File
@@ -212,7 +212,7 @@ init_SI(
LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB1-MBMS Subcarrier Spacing MBMS: %s\n",
PROTOCOL_RRC_CTXT_ARGS(ctxt_pP),
(*RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9.list.array[i]->ext1->subcarrierSpacingMBMS_r14 ==
LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_khz_1dot25 ? "khz_1dot25": "khz_7dot5"));
LTE_MBSFN_AreaInfo_r9__ext1__subcarrierSpacingMBMS_r14_kHz1dot25 ? "khz_1dot25": "khz_7dot5"));
}
}
+24
View File
@@ -481,6 +481,14 @@ static uint8_t rrc_M2AP_do_SIB1_MBMS_SIB13(
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26a_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib27_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib28_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib29_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
LOG_I(RRC, "Adding MBSFN subframe Configuration 1 to SIB2\n");
@@ -784,6 +792,14 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2(
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26a_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib27_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib28_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib29_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2);
@@ -1140,6 +1156,14 @@ static uint8_t rrc_M2AP_do_SIB23_SIB2_SIB13(
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26_v1530:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib26a_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib27_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib28_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib29_v1610:
break;
case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2:
LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2, %p %p\n",&typeandinfo->choice.sib2,*sib2);
+4 -2
View File
@@ -460,8 +460,10 @@ void free_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
{
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, *rbconfig);
*rbconfig = NULL;
ASN_STRUCT_FREE(asn_DEF_NR_RLC_BearerConfig, *rlc_rbconfig);
*rlc_rbconfig = NULL;
if (rlc_rbconfig != NULL) {
ASN_STRUCT_FREE(asn_DEF_NR_RLC_BearerConfig, *rlc_rbconfig);
*rlc_rbconfig = NULL;
}
}
//------------------------------------------------------------------------------
+6 -1
View File
@@ -1046,11 +1046,16 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
for (int srb_id = 1; srb_id < maxSRBs; srb_id++) {
if (ue_p->Srb[srb_id].Active) {
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
// TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
}
// TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag
nr_pdcp_reestablishment(ue_p->rrc_ue_id);
for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) {
if (ue_p->established_drbs[drb_id - 1].status != DRB_INACTIVE)
nr_pdcp_reestablishment(ue_p->rrc_ue_id, drb_id, false);
}
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
+1 -1
View File
@@ -807,7 +807,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
drb->discardTimer = E1AP_DiscardTimer_infinity;
drb->reorderingTimer = E1AP_T_Reordering_ms0;
drb->reorderingTimer = E1AP_T_Reordering_ms100;
drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
+34 -3
View File
@@ -33,10 +33,41 @@
#include "defs.h"
#include "rrc_proto.h"
#include "common/utils/LOG/log.h"
#include "executables/softmodem-common.h"
NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* reconfig_file, char* rbconfig_file)
NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap)
{
// LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n");
return openair_rrc_top_init_ue_nr(uecap);
}
return openair_rrc_top_init_ue_nr(uecap, reconfig_file, rbconfig_file);
void init_nsa_message(NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file)
{
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
// read in files for RRCReconfiguration and RBconfig
LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
FILE *fd = fopen(reconfig_file, "r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
reconfig_file,
errno,
strerror(errno));
char buffer[1024];
int msg_len = fread(buffer, 1, 1024, fd);
fclose(fd);
process_nsa_message(rrc, nr_SecondaryCellGroupConfig_r15, buffer, msg_len);
LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", rbconfig_file);
fd = fopen(rbconfig_file, "r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
rbconfig_file,
errno,
strerror(errno));
msg_len = fread(buffer, 1, 1024, fd);
fclose(fd);
process_nsa_message(rrc, nr_RadioBearerConfigX_r15, buffer,msg_len);
}
else
LOG_D(NR_RRC, "In NSA mode \n");
}
+97 -201
View File
@@ -147,7 +147,6 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
static void nr_rrc_ue_generate_RRCSetupRequest(rnti_t rnti);
static void nr_rrc_ue_generate_rrcReestablishmentComplete(NR_RRCReestablishment_t *rrcReestablishment);
static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_len);
static void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config);
static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
int gNB_index,
rnti_t rnti,
@@ -162,20 +161,6 @@ static void nr_rrc_ue_process_masterCellGroup(instance_t instance,
void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig);
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
static int8_t nr_rrc_ue_decode_secondary_cellgroup_config(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cell_group_config)
{
if (rrc->scell_group_config == NULL)
rrc->scell_group_config = cell_group_config;
else
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0);
if(cell_group_config->spCellConfig != NULL)
configure_spcell(rrc, cell_group_config->spCellConfig);
return 0;
}
static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
int gNB_index,
rnti_t rnti,
@@ -189,8 +174,6 @@ static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
NR_RRCReconfiguration_IEs_t *ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
if (ie->radioBearerConfig != NULL) {
if (rrc->radio_bearer_config == NULL)
rrc->radio_bearer_config = ie->radioBearerConfig;
LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
nr_rrc_ue_process_RadioBearerConfig(rrc, rnti, rrcNB, ie->radioBearerConfig);
if (LOG_DEBUGFLAG(DEBUG_ASN1))
@@ -217,10 +200,10 @@ static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
}
if (ie->secondaryCellGroup != NULL) {
NR_CellGroupConfig_t *secondCellGroupConfig = NULL;
NR_CellGroupConfig_t *cellGroupConfig = NULL;
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_CellGroupConfig, // might be added prefix later
(void **)&secondCellGroupConfig,
(void **)&cellGroupConfig,
(uint8_t *)ie->secondaryCellGroup->buf,
ie->secondaryCellGroup->size,
0,
@@ -232,33 +215,18 @@ static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
LOG_E(NR_RRC, "%02x ", buffer[i]);
LOG_E(NR_RRC, "\n");
// free the memory
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)secondCellGroupConfig, 1);
return;
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1);
}
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)secondCellGroupConfig);
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
if (get_softmodem_params()->sa || get_softmodem_params()->nsa) {
// remote NB index lost ????
nr_rrc_manage_rlc_bearers(instance, secondCellGroupConfig, rrc->perNB + 0, rrc->rnti);
if (rrc->cell_group_config == NULL) {
// first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good
// implementation, need to maintain RRC_INST own structure every time.
rrc->cell_group_config = secondCellGroupConfig;
} else {
// after first time, update it and free the memory after.
SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)rrc->cell_group_config, 0);
rrc->cell_group_config = secondCellGroupConfig;
}
nr_rrc_cellgroup_configuration(rrcNB,
instance,
cellGroupConfig);
if (secondCellGroupConfig->spCellConfig != NULL)
configure_spcell(rrc, secondCellGroupConfig->spCellConfig);
if (get_softmodem_params()->nsa) {
nr_rrc_mac_config_req_scg(0, 0, secondCellGroupConfig);
}
} else
nr_rrc_ue_decode_secondary_cellgroup_config(rrc, secondCellGroupConfig);
if (!get_softmodem_params()->sa)
nr_rrc_mac_config_req_cg(0, 0, cellGroupConfig);
}
if (ie->measConfig != NULL) {
LOG_I(NR_RRC, "Measurement Configuration is present\n");
@@ -279,11 +247,10 @@ static void nr_rrc_ue_process_rrcReconfiguration(const instance_t instance,
default:
break;
}
return;
}
static void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
{
switch (nsa_message_type) {
case nr_SecondaryCellGroupConfig_r15:
@@ -341,7 +308,7 @@ static void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message
}
}
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file)
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file)
{
if(NB_NR_UE_INST > 0) {
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
@@ -350,53 +317,24 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_fi
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
rrc->selected_plmn_identity = 1;
rrc->bwpd = NULL;
rrc->ubwpd = NULL;
rrc->dl_bwp_id = 0;
rrc->ul_bwp_id = 0;
rrc->as_security_activated = false;
for (int i = 0; i < NB_CNX_UE; i++) {
rrcPerNB_t *ptr = &rrc->perNB[i];
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
for (int j = 0; j < NR_NUM_SRB; j++)
ptr->Srb[j] = (NR_UE_RRC_SRB_INFO_t){0};
ptr->Srb[j] = RB_NOT_PRESENT;
for (int j = 0; j < MAX_DRBS_PER_UE; j++)
ptr->active_DRBs[j] = false;
ptr->status_DRBs[j] = RB_NOT_PRESENT;
// SRB0 activated by default
ptr->Srb[0].status = RB_ESTABLISHED;
ptr->Srb[0] = RB_ESTABLISHED;
}
}
NR_UE_rrc_inst->uecap_file = uecap_file;
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
// read in files for RRCReconfiguration and RBconfig
LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
FILE *fd = fopen(reconfig_file,"r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
reconfig_file,
errno,
strerror(errno));
char buffer[1024];
int msg_len=fread(buffer,1,1024,fd);
fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", rbconfig_file);
fd = fopen(rbconfig_file,"r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
rbconfig_file,
errno,
strerror(errno));
msg_len=fread(buffer,1,1024,fd);
fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len);
} else if (get_softmodem_params()->nsa) {
LOG_D(NR_RRC, "In NSA mode \n");
}
if (get_softmodem_params()->sl_mode) {
configure_NR_SL_Preconfig(get_softmodem_params()->sync_ref);
}
@@ -754,7 +692,9 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(instance_t instance,
if(SI_info->sib1)
ASN_STRUCT_FREE(asn_DEF_NR_SIB1, SI_info->sib1);
NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
SI_info->sib1 = sib1;
if(!SI_info->sib1)
SI_info->sib1 = calloc(1, sizeof(*SI_info->sib1));
memcpy(SI_info->sib1, sib1, sizeof(NR_SIB1_t));
if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1);
LOG_A(NR_RRC, "SIB1 decoded\n");
@@ -768,7 +708,6 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(instance_t instance,
// configure timers and constant
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
// take ServingCellConfigCommon and configure L1/L2
rrc->servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
nr_rrc_mac_config_req_sib1(instance, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon);
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
@@ -827,13 +766,75 @@ static void nr_rrc_manage_rlc_bearers(const instance_t instance,
cellGroupConfig->rlc_BearerToReleaseList);
}
void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB,
instance_t instance,
NR_CellGroupConfig_t *cellGroupConfig)
{
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
if(spCellConfig != NULL) {
if (spCellConfig->reconfigurationWithSync != NULL) {
NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync;
// perform Reconfiguration with sync according to 5.3.5.5.2
if (!rrc->as_security_activated && rrc->nrRrcState != RRC_STATE_IDLE_NR) {
// perform the actions upon going to RRC_IDLE as specified in 5.3.11
// with the release cause 'other' upon which the procedure ends
// TODO
}
if (tac->T310_active) {
tac->T310_active = false;
tac->T310_cnt = 0;
}
nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync);
tac->T304_active = true;
tac->T304_cnt = 0;
rrc->rnti = reconfigurationWithSync->newUE_Identity;
// resume suspended radio bearers
for (int i = 0; i < NR_NUM_SRB; i++) {
if (rrcNB->Srb[i] == RB_SUSPENDED)
rrcNB->Srb[i] = RB_ESTABLISHED;
}
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (rrcNB->status_DRBs[i] == RB_SUSPENDED)
rrcNB->status_DRBs[i] = RB_ESTABLISHED;
}
// TODO reset MAC
}
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants);
if (spCellConfig->spCellConfigDedicated) {
if (spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id)
rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id;
if (spCellConfig->spCellConfigDedicated->uplinkConfig &&
spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)
rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id;
}
}
if(cellGroupConfig->mac_CellGroupConfig != NULL) {
// TODO handle MAC CellGroupConfig
}
// TODO verify why we need this limitation
if (get_softmodem_params()->sa || get_softmodem_params()->nsa)
nr_rrc_manage_rlc_bearers(instance, cellGroupConfig, rrcNB, rrc->rnti);
AssertFatal(cellGroupConfig->sCellToReleaseList == NULL,
"Secondary serving cell release not implemented\n");
AssertFatal(cellGroupConfig->sCellToAddModList == NULL,
"Secondary serving cell addition not implemented\n");
}
static void nr_rrc_ue_process_masterCellGroup(instance_t instance,
rnti_t rnti,
rrcPerNB_t *rrcNB,
OCTET_STRING_t *masterCellGroup,
long *fullConfig)
{
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
AssertFatal(!fullConfig, "fullConfig not supported yet\n");
NR_CellGroupConfig_t *cellGroupConfig = NULL;
uper_decode(NULL,
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
@@ -845,116 +846,12 @@ static void nr_rrc_ue_process_masterCellGroup(instance_t instance,
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
}
if(rrc->cell_group_config == NULL){
rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
}
nr_rrc_manage_rlc_bearers(instance, cellGroupConfig, rrcNB, rnti);
nr_rrc_cellgroup_configuration(rrcNB,
instance,
cellGroupConfig);
if(cellGroupConfig->mac_CellGroupConfig != NULL){
//TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
if(rrc->cell_group_config->mac_CellGroupConfig != NULL){
LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
// Laurent: there are cases where the not NULL value is also not coming from a previous malloc
// so it is better to let the potential memory leak than corrupting the heap
//free(rrc->cell_group_config->mac_CellGroupConfig);
}
rrc->cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
memcpy(rrc->cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
sizeof(struct NR_MAC_CellGroupConfig));
}
if(cellGroupConfig->sCellToReleaseList != NULL) {
//TODO (perform SCell release as specified in 5.3.5.5.8)
}
if(cellGroupConfig->spCellConfig != NULL) {
configure_spcell(rrc, cellGroupConfig->spCellConfig);
// TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync
if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
if(fullConfig)
set_default_timers_and_constants(&rrc->timers_and_constants);
LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync;
rrc->timers_and_constants.T304_active = true;
nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync);
// TODO: Implementation of the remaining procedures regarding the reception of the reconfigurationWithSync, TS 38.331 - Section 5.3.5.5.2
}
if (rrc->cell_group_config &&
rrc->cell_group_config->spCellConfig) {
memcpy(rrc->cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
sizeof(struct NR_SpCellConfig));
} else {
if (rrc->cell_group_config)
rrc->cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
else
rrc->cell_group_config = cellGroupConfig;
}
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
nr_rrc_mac_config_req_mcg(instance, 0, cellGroupConfig);
}
if(fullConfig)
// full configuration after re-establishment or during RRC resume
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, rrcNB->SInfo.sib1);
if( cellGroupConfig->sCellToAddModList != NULL){
//TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
}
if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){
//TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
}
if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){
//TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
}
}
static void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config)
{
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spcell_config->rlf_TimersAndConstants);
if(spcell_config->spCellConfigDedicated) {
NR_ServingCellConfig_t *scd = spcell_config->spCellConfigDedicated;
if(scd->firstActiveDownlinkBWP_Id) {
if(*scd->firstActiveDownlinkBWP_Id == 0)
rrc->bwpd = scd->initialDownlinkBWP;
else {
AssertFatal(scd->downlinkBWP_ToAddModList, "No DL BWP list configured\n");
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = scd->downlinkBWP_ToAddModList;
NR_BWP_Downlink_t *dl_bwp = NULL;
for (int i = 0; i < bwpList->list.count; i++) {
dl_bwp = bwpList->list.array[i];
if(dl_bwp->bwp_Id == *scd->firstActiveDownlinkBWP_Id)
break;
}
AssertFatal(dl_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->firstActiveDownlinkBWP_Id);
rrc->bwpd = dl_bwp->bwp_Dedicated;
}
// if any of the reference signal(s) that are used for radio link monitoring are reconfigured by the received spCellConfigDedicated
// reset RLF timers and constants
if (rrc->bwpd->radioLinkMonitoringConfig)
reset_rlf_timers_and_constants(&rrc->timers_and_constants);
}
if(scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id) {
if(*scd->uplinkConfig->firstActiveUplinkBWP_Id == 0)
rrc->ubwpd = scd->uplinkConfig->initialUplinkBWP;
else {
AssertFatal(scd->uplinkConfig->uplinkBWP_ToAddModList, "No UL BWP list configured\n");
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = scd->uplinkConfig->uplinkBWP_ToAddModList;
NR_BWP_Uplink_t *ul_bwp = NULL;
for (int i = 0; i < ubwpList->list.count; i++) {
ul_bwp = ubwpList->list.array[i];
if(ul_bwp->bwp_Id == *scd->uplinkConfig->firstActiveUplinkBWP_Id)
break;
}
AssertFatal(ul_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id);
rrc->ubwpd = ul_bwp->bwp_Dedicated;
}
}
}
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
nr_rrc_mac_config_req_cg(instance, 0, cellGroupConfig);
}
static void rrc_ue_generate_RRCSetupComplete(instance_t instance, rnti_t rnti, const uint8_t Transaction_id, uint8_t sel_plmn_id)
@@ -1025,7 +922,7 @@ static int8_t nr_rrc_ue_decode_ccch(const instance_t instance,
// Get configuration
// Release T300 timer
rrc->timers_and_constants.T300_active = 0;
rrc->rnti = rnti;
nr_rrc_ue_process_masterCellGroup(
instance,
rnti,
@@ -1038,7 +935,7 @@ static int8_t nr_rrc_ue_decode_ccch(const instance_t instance,
rrc->perNB + gNB_index,
&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
rrc->nrRrcState = RRC_STATE_CONNECTED_NR;
rrc->rnti = rnti;
rrc_ue_generate_RRCSetupComplete(instance,
rnti,
dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
@@ -1132,7 +1029,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
// configure lower layers to apply SRB integrity protection and ciphering
for (int i = 1; i < NR_NUM_SRB; i++) {
if (ue_rrc->perNB[gNB_index].Srb[i].status == RB_ESTABLISHED)
if (ue_rrc->perNB[gNB_index].Srb[i] == RB_ESTABLISHED)
nr_pdcp_config_set_security(rnti, i, security_mode, kRRCenc, kRRCint, kUPenc);
}
} else {
@@ -1325,8 +1222,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (radioBearerConfig->srb_ToAddModList != NULL) {
for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt];
NR_UE_RRC_SRB_INFO_t *Srb_info = &rrcNB->Srb[srb->srb_Identity];
if (Srb_info->status == RB_NOT_PRESENT)
if (rrcNB->Srb[srb->srb_Identity] == RB_NOT_PRESENT)
add_srb(false,
rnti,
radioBearerConfig->srb_ToAddModList->list.array[cnt],
@@ -1340,7 +1236,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
nr_pdcp_reconfigure_srb(rnti, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
}
Srb_info->status = RB_ESTABLISHED;
rrcNB->Srb[srb->srb_Identity] = RB_ESTABLISHED;
}
}
@@ -1357,7 +1253,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
int DRB_id = drb->drb_Identity;
if (rrcNB->active_DRBs[DRB_id]) {
if (rrcNB->status_DRBs[DRB_id] == RB_ESTABLISHED) {
AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering)
@@ -1365,7 +1261,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if (drb->cnAssociation)
AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
} else {
rrcNB->active_DRBs[DRB_id] = true;
rrcNB->status_DRBs[DRB_id] = RB_ESTABLISHED;
add_drb(false,
rnti,
radioBearerConfig->drb_ToAddModList->list.array[cnt],
@@ -1515,10 +1411,10 @@ void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded)
// reconfigurationWithSync is included in spCellConfig
}
}
void *rrc_nrue_task(void *args_p)
{
itti_mark_task_ready(TASK_RRC_NRUE);
while (1) {
rrc_nrue(NULL);
}
@@ -1608,7 +1504,7 @@ void *rrc_nrue(void *notUsed)
/* Transfer data to PDCP */
// check if SRB2 is created, if yes request data_req on SRB2
// error: the remote gNB is hardcoded here
rb_id_t srb_id = rrc->perNB[0].Srb[2].status == RB_ESTABLISHED ? 2 : 1;
rb_id_t srb_id = rrc->perNB[0].Srb[2] == RB_ESTABLISHED ? 2 : 1;
nr_pdcp_data_req_srb(rrc->rnti, srb_id, 0, length, buffer, deliver_pdu_srb_rlc, NULL);
break;
}
+4 -13
View File
@@ -180,18 +180,14 @@ typedef enum {
typedef enum { RB_NOT_PRESENT, RB_ESTABLISHED, RB_SUSPENDED } NR_RB_status_t;
typedef struct NR_UE_RRC_SRB_INFO_s {
NR_RB_status_t status;
} NR_UE_RRC_SRB_INFO_t;
typedef struct rrcPerNB {
NR_MeasObjectToAddMod_t *MeasObj[MAX_MEAS_OBJ];
NR_ReportConfigToAddMod_t *ReportConfig[MAX_MEAS_CONFIG];
NR_QuantityConfig_t *QuantityConfig;
NR_MeasIdToAddMod_t *MeasId[MAX_MEAS_ID];
NR_MeasGapConfig_t *measGapConfig;
NR_UE_RRC_SRB_INFO_t Srb[NR_NUM_SRB];
bool active_DRBs[MAX_DRBS_PER_UE];
NR_RB_status_t Srb[NR_NUM_SRB];
NR_RB_status_t status_DRBs[MAX_DRBS_PER_UE];
bool active_RLC_entity[NR_MAX_NUM_LCID];
NR_UE_RRC_SI_INFO SInfo;
NR_RSRP_Range_t s_measure;
@@ -199,10 +195,6 @@ typedef struct rrcPerNB {
typedef struct NR_UE_RRC_INST_s {
NR_MeasConfig_t *meas_config;
NR_CellGroupConfig_t *cell_group_config;
NR_ServingCellConfigCommonSIB_t *servingCellConfigCommonSIB;
NR_CellGroupConfig_t *scell_group_config;
NR_RadioBearerConfig_t *radio_bearer_config;
rrcPerNB_t perNB[NB_CNX_UE];
@@ -215,9 +207,8 @@ typedef struct NR_UE_RRC_INST_s {
// NR_MIB_t *mib;
// active BWPs
NR_BWP_DownlinkDedicated_t *bwpd;
NR_BWP_UplinkDedicated_t *ubwpd;
NR_BWP_Id_t dl_bwp_id;
NR_BWP_Id_t ul_bwp_id;
/* KeNB as computed from parameters within USIM card */
uint8_t kgnb[32];
+9 -2
View File
@@ -56,14 +56,21 @@ extern queue_t nr_ul_tti_req_queue;
// main_rrc.c
//
/**\brief Layer 3 initialization*/
NR_UE_RRC_INST_t *nr_l3_init_ue(char *, char *, char *);
NR_UE_RRC_INST_t *nr_l3_init_ue(char *);
//
// UE_rrc.c
//
/**\brief Initial the top level RRC structure instance*/
NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *, char *, char *);
NR_UE_RRC_INST_t *openair_rrc_top_init_ue_nr(char *);
void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file);
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len);
void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB,
instance_t instance,
NR_CellGroupConfig_t *cellGroupConfig);
/**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP)
\param module_id module id
+6
View File
@@ -1119,5 +1119,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
}
}
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
perror("SIGPIPE");
exit(1);
}
return 0;
}
@@ -0,0 +1,264 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
sa = 1;
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
nr_cellid = 12345678L;
////////// Physical parameters:
do_CSIRS = 1;
do_SRS = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 423130;
dl_frequencyBand = 1;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 422194;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 0;
dl_carrierBandwidth = 52;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 14025;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 0;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 7;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 1;
ul_absoluteFrequencyPointA = 384194;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 0;
ul_carrierBandwidth = 52;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 14025;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 0;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -90;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 0;
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -70;
n_TimingAdvanceOffset = 0;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 0;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 0;
# pattern1
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ul_max_mcs = 28;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
pucch0_dtx_threshold = 100;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 10;
att_rx = 10;
bands = [1];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = 4043;
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};