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:
@@ -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:
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/},\
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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}")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
Reference in New Issue
Block a user