Commit 513f060f authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2024_w04' into 'develop'

Integration: 2024.w04

See merge request oai/openairinterface5g!2535

* !2522 Integration of O-RAN 7.2 FH using OSC xRAN library
* !2416 fix-ue-scheduler-multi-thread-storage-list-mutex-protection
* !2488 LDPC T2 card encoding: rate matching and interleaving on the T2 card
* !2497 Read NoS1 bearer configuration from gNB-generated file
* !2518 Extension of E1AP procedures
* !2533 This limits PUCCH payload to 11 bits, 7 CSI + 3 ACKNACK + 1 SR maximum.
* !2526 prepare MSG3 in advance at RRC UE
* !2451 MAC procedures to handle DLSCH allocation type 0
* !2525 NR UE fix for function to find PUCCH resource set
* !2536 Improve Precoding Matrix computation taking in consideration the DCI format
* some documentation+config file updates for 7.2
* !2501 Improvements for NR implementation of timers
* !2531 Fix unit test build and build unit tests in CI
parents da5ce90d ddec7e75
......@@ -424,14 +424,13 @@ class Containerize():
# Let's remove any previous run artifacts if still there
cmd.run(f"{self.cli} image prune --force")
if forceBaseImageBuild:
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
for image,pattern,name,option in imageNames:
cmd.run(f"{self.cli} image rm {name}:{imageTag}")
# Build the base image only on Push Events (not on Merge Requests)
# On when the base image docker file is being modified.
if forceBaseImageBuild:
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} . &> cmake_targets/log/ran-base.log", timeout=1600)
# First verify if the base image was properly created.
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
......@@ -445,7 +444,7 @@ class Containerize():
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTabFooter(False)
sys.exit(1)
return False
else:
result = re.search('Size *= *(?P<size>[0-9\-]+) *bytes', cmd.getBefore())
if result is not None:
......@@ -506,10 +505,11 @@ class Containerize():
cmd.run(f"{self.cli} image prune --force")
# Remove all intermediate build images and clean up
if self.ranAllowMerge and forceBaseImageBuild:
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag}")
cmd.run(f"{self.cli} volume prune --force")
# Remove any cached artifacts: we don't use the cache for now, prevent
# out of diskspace problem
cmd.run(f"{self.cli} buildx prune --force")
# create a zip with all logs
build_log_name = f'build_log_{self.testCase_id}'
......@@ -523,12 +523,13 @@ class Containerize():
logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
return True
else:
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
HTML.CreateHtmlTabFooter(False)
sys.exit(1)
return False
def BuildProxy(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
......@@ -611,7 +612,7 @@ class Containerize():
mySSH.close()
HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTabFooter(False)
sys.exit(1)
return False
else:
logging.debug('L2sim proxy image for tag ' + tag + ' already exists, skipping build')
......@@ -673,6 +674,87 @@ class Containerize():
HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
def BuildRunTests(self, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '1':
lIpAddr = self.eNB1IPAddress
lUserName = self.eNB1UserName
lPassWord = self.eNB1Password
lSourcePath = self.eNB1SourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '2':
lIpAddr = self.eNB2IPAddress
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSourcePath = self.eNB2SourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.RemoteCmd(lIpAddr)
cmd.cd(lSourcePath)
ret = cmd.run('hostnamectl')
result = re.search('Ubuntu', ret.stdout)
host = result.group(0)
if host != 'Ubuntu':
cmd.close()
raise Exception("Can build unit tests only on Ubuntu server")
logging.debug('running on Ubuntu as expected')
if self.forcedWorkspaceCleanup:
cmd.run(f'sudo -S rm -Rf {lSourcePath}')
self.testCase_id = HTML.testCase_id
# check that ran-base image exists as we expect it
baseImage = 'ran-base'
baseTag = 'develop'
if self.ranAllowMerge:
if self.ranTargetBranch == 'develop':
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
result = re.search('index', cmd.getBefore())
if result is not None:
baseTag = 'develop'
ret = cmd.run(f"docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
if ret.returncode != 0:
logging.error(f'No {baseImage} image present, cannot build tests')
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTabFooter(False)
return False
# build ran-unittests image
dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu20"
ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {lSourcePath}/cmake_targets/log/unittest-build.log')
if ret.returncode != 0:
logging.error(f'Cannot build unit tests')
HTML.CreateHtmlTestRow("Unit test build failed", 'KO', [dockerfile])
HTML.CreateHtmlTabFooter(False)
return False
HTML.CreateHtmlTestRowQueue("Build unit tests", 'OK', [dockerfile])
# it worked, build and execute tests, and close connection
ret = cmd.run(f'docker run -a STDOUT --rm ran-unittests:develop ctest --output-on-failure --no-label-summary -j$(nproc)')
cmd.run(f'docker rmi ran-unittests:develop')
build_log_name = f'build_log_{self.testCase_id}'
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
cmd.close()
if ret.returncode == 0:
HTML.CreateHtmlTestRowQueue('Unit tests succeeded', 'OK', [ret.stdout])
HTML.CreateHtmlTabFooter(True)
return True
else:
HTML.CreateHtmlTestRowQueue('Unit tests failed (see also doc/UnitTests.md)', 'KO', [ret.stdout])
HTML.CreateHtmlTabFooter(False)
return False
def Push_Image_to_Local_Registry(self, HTML):
if self.registrySvrId == '0':
lIpAddr = self.eNBIPAddress
......
#/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with
# * this work for additional information regarding copyright ownership.
# * The OpenAirInterface Software Alliance licenses this file to You under
# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
# * except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.openairinterface.org/?page_id=698
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *-------------------------------------------------------------------------------
# * For more information about the OpenAirInterface (OAI) Software Alliance:
# * contact@openairinterface.org
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 20.04
#
#---------------------------------------------------------------------
FROM ran-base:develop as ran-tests
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
WORKDIR /oai-ran/build
RUN cmake -GNinja -DENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug .. && ninja tests
This diff is collapsed.
......@@ -34,6 +34,7 @@
- IdleSleep
- Perform_X2_Handover
- Build_Image
- Build_Run_Tests
- Deploy_Object
- Undeploy_Object
- Cppcheck_Analysis
......
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-run-test-tab</htmlTabRef>
<htmlTabName>Build and Run Unit Tests</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="030201">
<class>Build_Run_Tests</class>
<desc>Build and Run UnitTests</desc>
<kind>all</kind>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>
......@@ -21,7 +21,6 @@
#include "byte_array.h"
#include "common/utils/assertions.h"
#include <assert.h>
#include <string.h>
......@@ -29,7 +28,7 @@ byte_array_t copy_byte_array(byte_array_t src)
{
byte_array_t dst = {0};
dst.buf = malloc(src.len);
AssertFatal(dst.buf != NULL, "Memory exhausted");
assert(dst.buf != NULL && "Memory exhausted");
memcpy(dst.buf, src.buf, src.len);
dst.len = src.len;
return dst;
......
......@@ -4,6 +4,9 @@
int T_stdout;
#endif
struct configmodule_interface_s;
struct configmodule_interface_s *uniqCfg = NULL;
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
if (assert) {
......
......@@ -865,3 +865,44 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates
delay->delay_max_val = max_val;
delay->est_delay = max_pos - sync_pos;
}
void nr_timer_start(NR_timer_t *timer)
{
timer->active = true;
timer->counter = 0;
}
void nr_timer_stop(NR_timer_t *timer)
{
timer->active = false;
timer->counter = 0;
}
bool is_nr_timer_active(NR_timer_t timer)
{
return timer.active;
}
bool nr_timer_tick(NR_timer_t *timer)
{
bool expired = false;
if (timer->active) {
timer->counter += timer->step;
expired = nr_timer_expired(*timer);
if (expired)
timer->active = false;
}
return expired;
}
bool nr_timer_expired(NR_timer_t timer)
{
return (timer.counter >= timer.target);
}
void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t step)
{
timer->target = target;
timer->step = step;
nr_timer_stop(timer);
}
......@@ -116,6 +116,49 @@ typedef struct {
int delay_max_val;
} delay_t;
typedef struct {
bool active;
uint32_t counter;
uint32_t target;
uint32_t step;
} NR_timer_t;
/**
* @brief To start a timer
* @param timer Timer to be started
*/
void nr_timer_start(NR_timer_t *timer);
/**
* @brief To stop a timer
* @param timer Timer to stopped
*/
void nr_timer_stop(NR_timer_t *timer);
/**
* @brief If active, it increases timer counter by an amout of units equal to step. It stops timer if expired
* @param timer Timer to be handled
* @return Indication if the timer is expired or not
*/
bool nr_timer_tick(NR_timer_t *timer);
/**
* @brief To setup a timer
* @param timer Timer to setup
* @param target Target value for timer (when reached, timer is considered expired)
* @param step Amount of units to add to timer counter every tick
*/
void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t step);
/**
* @brief To check if a timer is expired
* @param timer Timer to be checked
* @return Indication if the timer is expired or not
*/
bool nr_timer_expired(NR_timer_t timer);
/**
* @brief To check if a timer is active
* @param timer Timer to be checked
* @return Indication if the timer is active or not
*/
bool is_nr_timer_active(NR_timer_t timer);
extern const nr_bandentry_t nr_bandtable[];
static inline int get_num_dmrs(uint16_t dmrs_mask ) {
......
......@@ -218,4 +218,10 @@ time_stats_t *register_meas(char *name);
void send_meas(time_stats_t *ts, int msgid);
void end_meas(void);
#define timeIt(a) \
{ \
uint64_t deb = rdtsc_oai(); \
a; \
LOG_W(UTIL, #a ": %llu\n", (rdtsc_oai() - deb) / 3000); \
}
#endif
......@@ -63,6 +63,8 @@ Calling the `build_oai` script with the `-h` option gives the list of all availa
- `--ninja` is to use the `ninja` build tool, which speeds up compilation.
- `-c` is to clean the workspace and force a complete rebuild.
`build_oai` also provides various options to enable runtime error checkers, i.e. sanitizers in order to find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. Refer to [sanitizers.md](./dev_tools/sanitizers.md) for more details.
## Installing dependencies
Install all dependencies by issuing the `-I` option. To install furthermore libraries for optional libraries, use the `--install-optional-packages` option. The `-I` option will also install dependencies for an SDR when paired with `-w`. For instance, in order to install all dependencies and the ones for USRP, run:
......
......@@ -17,17 +17,22 @@ connection setup only in split-mode, the rest is the same for CU):
sequenceDiagram
participant c as CUCP
participant u as CUUP
Note over c,u: E1 Setup Procedure
u->c: SCTP connection setup (in split mode)
u->>c: E1AP Setup Request
u->>c: E1 Setup Request
Note over c: Execute rrc_gNB_process_e1_setup_req()
c->>u: E1AP Setup Response
c->>u: E1 Setup Response
c-->>u: E1 Setup Failure
Note over c,u: E1 Bearer Context Setup Procedure
Note over c: Receives PDU session setup request from AMF
c->>u: Bearer Context Setup Request
Note over u: Execute e1_bearer_context_setup()<br/>Configure DRBs and create GTP Tunnels for F1-U and N3
u->>c: Bearer Context Setup Response
Note over c: Execute rrc_gNB_process_e1_setup_req()<br/>Sends F1-U UL TNL info to DU and receives DL TNL info
Note over c,u: E1 Bearer Context Modification (CU-CP Initiated) Procedure
c->>u: Bearer Context Modification Request
Note over u: Execute e1_bearer_context_modif()<br/>Updates GTP Tunnels with received info
u->>c: Bearer Context Modification Response
......@@ -40,19 +45,63 @@ sequenceDiagram
Note over c: Execute rrc_gNB_process_e1_bearer_context_release_cplt()
```
The files that implement the callback towards these handlers are in
- `cucp_cuup_direct.c`: integrated CU (for CP=>UP messages)
- `cucp_cuup_e1ap.c`: E1 split mode (for CP=>UP messages)
- `cuup_cucp_direct.c`: integrated CU (for UP=>CP messages)
- `cuup_cucp_e1ap.c`: E1 split mode (for UP=>CP messages)
The implementation of callbacks towards these handlers is distributed across the following file, depending on the operating mode:
| Mode | CP=>UP messages |UP=>CP messages |
| --------------| --------------------|--------------------|
| Integrated CU | `cucp_cuup_direct.c`|`cuup_cucp_direct.c`|
| E1 Split | `cucp_cuup_e1ap.c` |`cuup_cucp_e1ap.c` |
As long as concerns E1 Interface Management Procedures, the code flow of request messages towards northbound looks like this:
```mermaid
sequenceDiagram
participant r as RRC
participant c as CUCP
participant u as CUUP
Note over u: E1AP_CUUP_task (SCTP Handler)
Note over u: ASN1 encoder
u->>c: e.g. E1 Setup Request (SCTP)
Note over c: E1AP_CUCP_task (SCTP Handler)
Note over c: ASN1 decoder
c->>r: E1AP_SETUP_REQ (ITTI)
Note over r: TASK_RRC_GNB (RRC Handler)
r->>c: E1AP_SETUP_RESP (ITTI)
Note over c: E1AP_CUCP_task (E1AP Callback)
Note over c: ASN1 encoder
c->>u: e.g. E1 Setup Response/Failure
Note over u: E1AP_CUUP_task (SCTP Handler)
Note over u: ASN1 decoder
```
# 2. Running the E1 Split
The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./F1-design.md) for local deployment of the DU.
## 2.1 Configuration File
The gNB is started based on the node type that is specified in the configuration file. To start a gNB instance in CUCP or CUUP, the `tr_s_preference` should be set to "f1" and the config member `E1_INTERFACE` should be present in the config file. The `type` parameter within the `E1_INTERFACE` should be set to `cp`, and executable `nr-softmodem` should be used to run a CU-CP. The type should be `up` and executable `nr-cuup` should be used to run the CU-UP. Further, there are the parameters `ipv4_cucp` and `ipv4_cuup` to specify the IP addresses of the respective network functions.
The gNB is started based on the node type that is specified in the configuration file. The following parameters must be configured accordingly.
On either CUCP and CUUP:
* The southbound transport preference `gNBs.[0].tr_s_preference` set to `f1`
* config section `E1_INTERFACE` should be present
On the CU-CP:
* `type` parameter within the `E1_INTERFACE` should be set to `cp`
On the CU-UP:
* `type` parameter within the `E1_INTERFACE` should be set to `up`
Executables:
* executable `nr-softmodem` to run a CU-CP
* executable `nr-cuup` to run the CU-UP
In the `E1_INTERFACE` configuration section, the parameters `ipv4_cucp` and `ipv4_cuup` must be configured to specify the IP addresses of the respective network functions.
For CUCP, a typical `E1_INTERFACE` config looks like
For CUCP, a typical `E1_INTERFACE` config looks like:
```
E1_INTERFACE =
(
......@@ -64,7 +113,7 @@ E1_INTERFACE =
)
```
For CUUP, it is
For CUUP, it is:
```
E1_INTERFACE =
(
......@@ -77,7 +126,7 @@ E1_INTERFACE =
```
One could take an existing CU configuration file and add the above parameters to run the gNB as CUCP or CUUP.
The CUUP uses the IP address specified in `local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member.
The CUUP uses the IP address specified in `gNBs.[0].local_s_address` for F1-U and `GNB_IPV4_ADDRESS_FOR_NGU` for N3 links. Note that `local_s_address` is under `gNBs` and `GNB_IPV4_ADDRESS_FOR_NGU` is part of the `NETWORK_INTERFACES` config member.
Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.f1.conf` and `ci-scripts/conf_files/gnb-cuup.sa.f1.conf`.
......
......@@ -20,15 +20,15 @@ The F1 interface is the functional split of 3GPP between the CU (centralized
unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is
standardized in TS 38.470 - 38.473 for 5G NR. No equivalent for 4G exists.
We assume that each DU handles only one cell. Multiple DUs connected to one CU
We assume that each DU handles only one cell. Multiple DUs connected to one CU
are supported. Mobility over F1 is not yet supported.
# Control plane status (F1-C)
## Implementation Status
Note that OAI uses F1 "internally". That means, that even if you run a
monolithic gNB, the internal information exchange uses F1. You can therefore
Note that OAI uses F1 "internally". That means, that even **if you run a
monolithic gNB, the internal information exchange uses F1**. You can therefore
expect that everything working in a monolithic deployment should also work in
F1. The current implementation is based on R16.3.
......@@ -118,13 +118,13 @@ see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/dock
The rules to decide if a config triggers a start of a DU, CU, or monolithic
gNB, are, in order:
1. If the `MACRLCs` section lists `f1` as northbound transport preference
1. If the `MACRLCs` section lists `f1` as **northbound transport preference**
(`tr_n_preference`), it is a DU.
2. If the `gNBs` section lists `f1` as a southound transport preference
2. If the `gNBs` section lists `f1` as a **southound transport preference**
(`tr_s_preference`), it is a CU.
3. It is a (monolithic) gNB.
## Configuration of F1 IP/port information
## Local network deployment of F1
For a local deployment, you should update the following fields.
We assume that the CU will bind on `192.168.70.129` towards the core,
......
......@@ -191,22 +191,30 @@ Furthermore, the gNB and UE support
## gNB F1AP
- Integration of F1AP messages and procedures for the control plane exchanges between the CU and DU entities according to 38.473 Rel. 16
- F1 Setup request/response
- F1 Setup request/response/failure
- F1 DL/UL RRC message transfer
- F1 Initial UL RRC message transfer
- F1 UE Context setup request/response
- F1 UE Context modification request/response
- F1 UE Context release
- F1 UE Context modification required
- F1 UE Context release req/cmd/complete
- F1 gNB CU configuration update
- Interface with RRC
- Interface with gtp-u (tunnel creation/handling for F1-U interface)
## gNB E1AP
- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to 38.463 Rel. 16
- gNB-CU-UP E1 Setup Setup request/response
- E1 Bearer Context Setup
- Integration of E1AP messages and procedures for exchange between CU-CP and CU-UP according to TS 38.463 Rel. 16
- E1 Setup (gNB-CU-UP initiated)
- E1 Setup Request
- E1 Setup Response
- E1 Setup Failure
- E1 Bearer Context Setup (gNB-CU-CP initiated)
- E1 Bearer Context Setup Request
- E1 Bearer Context Setup Response
- Bearer Context Modification (gNB-CU-CP initiated)
- E1 Bearer Context Modification Request
- E1 Bearer Context Modification Response
- Interface with RRC and PDCP
## gNB GTP-U
......
......@@ -62,7 +62,7 @@ sudo python3 ~/dpdk-stable/usertools/dpdk-devbind.py --bind=vfio-pci 41:00.0
Replace PCI address of the card *41:00.0* by address detected by *lspci | grep "Xilinx"* command
- hugepages setup (10 x 1GB hugepages)
```
sudo python3 ~/dpdk-stable/usertools/dpdk-hugepages.py -p 1G --setup 10G`
sudo python3 ~/dpdk-stable/usertools/dpdk-hugepages.py -p 1G --setup 10G
```
*Note: device binding and hugepages setup has to be done after every reboot of
......@@ -144,7 +144,6 @@ sudo ./nr-softmodem --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa
# Limitations
## AMD Xilinx T2 card
- offload of the LDPC encoding implemented for MCS > 2, OAI CPU encoder is used for MCS =< 2
- functionality of the LDPC encoding and decoding offload verified in OTA SISO setup with USRP N310 and Quectel RM500Q, blocking of the card reported for MIMO setup (2 layers)
*Note: AMD Xilinx T1 Telco card is not supported anymore.*
......@@ -442,9 +442,9 @@ We are evaluating if we can share RU configuration steps.
# Configure OAI gNB
Sample configuration files for OAI gNB, specific to the manufacturer of the radio unit, are available at:
1. LITE-ON RU: [`gnb.sa.band78.273prb.fhi72.4x4-liteon.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf) (band n78, 273 PRBs, 3.5GHz center freq, 4x4 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2x2 DL MIMO, UL SISO)
2. Benetel 650 RU: [`gnb.sa.band78.273prb.fhi72.4x2-benetel650.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel650.conf) (band n78, 273 PRBs, 3.5GHz center freq, 4x2 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2x2 DL MIMO, UL SISO)
3. VVDN RU: [`gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf) (band n77, 273 PRBs, 4.0GHz center freq, 4x4 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2x2 DL MIMO, UL SISO)
1. LITE-ON RU: [`gnb.sa.band78.273prb.fhi72.4x4-liteon.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf) (band n78, 273 PRBs, 3.5GHz center freq, 4x4 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2-layer DL MIMO, UL SISO)
2. Benetel 650 RU: [`gnb.sa.band78.273prb.fhi72.4x2-benetel650.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel650.conf) (band n78, 273 PRBs, 3.5GHz center freq, 4x2 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2-layer DL MIMO, UL SISO)
3. VVDN RU: [`gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf) (band n77, 273 PRBs, 4.0GHz center freq, 4x4 antenna configuration with 9 bit I/Q samples (compressed) for PUSCH/PDSCH/PRACH, 2-layer DL MIMO, UL SISO)
## Adapt the OAI-gNB configuration file to your system/workspace
......
......@@ -21,6 +21,7 @@
- [BUILD.md](./BUILD.md): how to build the sources
- [cross-compile.md](./cross-compile.md): how to cross-compile OAI for ARM
- [clang-format.md](./clang-format.md): how to format the code
- [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan
- [environment-variables.md](./environment-variables.md): the environment variables used by OAI
There is some general information in the [OpenAirInterface Gitlab Wiki](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/home)
......
......@@ -109,6 +109,7 @@ information on how the images are built.
- 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
- run formatting check from `ci-scripts/docker/Dockerfile.formatting.bionic`
- 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
......@@ -118,6 +119,7 @@ information on how the images are built.
- target image from `Dockerfile.nrUE.ubuntu20`
- target image from `Dockerfile.lteUE.ubuntu20`
- target image from `Dockerfile.lteRU.ubuntu20`
- build unit tests from `ci-scripts/docker/Dockerfile.unittest.ubuntu20`, and run them
#### Image Test pipelines
......
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Build Procedures</font></b>
</td>
</tr>
</table>
[[_TOC_]]
# Sanitize options in `build_oai`
The `build_oai` script provides various [Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) to add run-time instrumentation to the code and enable runtime error checkers, i.e. sanitizers, in order to help find various types of bugs in the codebase and eventually enhance the stability of the OAI softmodems. The following sanitizers can be enabled using different build options:
## Address Sanitizer (ASAN)
[Address Sanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) is enabled using the `--sanitize-address` option or its shorthand `-fsanitize=address`. It serves as a fast memory error detector and helps detect issues like out-of-bounds accesses, use-after-free bugs, and memory leaks.
### Run OAI Softmodem with ASAN on
It is necessary to add the envinronment variable `LD_LIBRARY_PATH` to the run command, e.g.:
```
cd cmake_targets/ran_build/build
sudo LD_LIBRARY_PATH=. ./nr-softmodem ...
```
## Undefined Behavior Sanitizer (UBSAN)
[Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) (UBSAN) is a runtime undefined behavior checker. It uses compile-time instrumentation to catch undefined behavior by inserting code that performs specific checks before operations that may cause it. UBSAN can be activated with the `--sanitize-undefined` option or `-fsanitize=undefined`.
UBSAN offers a range of suboptions that enable precise checks for various types of undefined behavior at runtime. These suboptions can be set by tweaking the [CMakeLists.txt](../../CMakeLists.txt) file. Here is an overview of some key suboptions:
* `-fsanitize=shift`: Enables checks for the result of shift operations, with suboptions for base and exponent.
* `-fsanitize=integer-divide-by-zero`: Detects integer division by zero.
* `-fsanitize=null`: Enables pointer checking, issuing an error message when dereferencing a NULL pointer or binding a reference to a NULL pointer.
* `-fsanitize=signed-integer-overflow`: Detects signed integer overflow.
* `-fsanitize=bounds`: Instruments array bounds, detecting various out-of-bounds accesses.
* `-fsanitize=alignment`: Checks the alignment of pointers when dereferenced or when a reference is bound to an insufficiently aligned target.
* `-fsanitize=object-size`: Checks out-of-bounds pointer accesses.
* `-fsanitize=float-divide-by-zero`: Detects floating-point division by zero.
## Memory Sanitizer
To enable [Memory Sanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), use the `--sanitize-memory` option or `-fsanitize=memory`. It requires clang and is incompatible with ASAN and UBSAN. Building with this option helps catch issues related to uninitialized memory reads.
To build with Memory Sanitizer, use the following command:
```
CC=/usr/bin/clang CXX=/usr/bin/clang++ ./build_oai ... --sanitize-memory
```
## Thread Sanitizer
[Thread Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) can be activated using the `--sanitize-thread` option or `-fsanitize=thread`. This sanitizer helps identify data races and other threading-related issues in the code.
# Summary of Sanitizer Options
- `--sanitize`: Shortcut for using both ASAN and UBSAN.
- `--sanitize-address` or `-fsanitize=address`: Enable ASAN on all targets.
- `--sanitize-undefined` or `-fsanitize=undefined`: Enable UBSAN on all targets.
- `--sanitize-memory` or `-fsanitize=memory`: Enable Memory Sanitizer on all targets (requires clang).
- `--sanitize-thread` or `-fsanitize=thread`: Enable Thread Sanitizer on all targets.
......@@ -400,7 +400,7 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
}
}
// If CU
// E1AP initialisation, whether the node is a CU or has integrated CU
if (node_type == ngran_gNB_CU || node_type == ngran_gNB) {
MessageDef *msg = RCconfig_NR_CU_E1(NULL);
instance_t inst = 0;
......
......@@ -310,16 +310,13 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
int CC_id = 0;
uint8_t gNB_id = 0;
nr_uplink_indication_t ul_info;
int slots_per_frame = 20; //30 kHZ subcarrier spacing
int slot_ahead = 2; // TODO: Make this dynamic
ul_info.cc_id = CC_id;
ul_info.gNB_index = gNB_id;
ul_info.module_id = mod_id;
ul_info.frame_rx = frame;
ul_info.slot_rx = slot;
ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame;
ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx;
nr_uplink_indication_t ul_info = {.cc_id = CC_id,
.gNB_index = gNB_id,
.module_id = mod_id,
.slot = (slot + slot_ahead) % slots_per_frame,
.frame = (slot + slot_ahead >= slots_per_frame) ? (frame + 1) % 1024 : frame};
if (pthread_mutex_lock(&mac->mutex_dl_info)) abort();
......@@ -330,8 +327,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
free_and_zero(ch_info);
}
if (is_nr_DL_slot(mac->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_rx)) {
if (is_nr_DL_slot(mac->tdd_UL_DL_ConfigurationCommon, slot)) {
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
mac->dl_info.gNB_index = gNB_id;
......@@ -345,9 +341,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_tx, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot_tx);
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info.slot, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot);
nr_ue_ul_scheduler(&ul_info);
}
process_queued_nr_nfapi_msgs(mac, sfn_slot);
......@@ -545,7 +540,12 @@ void processSlotTX(void *arg) {
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_tx_t phy_data = {0};
LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
LOG_D(PHY,
"SlotTx %d.%d => slot type %d, wait: %d \n",
proc->frame_tx,
proc->nr_slot_tx,
proc->tx_slot_type,
rxtxD->tx_wait_for_dlsch);
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
if (rxtxD->tx_wait_for_dlsch)
LOG_D(PHY, "enter wait for tx, slot %d, nb events to wait %d; ", proc->nr_slot_tx, rxtxD->tx_wait_for_dlsch);
......@@ -587,17 +587,12 @@ void processSlotTX(void *arg) {
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
start_meas(&UE->ue_ul_indication_stats);
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
ul_indication.module_id = UE->Mod_id;
ul_indication.gNB_index = proc->gNB_id;
ul_indication.cc_id = UE->CC_id;
ul_indication.frame_rx = proc->frame_rx;
ul_indication.slot_rx = proc->nr_slot_rx;
ul_indication.frame_tx = proc->frame_tx;
ul_indication.slot_tx = proc->nr_slot_tx;
ul_indication.phy_data = &phy_data;
nr_uplink_indication_t ul_indication = {.module_id = UE->Mod_id,
.gNB_index = proc->gNB_id,
.cc_id = UE->CC_id,
.frame = proc->frame_tx,
.slot = proc->nr_slot_tx,
.phy_data = &phy_data};
UE->if_inst->ul_indication(&ul_indication);
stop_meas(&UE->ue_ul_indication_stats);
......@@ -989,29 +984,8 @@ void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconf
NR_UE_MAC_INST_t *mac = get_mac_inst(i);
AssertFatal((mac->if_module = nr_ue_if_module_init(i)) != NULL, "can not initialize IF module\n");
if (!get_softmodem_params()->sa) {
init_nsa_message(&rrc_inst[i], 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(i, 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, i, rbconfig->drb_ToAddModList, 0, NULL, NULL);
nr_rlc_add_drb(i, 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);
}
init_nsa_message(rrc_inst, reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac_inst->crnti, NULL, send_srb0_rrc);
}
}
}
......
......@@ -368,7 +368,8 @@ void init_openair0(void) {
}
}
static void init_pdcp(int ue_id) {
static void init_pdcp(int ue_id)
{
uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
/*if (IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
......@@ -510,8 +511,6 @@ int main(int argc, char **argv)
memset(PHY_vars_UE_g[0][CC_id], 0, sizeof(*PHY_vars_UE_g[0][CC_id]));
}
init_NR_UE(NB_UE_INST, uecap_file, reconfig_file, rbconfig_file);
int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1;
uint16_t node_number = get_softmodem_params()->node_number;
ue_id_g = (node_number == 0) ? 0 : node_number - 2;
......@@ -525,6 +524,8 @@ int main(int argc, char **argv)
}
}
init_NR_UE(NB_UE_INST, uecap_file, reconfig_file, rbconfig_file);
if (get_softmodem_params()->emulate_l1) {
RCconfig_nr_ue_macrlc();
get_channel_model_mode(uniqCfg);
......
......@@ -69,4 +69,5 @@
#define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04
#define FAPI_NR_UL_CONFIG_TYPES 0x04
#define FAPI_NR_END 0xff
#endif
......@@ -168,7 +168,6 @@ typedef struct {
typedef struct {
uint16_t pdu_length;
uint16_t pdu_index;
uint8_t* pdu;
} fapi_nr_tx_request_body_t;
......@@ -337,7 +336,7 @@ typedef struct
uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
uint8_t resource_alloc;
uint8_t rb_bitmap[36];//
uint8_t rb_bitmap[36];
uint16_t rb_start;
uint16_t rb_size;
uint8_t vrb_to_prb_mapping;
......@@ -358,6 +357,7 @@ typedef struct
nfapi_nr_ue_ul_beamforming_t beamforming;
//OAI specific
int8_t absolute_delta_PUSCH;
fapi_nr_tx_request_body_t tx_request_body;
} nfapi_nr_ue_pusch_pdu_t;
typedef struct {
......@@ -391,24 +391,25 @@ typedef struct {
} fapi_nr_ul_config_srs_pdu;
typedef struct {
uint8_t pdu_type;
int pdu_type;
union {
fapi_nr_ul_config_prach_pdu prach_config_pdu;
fapi_nr_ul_config_pucch_pdu pucch_config_pdu;
nfapi_nr_ue_pusch_pdu_t pusch_config_pdu;
fapi_nr_ul_config_srs_pdu srs_config_pdu;
};
pthread_mutex_t* lock;
int* privateNBpdus;
} fapi_nr_ul_config_request_pdu_t;
typedef struct {
uint16_t sfn;
uint16_t slot;
uint8_t number_pdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM];
int frame;
int slot;
int number_pdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM + 1]; // +1 to have space for iterator ending
pthread_mutex_t mutex_ul_config;
} fapi_nr_ul_config_request_t;
typedef struct {
uint16_t rnti;
uint16_t BWPSize;
......@@ -438,7 +439,9 @@ typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interlea
typedef struct {
uint16_t BWPSize;
uint16_t BWPStart;
uint8_t SubcarrierSpacing;
uint8_t SubcarrierSpacing;
uint8_t resource_alloc;
uint8_t rb_bitmap[36];
uint16_t number_rbs;
uint16_t start_rb;
uint16_t number_symbols;
......
......@@ -568,14 +568,14 @@ static void set_ldpc_enc_op(struct rte_bbdev_enc_op **ops,
{
// struct rte_bbdev_op_ldpc_enc *ldpc_enc = &ref_op->ldpc_enc;
for (int i = 0; i < n; ++i) {
ops[i]->ldpc_enc.cb_params.e = 3 * p_offloadParams->E; // Fix mee: what is the correct size for "e" ???
ops[i]->ldpc_enc.cb_params.e = p_offloadParams->E;
ops[i]->ldpc_enc.basegraph = p_offloadParams->BG;
ops[i]->ldpc_enc.z_c = p_offloadParams->Z;
ops[i]->ldpc_enc.q_m = p_offloadParams->Qm;
ops[i]->ldpc_enc.n_filler = p_offloadParams->F;
ops[i]->ldpc_enc.n_cb = p_offloadParams->n_cb;
ops[i]->ldpc_enc.rv_index = p_offloadParams->rv;
ops[i]->ldpc_enc.op_flags = RTE_BBDEV_LDPC_INTERLEAVER_BYPASS; // RTE_BBDEV_LDPC_RATE_MATCH;
ops[i]->ldpc_enc.op_flags = RTE_BBDEV_LDPC_RATE_MATCH;
ops[i]->ldpc_enc.code_block_mode = 1;
ops[i]->ldpc_enc.output = outputs[start_idx + i];
ops[i]->ldpc_enc.input = inputs[start_idx + i];
......@@ -613,7 +613,7 @@ static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n,
for (i = 0; i < n; ++i) {
output = &ops[i]->ldpc_enc.output;
m = output->data;
uint16_t data_len = min((384 * 68) / 8, rte_pktmbuf_data_len(m)); // fix me
uint16_t data_len = min((LDPC_MAX_CB_SIZE) / 8, rte_pktmbuf_data_len(m)); // fix me
data = m->buf_addr;
for (int byte = 0; byte < data_len; byte++)
for (int bit = 0; bit < 8; bit++)
......@@ -1103,10 +1103,10 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple
.n_cb = (BG == 1) ? (66 * Zc) : (50 * Zc),
.BG = BG,
.Z = Zc,
.rv = 0, //impp->rv,
.F = 0, //impp->F,
.rv = impp->rv,
.F = impp->F,
.Qm = impp->Qm,
.Kr = impp->Kr};
.Kr = (impp->K - impp->F + 7) / 8};
struct rte_bbdev_info info;
rte_bbdev_info_get(ad->dev_id, &info);
int socket_id = GET_SOCKET(info.socket_id);
......@@ -1126,7 +1126,7 @@ int32_t LDPCencoder(unsigned char **input, unsigned char **output, encoder_imple
for (enum op_data_type type = DATA_INPUT; type < 3; type += 2) {
int ret = init_op_data_objs(*queue_ops[type],
*input,
(offloadParams.Kr + 7) / 8,
offloadParams.Kr,
m_head[type],
mbuf_pools[type],
1,
......
......@@ -363,7 +363,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
impp.tparity = tparity;
impp.toutput = toutput;
impp.harq = harq;
if (gNB->ldpc_offload_flag && *rel15->mcsIndex > 2) {
if (gNB->ldpc_offload_flag) {
impp.Qm = rel15->qamModOrder[0];
impp.rv = rel15->rvIndex[0];
int nb_re_dmrs =
......@@ -375,26 +375,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
harq->unav_res,
rel15->qamModOrder[0],
rel15->nrOfLayers);
uint8_t tmp[68 * 384] __attribute__((aligned(32)));
uint8_t *d = tmp;
int r_offset = 0;
for (int r = 0; r < impp.n_segments; r++) {
impp.E = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r);
impp.Kr = impp.K;
ldpc_interface_offload.LDPCencoder(&harq->c[r], &d, &impp);
uint8_t e[impp.E];
bzero(e, impp.E);
nr_rate_matching_ldpc(rel15->maintenance_parms_v3.tbSizeLbrmBytes,
impp.BG,
impp.Zc,
tmp,
e,
impp.n_segments,
impp.F,
impp.K - impp.F - 2 * impp.Zc,
impp.rv,
impp.E);
nr_interleaving_ldpc(impp.E, impp.Qm, e, impp.output + r_offset);
uint8_t *f = impp.output + r_offset;
ldpc_interface_offload.LDPCencoder(&harq->c[r], &f, &impp);
r_offset += impp.E;
}
} else {
......
......@@ -268,8 +268,6 @@ typedef enum {
#endif
typedef struct {
int nb_search_space;
uint16_t sfn;
uint16_t slot;
fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
} NR_UE_PDCCH_CONFIG;
......@@ -330,7 +328,7 @@ typedef struct UE_NR_SCAN_INFO_s {
} UE_NR_SCAN_INFO_t;
/// Top-level PHY Data Structure for UE
typedef struct {
typedef struct PHY_VARS_NR_UE_s {
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance
......
This diff is collapsed.
......@@ -51,6 +51,6 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config);
\param synch_request including target_Nid_cell*/
void nr_ue_synch_request(nr_synch_request_t *synch_request);
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack);
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nack);
#endif
......@@ -510,6 +510,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
uint16_t s0 = dlsch0->dlsch_config.start_symbol;
uint16_t s1 = dlsch0->dlsch_config.number_symbols;
AssertFatal(dlsch0->dlsch_config.resource_alloc == 1,
"DLSCH resource allocation type0 not supported at PHY\n");
LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), BWP start %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,BWPStart,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
......@@ -1025,7 +1028,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
time_stats_t meas = {0};
start_meas(&meas);
// do procedures for C-RNTI
int ret_pdsch = 0;
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
......@@ -1081,11 +1083,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
llr[i] = (int16_t *)malloc16_clear(rx_llr_buf_sz * sizeof(int16_t));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
ret_pdsch = nr_ue_pdsch_procedures(ue,
proc,
dlsch,
llr,
rxdataF);
// it returns -1 in case of internal failure, or 0 in case of normal result
int ret_pdsch = nr_ue_pdsch_procedures(ue, proc, dlsch, llr, rxdataF);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
......@@ -1103,6 +1102,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
send_dl_done_to_tx_thread(
ue->tx_resume_ind_fifo + (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame,
proc->nr_slot_rx);
LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx);
}
stop_meas(&ue->dlsch_procedures_stat);
......
......@@ -871,27 +871,14 @@ int main(int argc, char **argv)
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup);
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
UE_mac->state = UE_CONNECTED;
UE_mac->ra.ra_state = RA_SUCCEEDED;
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
nr_phy_data_t phy_data = {0};
memset((void*)&dcireq,0,sizeof(dcireq));
memset((void*)&scheduled_response,0,sizeof(scheduled_response));
dcireq.module_id = 0;
dcireq.gNB_index = 0;
dcireq.cc_id = 0;
scheduled_response.dl_config = &dcireq.dl_config_req;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = 0;
scheduled_response.CC_id = 0;
scheduled_response.frame = frame;
scheduled_response.slot = slot;
scheduled_response.phy_data = &phy_data;
fapi_nr_dl_config_request_t dl_config = {.sfn = frame, .slot = slot};
nr_scheduled_response_t scheduled_response = {.dl_config = &dl_config, .phy_data = &phy_data, .mac = UE_mac};
nr_ue_phy_config_request(&UE_mac->phy_config);
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
......@@ -976,9 +963,6 @@ int main(int argc, char **argv)
UE_proc.frame_rx = frame;
UE_proc.nr_slot_rx = slot;
UE_proc.gNB_id = 0;
dcireq.frame = frame;
dcireq.slot = slot;
NR_UE_DLSCH_t *dlsch0 = &phy_data.dlsch[0];
......@@ -1114,8 +1098,9 @@ int main(int argc, char **argv)
// Apply MIMO Channel
multipath_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
add_noise(UE->common_vars.rxdata, (const double **) r_re, (const double **) r_im, sigma2, slot_length, slot_offset, ts, delay, pdu_bit_map, 0x1, frame_parms->nb_antennas_rx);
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
dl_config.sfn = frame;
dl_config.slot = slot;
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
nr_ue_scheduled_response(&scheduled_response);
pbch_pdcch_processing(UE,
......
......@@ -718,9 +718,7 @@ int main(int argc, char *argv[])
uint32_t errors_decoding = 0;
nr_scheduled_response_t scheduled_response={0};
fapi_nr_ul_config_request_t ul_config={0};
fapi_nr_tx_request_t tx_req={0};
fapi_nr_ul_config_request_t ul_config = {0};
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
......@@ -1073,24 +1071,7 @@ int main(int argc, char *argv[])
nr_schedule_response(Sched_INFO);
// --------- setting parameters for UE --------
scheduled_response.module_id = 0;
scheduled_response.CC_id = 0;
scheduled_response.frame = frame;
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
scheduled_response.tx_request = &tx_req;
scheduled_response.phy_data = (void *)&phy_data;
// Config UL TX PDU
tx_req.slot = slot;
tx_req.sfn = frame;
tx_req.number_of_pdus = 1; //do_SRS == 1 ? 2 : 1;
tx_req.tx_request_body[0].pdu_length = TBS / 8;
tx_req.tx_request_body[0].pdu_index = 0;
tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0];
nr_scheduled_response_t scheduled_response = {.ul_config = &ul_config, .phy_data = (void *)&phy_data};
ul_config.slot = slot;
ul_config.number_pdus = do_SRS == 1 ? 2 : 1;
......@@ -1098,6 +1079,9 @@ int main(int argc, char *argv[])
fapi_nr_ul_config_request_pdu_t *ul_config0 = &ul_config.ul_config_list[0];
ul_config0->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config0->pusch_config_pdu;
// Config UL TX PDU
pusch_config_pdu->tx_request_body.pdu = ulsch_input_buffer;
pusch_config_pdu->tx_request_body.pdu_length = TBS / 8;
pusch_config_pdu->rnti = n_rnti;
pusch_config_pdu->pdu_bit_map = pdu_bit_map;
pusch_config_pdu->qam_mod_order = mod_order;
......
......@@ -22,18 +22,27 @@
/* gNB_CUUP application layer -> E1AP messages */
MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req)
/* E1AP messages -> RRC (CU-CP) */
MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req)
/* E1AP -> RRC to inform about lost connection */
MESSAGE_DEF(E1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, e1ap_lost_connection_t, e1ap_lost_connection)
/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */
/* E1AP Interface Management Messages */
/* E1AP Setup Request: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req)
/* E1AP Setup Response: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp)
/* E1AP Setup Failure: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_SETUP_FAIL, MESSAGE_PRIORITY_MED, e1ap_setup_fail_t, e1ap_setup_fail)
/* E1AP Bearer Context Management Procedures */
/* E1AP Bearer Context Setup Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req)
/* E1AP Bearer Context Setup Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp)
/* E1AP Bearer Context Modification Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req)
/* E1AP Bearer Context Modification Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, e1ap_bearer_modif_resp_t, e1ap_bearer_modif_resp)
/* E1AP Bearer Context Release Request: gNB-CU-CP -> gNB-CU-UP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cmd_t, e1ap_bearer_release_cmd)
/* E1AP Bearer Context Release Response: gNB-CU-UP -> gNB-CU-CP */
MESSAGE_DEF(E1AP_BEARER_CONTEXT_RELEASE_CPLT, MESSAGE_PRIORITY_MED, e1ap_bearer_release_cplt_t, e1ap_bearer_release_cplt)
......@@ -44,12 +44,14 @@
#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
#define E1AP_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_fail
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
#define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp
#define E1AP_BEARER_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cmd
#define E1AP_BEARER_CONTEXT_RELEASE_CPLT(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cplt
#define E1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.e1ap_lost_connection
typedef net_ip_address_t e1ap_net_ip_address_t;
......@@ -94,6 +96,11 @@ typedef struct e1ap_setup_resp_s {
long transac_id;
} e1ap_setup_resp_t;
/* E1AP Setup Failure */
typedef struct e1ap_setup_fail_s {
long transac_id;
} e1ap_setup_fail_t;
typedef struct cell_group_s {
long id;
} cell_group_t;
......@@ -273,4 +280,10 @@ typedef struct e1ap_bearer_modif_resp_s {
pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
} e1ap_bearer_modif_resp_t;
/* E1AP Connection Loss indication */
typedef struct e1ap_lost_connection_t {
int dummy;
} e1ap_lost_connection_t;
#endif /* E1AP_MESSAGES_TYPES_H */
This diff is collapsed.
......@@ -148,7 +148,7 @@ void *gNB_app_task(void *args_p)
AssertFatal(false, "Create task for E1AP CP failed\n");
E1_t e1type = CPtype;
MessageDef *msg = RCconfig_NR_CU_E1(&e1type);
AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n");
AssertFatal(msg != NULL, "Send ITTI to task for E1AP CP failed\n");
// this sends the E1AP_REGISTER_REQ to CU-CP so it sets up the socket
// it does NOT use the E1AP part
itti_send_msg_to_task(TASK_CUCP_E1, 0, msg);
......
......@@ -2607,20 +2607,23 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
}
// Table 5.1.2.2.1-1 38.214
uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) {
AssertFatal(bwp_size < 276,"Invalid BWP Size > 275\n");
if (bwp_size < 37) return (rbg_size_config ? 4 : 2);
if (bwp_size < 73) return (rbg_size_config ? 8 : 4);
if (bwp_size < 145) return (rbg_size_config ? 16 : 8);
else return 16;
uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config)
{
AssertFatal(bwp_size < 276, "Invalid BWP Size %d\n", bwp_size);
if (bwp_size < 37)
return (rbg_size_config ? 4 : 2);
if (bwp_size < 73)
return (rbg_size_config ? 8 : 4);
if (bwp_size < 145)
return (rbg_size_config ? 16 : 8);
else
return 16;
}
uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) {
uint8_t rbg_size = getRBGSize(bwp_size,rbg_size_config);
return (uint8_t)ceil((float)(bwp_size+(bwp_start % rbg_size))/(float)rbg_size);
uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config)
{
uint8_t rbg_size = getRBGSize(bwp_size, rbg_size_config);
return (uint8_t)ceil((float)(bwp_size + (bwp_start % rbg_size)) / (float)rbg_size);
}
uint8_t getAntPortBitWidth(NR_SetupRelease_DMRS_DownlinkConfig_t *typeA, NR_SetupRelease_DMRS_DownlinkConfig_t *typeB) {
......
......@@ -109,6 +109,8 @@ NR_tda_info_t get_dl_tda_info(const NR_UE_DL_BWP_t *dl_BWP,
int coresetid,
bool sib1);
uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config);
uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
const NR_UE_UL_BWP_t *UL_BWP,
const NR_UE_ServingCell_Info_t *sc_info,
......
......@@ -669,29 +669,29 @@ void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long chan
}
}
static uint16_t nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration)
static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
{
switch (bucketsizeduration) {
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5:
return 5;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms10:
return 10;
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms20:
return 20;
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;
AssertFatal(false, "Invalid bucketSizeDuration %ld\n", bucketsizeduration);
}
}
......@@ -724,9 +724,9 @@ void nr_configure_mac_config_logicalChannelBearer(module_id_t module_id,
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)
static void configure_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_torelease_list) {
......@@ -1956,6 +1956,10 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
}
}
configure_logicalChannelBearer(module_id,
cell_group_config->rlc_BearerToAddModList,
cell_group_config->rlc_BearerToReleaseList);
// Setup the SSB to Rach Occasions mapping according to the config
// Only if RACH is configured for current BWP
if (mac->current_UL_BWP->rach_ConfigCommon)
......@@ -1963,6 +1967,4 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
if (!mac->dl_config_request || !mac->ul_config_request)
ue_init_config_request(mac, mac->current_DL_BWP->scs);
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cell_group_config);
}
......@@ -450,7 +450,7 @@ typedef struct {
} NR_BWP_PDCCH_t;
/*!\brief Top level UE MAC structure */
typedef struct {
typedef struct NR_UE_MAC_INST_s {
module_id_t ue_id;
NR_UE_L2_STATE_t state;
int servCellIndex;
......
......@@ -177,10 +177,6 @@ void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index);
void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index);
void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long channel_identity);
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_cg(module_id_t module_id,
int cc_idP,
NR_CellGroupConfig_t *cell_group_config);
......@@ -215,26 +211,6 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac);
void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info);
void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info);
/**\brief fill nr_scheduled_response struct instance
@param nr_scheduled_response_t * pointer to scheduled_response instance to fill
@param fapi_nr_dl_config_request_t* pointer to dl_config,
@param fapi_nr_ul_config_request_t* pointer to ul_config,
@param fapi_nr_tx_request_t* pointer to tx_request;
@param module_id_t mod_id module ID
@param int cc_id CC ID
@param frame_t frame frame number
@param int slot reference number
@param void *phy_pata pointer to a PHY specific structure to be filled in the scheduler response (can be null) */
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
fapi_nr_dl_config_request_t *dl_config,
fapi_nr_ul_config_request_t *ul_config,
fapi_nr_tx_request_t *tx_request,
module_id_t mod_id,
int cc_id,
frame_t frame,
int slot,
void *phy_data);
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and
DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and
......@@ -379,8 +355,6 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size);
void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
......@@ -402,7 +376,7 @@ int get_deltatf(uint16_t nb_of_prbs,
int N_sc_ctrl_RB,
int O_UCI);
void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int slot,
uint16_t rnti,
PUCCH_sched_t *pucch,
......@@ -489,24 +463,28 @@ void nr_Msg1_transmitted(module_id_t mod_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void nr_get_msg3_payload(module_id_t mod_id, uint8_t *buf, int TBS_max);
void send_msg3_rrc_request(module_id_t mod_id, int rnti);
void nr_ue_msg2_scheduler(module_id_t mod_id, uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot);
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
NR_PDSCH_Config_t *pdsch_Config,
uint16_t n_RB_ULBWP,
uint16_t n_RB_DLBWP,
uint16_t riv);
int start_DLBWP,
dci_field_t frequency_domain_assignment);
void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs);
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time);
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu);
fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx);
void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
......@@ -516,7 +494,13 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// - in which ULSCH should be scheduled. K2 is configured in RRC configuration.
// PUSCH Msg3 scheduler:
// - scheduled by RAR UL grant according to 8.3 of TS 38.213
int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t current_frame, int current_slot, frame_t *frame_tx, int *slot_tx, long k2);
int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
const uint8_t is_Msg3,
const frame_t current_frame,
const int current_slot,
frame_t *frame_tx,
int *slot_tx,
const long k2);
int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti);
......
......@@ -53,12 +53,6 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data
itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, message_p);
}
void send_msg3_rrc_request(module_id_t mod_id, int rnti)
{
nr_rlc_activate_srb0(mod_id, NULL, send_srb0_rrc);
nr_mac_rrc_msg3_ind(mod_id, rnti);
}
void nr_ue_init_mac(module_id_t module_idP)
{
LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP);
......@@ -129,6 +123,10 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
int rc = rlc_module_init(0);
AssertFatal(rc == 0, "Could not initialize RLC layer\n");
for (int j = 0; j < nb_inst; j++) {
nr_rlc_activate_srb0(j, NULL, send_srb0_rrc);
}
return (nr_ue_mac_inst);
}
......
......@@ -949,19 +949,12 @@ 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;
PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE,
.N_CCE = current_harq->N_CCE,
.delta_pucch = current_harq->delta_pucch,
.ack_payload = ack_nack,
.n_harq = 1};
current_harq->active = false;
current_harq->ack_received = false;
if (get_softmodem_params()->emulate_l1) {
......@@ -969,11 +962,11 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
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);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
if (!pdu)
return;
int ret = nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
if (ret != 0)
remove_ul_config_last_item(pdu);
release_ul_config(pdu, false);
}
This diff is collapsed.
......@@ -668,7 +668,8 @@ static void pf_dl(module_id_t module_id,
else
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
sched_pdsch->nrOfLayers = get_dl_nrOfLayers(sched_ctrl, current_BWP->dci_format);
sched_pdsch->pm_index = mac->identity_pm ? 0 : get_pm_index(mac, UE, sched_pdsch->nrOfLayers, mac->radio_config.pdsch_AntennaPorts.XP);
sched_pdsch->pm_index =
get_pm_index(mac, UE, current_BWP->dci_format, sched_pdsch->nrOfLayers, mac->radio_config.pdsch_AntennaPorts.XP);
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx);
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx);
uint32_t tbs = nr_compute_tbs(Qm,
......
......@@ -131,19 +131,19 @@ uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl,
uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
const NR_UE_info_t *UE,
nr_dci_format_t dci_format,
int layers,
int xp_pdsch_antenna_ports)
{
if (dci_format == NR_DL_DCI_FORMAT_1_0 || nrmac->identity_pm || xp_pdsch_antenna_ports == 1)
return 0; //identity matrix (basic 5G configuration handled by PMI report is with XP antennas)
const NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id;
const nr_csi_report_t *csi_report = &UE->csi_report_template[report_id];
const int N1 = csi_report->N1;
const int N2 = csi_report->N2;
const int antenna_ports = (N1 * N2) << 1;
if (xp_pdsch_antenna_ports == 1)
return 0; //identity matrix (basic 5G configuration handled by PMI report is with XP antennas)
const int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1;
const int x2 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2;
LOG_D(NR_MAC,"PMI report: x1 %d x2 %d layers: %d\n", x1, x2, layers);
......
......@@ -1268,6 +1268,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
curr_pucch->csi_bits + curr_pucch->dai_c + 2,
curr_pucch->resource_indicator))
continue;
// TODO temporarily limit ack/nak to 3 bits because of performances of polar for PUCCH (required for > 11 bits)
if (curr_pucch->csi_bits > 0 && curr_pucch->dai_c >= 3)
continue;
// otherwise we can schedule in this active PUCCH
// no need to check VRB occupation because already done when PUCCH has been activated
......
......@@ -379,6 +379,7 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
const NR_UE_info_t *UE,
nr_dci_format_t dci_format,
int layers,
int xp_pdsch_antenna_ports);
......
This diff is collapsed.
......@@ -58,22 +58,6 @@ typedef struct {
/// slot
int slot;
fapi_nr_dl_config_request_t dl_config_req;
fapi_nr_ul_config_request_t ul_config_req;
} nr_dcireq_t;
typedef struct {
/// module id
module_id_t module_id;
/// gNB index
uint32_t gNB_index;
/// component carrier id
int cc_id;
/// frame
frame_t frame;
/// slot
int slot;
/// NR UE FAPI-like P7 message, direction: L1 to L2
/// data reception indication structure
fapi_nr_rx_indication_t *rx_ind;
......@@ -95,14 +79,10 @@ typedef struct {
uint32_t gNB_index;
/// component carrier id
int cc_id;
/// frame
frame_t frame_rx;
/// slot rx
uint32_t slot_rx;
/// frame tx
frame_t frame_tx;
frame_t frame;
/// slot tx
uint32_t slot_tx;
uint32_t slot;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
......@@ -142,17 +122,13 @@ typedef struct {
// Downlink subframe P7
struct PHY_VARS_NR_UE_s;
struct NR_UE_MAC_INST_s;
typedef struct {
/// module id
module_id_t module_id;
/// component carrier id
int CC_id;
/// frame
frame_t frame;
/// slot
int slot;
/// NR UE FAPI-like P7 message, direction: L2 to L1
/// downlink transmission configuration request structure
fapi_nr_dl_config_request_t *dl_config;
......@@ -166,12 +142,10 @@ typedef struct {
// Sidelink TX configuration request
sl_nr_tx_config_request_t *sl_tx_config;
/// data transmission request structure
fapi_nr_tx_request_t *tx_request;
/// PHY data structure initially passed on to L2 via the nr_downlink_indication_t and
/// returned to L1 via nr_scheduled_response_t
void *phy_data;
struct NR_UE_MAC_INST_s *mac;
} nr_scheduled_response_t;
typedef struct {
......@@ -322,46 +296,11 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
bool sfn_slot_matcher(void *wanted, void *candidate);
/**\brief done free of memory allocation by module_id and release to pointer pool.
\param module_id module id*/
int nr_ue_if_module_kill(uint32_t module_id);
/**\brief interface between L1/L2, indicating the downlink related information, like dci_ind and rx_req
\param dl_info including dci_ind and rx_request messages*/
int nr_ue_dl_indication(nr_downlink_indication_t *dl_info);
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info);
int nr_ue_dcireq(nr_dcireq_t *dcireq);
// TODO check
/**\brief handle BCCH-BCH message from dl_indication
\param phy_data PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
\param pduP pointer to bch pdu
\param additional_bits corresponding to 38.212 ch.7
\param ssb_index SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
\param ssb_length corresponding to L1 parameter L_ssb
\param cell_id cell id */
int handle_bcch_bch(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
void *phy_data,
uint8_t *pduP,
unsigned int additional_bits,
uint32_t ssb_index,
uint32_t ssb_length,
uint16_t ssb_start_subcarrier,
uint16_t cell_id);
// TODO check
/**\brief handle BCCH-DL-SCH message from dl_indication
\param pdu_len length(bytes) of pdu
\param pduP pointer to pdu*/
int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len);
int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
#endif
......@@ -72,8 +72,7 @@ typedef struct {
extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
extern nr_bler_struct nr_mimo_bler_data[NR_NUM_MCS];
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdu, int sf, int index);
float get_bler_val(uint8_t mcs, int sinr);
bool should_drop_transport_block(int slot, uint16_t rnti);
bool is_channel_modeling(void);
......
......@@ -129,6 +129,9 @@ sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_
sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd);
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req);
/* Process indication of E1 connection loss on CU-CP */
void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id);
void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
instance_t instance);
......
......@@ -2065,6 +2065,9 @@ static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi,
return NULL;
}
/**
* @brief E1AP Bearer Context Setup Response processing on CU-CP
*/
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
......@@ -2172,6 +2175,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req);
}
/**
* @brief E1AP Bearer Context Modification Response processing on CU-CP
*/
void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t *resp)
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
......@@ -2188,6 +2194,9 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
}
}
/**
* @brief E1AP Bearer Context Release processing
*/
void rrc_gNB_process_e1_bearer_context_release_cplt(const e1ap_bearer_release_cplt_t *cplt)
{
// there is not really anything to do here as of now
......@@ -2467,6 +2476,10 @@ void *rrc_gnb_task(void *args_p) {
rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p));
break;
case E1AP_LOST_CONNECTION: /* CUCP */
rrc_gNB_process_e1_lost_connection(RC.nrrrc[0], &E1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance);
break;
case NGAP_PAGING_IND:
rrc_gNB_process_PAGING_IND(msg_p, instance);
break;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -33,7 +33,7 @@
#ifndef _RRC_PROTO_H_
#define _RRC_PROTO_H_
#include "oai_asn1.h"
#include "rrc_defs.h"
#include "NR_RRCReconfiguration.h"
#include "NR_MeasConfig.h"
......@@ -108,6 +108,7 @@ extern void start_oai_nrue_threads(void);
int get_from_lte_ue_fd();
void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo);
void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo);
void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id);
void handle_t300_expiry(NR_UE_RRC_INST_t *rrc);
......@@ -115,9 +116,8 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc);
void reset_rlf_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void set_default_timers_and_constants(NR_UE_Timers_Constants_t *tac);
void nr_rrc_set_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1);
void nr_rrc_set_T304(NR_UE_Timers_Constants_t *tac, NR_ReconfigurationWithSync_t *reconfigurationWithSync);
void handle_rlf_sync(NR_UE_Timers_Constants_t *tac,
nr_sync_msg_t sync_msg);
int nr_rrc_get_T304(long t304);
void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, nr_sync_msg_t sync_msg);
void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc,
struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants);
......
......@@ -48,7 +48,6 @@
#include "intertask_interface.h"
#include "openair2/RRC/NAS/nas_config.h"
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
#include <openair1/PHY/phy_extern_nr_ue.h>
#include <openair1/SIMULATION/ETH_TRANSPORT/proto.h>
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
#include "openair3/SECU/nas_stream_eia2.h"
......
......@@ -194,7 +194,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 80;
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
# dl_bler_target_upper=.35;
# dl_bler_target_lower=.15;
......
......@@ -193,7 +193,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 100;
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 230;
dl_bler_target_upper=.35;
dl_bler_target_lower=.15;
......@@ -235,12 +235,8 @@ RUs = (
sl_ahead = 10;
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000,0x00007fff, 0x0000];
#clock_src = "internal";
sdr_addrs = "dummy --usecasefile /home/eurecom/raymond/usecase_du_3450_4ant.cfg --num_eth_vfs 2 --vf_addr_o_xu_a \"0000:31:06.0,0000:31:06.1\""
clock_src = "internal";
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
......
......@@ -193,7 +193,7 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
# dl_bler_target_upper=.35;
# dl_bler_target_lower=.15;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment