From d236d92a3abdcbaf9229bf91dd4be0092bd448b5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 May 2023 15:50:32 +0200 Subject: [PATCH 01/39] Add SRBID to Release Command and encode/decode for F1AP --- openair2/COMMON/f1ap_messages_types.h | 1 + openair2/F1AP/f1ap_cu_ue_context_management.c | 7 +++++++ openair2/F1AP/f1ap_du_ue_context_management.c | 12 ++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 9d507df8f3..6850c784b5 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -425,6 +425,7 @@ typedef struct f1ap_ue_context_release_s { long cause_value; uint8_t *rrc_container; int rrc_container_length; + int srb_id; } f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cplt_t; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index bfa48a4f88..61bd6e7ff5 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -900,6 +900,13 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, cmd->rrc_container_length); + + // conditionally have SRBID if RRC Container + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_SRBID; + ie5->criticality = F1AP_Criticality_ignore; + ie5->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_SRBID; + ie5->value.choice.SRBID = cmd->srb_id; } /* encode */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 4c119dd8ad..6f7a72b741 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -680,8 +680,16 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false); - f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); - memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + if (ie != NULL) { + f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); + AssertFatal(f1ap_ue_context_release_cmd->rrc_container != NULL, "out of memory\n"); + memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + f1ap_ue_context_release_cmd->rrc_container_length = ie->value.choice.RRCContainer.size; + + // conditionally have SRB ID if there is RRC container + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true); + f1ap_ue_context_release_cmd->srb_id = ie->value.choice.SRBID; + } F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); From 8bffe28ed3c22f1673916fc59cfaba746ba1cdb5 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Fri, 19 May 2023 12:26:13 +0100 Subject: [PATCH 02/39] Set kernel parameters for X4x0 --- radio/USRP/USERSPACE/LIB/usrp_lib.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp index 8053411516..6a5bbe811e 100644 --- a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1127,6 +1127,10 @@ extern "C" { device->type = USRP_X400_DEV; usrp_master_clock = 245.76e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + + // https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks + if (0 != system("sysctl -w net.core.rmem_max=62500000 net.core.wmem_max=62500000")) + LOG_W(HW, "Can't set kernel parameters for X4x0\n"); } s->usrp = uhd::usrp::multi_usrp::make(args); From 7afedd21f537590d199c28ed38123e53770bdd9f Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 3 May 2023 17:14:20 +0200 Subject: [PATCH 03/39] CI: Pull cluster image - modif of OC project selection --- ci-scripts/cls_cluster.py | 5 +++-- ci-scripts/cls_containerize.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index 648d132b9e..aef6da8a38 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -199,9 +199,10 @@ class Cluster: HELP.EPCSrvHelp(self.imageToPull) sys.exit('Insufficient eNB Parameters') lIpAddr = self.eNBIPAddress + ocProjectName = NAMESPACE self.testCase_id = HTML.testCase_id cmd = cls_cmd.getConnection(lIpAddr) - succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, self.OCProjectName) + succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, ocProjectName) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) @@ -214,7 +215,7 @@ class Cluster: HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) return False for image in self.imageToPull: - imagePrefix = f'{self.OCRegistry}{self.OCProjectName}' + imagePrefix = f'{self.OCRegistry}{ocProjectName}' imageTag = cls_containerize.ImageTagToUse(image, self.ranCommitID, self.ranBranch, self.ranAllowMerge) ret = cmd.run(f'docker pull {imagePrefix}/{imageTag}') if ret.returncode != 0: diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 8c684a62d8..6b5e4e50af 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -800,7 +800,7 @@ class Containerize(): logging.debug('Removing test images locally') myCmd = cls_cmd.LocalCmd() - imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup'] + imageNames = ['oai-enb', 'oai-gnb', 'oai-lte-ue', 'oai-nr-ue', 'oai-lte-ru', 'oai-nr-cuup', 'oai-gnb-aw2s'] for image in imageNames: imageTag = ImageTagToUse(image, self.ranCommitID, self.ranBranch, self.ranAllowMerge) cmd = f'docker rmi oai-ci/{imageTag}' From d237e43f6cf5b6834735e6841677c59ad2e97204 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 3 May 2023 17:47:38 +0200 Subject: [PATCH 04/39] CI: AW2S pipeline - iperf test added - IPERF3 option created in cls_oaicitest.py - retrieval of CN amf and traffic-server IP address from pods - modification of gNB config file (do_SRS set, max UL MCS increased), removal of unused config file - change of AmariUE config file to support 2x2 - modification of xml file for aw2s pipeline - iperf test added - new xml file for cleanup (terminate AmariUE, clean test server images) created --- ci-scripts/ci_ueinfra.yaml | 2 +- ci-scripts/cls_oaicitest.py | 46 ++++++++++++- ...nf => gnb.sa.band78.51prb.aw2s.dddsu.conf} | 8 +-- .../xml_files/container_sa_aw2s_asue.xml | 64 ++++++++++++++++--- .../container_sa_aw2s_asue_cleanup.xml | 46 +++++++++++++ .../yaml_files/sa_aw2s_gnb/docker-compose.yml | 2 +- 6 files changed, 151 insertions(+), 17 deletions(-) rename ci-scripts/conf_files/{gnb.sa.band78.51prb.aw2s.ddsuu.conf => gnb.sa.band78.51prb.aw2s.dddsu.conf} (99%) create mode 100644 ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index 52049f58c1..cb6f500628 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -49,7 +49,7 @@ adb_ue_2: amarisoft_ue: Host: amariue - InitScript: /root/NV18-06-2022/lteue-linux-2023-03-17/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-20897.cfg & + InitScript: /root/NV18-06-2022/lteue-linux-2023-03-17/lteue /root/oaicicd/ran_sa_aw2s_asue/aw2s-multi-20897-2x2.cfg & TermScript: /root/NV18-06-2022/lteue-linux-2023-03-17/doc/ws.js 127.0.0.1:9002 '{"message":"quit"}' amarisoft_ue_1: Host: amariue diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 623fc928c0..e97a1dd18e 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -49,6 +49,7 @@ import concurrent.futures #import our libs import helpreadme as HELP import constants as CONST +import cls_cluster as OC import sshconnection import cls_module_ue @@ -58,6 +59,7 @@ logging.getLogger("matplotlib").setLevel(logging.WARNING) import matplotlib.pyplot as plt import numpy as np +OC_CN_PROJECT = "oaicicd-core-for-ci-ran" #----------------------------------------------------------- # OaiCiTest Class Definition #----------------------------------------------------------- @@ -231,7 +233,6 @@ class OaiCiTest(): [f.result() for f in futures] HTML.CreateHtmlTestRowQueue('N/A', 'OK', messages) - def InitializeOAIUE(self,HTML,RAN,EPC,CONTAINERS): if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -995,7 +996,9 @@ class OaiCiTest(): cn_target_ip = result.group('trf_ip_addr') SSH.close() cn_iperf_prefix = "docker exec prod-trf-gen" # -w /iperf-2.0.13 necessary? - else: # ltebox, sabox + if (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): + cn_target_ip = EPC.IperfSrvIPAddress + else: # lteboix, sabox cn_target_ip = "192.172.0.1" cn_iperf_prefix = "" @@ -1077,6 +1080,26 @@ class OaiCiTest(): self.Iperf_analyzeV2BIDIR(lock, ue.getHost(), ue.getName(), statusQueue, server_filename, client_filename) + elif self.iperf_direction == "IPERF3": + logging.debug("Iperf3 requested") + + cmd = cls_cmd.getConnection(ue.getHost()) + cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False) + port = f'-p {5002+idx}' + cmd.run(f'{ue.getCmdPrefix()} iperf3 -c {cn_target_ip} {port} {iperf_opt} &> /tmp/{server_filename}', timeout=iperf_time*1.5) + cmd.close() + time.sleep(1) + cmd = cls_cmd.getConnection(ue.getHost()) + cmd.copyin(f'/tmp/{server_filename}', server_filename) + cmd.close() + + if udpIperf: + self.Iperf_analyzeV2Server(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, server_filename, 1) + else: + cmd = cls_cmd.getConnection(EPC.IPAddress) + self.Iperf_analyzeV2TCPOutput(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, EPC, cmd, f'/tmp/{server_filename}') + cmd.close() + else : raise Exception("Incorrect or missing IPERF direction in XML") @@ -1216,6 +1239,25 @@ class OaiCiTest(): #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) #if result is not None: # dummyIperfVersion = '2.0.10' + if (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): + lOcProject = OC_CN_PROJECT + mySSH = cls_cmd.getConnection(EPC.IPAddress) + succeeded = OC.OC_login(mySSH, EPC.OCUserName, EPC.OCPassword, lOcProject) + if not succeeded: + logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) + HTML.CreateHtmlTabFooter(False) + return False + ret = mySSH.run('oc describe pod oai-traffic-server | grep -w "ips" -A 1 | tail -n 1 | awk \'{{print $1}}\' | sed \'s/"//g\'') + EPC.IperfSrvIPAddress = ret.stdout + if not EPC.IperfSrvIPAddress: + logging.debug('IP address of oai-traffic-server not found!') + OC.OC_logout(mySSH) + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) + HTML.CreateHtmlTabFooter(False) + raise Exception("could not obtain oai-traffic-server IP address") + return Fals + OC.OC_logout(mySSH) multi_jobs = [] ue_num = len(ues) diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf similarity index 99% rename from ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf rename to ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf index 73ea955f63..c8c2643e50 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf @@ -24,7 +24,7 @@ gNBs = pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; - do_SRS = 0; + do_SRS = 1; pdcch_ConfigSIB1 = ( { @@ -152,9 +152,9 @@ gNBs = # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 2; + nrofDownlinkSlots = 3; nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; + nrofUplinkSlots = 1; nrofUplinkSymbols = 4; ssPBCH_BlockPower = -10; @@ -200,7 +200,7 @@ MACRLCs = ( pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; ulsch_max_frame_inactivity = 10; - ul_max_mcs = 15; + ul_max_mcs = 28; } ); diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 7d1709d53f..f4cc56933e 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -30,8 +30,14 @@ 001000 020000 002000 + 002001 002002 + 002003 + 002004 + 002005 000100 + 000010 + 000020 000200 003000 004000 @@ -43,6 +49,7 @@ Pull_Cluster_Image Pull Images from Cluster + oaicicd-ran oai-gnb-aw2s @@ -60,7 +67,7 @@ amarisoft_ue - + Attach_UE Attach UE amarisoft_ue_1 @@ -72,28 +79,68 @@ amarisoft_ue_2 + + Attach_UE + Attach UE + amarisoft_ue_3 + + + + Attach_UE + Attach UE + amarisoft_ue_4 + + + + Attach_UE + Attach UE + amarisoft_ue_5 + + + + Iperf + iperf (DL/30Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 90M -t 30 -i 1 -R + IPERF3 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 + 25 + 80 + balanced + + + + Iperf + iperf (UL/5Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 15M -t 30 -i 1 + IPERF3 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 + 25 + 80 + balanced + + Ping - Ping: 20pings in 20sec - amarisoft_ue_1 amarisoft_ue_2 + Ping: 20pings in 20sec, multi-ue + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 -c 20 1 - 15 + 25 Ping - Ping: 100pings in 20sec - amarisoft_ue_1 amarisoft_ue_2 + Ping: 100pings in 20sec, multi-ue + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 -c 100 -i 0.2 1 - 15 + 30 Detach_UE Detach UE - amarisoft_ue_1 amarisoft_ue_2 + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 @@ -119,4 +166,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml new file mode 100644 index 0000000000..8c8daf9e04 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml @@ -0,0 +1,46 @@ + + + test-aw2s-cleanup + CleanUp AW2S ASUE + trash + + 111111 + 222222 + + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + + + Terminate_UE + Terminate UE + amarisoft_ue + + + + diff --git a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml index 7468df5e62..f2747098c2 100644 --- a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml @@ -10,7 +10,7 @@ services: USE_VOLUMED_CONF: 'yes' USE_ADDITIONAL_OPTIONS: --sa volumes: - - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf:/opt/oai-gnb-aw2s/etc/mounted.conf + - ../../conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf:/opt/oai-gnb-aw2s/etc/mounted.conf healthcheck: test: /bin/bash -c "pgrep nr-softmodem" interval: 10s From d5b78067283d9075e3233cbefca56b6799c5b155 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 3 May 2023 17:59:16 +0200 Subject: [PATCH 05/39] CI: AW2S pipeline - CN deployment on OC - CN path, OC project changed --- ci-scripts/epc.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index f3f23f198c..534485fb3b 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -240,9 +240,9 @@ class EPCManagement(): HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) def Initialize5GCN(self, HTML): - if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '': + if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.Type == '': HELP.GenericHelp(CONST.Version) - HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type) + HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.Type) sys.exit('Insufficient EPC Parameters') mySSH = cls_cmd.getConnection(self.IPAddress) html_cell = '' @@ -299,8 +299,9 @@ class EPCManagement(): imageNames = ["oai-nrf", "oai-amf", "oai-smf", "oai-spgwu-tiny", "oai-ausf", "oai-udm", "oai-udr", "mysql","oai-traffic-server"] logging.debug('Deploying OAI CN5G on Openshift Cluster') lIpAddr = self.IPAddress - lSourcePath = self.SourceCodePath - succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, self.OCProjectName) + lOcProject = 'oaicicd-core-for-ci-ran' + lSourcePath = "/opt/oai-cn5g-fed-develop-2023-04-28-20897" + succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, lOcProject) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) @@ -595,11 +596,12 @@ class EPCManagement(): elif re.match('OC-OAI-CN5G', self.Type, re.IGNORECASE): logging.debug('Terminating OAI CN5G on Openshift Cluster') lIpAddr = self.IPAddress + lOcProject = 'oaicicd-core-for-ci-ran' lSourcePath = self.SourceCodePath mySSH.run(f'rm -Rf {lSourcePath}/logs') mySSH.run(f'mkdir -p {lSourcePath}/logs') logging.debug('OC OAI CN5G - Collecting Log files to workspace') - succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, self.OCProjectName) + succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, lOcProject) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) @@ -618,7 +620,7 @@ class EPCManagement(): mySSH.run(f'cd {lSourcePath}/logs && zip -r -qq test_logs_CN.zip *.log') mySSH.copyin(f'{lSourcePath}/logs/test_logs_CN.zip','test_logs_CN.zip') ret = mySSH.run(f'oc get pods', silent=True) - res = re.search('No resources found in oaicicd-ran namespace.', ret.stdout) + res = re.search(f'No resources found in {lOcProject} namespace.', ret.stdout) if res is not None: logging.debug('OC OAI CN5G components uninstalled') message = 'OC OAI CN5G components uninstalled' From 3daeb91a390a67b5824a7eefd51e053996200154 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Thu, 18 May 2023 00:55:07 +0200 Subject: [PATCH 06/39] Constants for CI OC RAN and CN namespace created - CI_OC_RAN_NAMESPACE for RAN images - CI_OC_CORE_NAMESPACE for CN deployment - usage of the created constants for pulling images from cluster, CN deployement, iperf/ping --- ci-scripts/cls_cluster.py | 13 ++++++------- ci-scripts/cls_oaicitest.py | 10 +--------- ci-scripts/epc.py | 9 +++------ 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index aef6da8a38..b075ea3a1c 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -42,7 +42,8 @@ IMAGE_REGISTRY_SERVICE_NAME = "image-registry.openshift-image-registry.svc" NAMESPACE = "oaicicd-ran" OCUrl = "https://api.oai.cs.eurecom.fr:6443" OCRegistry = "default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/" - +CI_OC_RAN_NAMESPACE = "oaicicd-ran" +CI_OC_CORE_NAMESPACE = "oaicicd-core-for-ci-ran" def OC_login(cmd, ocUserName, ocPassword, ocProjectName): if ocUserName == '' or ocPassword == '' or ocProjectName == '': @@ -198,24 +199,22 @@ class Cluster: HELP.GenericHelp(CONST.Version) HELP.EPCSrvHelp(self.imageToPull) sys.exit('Insufficient eNB Parameters') - lIpAddr = self.eNBIPAddress - ocProjectName = NAMESPACE self.testCase_id = HTML.testCase_id - cmd = cls_cmd.getConnection(lIpAddr) - succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, ocProjectName) + cmd = cls_cmd.getConnection(self.eNBIPAddress) + succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, CI_OC_RAN_NAMESPACE) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) return False ret = cmd.run(f'oc whoami -t | docker login -u oaicicd --password-stdin {self.OCRegistry}') if ret.returncode != 0: - logging.error(f'\u001B[1m Unable to access OC project {ocProjectName}\u001B[0m') + logging.error(f'\u001B[1m Unable to access OC project {CI_OC_RAN_NAMESPACE}\u001B[0m') OC_logout(cmd) cmd.close() HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) return False for image in self.imageToPull: - imagePrefix = f'{self.OCRegistry}{ocProjectName}' + imagePrefix = f'{self.OCRegistry}{CI_OC_RAN_NAMESPACE}' imageTag = cls_containerize.ImageTagToUse(image, self.ranCommitID, self.ranBranch, self.ranAllowMerge) ret = cmd.run(f'docker pull {imagePrefix}/{imageTag}') if ret.returncode != 0: diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index e97a1dd18e..deba23b36c 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -59,7 +59,6 @@ logging.getLogger("matplotlib").setLevel(logging.WARNING) import matplotlib.pyplot as plt import numpy as np -OC_CN_PROJECT = "oaicicd-core-for-ci-ran" #----------------------------------------------------------- # OaiCiTest Class Definition #----------------------------------------------------------- @@ -1081,18 +1080,12 @@ class OaiCiTest(): self.Iperf_analyzeV2BIDIR(lock, ue.getHost(), ue.getName(), statusQueue, server_filename, client_filename) elif self.iperf_direction == "IPERF3": - logging.debug("Iperf3 requested") - cmd = cls_cmd.getConnection(ue.getHost()) cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False) port = f'-p {5002+idx}' cmd.run(f'{ue.getCmdPrefix()} iperf3 -c {cn_target_ip} {port} {iperf_opt} &> /tmp/{server_filename}', timeout=iperf_time*1.5) - cmd.close() - time.sleep(1) - cmd = cls_cmd.getConnection(ue.getHost()) cmd.copyin(f'/tmp/{server_filename}', server_filename) cmd.close() - if udpIperf: self.Iperf_analyzeV2Server(lock, ue.getIP(), ue.getName(), statusQueue, iperf_opt, server_filename, 1) else: @@ -1240,9 +1233,8 @@ class OaiCiTest(): #if result is not None: # dummyIperfVersion = '2.0.10' if (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): - lOcProject = OC_CN_PROJECT mySSH = cls_cmd.getConnection(EPC.IPAddress) - succeeded = OC.OC_login(mySSH, EPC.OCUserName, EPC.OCPassword, lOcProject) + succeeded = OC.OC_login(mySSH, EPC.OCUserName, EPC.OCPassword, OC.CI_OC_CORE_NAMESPACE) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 534485fb3b..30a9fc87a4 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -75,7 +75,6 @@ class EPCManagement(): self.OCRegistry = "default-route-openshift-image-registry.apps.oai.cs.eurecom.fr/" self.OCUserName = '' self.OCPassword = '' - self.OCProjectName = '' self.imageToPull = '' self.eNBSourceCodePath = '' @@ -299,9 +298,8 @@ class EPCManagement(): imageNames = ["oai-nrf", "oai-amf", "oai-smf", "oai-spgwu-tiny", "oai-ausf", "oai-udm", "oai-udr", "mysql","oai-traffic-server"] logging.debug('Deploying OAI CN5G on Openshift Cluster') lIpAddr = self.IPAddress - lOcProject = 'oaicicd-core-for-ci-ran' lSourcePath = "/opt/oai-cn5g-fed-develop-2023-04-28-20897" - succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, lOcProject) + succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, OC.CI_OC_CORE_NAMESPACE) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) @@ -596,12 +594,11 @@ class EPCManagement(): elif re.match('OC-OAI-CN5G', self.Type, re.IGNORECASE): logging.debug('Terminating OAI CN5G on Openshift Cluster') lIpAddr = self.IPAddress - lOcProject = 'oaicicd-core-for-ci-ran' lSourcePath = self.SourceCodePath mySSH.run(f'rm -Rf {lSourcePath}/logs') mySSH.run(f'mkdir -p {lSourcePath}/logs') logging.debug('OC OAI CN5G - Collecting Log files to workspace') - succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, lOcProject) + succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, OC.CI_OC_CORE_NAMESPACE) if not succeeded: logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) @@ -620,7 +617,7 @@ class EPCManagement(): mySSH.run(f'cd {lSourcePath}/logs && zip -r -qq test_logs_CN.zip *.log') mySSH.copyin(f'{lSourcePath}/logs/test_logs_CN.zip','test_logs_CN.zip') ret = mySSH.run(f'oc get pods', silent=True) - res = re.search(f'No resources found in {lOcProject} namespace.', ret.stdout) + res = re.search(f'No resources found in {OC.CI_OC_CORE_NAMESPACE} namespace.', ret.stdout) if res is not None: logging.debug('OC OAI CN5G components uninstalled') message = 'OC OAI CN5G components uninstalled' From 4911835ea3a78096f9b682232a08b46eb794b04c Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Sun, 21 May 2023 16:48:38 +0200 Subject: [PATCH 07/39] Update of aw2s xml file for iperf test in ddsuu TDD config --- ci-scripts/xml_files/container_sa_aw2s_asue.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index f4cc56933e..7959718eb0 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -99,8 +99,8 @@ Iperf - iperf (DL/30Mbps/UDP)(30 sec)(multi-ue profile) - -u -b 90M -t 30 -i 1 -R + iperf (DL/20Mbps/UDP)(30 sec)(multi-ue profile) + -u -b 60M -t 30 -i 1 -R IPERF3 amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 25 From d72aa770d69ffaca2c077beed5a2923e6be812c8 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Sun, 21 May 2023 16:51:52 +0200 Subject: [PATCH 08/39] aw2s gnb config file, change back to ddsuu config --- ....aw2s.dddsu.conf => gnb.sa.band78.51prb.aw2s.ddsuu.conf} | 6 +++--- ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename ci-scripts/conf_files/{gnb.sa.band78.51prb.aw2s.dddsu.conf => gnb.sa.band78.51prb.aw2s.ddsuu.conf} (99%) diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf similarity index 99% rename from ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf rename to ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf index c8c2643e50..5c37a2a413 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf @@ -24,7 +24,7 @@ gNBs = pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; - do_SRS = 1; + do_SRS = 0; pdcch_ConfigSIB1 = ( { @@ -152,9 +152,9 @@ gNBs = # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 3; + nrofDownlinkSlots = 2; nrofDownlinkSymbols = 6; - nrofUplinkSlots = 1; + nrofUplinkSlots = 2; nrofUplinkSymbols = 4; ssPBCH_BlockPower = -10; diff --git a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml index f2747098c2..7468df5e62 100644 --- a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml @@ -10,7 +10,7 @@ services: USE_VOLUMED_CONF: 'yes' USE_ADDITIONAL_OPTIONS: --sa volumes: - - ../../conf_files/gnb.sa.band78.51prb.aw2s.dddsu.conf:/opt/oai-gnb-aw2s/etc/mounted.conf + - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf:/opt/oai-gnb-aw2s/etc/mounted.conf healthcheck: test: /bin/bash -c "pgrep nr-softmodem" interval: 10s From 4514244f4ac674e0eae969da0b4454ce65066ad6 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Sun, 21 May 2023 16:55:52 +0200 Subject: [PATCH 09/39] Adding OC CN ip addresses for iperf/ping test --- ci-scripts/cls_oaicitest.py | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index deba23b36c..8166c50697 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -996,7 +996,7 @@ class OaiCiTest(): SSH.close() cn_iperf_prefix = "docker exec prod-trf-gen" # -w /iperf-2.0.13 necessary? if (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): - cn_target_ip = EPC.IperfSrvIPAddress + cn_target_ip = "172.21.6.102" else: # lteboix, sabox cn_target_ip = "192.172.0.1" cn_iperf_prefix = "" @@ -1082,8 +1082,8 @@ class OaiCiTest(): elif self.iperf_direction == "IPERF3": cmd = cls_cmd.getConnection(ue.getHost()) cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False) - port = f'-p {5002+idx}' - cmd.run(f'{ue.getCmdPrefix()} iperf3 -c {cn_target_ip} {port} {iperf_opt} &> /tmp/{server_filename}', timeout=iperf_time*1.5) + port = f'{5002+idx}' + cmd.run(f'{ue.getCmdPrefix()} iperf3 -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5) cmd.copyin(f'/tmp/{server_filename}', server_filename) cmd.close() if udpIperf: @@ -1232,25 +1232,6 @@ class OaiCiTest(): #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) #if result is not None: # dummyIperfVersion = '2.0.10' - if (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): - mySSH = cls_cmd.getConnection(EPC.IPAddress) - succeeded = OC.OC_login(mySSH, EPC.OCUserName, EPC.OCPassword, OC.CI_OC_CORE_NAMESPACE) - if not succeeded: - logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') - HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL) - HTML.CreateHtmlTabFooter(False) - return False - ret = mySSH.run('oc describe pod oai-traffic-server | grep -w "ips" -A 1 | tail -n 1 | awk \'{{print $1}}\' | sed \'s/"//g\'') - EPC.IperfSrvIPAddress = ret.stdout - if not EPC.IperfSrvIPAddress: - logging.debug('IP address of oai-traffic-server not found!') - OC.OC_logout(mySSH) - HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) - HTML.CreateHtmlTabFooter(False) - raise Exception("could not obtain oai-traffic-server IP address") - return Fals - OC.OC_logout(mySSH) - multi_jobs = [] ue_num = len(ues) i = 0 From 27f9d6cc60823526c4a166ddf5f0e8857246e184 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Mon, 22 May 2023 15:26:43 +0200 Subject: [PATCH 10/39] fix pdu session release bug --- openair2/RRC/NR/rrc_gNB_radio_bearers.c | 10 ++++++---- openair3/NGAP/ngap_gNB_decoder.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index f7280e209a..9e6e7961d6 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -28,10 +28,12 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create) for (j = 0; j < ue->nb_of_pdusessions; j++) if (id == ue->pduSession[j].param.pdusession_id) break; - if (j == ue->nb_of_pdusessions && create) - ue->nb_of_pdusessions++; - else - return NULL; + if (j == ue->nb_of_pdusessions) { + if (create) + ue->nb_of_pdusessions++; + else + return NULL; + } return ue->pduSession + j; } diff --git a/openair3/NGAP/ngap_gNB_decoder.c b/openair3/NGAP/ngap_gNB_decoder.c index c752ace05d..4ea3f69fec 100644 --- a/openair3/NGAP/ngap_gNB_decoder.c +++ b/openair3/NGAP/ngap_gNB_decoder.c @@ -78,7 +78,7 @@ static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) { case NGAP_ProcedureCode_id_PDUSessionResourceRelease: res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); free(res.buffer); - NGAP_INFO("TODO PDUSESSIONRelease initiating message\n"); + NGAP_INFO("PDUSESSIONRelease initiating message\n"); break; case NGAP_ProcedureCode_id_ErrorIndication: From 9825842e97b5ccb76979f7f755b91b5558f4530e Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 5 May 2023 13:13:09 -0400 Subject: [PATCH 11/39] Adjust samples in time only when valid PBCH is present --- executables/nr-ue.c | 25 ++++++------------- .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 4 +++ .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- openair1/PHY/defs_nr_UE.h | 1 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 18 +++++++------ 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 5860d7c64d..38c3020dc9 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -734,16 +734,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { } } -int computeSamplesShift(PHY_VARS_NR_UE *UE) { - int samples_shift = -(UE->rx_offset>>1); - if (samples_shift != 0) { - LOG_I(NR_PHY,"Adjusting frame in time by %i samples\n", samples_shift); - UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame - UE->max_pos_fil += samples_shift << 15; // reset IIR filter when sample shift is applied - } - return samples_shift; -} - static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { if (fp->numerology_index == 0) return fp->nb_prefix_samples0 + fp->ofdm_symbol_size; @@ -904,14 +894,13 @@ void *UE_thread(void *arg) { int readBlockSize, writeBlockSize; - if (slot_nr<(nb_slot_frame - 1)) { - readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms); - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); - } else { - UE->rx_offset_diff = computeSamplesShift(UE); - readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) - - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff; + readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms); + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); + if (UE->apply_timing_offset && (slot_nr == nb_slot_frame-1)) { + const int sampShift = -(UE->rx_offset>>1); + readBlockSize -= sampShift; + writeBlockSize -= sampShift; + UE->apply_timing_offset = false; } AssertFatal(readBlockSize == diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index feed70b854..3d89464d33 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -94,6 +94,10 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, else ue->rx_offset = diff; + const int sample_shift = -(ue->rx_offset>>1); + // reset IIR filter for next offset calculation + ue->max_pos_fil += sample_shift << 15; + if(abs(diff)<5) count_max_pos_ok ++; else diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 470164817b..1c049acbc6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -284,7 +284,7 @@ void nr_processDLSegment(void* arg) { if (no_iteration_ldpc > dlsch->max_ldpc_iterations) no_iteration_ldpc = dlsch->max_ldpc_iterations; } else { - LOG_I(PHY,"%d.%d CRC NOT OK\n",rdata->proc->frame_rx,rdata->proc->nr_slot_rx); + LOG_D(PHY,"%d.%d CRC NOT OK\n",rdata->proc->frame_rx,rdata->proc->nr_slot_rx); no_iteration_ldpc = dlsch->max_ldpc_iterations + 1; } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index aa8af44199..5a348f4998 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -516,6 +516,7 @@ typedef struct { int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int max_pos_fil; /// Timing offset IIR filter + bool apply_timing_offset; /// Do time sync for current frame int time_sync_cell; /// Timing Advance updates variables diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 8dec02b0a1..5609f7d608 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -352,12 +352,12 @@ void nr_ue_measurement_procedures(uint16_t l, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT); } -static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - int estimateSz, - struct complex16 dl_ch_estimates[][estimateSz], - nr_phy_data_t *phy_data, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { +static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int estimateSz, + struct complex16 dl_ch_estimates[][estimateSz], + nr_phy_data_t *phy_data, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int ret = 0; DevAssert(ue); @@ -420,6 +420,7 @@ static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, } + return ret; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } @@ -929,9 +930,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, if(ssb_index == fp->ssb_index) { LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF); + const int pbchSuccess = nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF); - if (ue->no_timing_correction==0) { + if (ue->no_timing_correction==0 && pbchSuccess == 0) { LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); nr_adjust_synch_ue(fp, ue, @@ -943,6 +944,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, 0, 16384); } + ue->apply_timing_offset = true; } LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); nr_ue_rrc_measurements(ue, proc, rxdataF); From 40f76a8ba1bded21d4bdc03dc086367980859b23 Mon Sep 17 00:00:00 2001 From: Bruno Mongazon-Cazavet Date: Tue, 23 May 2023 15:21:31 +0200 Subject: [PATCH 12/39] handle --disable-stats in rrc gNB --- openair2/RRC/NR/rrc_gNB.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7941d1642b..74ed21b379 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3060,10 +3060,12 @@ void *rrc_gnb_task(void *args_p) { int result; protocol_ctxt_t ctxt = {.module_id = 0, .enb_flag = 1, .instance = 0, .rntiMaybeUEid = 0, .frame = -1, .subframe = -1, .eNB_index = 0, .brOption = false}; - /* timer to write stats to file */ long stats_timer_id = 1; - timer_setup(1, 0, TASK_RRC_GNB, 0, TIMER_PERIODIC, NULL, &stats_timer_id); - + if (!IS_SOFTMODEM_NOSTATS_BIT) { + /* timer to write stats to file */ + timer_setup(1, 0, TASK_RRC_GNB, 0, TIMER_PERIODIC, NULL, &stats_timer_id); + } + itti_mark_task_ready(TASK_RRC_GNB); LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n"); From b08041caa41a358d2840d120b8caaa915c772b15 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Wed, 24 May 2023 09:06:05 +0100 Subject: [PATCH 13/39] Tutorials: update ubuntu iso download link to 22.04.2, update Windows Quectel driver version, remove nokrnmod flag, it is enabled by default --- doc/NR_SA_Tutorial_COTS_UE.md | 4 ++-- doc/NR_SA_Tutorial_OAI_CN5G.md | 2 +- doc/NR_SA_Tutorial_OAI_nrUE.md | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/NR_SA_Tutorial_COTS_UE.md b/doc/NR_SA_Tutorial_COTS_UE.md index 88ca97e863..25997f8f88 100644 --- a/doc/NR_SA_Tutorial_COTS_UE.md +++ b/doc/NR_SA_Tutorial_COTS_UE.md @@ -21,14 +21,14 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.1-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.2-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB - Laptop for UE - Operating System: Microsoft Windows 10 x64 - CPU: 4 cores x86_64 - RAM: 8 GB - - Windows driver for Quectel MUST be equal or higher than version **2.2.4** + - Windows driver for Quectel MUST be equal or higher than version **2.4.6** - [USRP B210](https://www.ettus.com/all-products/ub210-kit/), [USRP N300](https://www.ettus.com/all-products/USRP-N300/) or [USRP X300](https://www.ettus.com/all-products/x300-kit/) - Please identify the network interface(s) on which the USRP is connected and update the gNB configuration file - Quectel RM500Q diff --git a/doc/NR_SA_Tutorial_OAI_CN5G.md b/doc/NR_SA_Tutorial_OAI_CN5G.md index cee4c904cf..8573391b67 100644 --- a/doc/NR_SA_Tutorial_OAI_CN5G.md +++ b/doc/NR_SA_Tutorial_OAI_CN5G.md @@ -21,7 +21,7 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.1-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.2-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB diff --git a/doc/NR_SA_Tutorial_OAI_nrUE.md b/doc/NR_SA_Tutorial_OAI_nrUE.md index f49b57354b..0d0ec23346 100644 --- a/doc/NR_SA_Tutorial_OAI_nrUE.md +++ b/doc/NR_SA_Tutorial_OAI_nrUE.md @@ -21,11 +21,11 @@ In this tutorial we describe how to configure and run a 5G end-to-end setup with Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.1-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.2-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 32 GB - Laptop for UE - - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.1-desktop-amd64.iso) + - Operating System: [Ubuntu 22.04 LTS](https://releases.ubuntu.com/22.04/ubuntu-22.04.2-desktop-amd64.iso) - CPU: 8 cores x86_64 @ 3.5 GHz - RAM: 8 GB - [USRP B210](https://www.ettus.com/all-products/ub210-kit/), [USRP N300](https://www.ettus.com/all-products/USRP-N300/) or [USRP X300](https://www.ettus.com/all-products/x300-kit/) @@ -155,7 +155,7 @@ Run OAI nrUE cd ~/openairinterface5g source oaienv cd cmake_targets/ran_build/build -sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --ue-fo-compensation --sa -E --uicc0.imsi 001010000000001 +sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ue-fo-compensation --sa -E --uicc0.imsi 001010000000001 ``` ## 5.2 Testing OAI nrUE with RFsimulator @@ -168,7 +168,7 @@ Run OAI nrUE with RFsimulator cd ~/openairinterface5g source oaienv cd cmake_targets/ran_build/build -sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --rfsim --sa --uicc0.imsi 001010000000001 +sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --uicc0.imsi 001010000000001 ``` ### 5.2.1 Ping test From 655925ddea836dbb69450070ae474c1b0c8ed22f Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Wed, 24 May 2023 09:30:02 +0100 Subject: [PATCH 14/39] Remove outdated documentation --- doc/README.md | 1 - doc/TESTING_5GSA_setup.md | 230 ------------------------------------ radio/rfsimulator/README.md | 2 +- 3 files changed, 1 insertion(+), 232 deletions(-) delete mode 100644 doc/TESTING_5GSA_setup.md diff --git a/doc/README.md b/doc/README.md index 91101d18ba..6abca52f0b 100644 --- a/doc/README.md +++ b/doc/README.md @@ -36,7 +36,6 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https:// * (5G) Using SDAP and custom DRBs * IF setups and arbitrary frequencies * MIMO -- [How to run a 5G-SA setup](./TESTING_5GSA_setup.md) - [How to run a 5G-NSA setup](./TESTING_GNB_W_COTS_UE.md) - [How to run a 4G setup using L1 simulator](./L1SIM.md) _Note: we recommend the RFsimulator_ - [How to use the L2 simulator](./L2NFAPI.md) diff --git a/doc/TESTING_5GSA_setup.md b/doc/TESTING_5GSA_setup.md deleted file mode 100644 index 736005803d..0000000000 --- a/doc/TESTING_5GSA_setup.md +++ /dev/null @@ -1,230 +0,0 @@ - - - - - -
- - - - - - OAI 5G SA tutorial -
- -**Table of Contents** - -[[_TOC_]] - -In the following tutorial we describe how to deploy configure and test the two SA OAI setups: - - - SA setup with OAI gNB and COTS UE - - SA setup with OAI gNB and OAI UE - -The operating system and hardware requirements to support OAI 5G NR are described [here](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/5g-nr-development-and-setup). - -# 1. SA setup with COTS UE -At the moment of writing this document interoperability with the following COTS UE devices is being tested: - - - [Quectel RM500Q-GL](https://www.quectel.com/product/5g-rm500q-gl/) - - [Simcom SIMCOM8200EA](https://www.simcom.com/product/SIM8200EA_M2.html) - - Huawei Mate 30 Pro - - Oneplus 8 - - Google Pixel 5 - - End-to-end control plane signaling to achieve a 5G SA connection, UE registration and PDU session establishment with the CN, as well as some basic user-plane traffic tests have been validated so far using SIMCOM/Quectel modules and Huawei Mate 30 pro. In terms of interoperability with different 5G Core Networks, so far this setup has been tested with: - - - - [OAI CN](https://openairinterface.org/oai-5g-core-network-project/) - - Nokia SA Box - - [Free CN](https://www.free5gc.org/) - - -## 1.1 gNB build and configuration -To get the code and build the gNB executable: - -### Build gNB -```bash - git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git - git checkout develop - cd openairinterface5g/ - source oaienv - cd cmake_targets/ - ./build_oai -I -w USRP #For OAI first time installation only to install software dependencies - ./build_oai --gNB -w USRP -``` - -A reference configuration file for the **monolithic** gNB is provided [here](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf). - - -In the following, we highlight the fields of the file that have to be configured according to the configuration and interfaces of the Core Network. First, the PLMN section has to be filled with the proper values that match the configuration of the AMF and the UE USIM. -```bash - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 1; - plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) }); -``` -Then, the source and destination IP interfaces for the communication with -the Core Network also need to be set as shown below. - -```bash - ////////// 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 - }; -``` -In the first part (*amf_ip_address*) we specify the IP of the AMF and in the second part (*NETWORK_INTERFACES*) we specify the gNB local interface with AMF (N2 interface) and the UPF (N3 interface). - -**CAUTION:** the `192.168.70.132` AMF IF address is the OAI-CN5G `AMF` Container IP address. You certainly will need to do some networking manipulations for the `gNB` server to be able to see this AMF container. - -Please read [CN5G tutorial for more details](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/README.md). - -### gNB configuration in F1 (CU/DU split mode) - -For the configuration of the gNB in CU and DU blocks, the following sample configuration files are provided for the [CU](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf) and the [DU](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf) entities respectively. These configuration files have to be updated with the IP addresses of the CU and the DU over the F1 interface. For example, in the following section from the DU configuration file, *local_n_address* corresponds to the DU address and *remote_n_address* corresponds to the CU address: - -```bash -MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "f1"; - local_n_if_name = "lo"; - local_n_address = "127.0.0.3"; - remote_n_address = "127.0.0.4"; - local_n_portc = 601; - local_n_portd = 2152; - remote_n_portc = 600; - remote_n_portd = 2152; - - } -); -``` - -At the point of writing this document the control-plane exchanges between the CU and the DU over *F1-C* interface, as well as some IP traffic tests over *F1-U* have been validated using the OAI gNB/nrUE in RFSIMULATOR mode. - -### gNB configuration with F1 and E1 - -Please refer to [E1-design](E1-design) for more information. - -## 1.2 OAI 5G Core Network installation and configuration -The instructions for the installation of OAI CN components (AMF, SMF, NRF, UPF) using `docker-compose` can be found [here](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/README.md). - -## 1.3 Execution of SA scenario - -After having configured the gNB, we can start the individual components in the following sequence: - - - Launch 5G Core Network - - Launch gNB - - Launch COTS UE (disable airplane mode) - -The execution command to start the gNB (in monolithic mode) is the following: -```bash -cd cmake_targets/ran_build/build -sudo ./nr-softmodem -E --sa -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf -``` - -# 2. SA Setup with OAI NR UE Softmodem -The SA setup with OAI UE has been validated with **RFSIMULATOR**. Both control plane and user plane for the successful UE registration and PDU Session establishment has been verified with OAI and Nokia SA Box CNs. - -In the following, we provide the instructions on how to build, configure and execute this SA setup. - -As another option, if you do not want to build anything and instead deploy the OAI RAN (RFSIMULATOR) and Core Network components directly using docker images and docker-compose, please have a look at [this tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/ci-scripts/yaml_files/5g_rfsimulator/README.md). - -### NAS configuration for the OAI UE -The NAS configuration parameters of the OAI UE can be set as input parameters, configuration file or can be hardcoded. More specifically: -- SUCI (*Subscription Concealed Identifier*) -- USIM_API_K and OPc keys -- NSSAI (*Network Slice Assistance Information*) -- DNN (*Data Network Name*) - -Below is a sample configuration file that can be parsed through the execution command ([section 2.3](#23-execution-of-sa-scenario)). - -```bash -uicc0 = { -imsi = "208990000007487"; -key = "fec86ba6eb707ed08905757b1bb44b8f"; -opc= "C42449363BBAD02B66D16BC975D77CC1"; -dnn= "oai"; -nssai_sst=1; -nssai_sd=1; -} -``` - -For interoperability with OAI or other CNs, it should be ensured that the configuration of the aforementioned parameters match the configuration of the corresponding subscribed user at the core network. - - -## 2.1 Build and configuration -To build the gNB and OAI UE executables: - -```bash - cd cmake_targets - # Note: For OAI first time installation please install software dependencies as described in 1.1. - ./build_oai --gNB --nrUE -w SIMU -``` -The gNB configuration can be performed according to what is described in [section 1.1](#11--gnb-build-and-configuration), using the same reference configuration file as with the RF scenario. - -## 2.2 OAI 5G Core Network installation and configuration -The instructions for the installation of OAI CN components (AMF, SMF, NRF, UPF) using `docker-compose` can be found [here](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/README.md). - - -## 2.3 Execution of SA scenario - -The order of starting the different components should be the same as the one described in [section 1.3](#13--execution-of-sa-scenario). - -the gNB can be launched in 2 modes: - -- To launch the gNB in `monolithic` mode: - ```bash - sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa \ - -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf - ``` -- To launch the gNB in `CU/DU split` mode: - - 1. Launch the CU component: - ```bash - sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa \ - -O ../../../ci-scripts/conf_files/gNB_SA_CU.conf - ``` - 2. Launch the DU component: - ```bash - sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa \ - -O ../../../ci-scripts/conf_files/gNB_SA_DU.conf - ``` - -- To launch the OAI UE (valid in `monolithic` gNB and `CU/DU split` gNB): - ```bash -sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 \ - --rfsim --sa -O -``` - -If you get the following error: - -```bash -Assertion (k2 >= ((5))) failed! -In get_k2() /home/mir/workspace/openairinterface5g/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c:147 -Slot offset K2 (2) cannot be less than DURATION_RX_TO_TX (5). K2 set according to min_rxtxtime in config file. -``` - -Add the following parameter (i.e., min_rxtxtime) in the gNB configuration file, just after nr_cellid. - -```bash -nr_cellid = 12345678L; -min_rxtxtime=6; -``` -or --gNBs.[0].min_rxtxtime 6 to the gNB command line - - -The IP address at the execution command of the OAI UE corresponds to the target IP of the gNB host that the RFSIMULATOR at the UE will connect to. In the above example, we assume that the gNB and UE are running on the same host so the specified address (127.0.0.1) is the one of the loopback interface. diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index e3070538da..357e70e5a6 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -136,7 +136,7 @@ Notes: * `scp usera@machineA:/the/path/where/you/launched/nr-softmodem/r*config.raw userb@machineB:/the/path/where/you/will/launch/nr-uesoftmodem/` * Obviously this operation SHALL be done before launching the `nr-uesoftmodem` executable. 4. To enable the noS1 mode, `--noS1` option should be added to the command line. -5. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/TESTING_5GSA_setup.md#2-sa-setup-with-oai-nr-ue-softmodem). +5. To operate the gNB/UE with a 5GC, start them using the `--sa` option. More information can be found [here](../../../doc/NR_SA_Tutorial_OAI_CN5G.md). In the UE, you can add `-d` option to get the softscope. From 447150b05ac8378dc408c26b20b3ecbd9f2f79d8 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 24 May 2023 14:15:37 +0200 Subject: [PATCH 15/39] bugfix for PRACH format C2 --- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 04c3584fad..781d272de3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -450,7 +450,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); // here we have | Prefix | Prach | Prach | prach_len = (dftlen*2)+Ncp; - } else if (prach_fmt_id == 5) { // 4xdftlen + } else if (prach_fmt_id == 5 || prach_fmt_id == 10) { // 4xdftlen // here we have | empty | Prach | empty | empty | empty | memcpy(prach2+(dftlen<<1), prach2, (dftlen<<2)); // here we have | empty | Prach | Prach | empty | empty | From cfbeaf68c98b309d5ddaa96abd82eedafb9f7124 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 May 2023 17:30:40 +0200 Subject: [PATCH 16/39] F1AP: handle UE Context Release Request --- openair2/F1AP/f1ap_cu_ue_context_management.c | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 61bd6e7ff5..383f02f20a 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -776,10 +776,10 @@ int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, AssertFatal(1==0,"Not implemented yet\n"); } -int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { +int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ + MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); F1AP_UEContextReleaseRequest_t *container; F1AP_UEContextReleaseRequestIEs_t *ie; DevAssert(pdu); @@ -789,6 +789,8 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); const rnti_t rnti = f1ap_get_rnti_by_cu_id(true, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + req->rnti = rnti; + /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); @@ -796,35 +798,42 @@ int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, ie->value.choice.GNB_DU_UE_F1AP_ID); AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", rnti2, rnti); + /* Cause */ - /* We don't care for the moment F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true); switch(ie->value.choice.Cause.present) { case F1AP_Cause_PR_radioNetwork: - //ie->value.choice.Cause.choice.radioNetwork + req->cause = F1AP_CAUSE_RADIO_NETWORK; + req->cause_value = ie->value.choice.Cause.choice.radioNetwork; break; case F1AP_Cause_PR_transport: - //ie->value.choice.Cause.choice.transport + req->cause = F1AP_CAUSE_TRANSPORT; + req->cause_value = ie->value.choice.Cause.choice.transport; break; case F1AP_Cause_PR_protocol: - //ie->value.choice.Cause.choice.protocol + req->cause = F1AP_CAUSE_PROTOCOL; + req->cause_value = ie->value.choice.Cause.choice.protocol; break; case F1AP_Cause_PR_misc: - //ie->value.choice.Cause.choice.misc + req->cause = F1AP_CAUSE_MISC; + req->cause_value = ie->value.choice.Cause.choice.misc; break; case F1AP_Cause_PR_NOTHING: default: + req->cause = F1AP_CAUSE_NOTHING; break; } - */ - LOG_I(F1AP, "Received UE CONTEXT RELEASE REQUEST: Trigger RRC for RNTI %x\n", rnti); - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - AssertFatal(false,"must be devlopped\n"); - } + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, F1AP_ProtocolIE_ID_id_targetCellsToCancel, false); + if (ie != NULL) { + LOG_W(F1AP, "ignoring list of target cells to cancel in UE Context Release Request: implementation missing\n"); + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg); + return 0; } From e5b4ab230d66613df8d5354aba7f2e44515283a8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 May 2023 15:51:52 +0200 Subject: [PATCH 17/39] Reduce logging verbosity --- openair2/F1AP/f1ap_common.c | 2 +- openair2/F1AP/f1ap_du_ue_context_management.c | 6 ------ openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 3 +-- openair2/RRC/NR/rrc_gNB.c | 4 ++-- openair2/RRC/NR/rrc_gNB_NGAP.c | 2 +- 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index 9bafbdf2d9..862e701b6d 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -180,7 +180,7 @@ int f1ap_du_add_cu_ue_id(instance_t instanceP, return -1; f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id; - LOG_I(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); + LOG_D(F1AP, "Adding cu_ue_f1ap_id %ld for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 6f7a72b741..058965d9b8 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -98,8 +98,6 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, if(f1ap_ue_context_setup_req->rnti<0) LOG_E(F1AP, "Could not retrieve UE rnti based on the CU/DU UE id \n"); - else - LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_setup_req->rnti); /* SpCell_ID */ F1AP_UEContextSetupRequestIEs_t *ieNet; @@ -695,19 +693,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, F1AP_ProtocolIE_ID_id_Cause, true); switch (ie->value.choice.Cause.present){ case F1AP_Cause_PR_radioNetwork: - LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; break; case F1AP_Cause_PR_transport: - LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT; break; case F1AP_Cause_PR_protocol: - LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL; break; case F1AP_Cause_PR_misc: - LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc); f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC; break; default: diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index e9a01d98f7..9b1062170d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -149,7 +149,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { - LOG_I(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); + LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); nr_rlc_srb_recv_sdu(dl_rrc->rnti, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); return 0; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ebd2d17842..a6878a1895 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -675,8 +675,7 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, req->offset = GTPU_HEADER_OVERHEAD_MAX; req->ue_id = ue_id; req->bearer_id = rb_id; - LOG_I(PDCP, "%s() (drb %d) sending message to gtp size %d\n", - __func__, rb_id, size); + LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); extern instance_t CUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p); } else { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7941d1642b..ae7e8f5132 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2205,9 +2205,9 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, break; case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - LOG_I(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); + LOG_D(NR_RRC, "Recived RRC GNB UL Information Transfer \n"); if (!ue_context_p) { - LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); + LOG_W(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid); break; } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d4409c94cb..bb3249d626 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -653,7 +653,7 @@ rrc_gNB_send_NGAP_UPLINK_NAS( // NGAP_UPLINK_NAS (msg_p).nas_pdu.length, // ue_context_pP); itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); - LOG_I(NR_RRC,"Send RRC GNB UL Information Transfer \n"); + LOG_D(NR_RRC,"Send RRC GNB UL Information Transfer \n"); } } From 1a5cb8a6e2b828eeb0650ef1d73f87c356742b21 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 26 Apr 2023 15:02:12 +0200 Subject: [PATCH 18/39] UE NAS: Add timeout before shutting down UE to RLC Ack the PDU --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e57e3800de..b7cc6de789 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1003,6 +1003,11 @@ void *nas_nrue_task(void *args_p) case NAS_CONN_RELEASE_IND: LOG_I(NAS, "[UE %ld] Received %s: cause %u\n", instance, ITTI_MSG_NAME (msg_p), NAS_CONN_RELEASE_IND (msg_p).cause); + /* the following is not clean, but probably necessary: we need to give + * time to RLC to Ack the SRB1 PDU which contained the RRC release + * message. Hence, we just below wait some time, before finally + * unblocking the nr-uesoftmodem, which will terminate the process. */ + usleep(100000); itti_wait_tasks_unblock(); /* will unblock ITTI to stop nr-uesoftmodem */ break; From b8d1e1101f6b5ba56a2721d1a807bd153754cfa6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 27 Apr 2023 09:53:31 +0200 Subject: [PATCH 19/39] Add AssertFatal for reestablishment in F1: not implemented --- openair2/RRC/NR/rrc_gNB.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ae7e8f5132..2bc3892c4d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1693,6 +1693,8 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti); + } else { + AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n"); } /* replace rnti in the context */ From c4448e49d3afb1bd9e15cdc923f9071ce781b9b1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 May 2023 18:05:58 +0200 Subject: [PATCH 20/39] Rename to clearer f1ap_ue_context_release_complete_t type --- openair2/COMMON/f1ap_messages_types.h | 3 +-- openair2/F1AP/f1ap_du_ue_context_management.c | 10 +++++----- openair2/F1AP/f1ap_du_ue_context_management.h | 4 +--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 6850c784b5..541188cbd2 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -426,8 +426,7 @@ typedef struct f1ap_ue_context_release_s { uint8_t *rrc_container; int rrc_container_length; int srb_id; -} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, - f1ap_ue_context_release_cplt_t; +} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_complete_t; typedef struct f1ap_paging_ind_s { uint16_t ueidentityindexvalue; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 058965d9b8..6383fdcc7f 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -713,8 +713,8 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, return 0; } -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, - f1ap_ue_context_release_cplt_t *cplt) { +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextReleaseComplete_t *out; /* Create */ @@ -731,14 +731,14 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, cplt->rnti); + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(DUtype, instance, complete->rnti); /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, cplt->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, complete->rnti); /* optional -> currently not used */ /* c3. CriticalityDiagnostics */ //if (0) { @@ -800,7 +800,7 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id); - f1ap_remove_ue(DUtype, instance, cplt->rnti); + f1ap_remove_ue(DUtype, instance, complete->rnti); return 0; } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index acf74f69d7..c834b3d84d 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -63,9 +63,7 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, /* * UE Context Release Complete (gNB-DU initiated) */ -int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, - f1ap_ue_context_release_cplt_t *cplt); - +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_complete_t *complete); /* * UE Context Modification (gNB-CU initiated) From 8b7b9271ee93195f0b5a1950b1643e9b5ab5b65c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 24 Apr 2023 17:42:28 +0200 Subject: [PATCH 21/39] Add stubs for F1 UE Context Release Req+Cmd+Cplt messages --- openair2/F1AP/f1ap_du_ue_context_management.c | 16 ++++++---------- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 5 +++++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h | 1 + openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h | 2 ++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 12 ++++++++++++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 12 ++++++++++++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 ++- openair2/RRC/NR/mac_rrc_dl.h | 1 + openair2/RRC/NR/mac_rrc_dl_direct.c | 1 + openair2/RRC/NR/mac_rrc_dl_f1ap.c | 6 ++++++ openair2/RRC/NR/nr_rrc_defs.h | 2 +- 11 files changed, 49 insertions(+), 12 deletions(-) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 6383fdcc7f..dfec14e1e3 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -647,18 +647,13 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, return 0; } -int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ F1AP_UEContextReleaseCommand_t *container; F1AP_UEContextReleaseCommandIEs_t *ie; - /* ITTI message to NR-RRC for the case of gNB-DU */ - MessageDef *msg_p; // message to NR-RRC - msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &F1AP_UE_CONTEXT_RELEASE_CMD(msg_p); - + f1ap_ue_context_release_req_t ue_context_release = {0}; + f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &ue_context_release; DevAssert(pdu); container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; @@ -709,7 +704,8 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, break; } - itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + + ue_context_release_command(f1ap_ue_context_release_cmd); return 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 9b1062170d..dfa01a8454 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -147,6 +147,11 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) free(resp.du_to_cu_rrc_information); } +void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) +{ + AssertFatal(false, "not implemented\n"); +} + int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { LOG_D(NR_MAC, "DL RRC Message Transfer with %d bytes for RNTI %04x SRB %d\n", dl_rrc->rrc_container_length, dl_rrc->rnti, dl_rrc->srb_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 25b51c2d84..5ad3794a27 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" void ue_context_setup_request(const f1ap_ue_context_setup_t *req); +void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 53736a1695..0eb37a8148 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -26,6 +26,8 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); +typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req); +typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete); typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index eafa544185..694b0906a2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -55,6 +55,16 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) +{ + AssertFatal(false, "not implemented\n"); +} + +static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) +{ + AssertFatal(false, "not implemented\n"); +} + static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -78,5 +88,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; + mac_rrc->ue_context_release_request = ue_context_release_request_direct; + mac_rrc->ue_context_release_complete = ue_context_release_complete_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index c5bcb8814a..b72795a3d3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -60,6 +60,16 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c itti_send_msg_to_task(TASK_DU_F1, 0, msg); } +static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) +{ + AssertFatal(false, "not implemented\n"); +} + +static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete) +{ + AssertFatal(false, "not implemented\n"); +} + static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); @@ -83,6 +93,8 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; + mac_rrc->ue_context_release_request = ue_context_release_request_f1ap; + mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5f25713650..2571754843 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -659,8 +659,9 @@ typedef struct NR_bler_options { } NR_bler_options_t; typedef struct nr_mac_rrc_ul_if_s { - /* TODO add other message types as necessary */ ue_context_setup_response_func_t ue_context_setup_response; + ue_context_release_request_func_t ue_context_release_request; + ue_context_release_complete_func_t ue_context_release_complete; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; } nr_mac_rrc_ul_if_t; diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 49ffccd4a7..46c7fc85f8 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); +typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index be416d6921..b1ec661238 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -34,5 +34,6 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; + mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index bfe19a161b..e5fcc1f43d 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -39,6 +39,11 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } +static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) +{ + AssertFatal(false, "not implemented\n"); +} + static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { /* TODO call F1AP function directly? no real-time constraint here */ @@ -58,5 +63,6 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; + mac_rrc->ue_context_release_command = ue_context_release_command_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 1b00c93b9d..fe48207d2e 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -389,8 +389,8 @@ typedef struct { } nr_security_configuration_t; typedef struct nr_mac_rrc_dl_if_s { - /* TODO add other message types as necessary */ ue_context_setup_request_func_t ue_context_setup_request; + ue_context_release_command_func_t ue_context_release_command; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; From 69bfe7fe87afbd6df6a02e6ab0ed1565b29b7005 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 26 Apr 2023 13:59:38 +0200 Subject: [PATCH 22/39] Implement basic F1 release procedure using F1 internally --- openair2/COMMON/f1ap_messages_def.h | 1 + openair2/COMMON/f1ap_messages_types.h | 4 +- openair2/F1AP/f1ap_du_task.c | 4 + .../NR_MAC_gNB/gNB_scheduler_primitives.c | 24 ++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 3 + .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 24 +++++- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 5 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/RRC/NR/rrc_gNB.c | 79 ++++++++++--------- 10 files changed, 103 insertions(+), 44 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 5db598409f..7b991e5918 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -39,6 +39,7 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_FAILURE, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_failure_t, f1ap_initial_context_setup_failure) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) +MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_complete_t, f1ap_ue_context_release_complete) /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 541188cbd2..9bdf7f0330 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -41,14 +41,14 @@ #define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message #define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req #define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp -#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp #define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail #define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req -#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_cmd +#define F1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_complete #define F1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging_ind diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 8717382dfc..098f957194 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -165,6 +165,10 @@ void *F1AP_DU_task(void *arg) { &F1AP_UE_CONTEXT_RELEASE_REQ(msg)); break; + case F1AP_UE_CONTEXT_RELEASE_COMPLETE: + DU_send_UE_CONTEXT_RELEASE_COMPLETE(myInstance, &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg)); + break; + case TERMINATE_MESSAGE: LOG_W(F1AP, " *** Exiting F1AP thread\n"); itti_exit_task(); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 33bd6831d1..9545f8feb7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2785,6 +2785,16 @@ void nr_mac_update_timers(module_id_t module_id, NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + + if (nr_mac_check_release(sched_ctrl, UE->rnti)) { + nr_rlc_remove_ue(UE->rnti); + mac_remove_nr_ue(RC.nrmac[module_id], UE->rnti); + // go back to examine the next UE, which is at the position the + // current UE was + UE--; + continue; + } + if (sched_ctrl->rrc_processing_timer > 0) { sched_ctrl->rrc_processing_timer--; if (sched_ctrl->rrc_processing_timer == 0) { @@ -2946,3 +2956,17 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) DevAssert(bearer->servedRadioBearer->choice.srb_Identity == 1); nr_rlc_add_srb(UE->rnti, DCCH, bearer); } + +void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) +{ + // trigger 60ms + sched_ctrl->release_timer = 60 << subcarrier_spacing; +} + +bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti) +{ + if (sched_ctrl->release_timer == 0) + return false; + sched_ctrl->release_timer--; + return sched_ctrl->release_timer == 0; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 80c1652b61..cf20ca5d1a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -671,8 +671,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) { LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n", UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt); - UE->UE_sched_ctrl.ul_failure = 1; - nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index c2cbe8799d..a94a99d452 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -440,4 +440,7 @@ void send_initial_ul_rrc_message(gNB_MAC_INST *mac, int rnti, const uint8_t *sdu void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); +void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); +bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index dfa01a8454..2cf37946ea 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -149,7 +149,29 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) { - AssertFatal(false, "not implemented\n"); + /* mark UE as to be deleted after PUSCH failure */ + gNB_MAC_INST *mac = RC.nrmac[0]; + pthread_mutex_lock(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); + if (UE->UE_sched_ctrl.ul_failure > 0 || cmd->rrc_container_length == 0) { + /* The UE is already not connected anymore or we have nothing to forward*/ + nr_rlc_remove_ue(cmd->rnti); + mac_remove_nr_ue(mac, cmd->rnti); + } else { + /* UE is in sync: forward release message and mark to be deleted + * after UL failure */ + nr_rlc_srb_recv_sdu(cmd->rnti, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); + nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); + } + pthread_mutex_unlock(&mac->sched_lock); + + f1ap_ue_context_release_complete_t complete = { + .rnti = cmd->rnti, + }; + mac->mac_rrc.ue_context_release_complete(&complete); + + if (cmd->rrc_container) + free(cmd->rrc_container); } int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 694b0906a2..5db1596a97 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -62,7 +62,10 @@ static void ue_context_release_request_direct(const f1ap_ue_context_release_req_ static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) { - AssertFatal(false, "not implemented\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); + *f1ap_msg = *complete; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 2571754843..8df47be1e9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -592,6 +592,7 @@ typedef struct { int pusch_consecutive_dtx_cnt; int pucch_consecutive_dtx_cnt; int ul_failure; + int release_timer; struct CSI_Report CSI_report; bool SR; /// information about every HARQ process diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 2bc3892c4d..b955c7147d 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2589,6 +2589,21 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance * messages (UE capability, to be specific) */ } +static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) +{ + const int instance = 0; + f1ap_ue_context_release_complete_t *complete = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_p); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, complete->rnti); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + + nr_pdcp_remove_UE(UE->rnti); + newGtpuDeleteAllTunnels(instance, UE->rnti); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->gNB_ue_ngap_id); + LOG_I(NR_RRC, "removed UE %04x \n", UE->rnti); + rrc_gNB_remove_ue_context(rrc, ue_context_p); +} + static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); @@ -3162,9 +3177,12 @@ void *rrc_gnb_task(void *args_p) { rrc_DU_process_ue_context_modification_request(msg_p, instance); break; - case F1AP_UE_CONTEXT_RELEASE_CMD: - LOG_W(NR_RRC, "Received F1AP_UE_CONTEXT_RELEASE_CMD for processing at the RRC layer of the DU. Processing function " - "implementation is pending\n"); + case F1AP_UE_CONTEXT_RELEASE_REQ: + AssertFatal(false, "F1 UE context release request to be implemented\n"); + break; + + case F1AP_UE_CONTEXT_RELEASE_COMPLETE: + rrc_CU_process_ue_context_release_complete(msg_p); break; /* Messages from X2AP */ @@ -3292,6 +3310,24 @@ rrc_gNB_generate_UECapabilityEnquiry( nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); } +static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) +{ + DevAssert(deliver_pdu_data != NULL); + gNB_RRC_INST *rrc = deliver_pdu_data; + uint8_t *rrc_container = malloc(size); + AssertFatal(rrc_container != NULL, "out of memory\n"); + memcpy(rrc_container, buf, size); + f1ap_ue_context_release_cmd_t ue_context_release_cmd = { + .rnti = ue_id, /* TODO: proper IDs! */ + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release + .srb_id = srb_id, + .rrc_container = rrc_container, + .rrc_container_length = size, + }; + rrc->mac_rrc.ue_context_release_command(&ue_context_release_cmd); +} + //----------------------------------------------------------------------------- /* * Generate the RRC Connection Release to UE. @@ -3306,49 +3342,16 @@ rrc_gNB_generate_RRCRelease( { uint8_t buffer[RRC_BUF_SIZE] = {0}; int size = do_NR_RRCRelease(buffer, RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - ue_p->ue_reestablishment_timer = 0; - ue_p->ue_release_timer = 0; - ue_p->ul_failure_timer = 0; - ue_p->ue_release_timer_rrc = 0; LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), size); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcRelease MUI %d) --->[PDCP][RB %u]\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - size, - rrc_gNB_mui, - DCCH); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, deliver_pdu_srb_f1, rrc); + nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, rrc); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); - ue_context_pP->ue_context.ue_release_timer_rrc = 1; - /* TODO: 38.331 says for RRC Release that the UE should release everything - * after 60ms or if lower layers acked receipt of release. Hence, from the - * gNB POV, we can free the UE's RRC context as soon as we sent the msg. - * Currently, without the F1 interface, the ue_release timer expiration also - * triggers MAC, so we give it some time. If we send an F1 UE Context release - * message, we can free it immediately. The MAC should release it after these - * 60ms, or the ack of the DLSCH transmission. */ - ue_context_pP->ue_context.ue_release_timer_thres_rrc = 5; - LOG_I(RRC, "delaying UE %ld context removal by 5ms\n", ctxt_pP->rntiMaybeUEid); - - if (NODE_IS_CU(rrc->node_type)) { - uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size); - memcpy (message_buffer, buffer, size); - MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rntiMaybeUEid; - F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; - F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release - F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer; - F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size; - itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); - } + /* UE will be freed after UE context release complete */ } int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ From d6fb5c2e314b7d185e9fe3fe68101725a56f1467 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 27 Apr 2023 08:44:19 +0200 Subject: [PATCH 23/39] Handle UE release request at CU, and trigger at DU at UL failure --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 11 ------ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 5 ++- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 39 +++++++++++++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 5 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 +++---- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 4 ++ .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 5 ++- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 +- openair2/RRC/NR/L2_nr_interface.c | 29 -------------- openair2/RRC/NR/rrc_gNB.c | 17 +++++++- .../ngap_gNB_context_management_procedures.c | 5 +++ 14 files changed, 85 insertions(+), 60 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 9f80475666..ccb630f63d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -271,17 +271,6 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, @returns transformPrecoding value */ long get_transformPrecoding(const NR_UE_UL_BWP_t *current_UL_BWP, nr_dci_format_t dci_format, uint8_t configuredGrant); -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - uint8_t number_of_bits_set(uint8_t buf); void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fb78ff0d13..0b5e261c5b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1796,8 +1796,7 @@ static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0); // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE - sched_ctrl->pusch_consecutive_dtx_cnt = 0; - sched_ctrl->ul_failure = 0; + nr_mac_reset_ul_failure(sched_ctrl); } static void nr_generate_Msg4(module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4d3d59c12e..3f1ea001b3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -577,7 +577,7 @@ static void pf_dl(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1) + if (sched_ctrl->ul_failure) continue; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; @@ -898,7 +898,8 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; UE->mac_stats.dl.current_bytes = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9545f8feb7..e9a985b670 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2795,6 +2795,9 @@ void nr_mac_update_timers(module_id_t module_id, continue; } + /* check if UL failure and trigger release request if necessary */ + nr_mac_check_ul_failure(RC.nrmac[module_id], UE->rnti, sched_ctrl); + if (sched_ctrl->rrc_processing_timer > 0) { sched_ctrl->rrc_processing_timer--; if (sched_ctrl->rrc_processing_timer == 0) { @@ -2970,3 +2973,39 @@ bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti) sched_ctrl->release_timer--; return sched_ctrl->release_timer == 0; } + +void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) +{ + if (sched_ctrl->ul_failure) { + /* already running */ + return; + } + sched_ctrl->ul_failure = true; + // 30 seconds till triggering release request + sched_ctrl->ul_failure_timer = 30000 << subcarrier_spacing; +} + +void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl) +{ + sched_ctrl->ul_failure = false; + sched_ctrl->ul_failure_timer = 0; + sched_ctrl->pusch_consecutive_dtx_cnt = 0; +} + +void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl) +{ + if (!sched_ctrl->ul_failure) + return; + if (sched_ctrl->ul_failure_timer > 0) + sched_ctrl->ul_failure_timer--; + /* to trigger only once: trigger when ul_failure_timer == 1, but timer will + * stop at 0 and we wait for a UE release command from upper layers */ + if (sched_ctrl->ul_failure_timer == 1) { + f1ap_ue_context_release_complete_t complete = { + .rnti = rnti, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others + }; + nrmac->mac_rrc.ue_context_release_request(&complete); + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 3309e1af34..c384691e87 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -260,8 +260,7 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot) sched_ctrl->sched_srs.srs_scheduled = false; } - if((sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) || - sched_ctrl->rrc_processing_timer > 0) { + if ((sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) || sched_ctrl->rrc_processing_timer > 0) { continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index e1716458d2..e09f684d25 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -209,7 +209,7 @@ void nr_csi_meas_reporting(int Mod_idP, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { + if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)) { continue; } const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; @@ -1216,7 +1216,8 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if (sched_ctrl->ul_failure==1 || sched_ctrl->rrc_processing_timer>0) continue; + if (sched_ctrl->ul_failure || sched_ctrl->rrc_processing_timer > 0) + continue; NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index cf20ca5d1a..e777fa5e0f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -671,7 +671,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) { LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n", UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt); - nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); + nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } } } else if(sduP) { @@ -755,11 +755,9 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->rnti); + nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); - UE_scheduling_control->pusch_consecutive_dtx_cnt = 0; - UE_scheduling_control->ul_failure = 0; UE_msg3_stage->ra_timer = 0; nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); process_CellGroup(ra->CellGroup, UE_scheduling_control); @@ -791,8 +789,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, return; } else { // The UE identified by C-RNTI still exists at the gNB - // Reset uplink failure flags/counters/timers at RRC - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti); + nr_mac_reset_ul_failure(&UE_C->UE_sched_ctrl); // Reset HARQ processes reset_dl_harq_list(&UE_C->UE_sched_ctrl); @@ -1636,7 +1633,7 @@ static void pf_ul(module_id_t module_id, UE_iterator(UE_list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure == 1) + if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure) continue; LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); @@ -2065,7 +2062,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; UE_iterator( UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a94a99d452..f01a47699a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -443,4 +443,8 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); +void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); +void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); +void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 2cf37946ea..6e444b9816 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -153,7 +153,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) gNB_MAC_INST *mac = RC.nrmac[0]; pthread_mutex_lock(&mac->sched_lock); NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); - if (UE->UE_sched_ctrl.ul_failure > 0 || cmd->rrc_container_length == 0) { + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_rlc_remove_ue(cmd->rnti); mac_remove_nr_ue(mac, cmd->rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 5db1596a97..e13991529c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -57,7 +57,10 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { - AssertFatal(false, "not implemented\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); + *f1ap_msg = *req; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 8df47be1e9..d9f3ed1188 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -591,7 +591,8 @@ typedef struct { uint8_t current_harq_pid; int pusch_consecutive_dtx_cnt; int pucch_consecutive_dtx_cnt; - int ul_failure; + bool ul_failure; + int ul_failure_timer; int release_timer; struct CSI_Report CSI_report; bool SR; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 4e9c077afa..74b08e7dfe 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -118,32 +118,3 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, return 0; } - -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - - if (ue_context_p != NULL) { - LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); - if(ue_context_p->ue_context.ul_failure_timer == 0) - ue_context_p->ue_context.ul_failure_timer=1; - } else { - LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); - } -} - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - if (ue_context_p != NULL) { - LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP); - ue_context_p->ue_context.ul_failure_timer=0; - } else { - LOG_W(RRC,"Frame %d, Subframe %d: UL failure reset: UE %x unknown \n",frameP,subframeP,rntiP); - } -} diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b955c7147d..a7f6aabb74 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2589,6 +2589,21 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance * messages (UE capability, to be specific) */ } +static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) +{ + const int instance = 0; + f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + + /* TODO: marshall types correctly */ + LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, + ue_context_p, + NGAP_CAUSE_RADIO_NETWORK, + NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); +} + static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) { const int instance = 0; @@ -3178,7 +3193,7 @@ void *rrc_gnb_task(void *args_p) { break; case F1AP_UE_CONTEXT_RELEASE_REQ: - AssertFatal(false, "F1 UE context release request to be implemented\n"); + rrc_CU_process_ue_context_release_request(msg_p); break; case F1AP_UE_CONTEXT_RELEASE_COMPLETE: diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index c9db35e8c8..b05f96b899 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -138,6 +138,11 @@ int ngap_ue_context_release_req(instance_t instance, /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_req_p->gNB_ue_ngap_id); + /* send response to free the UE: we don't know it, but it should be + * released since RRC seems to know it (e.g., there is no AMF) */ + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + NGAP_UE_CONTEXT_RELEASE_COMMAND(msg).gNB_ue_ngap_id = ue_release_req_p->gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance_p->instance, msg); return -1; } From 12866c07ca5190c76ab666fec2845bcfb88b2b74 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 27 Apr 2023 09:52:28 +0200 Subject: [PATCH 24/39] Remove all timers from RRC There are a number of timers in RRC. Those are not or only partially implemented, and certainly don't work in F1. Hence, remove them to replace with a better implementation later. --- openair2/RRC/NR/nr_rrc_defs.h | 11 --- openair2/RRC/NR/rrc_gNB.c | 140 ++------------------------------- openair2/RRC/NR/rrc_gNB_NGAP.c | 9 +-- 3 files changed, 7 insertions(+), 153 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index fe48207d2e..8395175e0d 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -313,17 +313,6 @@ typedef struct gNB_RRC_UE_s { int nb_of_pdusessions; rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION]; rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; - uint32_t ul_failure_timer; - uint32_t ue_release_timer; - uint32_t ue_release_timer_thres; - uint32_t ue_release_timer_s1; - uint32_t ue_release_timer_thres_s1; - uint32_t ue_release_timer_ng; - uint32_t ue_release_timer_thres_ng; - uint32_t ue_release_timer_rrc; - uint32_t ue_release_timer_thres_rrc; - uint32_t ue_reestablishment_timer; - uint32_t ue_reestablishment_timer_thres; uint8_t e_rab_release_command_flag; uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index a7f6aabb74..bfc3729b61 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -359,11 +359,6 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance, size, "[MSG] RRC Setup\n"); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; - nr_pdcp_add_srbs(true, rnti, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); f1ap_dl_rrc_message_t dl_rrc = { @@ -414,20 +409,11 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m nr_mac_config_sib1(RC.nrmac[rrc_instance_p->module_id], rrc_instance_p->carrier.siblock1); LOG_I(NR_RRC, " [RAPROC] rnti: %04x Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", rnti, size); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; // configure MAC protocol_ctxt_t ctxt = {0}; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, rnti, 0, 0); apply_macrlc_config(rrc_instance_p, ue_context_pP, &ctxt); - //nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.SRB_configList, 0, NULL, NULL); - //apply_pdcp_config(ue_context_pP,ctxt_pP); - /* init timers */ - // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; - f1ap_dl_rrc_message_t dl_rrc = { .old_gNB_DU_ue_id = 0xFFFFFF, .rrc_container = buf, @@ -1046,8 +1032,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; - ue_p->ue_reestablishment_timer = 0; - /* Derive the keys from kgnb */ if (DRB_configList != NULL) { nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); @@ -1406,12 +1390,7 @@ void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const c if (ret != 0) { LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - ue_p->ue_release_timer_s1 = 1; - ue_p->ue_release_timer_thres_s1 = 100; - ue_p->ue_release_timer = 0; - ue_p->ue_reestablishment_timer = 0; - ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - ue_p->ul_failure_timer = 0; + AssertFatal(false, "not implemented\n"); return; } } @@ -1470,7 +1449,6 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE; ue_p->StatusRrc = NR_RRC_CONNECTED; - ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid); RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid); RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); @@ -1665,9 +1643,8 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint * the current one must be removed from MAC/PHY (zombie UE) */ if ((ue_context_p = rrc_gNB_ue_context_random_exist(gnb_rrc_inst, random_value))) { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; LOG_W(NR_RRC, "new UE rnti (coming with random value) is already there, removing UE %x from MAC/PHY\n", rnti); - UE->ul_failure_timer = 20000; + AssertFatal(false, "not implemented\n"); } ue_context_p = rrc_gNB_create_ue_context(rnti, gnb_rrc_inst, random_value); @@ -1699,12 +1676,6 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint /* replace rnti in the context */ UE->rnti = rnti; - /* reset timers */ - UE->ul_failure_timer = 0; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - UE->ue_release_timer_s1 = 0; - UE->ue_release_timer_rrc = 0; } else { LOG_I(NR_RRC, "UE %04x 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 => %ld\n", rnti, s_tmsi_part1); @@ -1795,28 +1766,9 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint break; } - if (UE->ue_reestablishment_timer > 0) { - LOG_E(NR_RRC, "RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n", UE->StatusRrc); - UE->StatusRrc = NR_RRC_RECONFIGURED; - protocol_ctxt_t ctxt_old_p; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, module_id, GNB_FLAG_YES, c_rnti, 0, 0); - rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, xid); + /* TODO: start timer in ITTI and drop UE if it does not come back */ + (void) xid; /* xid currently not used */ - for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) { - if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { - UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; - } else { - UE->pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; - } - } - } - - /* reset timers */ - UE->ul_failure_timer = 0; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - // UE->ue_release_timer_s1 = 0; - UE->ue_release_timer_rrc = 0; // Insert C-RNTI to map for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; @@ -1944,11 +1896,6 @@ static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_p nr_rrc_mac_remove_ue(reestablish_rnti); UE->ue_reestablishment_counter++; - - // UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 1; - // remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered - UE->ue_reestablishment_timer_thres = 1000; return 0; } @@ -2106,8 +2053,6 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - - UE->ue_release_timer = 0; return 0; } @@ -2852,79 +2797,6 @@ static int get_dl_mimo_layers(const gNB_RRC_INST *rrc, const NR_UE_NR_Capability void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { MessageDef *msg; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - rrc_gNB_ue_context_t *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) - { - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - ctxt_pP->rntiMaybeUEid = UE->rnti; - - if (UE->ul_failure_timer > 0) { - UE->ul_failure_timer++; - - if (UE->ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", UE->rnti); - if (UE->StatusRrc >= NR_RRC_CONNECTED) { - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( - ctxt_pP->module_id, - ue_context_p, - NGAP_CAUSE_RADIO_NETWORK, - NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); - } - - // Remove here the MAC and RRC context when RRC is not connected - if (UE->StatusRrc < NR_RRC_CONNECTED) { - if (!NODE_IS_CU(rrc->node_type)) { - nr_rrc_mac_remove_ue(ctxt_pP->rntiMaybeUEid); - rrc_rlc_remove_ue(ctxt_pP); - nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid); - - /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, UE->rnti); - if (ue_context_p) { - LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); - rrc_gNB_remove_ue_context(rrc, ue_context_p); - break; // We must not access this UE context - } - } - // In case of CU trigger UE context release command towards the DU - else { - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); - f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p); - rel_cmd->rnti = UE->rnti; - rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; - rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release - itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p); - } - } - - break; // break RB_FOREACH - } - } - - if (UE->ue_release_timer_rrc > 0) { - UE->ue_release_timer_rrc++; - - if (UE->ue_release_timer_rrc >= UE->ue_release_timer_thres_rrc) { - LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", UE->rnti); - UE->ue_release_timer_rrc = 0; - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { - nr_rrc_mac_remove_ue(ctxt_pP->rntiMaybeUEid); - } - rrc_rlc_remove_ue(ctxt_pP); - nr_pdcp_remove_UE(ctxt_pP->rntiMaybeUEid); - newGtpuDeleteAllTunnels(ctxt_pP->instance, UE->rnti); - - /* remove RRC UE Context */ - LOG_I(NR_RRC, "remove UE %04x \n", UE->rnti); - - rrc_gNB_remove_ue_context(rrc, ue_context_p); - break; // break RB_FOREACH - } - } - } /* send a tick to x2ap */ if (is_x2ap_enabled()){ @@ -3063,9 +2935,9 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, "NR RRC UE rnti %04x:", rnti); if (ue_ctxt->Initialue_identity_5g_s_TMSI.presence) - fprintf(f, " S-TMSI %x\n", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); + fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); - fprintf(f, " failure timer %d/8\n", ue_ctxt->ul_failure_timer); + fprintf(f, "\n"); if (ue_ctxt->UE_Capability_nr) { fprintf(f, diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index bb3249d626..fbe4f7af28 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -396,12 +396,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb, sdap_data_req); if (ret != 0) { LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti); - UE->ue_release_timer_ng = 1; - UE->ue_release_timer_thres_ng = 100; - UE->ue_release_timer = 0; - UE->ue_reestablishment_timer = 0; - UE->ul_failure_timer = 20000; - UE->ul_failure_timer = 0; + AssertFatal(false, "release timer not implemented\n"); return (0); } @@ -1157,8 +1152,6 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE->ue_release_timer_ng = 0; - UE->ue_release_timer_thres_rrc = 1000; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0); ctxt.eNB_index = 0; rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); From 123d71d0e39fc3c7f8d89339c889dd5e22b44246 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 May 2023 19:03:25 +0200 Subject: [PATCH 25/39] Implement F1 Release using F1AP --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 12 ++++++++++-- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index b72795a3d3..718a595e74 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -62,12 +62,20 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) { - AssertFatal(false, "not implemented\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); + *f1ap_msg = *req; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); } static void ue_context_release_complete_f1ap(const f1ap_ue_context_release_complete_t *complete) { - AssertFatal(false, "not implemented\n"); + newGtpuDeleteAllTunnels(0, complete->rnti); + + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_COMPLETE); + f1ap_ue_context_release_complete_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_COMPLETE(msg); + *f1ap_msg = *complete; + itti_send_msg_to_task(TASK_DU_F1, 0, msg); } static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index e5fcc1f43d..0af1c79bd2 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -41,7 +41,10 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) { - AssertFatal(false, "not implemented\n"); + MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_cmd_t *msg = &F1AP_UE_CONTEXT_RELEASE_CMD(message_p); + *msg = *cmd; + itti_send_msg_to_task (TASK_CU_F1, 0, message_p); } static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) From 87c82e8a85e76bcdf7bc5c6a25cd09d7c4f96fae Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 May 2023 12:39:33 +0200 Subject: [PATCH 26/39] Don't send subframe process tick to RRC, to X2AP directly if necessary --- doc/SW-archi-graph.md | 1 - openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 5 +++-- openair2/RRC/NR/nr_rrc_proto.h | 3 --- openair2/RRC/NR/rrc_gNB.c | 26 ---------------------- openair2/X2AP/x2ap_eNB.c | 6 +++++ openair2/X2AP/x2ap_eNB.h | 1 + 6 files changed, 10 insertions(+), 32 deletions(-) diff --git a/doc/SW-archi-graph.md b/doc/SW-archi-graph.md index 8f8a6f6e5c..d397d07f43 100644 --- a/doc/SW-archi-graph.md +++ b/doc/SW-archi-graph.md @@ -31,7 +31,6 @@ rx_func_implem[rx_func] --> handle_nr_ulsch subgraph gNB_dlsch_ulsch_scheduler run_pdcp - --> nr_rrc_trigger --> schedule_xxxx end handle_nr_ulsch --> gNB_dlsch_ulsch_scheduler diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 2d4cd16eb4..05ee8efe52 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -40,7 +40,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" -#include "RRC/NR/nr_rrc_extern.h" +#include "openair2/X2AP/x2ap_eNB.h" #include "nr_pdcp/nr_pdcp_oai_api.h" @@ -174,7 +174,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ void nr_pdcp_tick(int frame, int subframe); nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing); - nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); + if (is_x2ap_enabled()) + x2ap_trigger(); /* if none of the above options, it must be NSA */ } for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 8cfc1e9132..384269748a 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -111,9 +111,6 @@ rrc_gNB_generate_RRCRelease( \param void *args_p Pointer on arguments to start the task. */ void *rrc_gnb_task(void *args_p); -/* Trigger RRC periodic processing. To be called once per ms. */ -void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe); - /**\ Function to set or overwrite PTRS DL RRC parameters. \ *bwp Pointer to dedicated RC config structure \ *ptrsNrb Pointer to K_ptrs N_RB related parameters diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index bfc3729b61..33ab4437a2 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2794,17 +2794,6 @@ static int get_dl_mimo_layers(const gNB_RRC_INST *rrc, const NR_UE_NR_Capability return(1); } -void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { - - MessageDef *msg; - - /* send a tick to x2ap */ - if (is_x2ap_enabled()){ - msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS); - itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); - } -} - int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); @@ -2993,10 +2982,6 @@ void *rrc_gnb_task(void *args_p) { write_rrc_stats(RC.nrrrc[0]); break; - case RRC_SUBFRAME_PROCESS: - nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); - break; - case F1AP_INITIAL_UL_RRC_MESSAGE: AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); @@ -3363,14 +3348,3 @@ int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t inst return 0; } - -void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) -{ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS); - RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; - RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; - LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe); - itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); -} - diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index c775726e87..831cad4742 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -767,3 +767,9 @@ mutex_error: LOG_E(X2AP, "mutex error\n"); exit(1); } + +void x2ap_trigger(void) +{ + MessageDef *msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_SUBFRAME_PROCESS); + itti_send_msg_to_task(TASK_X2AP, 0, msg); +} diff --git a/openair2/X2AP/x2ap_eNB.h b/openair2/X2AP/x2ap_eNB.h index afa6f11b8e..0f83ca64af 100644 --- a/openair2/X2AP/x2ap_eNB.h +++ b/openair2/X2AP/x2ap_eNB.h @@ -47,6 +47,7 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, void *x2ap_task(void *arg); int is_x2ap_enabled(void); +void x2ap_trigger(void); #endif /* X2AP_H_ */ From 820ec995a40df38f5e63ec0532e169c088592442 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 May 2023 17:36:38 +0200 Subject: [PATCH 27/39] Introduce separate F1AP types f1ap_ue_context_modif_req_t and f1ap_ue_context_modif_resp_t --- openair2/COMMON/f1ap_messages_def.h | 4 ++-- openair2/COMMON/f1ap_messages_types.h | 2 +- openair2/F1AP/f1ap_cu_task.c | 2 +- openair2/F1AP/f1ap_cu_ue_context_management.c | 7 ++++--- openair2/F1AP/f1ap_cu_ue_context_management.h | 3 +-- openair2/F1AP/f1ap_du_ue_context_management.c | 5 +++-- openair2/F1AP/f1ap_du_ue_context_management.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 10 +++++----- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 7b991e5918..7c67b22756 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -46,8 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) -MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) -MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp) /* CU -> DU*/ MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 9bdf7f0330..6ea19f39a6 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -409,7 +409,7 @@ typedef struct f1ap_ue_context_setup_s { ReconfigurationCompl_t ReconfigComplOutcome; uint8_t *rrc_container; int rrc_container_length; -} f1ap_ue_context_setup_t; +} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t; typedef enum F1ap_Cause_e { F1AP_CAUSE_NOTHING, /* No components present */ diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 901932f54b..7cc23e88fa 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -171,7 +171,7 @@ void *F1AP_CU_task(void *arg) { case F1AP_UE_CONTEXT_MODIFICATION_REQ: CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); + &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 383f02f20a..3e2197c282 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -981,7 +981,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) { +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; uint8_t *buffer=NULL; @@ -1600,7 +1601,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_UEContextModificationResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); - f1ap_ue_context_setup_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); + f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; int i; @@ -1609,7 +1610,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); + LOG_D(F1AP, "f1ap_ue_context_modif_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 87563e97b1..32a54bc6cc 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -72,8 +72,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - f1ap_ue_context_setup_t *f1ap_ue_context_modification_req); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index dfec14e1e3..e64cddab40 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -820,7 +820,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, int i; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_setup_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest; /* mandatory */ @@ -975,7 +975,8 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, } //void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; uint8_t *buffer=NULL; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index c834b3d84d..51b8fa6dce 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -72,7 +72,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp); int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 33ab4437a2..f618ccdf31 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2359,7 +2359,7 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance) { - f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + f1ap_ue_context_modif_req_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; @@ -2367,7 +2367,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in gNB_RRC_UE_t *UE = &ue_context_p->ue_context; MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); - f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); + f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); uint32_t incoming_teid = 0; NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -2508,7 +2508,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance) { - f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; @@ -2566,7 +2566,7 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { - f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); @@ -2829,7 +2829,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex // TODO: So many hard codings MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); + f1ap_ue_context_modif_req_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); req->rnti = UE->rnti; req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; From 3d352b0dd8cb2f5e2830bc56295e9a9e50c1e243 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 12 Apr 2023 16:36:19 +0200 Subject: [PATCH 28/39] Stubs for F1 UE Context Modification Req+Resp messages --- openair2/F1AP/f1ap_du_ue_context_management.c | 15 +++++---------- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 6 ++++++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h | 1 + openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h | 2 ++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 9 +++++++++ openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 8 ++++++++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/RRC/NR/mac_rrc_dl.h | 1 + openair2/RRC/NR/mac_rrc_dl_direct.c | 1 + openair2/RRC/NR/mac_rrc_dl_f1ap.c | 7 +++++++ openair2/RRC/NR/nr_rrc_defs.h | 1 + 11 files changed, 42 insertions(+), 10 deletions(-) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e64cddab40..10aa0ac1dc 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -810,17 +810,12 @@ static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, c return gtpv1Init(tmp); } -int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { - - MessageDef *msg_p; // message to RRC +int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ F1AP_UEContextModificationRequest_t *container; int i; - DevAssert(pdu); - msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + f1ap_ue_context_modif_req_t ue_context_modification = {0}; + f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &ue_context_modification; container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest; /* mandatory */ @@ -970,7 +965,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); } - itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + ue_context_modification_request(f1ap_ue_context_modification_req); return 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 6e444b9816..2c4f748fa8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -147,6 +147,12 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) free(resp.du_to_cu_rrc_information); } +void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) +{ + (void)req; + AssertFatal(false, "not implemented\n"); +} + void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) { /* mark UE as to be deleted after PUSCH failure */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 5ad3794a27..808277a7f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" void ue_context_setup_request(const f1ap_ue_context_setup_t *req); +void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 0eb37a8148..5d7a7cd644 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -26,6 +26,8 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); +typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req, + const f1ap_ue_context_modif_resp_t *resp); typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req); typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index e13991529c..51944970c3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -55,6 +55,14 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void ue_context_modification_response_direct(const f1ap_ue_context_modif_req_t *req, + const f1ap_ue_context_modif_resp_t *resp) +{ + (void)req; /* we don't need the request -- it is to set up GTP in F1 case */ + (void)resp; + AssertFatal(false, "not implemented yet\n"); +} + static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -94,6 +102,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; + mac_rrc->ue_context_modification_response = ue_context_modification_response_direct; mac_rrc->ue_context_release_request = ue_context_release_request_direct; mac_rrc->ue_context_release_complete = ue_context_release_complete_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 718a595e74..e1818917dc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -60,6 +60,13 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c itti_send_msg_to_task(TASK_DU_F1, 0, msg); } +static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_req_t *req, const f1ap_ue_context_modif_resp_t *resp) +{ + (void)req; + (void)resp; + AssertFatal(false, "not implemented\n"); +} + static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -101,6 +108,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; + mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap; mac_rrc->ue_context_release_request = ue_context_release_request_f1ap; mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index d9f3ed1188..b62c5f8562 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -662,6 +662,7 @@ typedef struct NR_bler_options { typedef struct nr_mac_rrc_ul_if_s { ue_context_setup_response_func_t ue_context_setup_response; + ue_context_modification_response_func_t ue_context_modification_response; ue_context_release_request_func_t ue_context_release_request; ue_context_release_complete_func_t ue_context_release_complete; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 46c7fc85f8..2728174603 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); +typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index b1ec661238..2d436c19e3 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -34,6 +34,7 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; + mac_rrc->ue_context_modification_request = ue_context_modification_request; mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 0af1c79bd2..5c4637dde2 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -39,6 +39,12 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) itti_send_msg_to_task(TASK_CU_F1, 0, msg); } +static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) +{ + (void)req; + AssertFatal(false, "not implemented yet\n"); +} + static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) { MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); @@ -66,6 +72,7 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; + mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap; mac_rrc->ue_context_release_command = ue_context_release_command_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 8395175e0d..25e7563bbc 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -379,6 +379,7 @@ typedef struct { typedef struct nr_mac_rrc_dl_if_s { ue_context_setup_request_func_t ue_context_setup_request; + ue_context_modification_request_func_t ue_context_modification_request; ue_context_release_command_func_t ue_context_release_command; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; From 46335741bfa58fcf4688fbf295eb18c15d0b3dde Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 16 Apr 2023 14:19:01 +0200 Subject: [PATCH 29/39] Implementation of dedicated RRC Reconfiguration using internal F1 UE context modification --- executables/nr-cuup.c | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 142 ++++++++++--- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 53 ++++- openair2/RRC/NR/cucp_cuup_direct.c | 26 ++- openair2/RRC/NR/nr_rrc_proto.h | 6 +- openair2/RRC/NR/rrc_gNB.c | 191 +++++++----------- 6 files changed, 265 insertions(+), 155 deletions(-) diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 832f785551..6fcf5b7ea3 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -84,7 +84,7 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch return 0; } -void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_CellGroupConfig_t *cell_groupConfig_from_DU) +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) { abort(); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 2c4f748fa8..006db8ac44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -33,25 +33,27 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_set return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket); } -static void handle_ue_context_srbs_setup(const f1ap_ue_context_setup_t *req, - f1ap_ue_context_setup_t *resp, - NR_CellGroupConfig_t *cellGroupConfig) +static int handle_ue_context_srbs_setup(int rnti, + int srbs_len, + const f1ap_srb_to_be_setup_t *req_srbs, + f1ap_srb_to_be_setup_t **resp_srbs, + NR_CellGroupConfig_t *cellGroupConfig) { - DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + DevAssert(req_srbs != NULL && resp_srbs != NULL && cellGroupConfig != NULL); - resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; - resp->srbs_to_be_setup = calloc(req->srbs_to_be_setup_length, sizeof(*resp->srbs_to_be_setup)); - AssertFatal(resp->srbs_to_be_setup != NULL, "out of memory\n"); - for (int i = 0; i < req->srbs_to_be_setup_length; i++) { - f1ap_srb_to_be_setup_t *srb = &req->srbs_to_be_setup[i]; + *resp_srbs = calloc(srbs_len, sizeof(**resp_srbs)); + AssertFatal(*resp_srbs != NULL, "out of memory\n"); + for (int i = 0; i < srbs_len; i++) { + const f1ap_srb_to_be_setup_t *srb = &req_srbs[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb); - nr_rlc_add_srb(req->rnti, srb->srb_id, rlc_BearerConfig); + nr_rlc_add_srb(rnti, srb->srb_id, rlc_BearerConfig); - resp->srbs_to_be_setup[i] = *srb; + (*resp_srbs)[i] = *srb; int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); } + return srbs_len; } static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb) @@ -61,27 +63,31 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority); } -static void handle_ue_context_drbs_setup(const f1ap_ue_context_setup_t *req, - f1ap_ue_context_setup_t *resp, - NR_CellGroupConfig_t *cellGroupConfig) +static int handle_ue_context_drbs_setup(int rnti, + int drbs_len, + const f1ap_drb_to_be_setup_t *req_drbs, + f1ap_drb_to_be_setup_t **resp_drbs, + NR_CellGroupConfig_t *cellGroupConfig) { - DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); /* Note: the actual GTP tunnels are created in the F1AP breanch of * ue_context_*_response() */ - resp->drbs_to_be_setup_length = req->drbs_to_be_setup_length; - resp->drbs_to_be_setup = calloc(req->drbs_to_be_setup_length, sizeof(*resp->drbs_to_be_setup)); - AssertFatal(resp->drbs_to_be_setup != NULL, "out of memory\n"); - for (int i = 0; i < req->drbs_to_be_setup_length; i++) { - f1ap_drb_to_be_setup_t *drb = &req->drbs_to_be_setup[i]; + *resp_drbs = calloc(drbs_len, sizeof(**resp_drbs)); + AssertFatal(*resp_drbs != NULL, "out of memory\n"); + for (int i = 0; i < drbs_len; i++) { + const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); - nr_rlc_add_drb(req->rnti, drb->drb_id, rlc_BearerConfig); + nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig); - resp->drbs_to_be_setup[i] = *drb; + (*resp_drbs)[i] = *drb; + // just put same number of tunnels in DL as in UL + (*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length; int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); } + return drbs_len; } void ue_context_setup_request(const f1ap_ue_context_setup_t *req) @@ -105,11 +111,20 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti); - if (req->srbs_to_be_setup_length > 0) - handle_ue_context_srbs_setup(req, &resp, UE->CellGroup); + if (req->srbs_to_be_setup_length > 0) { + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + req->srbs_to_be_setup_length, + req->srbs_to_be_setup, + &resp.srbs_to_be_setup, + UE->CellGroup); + } if (req->drbs_to_be_setup_length > 0) { - handle_ue_context_drbs_setup(req, &resp, NULL); + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + req->drbs_to_be_setup_length, + req->drbs_to_be_setup, + &resp.drbs_to_be_setup, + UE->CellGroup); } if (req->rrc_container != NULL) @@ -149,8 +164,81 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) { - (void)req; - AssertFatal(false, "not implemented\n"); + gNB_MAC_INST *mac = RC.nrmac[0]; + f1ap_ue_context_modif_resp_t resp = { + .gNB_CU_ue_id = req->gNB_CU_ue_id, + .gNB_DU_ue_id = req->gNB_DU_ue_id, + .rnti = req->rnti, + }; + + if (req->cu_to_du_rrc_information != NULL) { + AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n"); + AssertFatal(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList == NULL, "UE capabilities not handled yet\n"); + AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n"); + } + + NR_SCHED_LOCK(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); + + if (req->srbs_to_be_setup_length > 0) { + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + req->srbs_to_be_setup_length, + req->srbs_to_be_setup, + &resp.srbs_to_be_setup, + UE->CellGroup); + } + + if (req->drbs_to_be_setup_length > 0) { + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + req->drbs_to_be_setup_length, + req->drbs_to_be_setup, + &resp.drbs_to_be_setup, + UE->CellGroup); + } + + if (req->rrc_container != NULL) + nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + + if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { + LOG_E(NR_MAC, + "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); + } + + if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0) { + /* TODO: if we change e.g. BWP or MCS table, need to automatically call + * configure_UE_BWP() (form nr_mac_update_timers()) after some time? */ + + resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); + AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n"); + resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024); + AssertFatal(resp.du_to_cu_rrc_information->cellGroupConfig != NULL, "out of memory\n"); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + UE->CellGroup, + resp.du_to_cu_rrc_information->cellGroupConfig, + 1024); + AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); + resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; + + /* works? */ + nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup); + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + /* some sanity checks, since we use the same type for request and response */ + DevAssert(resp.cu_to_du_rrc_information == NULL); + // resp.du_to_cu_rrc_information can be either NULL or not + DevAssert(resp.rrc_container == NULL && resp.rrc_container_length == 0); + + mac->mac_rrc.ue_context_modification_response(req, &resp); + + /* free the memory we allocated above */ + free(resp.srbs_to_be_setup); + free(resp.drbs_to_be_setup); + if (resp.du_to_cu_rrc_information != NULL) { + free(resp.du_to_cu_rrc_information->cellGroupConfig); + free(resp.du_to_cu_rrc_information); + } } void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 51944970c3..6780fad873 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -59,8 +59,57 @@ static void ue_context_modification_response_direct(const f1ap_ue_context_modif_ const f1ap_ue_context_modif_resp_t *resp) { (void)req; /* we don't need the request -- it is to set up GTP in F1 case */ - (void)resp; - AssertFatal(false, "not implemented yet\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); + + f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; + f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id; + f1ap_msg->rnti = resp->rnti; + f1ap_msg->mcc = resp->mcc; + f1ap_msg->mnc = resp->mnc; + f1ap_msg->mnc_digit_length = resp->mnc_digit_length; + f1ap_msg->nr_cellid = resp->nr_cellid; + f1ap_msg->servCellIndex = resp->servCellIndex; + AssertFatal(resp->cellULConfigured == NULL, "not handled\n"); + f1ap_msg->servCellId = resp->servCellId; + + DevAssert(resp->cu_to_du_rrc_information == NULL && resp->cu_to_du_rrc_information_length == 0); + if (resp->du_to_cu_rrc_information) { + f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + } + + if (resp->drbs_to_be_setup_length > 0) { + DevAssert(resp->drbs_to_be_setup != NULL); + f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i) + f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i]; + } + + DevAssert(resp->drbs_to_be_modified == NULL && resp->drbs_to_be_modified_length == 0); + f1ap_msg->QoS_information_type = resp->QoS_information_type; + AssertFatal(resp->drbs_failed_to_be_setup_length == 0 && resp->drbs_failed_to_be_setup == NULL, "not implemented yet\n"); + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + + AssertFatal(resp->srbs_failed_to_be_setup_length == 0 && resp->srbs_failed_to_be_setup == NULL, "not implemented yet\n"); + + DevAssert(resp->rrc_container == NULL && resp->rrc_container_length == 0); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index d0d4365e70..9a74b3826b 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -187,6 +187,19 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); fill_DRB_configList(&ctxt, ue_context_p, xid); + e1ap_bearer_setup_resp_t resp = {0}; + resp.numPDUSessions = req->numPDUSessions; + for (int i = 0; i < resp.numPDUSessions; ++i) { + resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; + for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j; + DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j; + resp_drb->id = req_drb->id; + resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup; + for (int k = 0; k < resp_drb->numQosFlowSetup; k++) + resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id; + } + } gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // Fixme: xid not random, but almost! @@ -195,21 +208,26 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst); if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); + // Used to store teids: if monolithic, will simply be NULL if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + // intentionally empty } else { - e1ap_bearer_setup_resp_t resp; // Used to store teids int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; // GTP tunnel for DL fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr); - - prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } + // actually, we should receive the corresponding context setup response + // message at the RRC and always react to this one. So in the following, we + // just call the corresponding message handler + prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) { + // only update GTP tunnels if it is really a CU + if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) + return; instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 384269748a..504aced681 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -142,11 +142,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( uint32_t nas_length, uint8_t *nas_buffer); -void -rrc_gNB_generate_dedicatedRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_CellGroupConfig_t *cell_groupConfig_from_DU); +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP); void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f618ccdf31..1b4d09ba27 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -641,17 +641,10 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_contex } //----------------------------------------------------------------------------- -void -rrc_gNB_generate_dedicatedRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_CellGroupConfig_t *cell_groupConfig_from_DU -) +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - NR_CellGroupConfig_t *cellGroupConfig = NULL; int xid = -1; int drb_id_to_setup_start = 1; @@ -682,7 +675,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( } xid = ue_p->pduSession[j].xid; - drb_priority[DRB_config->drb_Identity - 1] = 13; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) } /* If list is empty free the list and reset the address */ @@ -691,20 +683,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( dedicatedNAS_MessageList = NULL; } - if(cell_groupConfig_from_DU == NULL){ - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - // FIXME: fill_mastercellGroupConfig() won't fill the right priorities - fill_mastercellGroupConfig(cellGroupConfig, - ue_p->masterCellGroup, - rrc->um_on_default_drb, - (drb_id_to_setup_start < 2) ? 1 : 0, - DRB_configList, - drb_priority); - } - else{ - LOG_I(NR_RRC, "Master cell group originating from the DU \n"); - cellGroupConfig = cell_groupConfig_from_DU; - } + NR_CellGroupConfig_t *cellGroupConfig = ue_p->masterCellGroup; AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid); NR_SRB_ToAddModList_t *SRB_configList2 = NULL; @@ -2572,69 +2551,46 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - e1ap_bearer_setup_req_t req = {0}; - req.numPDUSessionsMod = UE->nb_of_pdusessions; - req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; - req.rnti = UE->rnti; - for (int i=0; i < req.numPDUSessionsMod; i++) { - req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; - for (int j=0; j < resp->drbs_to_be_setup_length; j++) { - f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; - DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; + if (resp->drbs_to_be_setup_length > 0) { + e1ap_bearer_setup_req_t req = {0}; + req.numPDUSessionsMod = UE->nb_of_pdusessions; + req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; + req.rnti = UE->rnti; + for (int i = 0; i < req.numPDUSessionsMod; i++) { + req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; + for (int j = 0; j < resp->drbs_to_be_setup_length; j++) { + f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; + DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; - drb_e1->id = drb_f1->drb_id; - drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; - drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address; - drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid; - } - } - - // send the F1 response message up to update F1-U tunnel info - // it seems the rrc transaction id (xid) is not needed here - rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); - - NR_CellGroupConfig_t *cellGroupConfig = NULL; - - if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&cellGroupConfig, - (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, - (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"Cell group config decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 ); - return; - } - //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); - - if (UE->masterCellGroup == NULL) { - UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); - } - - if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ - if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) { - int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count; - for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ - asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]); - } - } else { - LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); - UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + drb_e1->id = drb_f1->drb_id; + drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; + drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address; + drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid; } } - LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n"); - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + + // send the F1 response message up to update F1-U tunnel info + // it seems the rrc transaction id (xid) is not needed here + rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); + } + + if (resp->du_to_cu_rrc_information != NULL && resp->du_to_cu_rrc_information->cellGroupConfig != NULL) { + LOG_W(RRC, "UE context modification response contains new CellGroupConfig for UE %04x, triggering reconfiguration\n", UE->rnti); + NR_CellGroupConfig_t *cellGroupConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n"); + + if (UE->masterCellGroup) { + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti); } + UE->masterCellGroup = cellGroupConfig; - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); - - free(cellGroupConfig->rlc_BearerToAddModList); - free(cellGroupConfig); + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p); } } @@ -2817,46 +2773,49 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { return 0; } -void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, - e1ap_bearer_setup_resp_t *e1ap_resp) { +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) +{ + /* Generate a UE context modification request message towards the DU to + * instruct the DU for SRB2 and DRB configuration and get the updates on + * master cell group config from the DU*/ - /*Generate a UE context modification request message towards the DU to instruct the DU - *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + gNB_RRC_INST *rrc = RC.nrrrc[0]; gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - // TODO: So many hard codings - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_modif_req_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); - req->rnti = UE->rnti; - req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; - req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; - req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; - req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; - - /*Instruction towards the DU for SRB2 configuration*/ - req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = 1; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - SRBs[0].srb_id = 2; - SRBs[0].lcid = 2; - - /*Instruction towards the DU for DRB configuration and tunnel creation*/ - req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup; - req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length); - for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) { - f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i; - DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; - DRBs[i].rlc_mode = RLC_MODE_AM; - DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; - DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; - DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; - DRBs[i].up_ul_tnl_length = 1; + /* Instruction towards the DU for DRB configuration and tunnel creation */ + int nb_drb = e1ap_resp->pduSession[0].numDRBSetup; + f1ap_drb_to_be_setup_t drbs[nb_drb]; + for (int i = 0; i < nb_drb; i++) { + drbs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; + drbs[i].rlc_mode = rrc->um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; + drbs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; + drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; + drbs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; + drbs[i].up_ul_tnl_length = 1; } - itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); + /* Instruction towards the DU for SRB2 configuration */ + int nb_srb = 1; + f1ap_srb_to_be_setup_t srbs[nb_srb]; + srbs[0].srb_id = 2; + srbs[0].lcid = 2; + srbs[0].rlc_mode = RLC_MODE_AM; + + f1ap_ue_context_modif_req_t ue_context_modif_req = { + .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .rnti = UE->rnti, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .srbs_to_be_setup_length = nb_srb, + .srbs_to_be_setup = srbs, + .drbs_to_be_setup_length = nb_drb, + .drbs_to_be_setup = drbs, + }; + rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { From a47d4aee02ad692ad5f328a166527a6684448ef8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 22 Apr 2023 09:07:00 +0200 Subject: [PATCH 30/39] Remove handling of UE context modification at DU RRC --- openair2/RRC/NR/rrc_gNB.c | 153 -------------------------------------- 1 file changed, 153 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 1b4d09ba27..696646096e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2336,155 +2336,6 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC rrc_remove_nsa_user(rrc, m->rnti); } -static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance) -{ - f1ap_ue_context_modif_req_t *req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); - protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance}; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); - f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); - uint32_t incoming_teid = 0; - NR_CellGroupConfig_t *cellGroupConfig = NULL; - - /* Configure SRB2 */ - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_SRB_ToAddModList_t *SRB_configList = NULL; - uint8_t SRBs_before_new_addition = 0; - - if(req->srbs_to_be_setup_length>0){ - if (UE->SRB_configList == NULL) { - LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); - UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList)); - } - SRB_configList = UE->SRB_configList; - SRBs_before_new_addition = SRB_configList->list.count; - for (int i=0; isrbs_to_be_setup_length; i++){ - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id; - asn1cSeqAdd(&SRB_configList->list, SRB2_config); - } - } - - /* Configure DRB */ - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t *DRB_configList = NULL; - int drb_id_to_setup_start = 0; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - if(req->drbs_to_be_setup_length>0){ - if (UE->DRB_configList == NULL) { - UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList)); - } - DRB_configList = UE->DRB_configList; - for (int i=0; idrbs_to_be_setup_length; i++){ - DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; - if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&DRB_configList->list, DRB_config); - f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; - transport_layer_addr_t addr; - memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); - addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; - extern instance_t DUuniqInstance; - if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; - incoming_teid = newGtpuCreateTunnel(DUuniqInstance, - req->rnti, - drb_p.drb_id, - drb_p.drb_id, - drb_p.up_ul_tnl[0].teid, - -1, // no qfi - addr, - drb_p.up_ul_tnl[0].port, - DURecvCb, - NULL); - /* TODO: hardcoded to 13 for the time being, to be changed? */ - drb_priority[DRB_config->drb_Identity-1] = 13; - } - } - - if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig, - UE->masterCellGroup, - rrc->um_on_default_drb, - drb_id_to_setup_start < 2 ? 1 : 0, - DRB_configList, - drb_priority); - apply_macrlc_config(rrc, ue_context_p, &ctxt); - } - if(req->ReconfigComplOutcome == RRCreconf_failure){ - LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n"); - } - else if(req->ReconfigComplOutcome == RRCreconf_success){ - LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n"); - if (UE->DRB_configList != NULL) { - LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); - uint8_t drb_id = UE->DRB_configList->list.array[0]->drb_Identity; - rnti_t rnti = UE->rnti; - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3); - LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); - MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, - sizeof(gtpv1u_tunnel_data_req_t)); - gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg); - req->pdusession_id = drb_id; - req->ue_id = rnti; - req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead - extern instance_t DUuniqInstance; - itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); - } - } - - /* Fill the UE context setup response ITTI message to send to F1AP */ - resp->gNB_CU_ue_id = req->gNB_CU_ue_id; - resp->rnti = ctxt.rntiMaybeUEid; - if(DRB_configList){ - if(DRB_configList->list.count > 0){ - resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); - resp->drbs_to_be_setup_length = DRB_configList->list.count; - for (int i=0; ilist.count; i++){ - resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; - resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; - resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid; - resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr); - resp->drbs_to_be_setup[i].up_dl_tnl_length = 1; - } - } - else{ - LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n"); - } - } - if(SRB_configList){ - if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){ - resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t)); - resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; - for (int i=SRBs_before_new_addition; ilist.count; i++){ - resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity; - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); - } - - //if(cellGroupConfig != NULL) { - resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t)); - resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - UE->masterCellGroup, //(void *)cellGroupConfig, - resp->du_to_cu_rrc_information->cellGroupConfig, - 1024); - resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; - //} - itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); -} - static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance) { f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); @@ -3004,10 +2855,6 @@ void *rrc_gnb_task(void *args_p) { rrc_CU_process_ue_context_modification_response(msg_p, instance); break; - case F1AP_UE_CONTEXT_MODIFICATION_REQ: - rrc_DU_process_ue_context_modification_request(msg_p, instance); - break; - case F1AP_UE_CONTEXT_RELEASE_REQ: rrc_CU_process_ue_context_release_request(msg_p); break; From 62ca311a1ae4ca8422d0b09a8ff27a5e229063e1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 May 2023 11:46:16 +0200 Subject: [PATCH 31/39] Handle GTP for DL in F1AP message encoder --- openair2/F1AP/f1ap_du_ue_context_management.c | 44 ++++++++++++------- openair2/RRC/NR/rrc_gNB.c | 17 ------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 10aa0ac1dc..40f33fd59d 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -37,29 +37,24 @@ #include "f1ap_du_ue_context_management.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" -#include "rrc_extern.h" -#include "openair2/RRC/NR/rrc_gNB_UE_context.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include -bool lteDURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) +{ // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); - // weird rb id management in 4G, not fully understand (looks bad design) - // overcomplex: if i understand, on the interface DRB start at 4 because there can be SRB 0..3 - // but it would be much simpler to use absolute numbering - // instead of this "srb flag" associated to these +/-4 - du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP-4,muiP, confirmP, sdu_buffer_sizeP, sdu); + du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); return true; } @@ -1058,6 +1053,21 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; + transport_layer_addr_t tl_addr = {0}; + memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); + tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; + drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(false, instance)->gtpInst, + resp->rnti, + drb->drb_id, + drb->drb_id, + drb->up_ul_tnl[j].teid, + -1, // no qfi + tl_addr, + drb->up_ul_tnl[0].port, + DURecvCb, + NULL); + /* ADD */ asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 696646096e..b0a4b812c5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -111,23 +111,6 @@ mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -bool DURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { - // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue - mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); - memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); - du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP,muiP, confirmP, sdu_buffer_sizeP, sdu); - return true; -} - static void nr_rrc_addmod_srbs(int rnti, const NR_SRB_ToAddModList_t *srb_list, const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) From 7c953e2c5ab7730799ea7445411c6020aeececef Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 15 May 2023 18:55:47 +0200 Subject: [PATCH 32/39] Remove RLC mode from SRBs: does not exist --- openair2/COMMON/f1ap_messages_types.h | 1 - openair2/RRC/NR/rrc_gNB.c | 1 - 2 files changed, 2 deletions(-) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 6ea19f39a6..08cc03c4fa 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -341,7 +341,6 @@ typedef struct f1ap_drb_to_be_setup_s { typedef struct f1ap_srb_to_be_setup_s { long srb_id; - rlc_mode_t rlc_mode; uint8_t lcid; } f1ap_srb_to_be_setup_t; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b0a4b812c5..8cb76ac743 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2633,7 +2633,6 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex f1ap_srb_to_be_setup_t srbs[nb_srb]; srbs[0].srb_id = 2; srbs[0].lcid = 2; - srbs[0].rlc_mode = RLC_MODE_AM; f1ap_ue_context_modif_req_t ue_context_modif_req = { .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ From 26352018826ba7e5d22576f8245e60aa603685e1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 May 2023 17:54:55 +0200 Subject: [PATCH 33/39] Remove per-UE RRC stuff --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e9a985b670..9794a55e7e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -44,10 +44,6 @@ #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" -/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ -#include "RRC/NR/nr_rrc_extern.h" -#include "RRC/NR/rrc_gNB_UE_context.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" @@ -2944,12 +2940,6 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) UE->CellGroup = cellGroupConfig; nr_mac_update_cellgroup(mac, UE->rnti, cellGroupConfig); - /* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ - if (NODE_IS_DU(rrc->node_type)) { - rrc_gNB_ue_context_t *ue = rrc_gNB_create_ue_context(UE->rnti, rrc, UE->rnti); - ue->ue_context.masterCellGroup = cellGroupConfig; - } - /* activate SRB0 */ nr_rlc_activate_srb0(UE->rnti, mac, UE, send_initial_ul_rrc_message); From e7ef1f6879b32b86b69ba2ff41798a9ad15a6841 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 21 May 2023 15:43:32 +0200 Subject: [PATCH 34/39] Implement UE Context Modification using F1AP --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 35 ++++++++++++++++++-- openair2/RRC/NR/mac_rrc_dl_f1ap.c | 30 +++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index e1818917dc..f122a13c34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -62,9 +62,38 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_req_t *req, const f1ap_ue_context_modif_resp_t *resp) { - (void)req; - (void)resp; - AssertFatal(false, "not implemented\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); + /* copy all fields, but reallocate rrc_containers! */ + *f1ap_msg = *resp; + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + if (resp->drbs_to_be_setup_length > 0) { + DevAssert(resp->drbs_to_be_setup != NULL); + f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i) + f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i]; + } + + if (resp->du_to_cu_rrc_information != NULL) { + f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + } + + itti_send_msg_to_task(TASK_DU_F1, 0, msg); } static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 5c4637dde2..5bfeda2dc8 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -30,6 +30,8 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); *f1ap_msg = *req; AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); + AssertFatal(req->drbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); + AssertFatal(req->srbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); if (req->rrc_container_length > 0) { f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); @@ -41,8 +43,32 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) { - (void)req; - AssertFatal(false, "not implemented yet\n"); + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); + *f1ap_msg = *req; + AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); + AssertFatal(req->drbs_to_be_modified_length == 0, "drbs_to_be_modified not supported yet\n"); + if (req->drbs_to_be_setup_length > 0) { + int n = req->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup_length = n; + f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup)); + AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n"); + memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup)); + } + if (req->srbs_to_be_setup_length > 0) { + int n = req->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup_length = n; + f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup)); + AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n"); + memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup)); + } + if (req->rrc_container_length > 0) { + f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); + AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); + f1ap_msg->rrc_container_length = req->rrc_container_length; + memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); + } + itti_send_msg_to_task(TASK_CU_F1, 0, msg); } static void ue_context_release_command_f1ap(const f1ap_ue_context_release_cmd_t *cmd) From 20e986be7d0e633c486f33b5ee7e53f92d5364fb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 May 2023 12:30:50 +0200 Subject: [PATCH 35/39] Reduce F1AP logging output that is not an error --- openair2/F1AP/f1ap_du_ue_context_management.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 40f33fd59d..9aa3c42213 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -133,7 +133,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size; - LOG_I(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + LOG_D(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); } } @@ -831,7 +831,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso if(f1ap_ue_context_modification_req->rnti<0) LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); else - LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); + LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); /* SRB */ F1AP_UEContextModificationRequestIEs_t *ieSrb; @@ -957,7 +957,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n"); } } else { - LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); + LOG_D(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); } ue_context_modification_request(f1ap_ue_context_modification_req); From 307e08cbc7cf92248af63683c6b0187b38c8cb4b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 May 2023 12:27:17 +0200 Subject: [PATCH 36/39] Reconfig complete: send ack to DU --- openair2/RRC/NR/rrc_gNB.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 8cb76ac743..5b2717a442 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2029,6 +2029,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid); + bool successful_reconfig = true; if (get_softmodem_params()->sa) { switch (UE->xids[xid]) { case RRC_PDUSESSION_RELEASE: { @@ -2047,10 +2048,29 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_FIRST_RECONF: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; + case RRC_DEFAULT_RECONF: + /* nothing to do */ + break; default: LOG_E(RRC, "Received unexpected xid: %d\n", xid); + successful_reconfig = false; + break; } } + + gNB_RRC_INST *rrc = RC.nrrrc[0]; + f1ap_ue_context_modif_req_t ue_context_modif_req = { + .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .rnti = UE->rnti, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure, + }; + rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } //----------------------------------------------------------------------------- int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, From 981d91bfe7de42906e70997cc5407790c8f7f603 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 26 May 2023 09:26:03 +0200 Subject: [PATCH 37/39] assertion to avoid config file with more logical than physical antenna ports --- executables/nr-ru.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 01a5e7fea8..857557c9e5 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1829,18 +1829,30 @@ void stop_RU(int nb_ru) { /* --------------------------------------------------------*/ /* from here function to use configuration module */ -static void NRRCconfig_RU(void) { - int i = 0, j = 0; +static void NRRCconfig_RU(void) +{ paramdef_t RUParams[] = RUPARAMS_DESC; paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; - config_getlist( &RUParamList, RUParams, sizeof(RUParams)/sizeof(paramdef_t), NULL); + config_getlist(&RUParamList, RUParams, sizeof(RUParams)/sizeof(paramdef_t), NULL); - if ( RUParamList.numelt > 0) { + paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + paramdef_t GNBParams[] = GNBPARAMS_DESC; + paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0}; + config_get(GNBSParams, sizeof(GNBSParams) / sizeof(paramdef_t), NULL); + int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; + AssertFatal(num_gnbs > 0, "Failed to parse config file no gnbs %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS); + config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL); + int N1 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr; + int N2 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr; + int XP = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr; + int num_logical_antennas = N1 * N2 * XP; + + if (RUParamList.numelt > 0) { RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); - RC.ru_mask=(1<idx = j; @@ -1849,12 +1861,13 @@ static void NRRCconfig_RU(void) { printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); RC.ru[j]->if_timing = synch_to_ext_device; - if (RC.nb_nr_L1_inst >0) + if (RC.nb_nr_L1_inst > 0) RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; else RC.ru[j]->num_gNB = 0; - for (i=0; inum_gNB; i++) RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]]; + for (int i = 0; i < RC.ru[j]->num_gNB; i++) + RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]]; if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); @@ -1909,7 +1922,7 @@ static void NRRCconfig_RU(void) { RC.ru[j]->openair0_cfg.tune_offset = get_softmodem_params()->tune_offset; if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { + if (!(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX))) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = gNodeB_3GPP; printf("Setting function for RU %d to gNodeB_3GPP\n",j); @@ -1983,6 +1996,8 @@ static void NRRCconfig_RU(void) { } /* strcmp(local_rf, "yes") != 0 */ RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); + AssertFatal(RC.ru[j]->nb_tx >= num_logical_antennas, + "Number of logical antenna ports (set in config file with pdsch_AntennaPorts) cannot be larger than physical antennas (nb_tx)\n"); RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); @@ -1991,7 +2006,8 @@ static void NRRCconfig_RU(void) { RC.ru[j]->do_precoding = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr); RC.ru[j]->sl_ahead = *(RUParamList.paramarray[j][RU_SL_AHEAD].iptr); RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - for (i=0; inum_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + for (int i = 0; i < RC.ru[j]->num_bands; i++) + RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; RC.ru[j]->openair0_cfg.nr_flag = *(RUParamList.paramarray[j][RU_NR_FLAG].iptr); RC.ru[j]->openair0_cfg.nr_band = RC.ru[j]->band[0]; RC.ru[j]->openair0_cfg.nr_scs_for_raster = *(RUParamList.paramarray[j][RU_NR_SCS_FOR_RASTER].iptr); @@ -2003,14 +2019,15 @@ static void NRRCconfig_RU(void) { RC.ru[j]->ru_thread_core = *(RUParamList.paramarray[j][RU_RU_THREAD_CORE].iptr); printf("[RU %d] Setting half-slot parallelization to %d\n",j,RC.ru[j]->half_slot_parallelization); AssertFatal(RC.ru[j]->num_tpcores <= RUParamList.paramarray[j][RU_TP_CORES].numelt, "Number of TP cores should be <=16\n"); - for (i=0; inum_tpcores; i++) RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i]; + for (int i = 0; i < RC.ru[j]->num_tpcores; i++) + RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i]; if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; - for (i=0; inum_gNB; i++) { + for (int i = 0; i < RC.ru[j]->num_gNB; i++) { RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t)); - - for (int b=0; bnb_bfw; b++) RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + for (int b = 0; b < RC.ru[j]->nb_bfw; b++) + RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; } } }// j=0..num_rus From bef1a28d6d972b3b8460ad97fdca218539856213 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 26 May 2023 12:29:23 +0200 Subject: [PATCH 38/39] Remove misleading comment --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 05ee8efe52..d5e3cf30d4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -175,7 +175,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing); if (is_x2ap_enabled()) - x2ap_trigger(); /* if none of the above options, it must be NSA */ + x2ap_trigger(); } for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { From c9012298de30013ace9b877219d7dc8d368f98fa Mon Sep 17 00:00:00 2001 From: mir Date: Thu, 11 May 2023 08:52:28 +0200 Subject: [PATCH 39/39] OSA SECU harmonization --- CMakeLists.txt | 45 +-- openair1/SIMULATION/NR_PHY/dlsim.c | 8 +- openair1/SIMULATION/NR_PHY/prachsim.c | 8 +- openair1/SIMULATION/NR_PHY/ulsim.c | 8 +- openair2/E1AP/e1ap_api.c | 11 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 36 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 11 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c | 44 +-- openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c | 4 - .../LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c | 13 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 8 - openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LTE/rrc_UE.c | 35 +- openair2/RRC/LTE/rrc_eNB.c | 29 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 29 +- openair2/RRC/NR/MESSAGES/asn1_msg.c | 4 +- openair2/RRC/NR/cucp_cuup_direct.c | 21 +- openair2/RRC/NR/cucp_cuup_e1ap.c | 3 +- openair2/RRC/NR/rrc_gNB.c | 42 +-- openair2/RRC/NR/rrc_gNB_NGAP.c | 16 +- openair2/RRC/NR/rrc_gNB_nsa.c | 12 +- openair2/RRC/NR_UE/rrc_UE.c | 62 ++-- openair2/UTIL/OSA/README | 18 - openair2/UTIL/OSA/osa_defs.h | 138 ------- openair2/UTIL/OSA/osa_key_deriver.c | 175 --------- openair2/UTIL/OSA/osa_snow3g.c | 344 ------------------ openair2/UTIL/OSA/osa_snow3g.h | 77 ---- openair2/UTIL/OSA/osa_stream_eea.c | 181 --------- openair2/UTIL/OSA/osa_stream_eia.c | 287 --------------- openair3/COMMON/common_types.h | 2 - openair3/COMMON/security_types.h | 44 --- openair3/NAS/COMMON/API/NETWORK/nas_message.c | 21 +- openair3/NAS/COMMON/milenage.h | 97 +++-- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 14 +- openair3/SECU/aes_128.h | 3 +- openair3/SECU/aes_128_ecb.c | 53 +++ openair3/SECU/aes_128_ecb.h | 30 ++ openair3/SECU/key_nas_deriver.c | 242 ++++++++++-- openair3/SECU/key_nas_deriver.h | 33 ++ openair3/SECU/nas_stream_eea0.c | 44 +++ .../SECU/nas_stream_eea0.h | 32 +- openair3/SECU/nas_stream_eea1.c | 9 +- openair3/SECU/nas_stream_eea1.h | 32 ++ openair3/SECU/nas_stream_eea2.c | 6 +- .../SECU/nas_stream_eea2.h | 10 + openair3/SECU/nas_stream_eia1.c | 19 +- openair3/SECU/nas_stream_eia1.h | 29 ++ openair3/SECU/nas_stream_eia2.c | 9 +- openair3/SECU/nas_stream_eia2.h | 29 ++ openair3/SECU/secu_defs.c | 106 ++---- openair3/SECU/secu_defs.h | 68 ++-- openair3/TEST/test_secu_knas_encrypt_eea1.c | 3 +- openair3/TEST/test_secu_knas_encrypt_eea2.c | 4 +- 53 files changed, 832 insertions(+), 1778 deletions(-) delete mode 100644 openair2/UTIL/OSA/README delete mode 100644 openair2/UTIL/OSA/osa_defs.h delete mode 100644 openair2/UTIL/OSA/osa_key_deriver.c delete mode 100644 openair2/UTIL/OSA/osa_snow3g.c delete mode 100644 openair2/UTIL/OSA/osa_snow3g.h delete mode 100644 openair2/UTIL/OSA/osa_stream_eea.c delete mode 100644 openair2/UTIL/OSA/osa_stream_eia.c create mode 100644 openair3/SECU/aes_128_ecb.c create mode 100644 openair3/SECU/aes_128_ecb.h create mode 100644 openair3/SECU/key_nas_deriver.h create mode 100644 openair3/SECU/nas_stream_eea0.c rename openair2/UTIL/OSA/osa_internal.h => openair3/SECU/nas_stream_eea0.h (59%) create mode 100644 openair3/SECU/nas_stream_eea1.h rename openair2/UTIL/OSA/osa_rijndael.h => openair3/SECU/nas_stream_eea2.h (96%) create mode 100644 openair3/SECU/nas_stream_eia1.h create mode 100644 openair3/SECU/nas_stream_eia2.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b0d99e805f..a4a4b94028 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -773,33 +773,25 @@ add_library(UTIL ${OPENAIR_DIR}/common/utils/time_stat.c ) -set(SECU_OSA_SRC - ${OPENAIR2_DIR}/UTIL/OSA/osa_key_deriver.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eea.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c - ) -add_library(SECU_OSA ${SECU_OSA_SRC} $ ) - -target_include_directories(SECU_OSA PRIVATE ${OPENAIR_DIR}/common/utils/ds/) - -set(SECU_CN_SRC +set(SECURITY_SRC ${OPENAIR3_DIR}/SECU/secu_defs.c ${OPENAIR3_DIR}/SECU/kdf.c ${OPENAIR3_DIR}/SECU/aes_128_ctr.c ${OPENAIR3_DIR}/SECU/aes_128_cbc_cmac.c + ${OPENAIR3_DIR}/SECU/aes_128_ecb.c ${OPENAIR3_DIR}/SECU/sha_256_hmac.c ${OPENAIR3_DIR}/SECU/rijndael.c ${OPENAIR3_DIR}/SECU/snow3g.c ${OPENAIR3_DIR}/SECU/key_nas_deriver.c + ${OPENAIR3_DIR}/SECU/nas_stream_eea0.c ${OPENAIR3_DIR}/SECU/nas_stream_eea1.c ${OPENAIR3_DIR}/SECU/nas_stream_eia1.c ${OPENAIR3_DIR}/SECU/nas_stream_eea2.c ${OPENAIR3_DIR}/SECU/nas_stream_eia2.c ) -add_library(SECU_CN ${SECU_CN_SRC} $) -target_include_directories(SECU_CN PRIVATE ${OPENAIR_DIR}/common/utils/ds/) +add_library(SECURITY ${SECURITY_SRC} $) +target_include_directories(SECURITY PRIVATE ${OPENAIR_DIR}/common/utils/ds/) # Physical Channel Procedures Scheduling ################################" @@ -1350,8 +1342,8 @@ set(NR_PDCP_SRC #these files should not be here, will be removed at some point when the #computation is done directly inside nr_pdcp_integrity_nia1.c instead #of reusing code of osa_stream_eia.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c + #${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c + #${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c ) set(NR_SDAP_SRC @@ -1993,7 +1985,7 @@ add_library(LIB_5GNAS_GNB ) target_include_directories(LIB_5GNAS_GNB PRIVATE ${OPENAIR_DIR}/common/utils/ds/) -target_link_libraries(LIB_5GNAS_GNB PRIVATE SECU_CN ${CRYPTO_LIBRARIES}) +target_link_libraries(LIB_5GNAS_GNB PRIVATE SECURITY ${CRYPTO_LIBRARIES}) target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) # Simulation library @@ -2156,7 +2148,7 @@ add_dependencies(lte-softmodem oai_iqplayer) target_link_libraries(lte-softmodem PRIVATE -Wl,--start-group - lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB + lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECURITY UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${NAS_UE_LIB} ITTI SIMU SIMU_ETH -Wl,--end-group z dl) @@ -2165,7 +2157,6 @@ target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYP target_link_libraries(lte-softmodem PRIVATE ${T_LIB}) target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) - add_executable(oairu ${OPENAIR_DIR}/executables/lte-ru.c ${OPENAIR_DIR}/executables/ru_control.c @@ -2218,7 +2209,7 @@ endif() target_link_libraries(lte-uesoftmodem PRIVATE -Wl,--start-group lte_rrc nr_rrc s1ap x2ap m2ap m3ap - SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON + SECURITY UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU L2_UE L2_LTE SIMU SIMU_ETH NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${NAS_UE_LIB} ITTI ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -2258,7 +2249,7 @@ add_executable(nr-softmodem target_link_libraries(nr-softmodem PRIVATE -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY ITTI ${NAS_UE_LIB} lte_rrc nr_rrc ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU SIMU_ETH x2ap f1ap m2ap m3ap e1ap @@ -2293,9 +2284,9 @@ add_executable(nr-cuup target_link_libraries(nr-cuup PRIVATE CONFIG_LIB ITTI SCTP_CLIENT GTPV1U e1ap e1_pdcp_if f1ap SIMU_ETH - SECU_OSA SECU_CN ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) + SECURITY ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) - + # nr-uesoftmodem is UE implementation ####################################### @@ -2320,7 +2311,7 @@ add_executable(nr-uesoftmodem target_link_libraries(nr-uesoftmodem PRIVATE -Wl,--start-group - nr_rrc SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB + nr_rrc SECURITY UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_NR_LIB ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} SIMU SIMU_ETH @@ -2464,7 +2455,7 @@ add_executable(nr_dlsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECU_CN ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2513,7 +2504,7 @@ if (ENABLE_LDPC_T1) endif() target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECU_CN ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2552,7 +2543,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} CONFIG_LIB + -Wl,--start-group SECURITY UTIL -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} CONFIG_LIB ) endforeach(myExe) @@ -2573,7 +2564,7 @@ if (${T_TRACER}) ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap params_libconfig oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer oai_eth_transpro oai_mobipass coding HASHTABLE UTIL OMG_SUMO - SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL + SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1f35072552..c0c8dac7aa 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -98,9 +98,8 @@ nfapi_ue_release_request_body_t release_rntis; instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) +void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - return 0; } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } @@ -124,10 +123,9 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } void processSlotTX(void *arg) {} diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 3f7087afa5..15ef6a1694 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -96,9 +96,8 @@ void deref_sched_response(int _) exit(1); } -int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) +void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - return 0; } void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) @@ -120,10 +119,9 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } nrUE_params_t nrUE_params; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 4ee528a6fc..835ba9ef99 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -94,9 +94,8 @@ nfapi_ue_release_request_body_t release_rntis; instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) +void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - return 0; } extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration @@ -133,10 +132,9 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, nr_bler_struct nr_bler_data[NR_NUM_MCS]; -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } void processSlotTX(void *arg) {} diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index b67525acca..6bbc827e84 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -23,11 +23,12 @@ #include #include "e1ap_api.h" -#include "UTIL/OSA/osa_defs.h" + #include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/RRC/NR/cucp_cuup_if.h" #include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" +#include "openair3/SECU/key_nas_deriver.h" #include "openair3/ocp-gtpu/gtp_itf.h" #include "e1ap_asnc.h" #include "e1ap_common.h" @@ -120,12 +121,12 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, } // Configure DRBs - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; - nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, &kUPenc); + nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, kUPenc); - nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, &kUPint); + nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, kUPint); nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE create_tunnel_req.ue_id, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index b7de2ffad4..b52f3fb9b4 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -50,14 +50,13 @@ #include "common/openairinterface5g_limits.h" #include "executables/lte-softmodem.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" -#include "UTIL/OSA/osa_defs.h" #include "openair2/RRC/NAS/nas_config.h" #include "intertask_interface.h" #include "openair3/S1AP/s1ap_eNB.h" #include #include "pdcp.h" -# include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair3/ocp-gtpu/gtp_itf.h" #include #include "ENB_APP/enb_config.h" @@ -2028,19 +2027,6 @@ pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, // pdcp_remove_UE(ctxt_pP); } - /* Security keys */ - if (pdcp_pP->kUPenc != NULL) { - free(pdcp_pP->kUPenc); - } - - if (pdcp_pP->kRRCint != NULL) { - free(pdcp_pP->kRRCint); - } - - if (pdcp_pP->kRRCenc != NULL) { - free(pdcp_pP->kRRCenc); - } - memset(pdcp_pP, 0, sizeof(pdcp_t)); break; @@ -2105,9 +2091,11 @@ pdcp_config_set_security( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), pdcp_pP->cipheringAlgorithm, pdcp_pP->integrityProtAlgorithm); - pdcp_pP->kRRCenc = kRRCenc; - pdcp_pP->kRRCint = kRRCint; - pdcp_pP->kUPenc = kUPenc; + + kRRCenc != NULL ? memcpy(pdcp_pP->kRRCenc, kRRCenc, 32) : memset(pdcp_pP->kRRCenc, 0, 32); + kRRCint != NULL ? memcpy(pdcp_pP->kRRCint, kRRCint, 32) : memset(pdcp_pP->kRRCint, 0, 32); + kUPenc != NULL ? memcpy(pdcp_pP->kUPenc, kUPenc, 32) : memset(pdcp_pP->kUPenc, 0, 32); + /* Activate security */ pdcp_pP->security_activated = 1; } @@ -2328,18 +2316,6 @@ pdcp_free ( pdcp_t *pdcp_p = (pdcp_t *)pdcp_pP; if (pdcp_p != NULL) { - if (pdcp_p->kUPenc != NULL) { - free(pdcp_p->kUPenc); - } - - if (pdcp_p->kRRCint != NULL) { - free(pdcp_p->kRRCint); - } - - if (pdcp_p->kRRCenc != NULL) { - free(pdcp_p->kRRCenc); - } - memset(pdcp_pP, 0, sizeof(pdcp_t)); free(pdcp_pP); } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 043ac7fb4a..9f4cdefb3b 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -45,6 +45,7 @@ #include "LTE_MBMS-SessionInfoList-r9.h" #include "LTE_PMCH-InfoList-r9.h" +#include "openair3/SECU/secu_defs.h" typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const, const srb_flag_t, const MBMS_flag_t, @@ -161,17 +162,17 @@ typedef struct pdcp_s { bool is_srb; /* Configured security algorithms */ - uint8_t cipheringAlgorithm; - uint8_t integrityProtAlgorithm; + eea_alg_id_e cipheringAlgorithm; + eia_alg_id_e integrityProtAlgorithm; /* User-Plane encryption key * Control-Plane RRC encryption key * Control-Plane RRC integrity key * These keys are configured by RRC layer */ - uint8_t *kUPenc; - uint8_t *kRRCint; - uint8_t *kRRCenc; + uint8_t kUPenc[32]; + uint8_t kRRCint[32]; + uint8_t kRRCenc[32]; uint8_t security_activated; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 6664dd2a33..a88d4028ae 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -30,7 +30,6 @@ #include "assertions.h" #include "common/utils/LOG/log.h" -#include "UTIL/OSA/osa_defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "executables/softmodem-common.h" @@ -39,6 +38,8 @@ #include "pdcp.h" #include "pdcp_primitives.h" +#include "openair3/SECU/secu_defs.h" + //----------------------------------------------------------------------------- static uint32_t pdcp_get_next_count_tx( @@ -110,7 +111,7 @@ pdcp_apply_security( ) { uint8_t *buffer_encrypted = NULL; - stream_cipher_t encrypt_params; + nas_stream_cipher_t encrypt_params = {0}; DevAssert(pdcp_pP != NULL); DevAssert(pdcp_pdu_buffer != NULL); @@ -156,9 +157,7 @@ pdcp_apply_security( buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len]; /* Apply ciphering if any requested */ - stream_encrypt(pdcp_pP->cipheringAlgorithm, - &encrypt_params, - &buffer_encrypted); + stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &encrypt_params, buffer_encrypted); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT); @@ -180,7 +179,7 @@ pdcp_validate_security( ) { uint8_t *buffer_decrypted = NULL; - stream_cipher_t decrypt_params; + nas_stream_cipher_t decrypt_params = {0}; DevAssert(pdcp_pP != NULL); @@ -199,33 +198,36 @@ pdcp_validate_security( decrypt_params.key_length = 16; if (srb_flagP) { - LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", - rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); + LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kRRCenc;// + 128; } else { - LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", - rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); + LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kUPenc;// + 128; } /* Uncipher the block */ - stream_decrypt(pdcp_pP->cipheringAlgorithm, - &decrypt_params, - &buffer_decrypted); + stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &decrypt_params, buffer_decrypted); + if (!IS_SOFTMODEM_IQPLAYER) { if (srb_flagP) { - /* Now check the integrity of the complete PDU */ + /* Now check the integrity of the complete PDU */ decrypt_params.message = pdcp_pdu_buffer; decrypt_params.blength = sdu_buffer_size << 3; decrypt_params.key = pdcp_pP->kRRCint + 16;// 128; - if (stream_check_integrity(pdcp_pP->integrityProtAlgorithm, - &decrypt_params, - &pdcp_pdu_buffer[sdu_buffer_size]) != 0) { - LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", - rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); - return -1; + if (pdcp_pP->integrityProtAlgorithm != EIA0_ALG_ID) { + uint8_t result[4] = {0}; + stream_compute_integrity(pdcp_pP->integrityProtAlgorithm, &decrypt_params, result); + + if (memcmp(result, &pdcp_pdu_buffer[sdu_buffer_size], 4) != 0) { + LOG_E(PDCP, + "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + rb_id, + (pdcp_pP->is_ue != 0) ? "UE" : "eNB", + ((long long unsigned int *)decrypt_params.key)[0]); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); + return -1; + } } } } /* !IQPLAYER */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index b102bf3b7f..d56c22f609 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -52,8 +52,4 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, } } else LOG_W(PDCP, "%s with void list\n", __FUNCTION__); - if (kUPenc) - free(kUPenc); - if (kUPint) - free(kUPint); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c index 08ec959937..a005bbbdf6 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c @@ -26,13 +26,12 @@ #include #include -#include "UTIL/OSA/osa_defs.h" - -int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]); +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key) { - stream_cipher_t *ret; + nas_stream_cipher_t *ret; ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort(); ret->key = malloc(16); if (ret->key == NULL) abort(); @@ -47,7 +46,7 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context, unsigned char *buffer, int length, int bearer, int count, int direction) { - stream_cipher_t *ctx = integrity_context; + nas_stream_cipher_t *ctx = integrity_context; ctx->message = buffer; ctx->count = count; @@ -55,12 +54,12 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context, ctx->direction = direction; ctx->blength = length * 8; - stream_compute_integrity_eia1(ctx, out); + stream_compute_integrity(EIA1_128_ALG_ID, ctx, out); } void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context) { - stream_cipher_t *ctx = integrity_context; + nas_stream_cipher_t *ctx = integrity_context; free(ctx->key); free(ctx); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ebd2d17842..0157a3596b 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -920,10 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo } } else LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); - if (kRRCenc) - free(kRRCenc); - if (kRRCint) - free(kRRCint); } void nr_pdcp_add_drbs(eNB_flag_t enb_flag, @@ -941,10 +937,6 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); - if (kUPenc) - free(kUPenc); - if (kUPint) - free(kUPint); } /* Dummy function due to dependency from LTE libraries */ diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9128b0f50e..dc79541624 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -104,7 +104,7 @@ #include "common/ran_context.h" -#include "secu_defs.h" +#include "key_nas_deriver.h" #if !defined (msg) #define msg printf diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 022875bc68..0cdac830d0 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -73,7 +73,7 @@ #include "rrc_UE_ral.h" #endif -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" #include "pdcp.h" #include "plmn_data.h" @@ -1246,12 +1246,11 @@ rrc_ue_process_radioResourceConfigDedicated( // Establish SRBs if present // loop through SRBToAddModList if (radioResourceConfigDedicated->srb_ToAddModList) { - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); - derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + derive_key_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCint); + // Refresh SRBs rrc_pdcp_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, @@ -1397,9 +1396,9 @@ rrc_ue_process_radioResourceConfigDedicated( LOG_I(RRC,"[UE %d] default DRB = %ld\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB); } - uint8_t *kUPenc = NULL; - derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); + uint8_t kUPenc[32] = {0}; + derive_key_nas(UP_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kUPenc); + // Refresh DRBs rrc_pdcp_config_asn1_req(ctxt_pP, (LTE_SRB_ToAddModList_t *)NULL, @@ -1549,9 +1548,9 @@ rrc_ue_process_securityModeCommand( ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure; } - uint8_t *kRRCenc = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kRRCint = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kUPenc[32] = {0}; + uint8_t kRRCint[32] = {0}; pdcp_t *pdcp_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; @@ -1577,12 +1576,10 @@ rrc_ue_process_securityModeCommand( UE_rrc_inst[ctxt_pP->module_id].kenb[20], UE_rrc_inst[ctxt_pP->module_id].kenb[21], UE_rrc_inst[ctxt_pP->module_id].kenb[22], UE_rrc_inst[ctxt_pP->module_id].kenb[23], UE_rrc_inst[ctxt_pP->module_id].kenb[24], UE_rrc_inst[ctxt_pP->module_id].kenb[25], UE_rrc_inst[ctxt_pP->module_id].kenb[26], UE_rrc_inst[ctxt_pP->module_id].kenb[27], UE_rrc_inst[ctxt_pP->module_id].kenb[28], UE_rrc_inst[ctxt_pP->module_id].kenb[29], UE_rrc_inst[ctxt_pP->module_id].kenb[30], UE_rrc_inst[ctxt_pP->module_id].kenb[31]); - derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); - derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); - derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); + + derive_key_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCint); + derive_key_nas(UP_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kUPenc); if (securityMode != 0xff) { pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index c2bf7a82f9..348e1a9fd4 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -44,7 +44,6 @@ #include "RRC/LTE/MESSAGES/asn1_msg.h" #include "LTE_RRCConnectionRequest.h" #include "LTE_RRCConnectionReestablishmentRequest.h" -//#include "ReestablishmentCause.h" #include "LTE_BCCH-BCH-Message.h" #include "LTE_UL-CCCH-Message.h" #include "LTE_DL-CCCH-Message.h" @@ -81,15 +80,14 @@ #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" -#include "UTIL/OSA/osa_defs.h" - #include "rrc_eNB_S1AP.h" #include "rrc_eNB_GTPV1U.h" #include "rrc_eNB_M2AP.h" #include "pdcp.h" +#include "openair3/SECU/key_nas_deriver.h" +#include "openair3/SECU/secu_defs.h" #include "openair3/ocp-gtpu/gtp_itf.h" -#include #include "intertask_interface.h" #include "softmodem-common.h" @@ -114,8 +112,9 @@ mui_t rrc_eNB_mui = 0; extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP); -extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP); -extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t *kenb_star); +extern void process_eNB_security_key(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *security_key_pP); extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config, OCTET_STRING_t *scg_RB_config); extern struct rrc_eNB_ue_context_s *get_first_ue_context(eNB_RRC_INST *rrc_instance_pP); @@ -5145,9 +5144,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( int drb_id; int oip_ifup = 0; int dest_ip_offset = 0; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + uint8_t kUPenc[32] = {0}; LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; @@ -5178,17 +5177,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* Derive the keys from kenb */ if (DRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kUPenc); + derive_key_nas(UP_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kUPenc); } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCint); + derive_key_nas(RRC_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, kRRCint); /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, SRB_configList, // NULL, diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index bc4fc6d8cd..141a70488e 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -46,12 +46,14 @@ #include "pdcp.h" #include "pdcp_primitives.h" -#include "UTIL/OSA/osa_defs.h" - #include "LTE_UERadioAccessCapabilityInformation.h" #include "openair3/ocp-gtpu/gtp_itf.h" #include + +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "RRC/LTE/rrc_eNB_GTPV1U.h" #include "TLVDecoder.h" @@ -485,9 +487,9 @@ rrc_pdcp_config_security( //------------------------------------------------------------------------------ { LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + uint8_t kUPenc[32] = {0}; pdcp_t *pdcp_p = NULL; static int print_keys= 1; hashtable_rc_t h_rc; @@ -495,19 +497,13 @@ rrc_pdcp_config_security( /* Derive the keys from kenb */ if (SRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kUPenc); + derive_key_nas(UP_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kUPenc); } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCint); - if (!IS_SOFTMODEM_IQPLAYER) { - SET_LOG_DUMP(DEBUG_SECURITY) ; + derive_key_nas(RRC_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, kRRCint); + if (!IS_SOFTMODEM_IQPLAYER) { + SET_LOG_DUMP(DEBUG_SECURITY); } @@ -953,6 +949,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char &ctxt, ue_context_p, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); + { uint8_t send_security_mode_command = true; rrc_pdcp_config_security( diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 51cf52bc63..2221843772 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -46,7 +46,9 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "asn1_msg.h" #include "../nr_rrc_proto.h" -#include "UTIL/OSA/osa_defs.h" + +#include "openair3/SECU/key_nas_deriver.h" + #include "RRC/NR/nr_rrc_extern.h" #include "NR_DL-CCCH-Message.h" #include "NR_UL-CCCH-Message.h" diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index d0d4365e70..fe47aca73b 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -29,7 +29,8 @@ #include "nr_rrc_proto.h" #include "nr_rrc_extern.h" #include "openair2/COMMON/e1ap_messages_types.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include @@ -38,6 +39,7 @@ #include "common/ran_context.h" #include "openair2/F1AP/f1ap_common.h" #include "openair2/E1AP/e1ap_common.h" + extern RAN_CONTEXT_t RC; void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, @@ -134,18 +136,19 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, 0); - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); - nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); } - nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); - nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %x\n", UE->rnti); diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index eeea7ed3a9..390ab232a7 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -29,7 +29,8 @@ #include "nr_rrc_extern.h" #include "cucp_cuup_if.h" #include "openair2/COMMON/e1ap_messages_types.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" + #include #include "common/ran_context.h" diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7941d1642b..ff6ec0180e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -75,7 +75,7 @@ #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" #include "rrc_gNB_NGAP.h" @@ -90,6 +90,7 @@ #include "executables/softmodem-common.h" #include #include +#include #include #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" @@ -1035,31 +1036,30 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid) { int drb_id; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList2[xid]; - NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList2[xid]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_p->DRB_Release_configList2[xid]; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; ue_p->ue_reestablishment_timer = 0; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); - nr_derive_key_up_int(ue_p->integrity_algorithm, ue_p->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kUPint); } - nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); + /* Refresh SRBs/DRBs */ - LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); - ue_id_t reestablish_ue_id = 0; if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) { for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { @@ -1226,16 +1226,16 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; /* Derive the keys from kgnb */ if (SRB_configList != NULL) { - nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); + nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); } - nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); /* Configure SRB1 for UE */ if (*SRB_configList != NULL) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d62a5466b3..d499fcf61e 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -47,7 +47,8 @@ #include "S1AP_NAS-PDU.h" #include "executables/softmodem-common.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "ngap_gNB_defs.h" #include "ngap_gNB_ue_context.h" #include "ngap_gNB_management_procedures.h" @@ -126,20 +127,21 @@ nr_rrc_pdcp_config_security( { NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; (void)SRB_configList; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; //uint8_t *k_kdf = NULL; static int print_keys= 1; gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; /* Derive the keys from kgnb */ if (UE->Srb[1].Active || UE->Srb[2].Active) { - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); } - nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); - nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + if (!IS_SOFTMODEM_IQPLAYER) { SET_LOG_DUMP(DEBUG_SECURITY) ; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a8d9241b7f..294ff79346 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -43,7 +43,9 @@ #include "executables/nr-softmodem.h" #include #include -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include #include "nr_pdcp/nr_pdcp_oai_api.h" #include "MESSAGES/asn1_msg.h" @@ -121,8 +123,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; - unsigned char *kUPenc = NULL; - unsigned char *kUPint = NULL; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; int i; gNB_RRC_UE_t *UE = &ue_context_p->ue_context; @@ -212,8 +214,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm); /* derive UP security key */ - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); - nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); e_NR_CipheringAlgorithm cipher_algo; switch (UE->ciphering_algorithm) { diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a3397a8de8..028807530a 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -57,7 +57,9 @@ #include "nr-uesoftmodem.h" #include "plmn_data.h" #include "nr_pdcp/nr_pdcp_oai_api.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -1522,18 +1524,22 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; } - uint8_t *kRRCenc = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kRRCint = NULL; - nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kUPenc); - nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kRRCenc); - nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kRRCint); + uint8_t kRRCenc[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + nr_derive_key(UP_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPenc); + nr_derive_key(RRC_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCenc); + nr_derive_key(RRC_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCint); + LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" "%02x%02x%02x%02x" "%02x%02x%02x%02x" @@ -1868,10 +1874,16 @@ nr_rrc_ue_establish_srb2( } } - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - nr_derive_key_rrc_enc(ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, &kRRCint); + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + nr_derive_key(RRC_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCenc); + nr_derive_key(RRC_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCint); // Refresh SRBs nr_pdcp_add_srbs(ctxt_pP->enb_flag, @@ -1959,12 +1971,16 @@ nr_rrc_ue_establish_srb2( } } - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; - - NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - nr_derive_key_up_enc(ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, &kUPenc); - nr_derive_key_up_int(ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, &kUPint); + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; + nr_derive_key(UP_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPenc); + nr_derive_key(UP_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPint); // Refresh DRBs nr_pdcp_add_drbs(ctxt_pP->enb_flag, diff --git a/openair2/UTIL/OSA/README b/openair2/UTIL/OSA/README deleted file mode 100644 index c605ebf379..0000000000 --- a/openair2/UTIL/OSA/README +++ /dev/null @@ -1,18 +0,0 @@ -OAISIM Security Algorithms v0.1 - -Dependencies: -- openssl >= 1.0.1 - -Compilation: - -When compiling oaisim, add SECU=1 to enable security features. The makefile will -check for required dependencies and disable this feature if not all dependencies -are met. - -OSA is based on 3GPP TS 33.401. -Note that only EEA2 and EIA2 algorithms are supported, SNOW-3G is not implemented. - -Currently the kenb used to derive kRRCint, kRRCenc and kUPenc is composed of the -UE_id. In the future this parameter can be either obtained by deriving KASME received -from core epc (in the S1AP initial context setup request) -or configurable via command line or XML file. diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h deleted file mode 100644 index c175f10c84..0000000000 --- a/openair2/UTIL/OSA/osa_defs.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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 - */ - -/*! - * \file secu_defs.h - * \brief Openair security algorithms functions implementing 3GPP TS 33.401 - * \note HMAC computations are done by openssl library - * \author Sebastien ROUX - * \date 2013 - * \version 0.1 - * @ingroup security -*/ - -#ifndef __UTIL_OSA_OSA_DEFS__H__ -#define __UTIL_OSA_OSA_DEFS__H__ - -#define EIA0_ALG_ID 0x00 -#define EIA1_128_ALG_ID 0x01 -#define EIA2_128_ALG_ID 0x02 - -#define EEA0_ALG_ID EIA0_ALG_ID -#define EEA1_128_ALG_ID EIA1_128_ALG_ID -#define EEA2_128_ALG_ID EIA2_128_ALG_ID - -#define SECU_DIRECTION_UPLINK 0 -#define SECU_DIRECTION_DOWNLINK 1 - -typedef enum { - NAS_ENC_ALG = 0x01, - NAS_INT_ALG = 0x02, - RRC_ENC_ALG = 0x03, - RRC_INT_ALG = 0x04, - UP_ENC_ALG = 0x05, - UP_INT_ALG = 0x06 -} algorithm_type_dist_t; - -//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); - -int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); - -int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t key[32], uint8_t **out); -int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out); - -int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star); - -//#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS) - -//#define derive_key_nas_int(aLGiD, kEY, kNAS) derive_key(NAS_INT_ALG, aLGiD, kEY, kNAS) - -#define derive_key_rrc_enc(aLGiD, kEY, kNAS) \ - derive_key(RRC_ENC_ALG, aLGiD, kEY, kNAS) - -#define derive_key_rrc_int(aLGiD, kEY, kNAS) \ - derive_key(RRC_INT_ALG, aLGiD, kEY, kNAS) - -#define derive_key_up_enc(aLGiD, kEY, kNAS) \ - derive_key(UP_ENC_ALG, aLGiD, kEY, kNAS) - -#define derive_key_up_int(aLGiD, kEY, kNAS) \ - derive_key(UP_INT_ALG, aLGiD, kEY, kNAS) - -// 5G SA -#define nr_derive_key_rrc_enc(aLGiD, kEY, kRRC) \ - nr_derive_key(RRC_ENC_ALG, aLGiD, kEY, kRRC) - -#define nr_derive_key_rrc_int(aLGiD, kEY, kRRC) \ - nr_derive_key(RRC_INT_ALG, aLGiD, kEY, kRRC) - -#define nr_derive_key_up_enc(aLGiD, kEY, kUP) \ - nr_derive_key(UP_ENC_ALG, aLGiD, kEY, kUP) - -#define nr_derive_key_up_int(aLGiD, kEY, kUP) \ - nr_derive_key(UP_INT_ALG, aLGiD, kEY, kUP) - -typedef struct { - uint8_t *key; - uint32_t key_length; - uint32_t count; - uint8_t bearer; - uint8_t direction; - uint8_t *message; - /* length in bits */ - uint32_t blength; -} stream_cipher_t; - -/*! - * @brief Encrypt/Decrypt a block of data based on the provided algorithm - * @param[in] algorithm Algorithm used to encrypt the data - * Possible values are: - * - EIA0_ALG_ID for NULL encryption - * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) - * - EIA2_128_ALG_ID for 128 bits AES LTE encryption - * @param[in] stream_cipher All parameters used to compute the encrypted block of data - * @param[out] out The encrypted block of data dynamically allocated - * @return 0 if everything OK, -1 if something failed - */ -int stream_encrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out); -#define stream_decrypt stream_encrypt - -int stream_compute_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t out[4]); - -/*! - * @brief Decrypt a block of data based on the provided algorithm - * @param[in] algorithm Algorithm used to encrypt the data - * Possible values are: - * - EIA0_ALG_ID for NULL encryption - * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) - * - EIA2_128_ALG_ID for 128 bits AES LTE encryption - * @param[in] stream_cipher All parameters used to compute the decrypted block of data - * @param[out] out The decrypted block of data dynamically allocated - * @return 0 if everything OK, -1 if something failed - */ -int stream_decrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out); - -int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t *expected); -#undef SECU_DEBUG - -#endif /* __UTIL_OSA_OSA_DEFS__H__ */ diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c deleted file mode 100644 index 06c0a3f9b2..0000000000 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 - */ - -#include "../../../openair3/SECU/kdf.h" - -#include -#include - -#include "osa_defs.h" -#include "osa_internal.h" -#include "common/utils/LOG/log.h" - -/*! - * @brief Derive the keys from key and perform truncate on the generated key to - * reduce his size to 128 bits. Definition of the derivation function can - * be found in 3GPP TS.33401 #A.7 - * @param[in] alg_type Algorithm distinguisher - * @param[in] alg_id Algorithm identifier. - * Possible values are: - * - 0 for EIA0 algorithm (Null Integrity Protection algorithm) - * - 1 for 128-EIA1 SNOW 3G - * - 2 for 128-EIA2 AES - * @param[in] key The top key used to derive other subkeys - * @param[out] out Pointer to reference where output of KDF will be stored. - * NOTE: knas is dynamically allocated by the KDF function - */ -int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) -{ - uint8_t string[7] = {0}; - - /* FC */ - string[0] = FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - string[1] = (uint8_t)(alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - string[2] = 0x00; - string[3] = 0x01; - - /* P1 */ - string[4] = alg_id; - - /* L1 = length(P1) = 1 */ - string[5] = 0x00; - string[6] = 0x01; - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * sizeof(string) + 1]; - int index = 0; - - for (i = 0; i < sizeof(string); i++) - index += sprintf(&payload[index], "0x%02x ", string[i]); - - LOG_D(OSA, "Key deriver input string: %s\n", payload); - } -#endif - - byte_array_t data = {.buf = string, .len = 7}; - if (*out == NULL) { - *out = malloc(sizeof(uint8_t) * 32); - DevAssert(*out != NULL && "Memory exhausted"); - } - kdf(key, data, 32, *out); - - return 0; -} - -int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) -{ - uint8_t string[7]; - - /* FC */ - string[0] = NR_FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - string[1] = (uint8_t)(alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - string[2] = 0x00; - string[3] = 0x01; - - /* P1 */ - string[4] = alg_id; - - /* L1 = length(P1) = 1 */ - string[5] = 0x00; - string[6] = 0x01; - - byte_array_t data = {.buf = string, .len = 7}; - - if (*out == NULL) { - *out = malloc(sizeof(uint8_t) * 32); - DevAssert(*out != NULL && "Memory exhausted"); - } - kdf(key, data, 32, *out); - - // in NR, we use the last 16 bytes, ignoring the first 16 ones - memcpy(*out, *out + 16, 16); - - return 0; -} - -int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) -{ - uint8_t s[10] = {0}; - - /* FC */ - s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; - - /* P0 = PCI */ - s[1] = (pci & 0x0000ff00) >> 8; - s[2] = (pci & 0x000000ff); - - /* L0 = length(P0) = 2 */ - s[3] = 0x00; - s[4] = 0x02; - - /* P1 = NR ARFCN */ - s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16; - s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8; - s[7] = (nr_arfcn_dl & 0x000000ff); - - /* L1 = length(P1) = 3 */ - s[8] = 0x00; - s[9] = 0x03; - - - byte_array_t data = {.buf = s, .len = 10}; - const uint32_t len_key = 32; - kdf(key, data, len_key, key_ng_ran_star); - - return 0; -} - -int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) -{ - uint8_t s[5] = {0}; - - /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ - s[0] = 0x1c; - - /* put sk_counter */ - s[1] = (sk_counter >> 8) & 0xff; - s[2] = sk_counter & 0xff; - - /* put length of sk_counter (2) */ - s[3] = 0x00; - s[4] = 0x02; - - byte_array_t data = {.buf = s, .len = 5}; - kdf(keNB, data, 32, skgNB); - - return 0; -} diff --git a/openair2/UTIL/OSA/osa_snow3g.c b/openair2/UTIL/OSA/osa_snow3g.c deleted file mode 100644 index c69e80a1fb..0000000000 --- a/openair2/UTIL/OSA/osa_snow3g.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include - -#include "osa_rijndael.h" -#include "osa_snow3g.h" - -static uint8_t OSA_MULx(uint8_t V, uint8_t c); -static uint8_t OSA_MULxPOW(uint8_t V, uint8_t i, uint8_t c); -static uint32_t OSA_MULalpha(uint8_t c); -static uint32_t OSA_DIValpha(uint8_t c); -static uint32_t OSA_S1(uint32_t w); -static uint32_t OSA_S2(uint32_t w); -static void osa_snow3g_clock_LFSR_initialization_mode(uint32_t F, osa_snow_3g_context_t *s3g_ctx_pP); -static void osa_snow3g_clock_LFSR_key_stream_mode(osa_snow_3g_context_t *snow_3g_context_pP); -static uint32_t osa_snow3g_clock_fsm(osa_snow_3g_context_t *snow_3g_context_pP); -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP); -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *ks, osa_snow_3g_context_t *snow_3g_context_pP); - - -/* OSA_MULx. -* Input V: an 8-bit input. -* Input c: an 8-bit input. -* Output : an 8-bit input. -* MULx maps 16 bits to 8 bits -*/ - -static uint8_t OSA_MULx(uint8_t V, uint8_t c) -{ - //If the leftmost (i.e. the most significant) bit of V equals 1 - if ( V & 0x80 ) - return ( (V << 1) ^ c); - else - return ( V << 1); -} - -/* OSA_MULxPOW. -* Input V: an 8-bit input. -* Input i: a positive integer. -* Input c: an 8-bit input. -* Output : an 8-bit output. -* MULxPOW maps 16 bits and a positive integer i to 8 bit. -*/ - -static uint8_t OSA_MULxPOW(uint8_t V, uint8_t i, uint8_t c) -{ - if ( i == 0) - return V; - else - return OSA_MULx( OSA_MULxPOW( V, i-1, c ), c); -} - -/* The function OSA_MULalpha. -* Input c: 8-bit input. -* Output : 32-bit output. -* maps 8 bits to 32 bits. -*/ - -static uint32_t OSA_MULalpha(uint8_t c) -{ - return ( ( ((uint32_t)OSA_MULxPOW(c,23, 0xa9)) << 24 ) | - ( ((uint32_t)OSA_MULxPOW(c, 245, 0xa9)) << 16 ) | - ( ((uint32_t)OSA_MULxPOW(c, 48, 0xa9)) << 8 ) | - ( ((uint32_t)OSA_MULxPOW(c, 239, 0xa9)) ) ) ; -} - - -/* The function DIV alpha. -* Input c: 8-bit input. -* Output : 32-bit output. -* maps 8 bits to 32 bit. -*/ - -static uint32_t OSA_DIValpha(uint8_t c) -{ - return ( ( ((uint32_t)OSA_MULxPOW(c, 16, 0xa9)) << 24 ) | - ( ((uint32_t)OSA_MULxPOW(c, 39, 0xa9)) << 16 ) | - ( ((uint32_t)OSA_MULxPOW(c, 6, 0xa9)) << 8 ) | - ( ((uint32_t)OSA_MULxPOW(c, 64, 0xa9)) ) ) ; -} - -/* The 32x32-bit S-Box S1 -* Input: a 32-bit input. -* Output: a 32-bit output of S1 box. -* The S-Box S1 maps a 32-bit input to a 32-bit output. -* w = w0 || w1 || w2 || w3 the 32-bit input with w0 the most and w3 the least significant byte. -* S1(w)= r0 || r1 || r2 || r3 with r0 the most and r3 the least significant byte. -*/ - -static uint32_t OSA_S1(uint32_t w) -{ - uint8_t r0=0, r1=0, r2=0, r3=0; - uint8_t srw0 = OSA_SR[ (uint8_t)((w >> 24) & 0xff) ]; - uint8_t srw1 = OSA_SR[ (uint8_t)((w >> 16) & 0xff) ]; - uint8_t srw2 = OSA_SR[ (uint8_t)((w >> 8) & 0xff) ]; - uint8_t srw3 = OSA_SR[ (uint8_t)((w) & 0xff) ]; - - r0 = ( ( OSA_MULx( srw0 , 0x1b) ) ^ - ( srw1 ) ^ - ( srw2 ) ^ - ( (OSA_MULx( srw3, 0x1b)) ^ srw3 ) - ); - - r1 = ( ( ( OSA_MULx( srw0 , 0x1b) ) ^ srw0 ) ^ - ( OSA_MULx(srw1, 0x1b) ) ^ - ( srw2 ) ^ - ( srw3 ) - ); - - r2 = ( ( srw0 ) ^ - ( ( OSA_MULx( srw1 , 0x1b) ) ^ srw1 ) ^ - ( OSA_MULx(srw2, 0x1b) ) ^ - ( srw3 ) - ); - - r3 = ( ( srw0 ) ^ - ( srw1 ) ^ - ( ( OSA_MULx( srw2 , 0x1b) ) ^ srw2 ) ^ - ( OSA_MULx( srw3, 0x1b) ) - ); - - return ( ( ((uint32_t)r0) << 24 ) | ( ((uint32_t)r1) << 16 ) | ( ((uint32_t)r2) << 8 ) | ( ((uint32_t)r3) ) ); -} - -/* The 32x32-bit S-Box S2 -* Input: a 32-bit input. -* Output: a 32-bit output of S2 box. -* The S-Box S2 maps a 32-bit input to a 32-bit output. -* Let w = w0 || w1 || w2 || w3 the 32-bit input with w0 the most and w3 the least significant byte. -* Let S2(w)= r0 || r1 || r2 || r3 with r0 the most and r3 the least significant byte. -*/ - -static uint32_t OSA_S2(uint32_t w) -{ - uint8_t r0=0, r1=0, r2=0, r3=0; - uint8_t sqw0 = OSA_SQ[ (uint8_t)((w >> 24) & 0xff) ]; - uint8_t sqw1 = OSA_SQ[ (uint8_t)((w >> 16) & 0xff) ]; - uint8_t sqw2 = OSA_SQ[ (uint8_t)((w >> 8) & 0xff) ]; - uint8_t sqw3 = OSA_SQ[ (uint8_t)((w) & 0xff) ]; - - - r0 = ( ( OSA_MULx( sqw0 , 0x69) ) ^ - ( sqw1 ) ^ - ( sqw2 ) ^ - ( (OSA_MULx( sqw3, 0x69)) ^ sqw3 ) - ); - - r1 = ( ( ( OSA_MULx( sqw0 , 0x69) ) ^ sqw0 ) ^ - ( OSA_MULx(sqw1, 0x69) ) ^ - ( sqw2 ) ^ - ( sqw3 ) - ); - - r2 = ( ( sqw0 ) ^ - ( ( OSA_MULx( sqw1 , 0x69) ) ^ sqw1 ) ^ - ( OSA_MULx(sqw2, 0x69) ) ^ - ( sqw3 ) - ); - - r3 = ( ( sqw0 ) ^ - ( sqw1 ) ^ - ( ( OSA_MULx( sqw2 , 0x69) ) ^ sqw2 ) ^ - ( OSA_MULx( sqw3, 0x69) ) - ); - - return ( ( ((uint32_t)r0) << 24 ) | ( ((uint32_t)r1) << 16 ) | ( ((uint32_t)r2) << 8 ) | ( ((uint32_t)r3) ) ); -} - -/* Clocking LFSR in initialization mode. -* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock. -* Input F: a 32-bit word comes from output of FSM. -* See section 3.4.4. -*/ - -static void osa_snow3g_clock_LFSR_initialization_mode(uint32_t F, osa_snow_3g_context_t *s3g_ctx_pP) -{ - uint32_t v = ( ( (s3g_ctx_pP->LFSR_S0 << 8) & 0xffffff00 ) ^ - ( OSA_MULalpha( (uint8_t)((s3g_ctx_pP->LFSR_S0>>24) & 0xff) ) ) ^ - ( s3g_ctx_pP->LFSR_S2 ) ^ - ( (s3g_ctx_pP->LFSR_S11 >> 8) & 0x00ffffff ) ^ - ( OSA_DIValpha( (uint8_t)( ( s3g_ctx_pP->LFSR_S11) & 0xff ) ) ) ^ - ( F ) - ); - - s3g_ctx_pP->LFSR_S0 = s3g_ctx_pP->LFSR_S1; - s3g_ctx_pP->LFSR_S1 = s3g_ctx_pP->LFSR_S2; - s3g_ctx_pP->LFSR_S2 = s3g_ctx_pP->LFSR_S3; - s3g_ctx_pP->LFSR_S3 = s3g_ctx_pP->LFSR_S4; - s3g_ctx_pP->LFSR_S4 = s3g_ctx_pP->LFSR_S5; - s3g_ctx_pP->LFSR_S5 = s3g_ctx_pP->LFSR_S6; - s3g_ctx_pP->LFSR_S6 = s3g_ctx_pP->LFSR_S7; - s3g_ctx_pP->LFSR_S7 = s3g_ctx_pP->LFSR_S8; - s3g_ctx_pP->LFSR_S8 = s3g_ctx_pP->LFSR_S9; - s3g_ctx_pP->LFSR_S9 = s3g_ctx_pP->LFSR_S10; - s3g_ctx_pP->LFSR_S10 = s3g_ctx_pP->LFSR_S11; - s3g_ctx_pP->LFSR_S11 = s3g_ctx_pP->LFSR_S12; - s3g_ctx_pP->LFSR_S12 = s3g_ctx_pP->LFSR_S13; - s3g_ctx_pP->LFSR_S13 = s3g_ctx_pP->LFSR_S14; - s3g_ctx_pP->LFSR_S14 = s3g_ctx_pP->LFSR_S15; - s3g_ctx_pP->LFSR_S15 = v; -} - -/* Clocking LFSR in keystream mode. -* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock. -* See section 3.4.5. -*/ -static void osa_snow3g_clock_LFSR_key_stream_mode(osa_snow_3g_context_t *snow_3g_context_pP) -{ - - uint32_t v = ( ( (snow_3g_context_pP->LFSR_S0 << 8) & 0xffffff00 ) ^ - ( OSA_MULalpha( (uint8_t)((snow_3g_context_pP->LFSR_S0>>24) & 0xff) ) ) ^ - ( snow_3g_context_pP->LFSR_S2 ) ^ - ( (snow_3g_context_pP->LFSR_S11 >> 8) & 0x00ffffff ) ^ - ( OSA_DIValpha( (uint8_t)( ( snow_3g_context_pP->LFSR_S11) & 0xff ) ) ) - ); - - snow_3g_context_pP->LFSR_S0 = snow_3g_context_pP->LFSR_S1; - snow_3g_context_pP->LFSR_S1 = snow_3g_context_pP->LFSR_S2; - snow_3g_context_pP->LFSR_S2 = snow_3g_context_pP->LFSR_S3; - snow_3g_context_pP->LFSR_S3 = snow_3g_context_pP->LFSR_S4; - snow_3g_context_pP->LFSR_S4 = snow_3g_context_pP->LFSR_S5; - snow_3g_context_pP->LFSR_S5 = snow_3g_context_pP->LFSR_S6; - snow_3g_context_pP->LFSR_S6 = snow_3g_context_pP->LFSR_S7; - snow_3g_context_pP->LFSR_S7 = snow_3g_context_pP->LFSR_S8; - snow_3g_context_pP->LFSR_S8 = snow_3g_context_pP->LFSR_S9; - snow_3g_context_pP->LFSR_S9 = snow_3g_context_pP->LFSR_S10; - snow_3g_context_pP->LFSR_S10 = snow_3g_context_pP->LFSR_S11; - snow_3g_context_pP->LFSR_S11 = snow_3g_context_pP->LFSR_S12; - snow_3g_context_pP->LFSR_S12 = snow_3g_context_pP->LFSR_S13; - snow_3g_context_pP->LFSR_S13 = snow_3g_context_pP->LFSR_S14; - snow_3g_context_pP->LFSR_S14 = snow_3g_context_pP->LFSR_S15; - snow_3g_context_pP->LFSR_S15 = v; -} - -/* Clocking FSM. -* Produces a 32-bit word F. -* Updates FSM registers R1, R2, R3. -* See Section 3.4.6. -*/ - -static uint32_t osa_snow3g_clock_fsm(osa_snow_3g_context_t *snow_3g_context_pP) -{ - uint32_t F = ( ( snow_3g_context_pP->LFSR_S15 + snow_3g_context_pP->FSM_R1 ) & 0xffffffff ) ^ snow_3g_context_pP->FSM_R2 ; - uint32_t r = ( snow_3g_context_pP->FSM_R2 + ( snow_3g_context_pP->FSM_R3 ^ snow_3g_context_pP->LFSR_S5 ) ) & 0xffffffff ; - - snow_3g_context_pP->FSM_R3 = OSA_S2(snow_3g_context_pP->FSM_R2); - snow_3g_context_pP->FSM_R2 = OSA_S1(snow_3g_context_pP->FSM_R1); - snow_3g_context_pP->FSM_R1 = r; - - return F; -} - -/* Initialization. - * Input k[4]: Four 32-bit words making up 128-bit key. - * Input IV[4]: Four 32-bit words making 128-bit initialization variable. - * Output: All the LFSRs and FSM are initialized for key generation. - * See Section 4.1. - */ - -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP) -{ - - uint8_t i = 0; - uint32_t F = 0x0; - - snow_3g_context_pP->LFSR_S15 = k[3] ^ IV[0]; - snow_3g_context_pP->LFSR_S14 = k[2]; - snow_3g_context_pP->LFSR_S13 = k[1]; - snow_3g_context_pP->LFSR_S12 = k[0] ^ IV[1]; - - snow_3g_context_pP->LFSR_S11 = k[3] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S10 = k[2] ^ 0xffffffff ^ IV[2]; - snow_3g_context_pP->LFSR_S9 = k[1] ^ 0xffffffff ^ IV[3]; - snow_3g_context_pP->LFSR_S8 = k[0] ^ 0xffffffff; - - snow_3g_context_pP->LFSR_S7 = k[3]; - snow_3g_context_pP->LFSR_S6 = k[2]; - snow_3g_context_pP->LFSR_S5 = k[1]; - snow_3g_context_pP->LFSR_S4 = k[0]; - - snow_3g_context_pP->LFSR_S3 = k[3] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S2 = k[2] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S1 = k[1] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S0 = k[0] ^ 0xffffffff; - - snow_3g_context_pP->FSM_R1 = 0x0; - snow_3g_context_pP->FSM_R2 = 0x0; - snow_3g_context_pP->FSM_R3 = 0x0; - - for(i=0; i<32; i++) { - F = osa_snow3g_clock_fsm(snow_3g_context_pP); - osa_snow3g_clock_LFSR_initialization_mode(F, snow_3g_context_pP); - } - -} - -/* Generation of Keystream. -* input n: number of 32-bit words of keystream. -* input z: space for the generated keystream, assumes -* memory is allocated already. -* output: generated keystream which is filled in z -* See section 4.2. -*/ - -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *ks, osa_snow_3g_context_t *snow_3g_context_pP) -{ - uint32_t t = 0; - uint32_t F = 0x0; - - osa_snow3g_clock_fsm(snow_3g_context_pP); /* Clock FSM once. Discard the output. */ - osa_snow3g_clock_LFSR_key_stream_mode(snow_3g_context_pP); /* Clock LFSR in keystream mode once. */ - - for ( t=0; tLFSR_S0; /* STEP 2 */ - - /* Note that ks[t] corresponds to z_{t+1} in section 4.2*/ - - osa_snow3g_clock_LFSR_key_stream_mode(snow_3g_context_pP); /* STEP 3 */ - } -} - diff --git a/openair2/UTIL/OSA/osa_snow3g.h b/openair2/UTIL/OSA/osa_snow3g.h deleted file mode 100644 index 5da81d23f3..0000000000 --- a/openair2/UTIL/OSA/osa_snow3g.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 - */ - -/*! \file snow3g.h -* \brief -* \author Open source Adapted from Specification of the 3GPP Confidentiality and -* Integrity Algorithms UEA2 & UIA2. Document 2: SNOW 3G Specification -* \integrators Kharbach Othmane, GAUTHIER Lionel. -* \date 2014 -* \version -* \note -* \bug -* \warning -*/ -#ifndef OSA_SNOW3G_H_ -#define OSA_SNOW3G_H_ - -typedef struct osa_snow_3g_context_s { - uint32_t LFSR_S0; - uint32_t LFSR_S1; - uint32_t LFSR_S2; - uint32_t LFSR_S3; - uint32_t LFSR_S4; - uint32_t LFSR_S5; - uint32_t LFSR_S6; - uint32_t LFSR_S7; - uint32_t LFSR_S8; - uint32_t LFSR_S9; - uint32_t LFSR_S10; - uint32_t LFSR_S11; - uint32_t LFSR_S12; - uint32_t LFSR_S13; - uint32_t LFSR_S14; - uint32_t LFSR_S15; - - /* FSM : The Finite State Machine has three 32-bit registers R1, R2 and R3. - */ - uint32_t FSM_R1; - uint32_t FSM_R2; - uint32_t FSM_R3; -} osa_snow_3g_context_t; - -/* Initialization. -* Input k[4]: Four 32-bit words making up 128-bit key. -* Input IV[4]: Four 32-bit words making 128-bit initialization variable. -* Output: All the LFSRs and FSM are initialized for key generation. -*/ -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP); - -/* Generation of Keystream. -* input n: number of 32-bit words of keystream. -* input z: space for the generated keystream, assumes -* memory is allocated already. -* output: generated keystream which is filled in z -*/ - -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *z, osa_snow_3g_context_t *snow_3g_context_pP); - -#endif diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c deleted file mode 100644 index 61f003bc32..0000000000 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include -#include - -#include "common/utils/LOG/log.h" -#include "byte_array.h" -#include "openair3//SECU//aes_128_ctr.h" - -#include "assertions.h" -#include "osa_defs.h" -#include "osa_snow3g.h" -#include "osa_internal.h" - -int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) -{ - uint8_t *data = NULL; - - uint32_t byte_length; - - DevAssert(stream_cipher != NULL); - DevAssert(out != NULL); - - LOG_D(OSA, - "Entering stream_encrypt_eea0, bits length %u, bearer %u, " - "count %u, direction %s\n", - stream_cipher->blength, - stream_cipher->bearer, - stream_cipher->count, - stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); - - byte_length = (stream_cipher->blength + 7) >> 3; - - if (*out == NULL) { - /* User did not provide output buffer */ - data = malloc(byte_length); - *out = data; - } else { - data = *out; - } - - memcpy(data, stream_cipher->message, byte_length); - - return 0; -} - -int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) -{ - osa_snow_3g_context_t snow_3g_context; - int n; - int i = 0; - uint32_t zero_bit = 0; - uint32_t *KS; - uint32_t K[4], IV[4]; - - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); - DevAssert(stream_cipher->key_length == 16); - DevAssert(out != NULL); - - n = (stream_cipher->blength + 31) / 32; - zero_bit = stream_cipher->blength & 0x7; - - memset(&snow_3g_context, 0, sizeof(snow_3g_context)); - /*Initialisation*/ - /* Load the confidentiality key for SNOW 3G initialization as in section - 3.4. */ - memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ - memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ - memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ - K[3] = hton_int32(K[3]); - K[2] = hton_int32(K[2]); - K[1] = hton_int32(K[1]); - K[0] = hton_int32(K[0]); - /* Prepare the initialization vector (IV) for SNOW 3G initialization as in - section 3.4. */ - IV[3] = stream_cipher->count; - IV[2] = ((((uint32_t)stream_cipher->bearer) << 3) | ((((uint32_t)stream_cipher->direction) & 0x1) << 2)) << 24; - IV[1] = IV[3]; - IV[0] = IV[2]; - - /* Run SNOW 3G algorithm to generate sequence of key stream bits KS*/ - osa_snow3g_initialize(K, IV, &snow_3g_context); - KS = (uint32_t *)malloc(4 * n); - osa_snow3g_generate_key_stream(n, (uint32_t *)KS, &snow_3g_context); - - if (zero_bit > 0) { - KS[n - 1] = KS[n - 1] & (uint32_t)(0xFFFFFFFF << (8 - zero_bit)); - } - - for (i = 0; i < n; i++) { - KS[i] = hton_int32(KS[i]); - } - - /* Exclusive-OR the input data with keystream to generate the output bit - stream */ - for (i = 0; i < n * 4; i++) { - stream_cipher->message[i] ^= *(((uint8_t *)KS) + i); - } - - if (zero_bit > 0) { - int ceil_index = (stream_cipher->blength + 7) >> 3; - stream_cipher->message[ceil_index - 1] = stream_cipher->message[ceil_index - 1] & (uint8_t)(0xFF << (8 - zero_bit)); - } - - free(KS); - *out = stream_cipher->message; - return 0; -} - -int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) -{ - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); - DevAssert(stream_cipher->key_length == 32); - DevAssert(stream_cipher->bearer < 32); - DevAssert(stream_cipher->direction < 2); - DevAssert(stream_cipher->message != NULL); - DevAssert(stream_cipher->blength > 7); - - if (*out == NULL) { - *out = calloc(1, (stream_cipher->blength >> 3) + 1); - DevAssert(*out != NULL && "Memory exhausted"); - } - - aes_128_t p = {0}; - memcpy(p.key, stream_cipher->key, stream_cipher->key_length); - p.type = AES_INITIALIZATION_VECTOR_16; - p.iv16.d.count = htonl(stream_cipher->count); - p.iv16.d.bearer = stream_cipher->bearer; - p.iv16.d.direction = stream_cipher->direction; - - DevAssert((stream_cipher->blength & 0x07) == 0 && "Cipher length must be multiple of one octet"); - const uint32_t byte_lenght = stream_cipher->blength >> 3; - // Precondition: out must have enough space, at least as much as the input - const size_t len_out = byte_lenght; - byte_array_t msg = {.buf = stream_cipher->message, .len =byte_lenght}; - aes_128_ctr(&p, msg, len_out, *out); - return 0; -} - -int stream_encrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out) -{ - if (algorithm == EEA0_ALG_ID) { - return stream_encrypt_eea0(stream_cipher, out); - } else if (algorithm == EEA1_128_ALG_ID) { - return stream_encrypt_eea1(stream_cipher, out); - } else if (algorithm == EEA2_128_ALG_ID) { - return stream_encrypt_eea2(stream_cipher, out); - } - - LOG_E(OSA, "Provided encryption algorithm is currently not supported = %u\n", algorithm); - return -1; -} diff --git a/openair2/UTIL/OSA/osa_stream_eia.c b/openair2/UTIL/OSA/osa_stream_eia.c deleted file mode 100644 index da4fd23e18..0000000000 --- a/openair2/UTIL/OSA/osa_stream_eia.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include -#include -#include - -#include "assertions.h" -#include "common/utils/LOG/log.h" - -#include "openair3/SECU/aes_128_cbc_cmac.h" - -#include "osa_defs.h" -#include "osa_snow3g.h" -#include "osa_internal.h" - -// see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1 - -/* OSA_MUL64x. - * Input V: a 64-bit input. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling - * function. - * See section 4.3.2 for details. - */ -uint64_t OSA_MUL64x(uint64_t V, uint64_t c) -{ - if (V & 0x8000000000000000) - return (V << 1) ^ c; - else - return V << 1; -} -/* OSA_MUL64xPOW. - * Input V: a 64-bit input. - * Input i: a positive integer. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling -function. - * See section 4.3.3 for details. - */ -uint64_t OSA_MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) -{ - if (i == 0) - return V; - else - return OSA_MUL64x(OSA_MUL64xPOW(V, i - 1, c), c); -} -/* OSA_MUL64. - * Input V: a 64-bit input. - * Input P: a 64-bit input. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling - * function. - * See section 4.3.4 for details. - */ -uint64_t OSA_MUL64(uint64_t V, uint64_t P, uint64_t c) -{ - uint64_t result = 0; - int i = 0; - - for (i = 0; i < 64; i++) { - if ((P >> i) & 0x1) - result ^= OSA_MUL64xPOW(V, i, c); - } - - return result; -} - -/* osa_mask32bit. - * Input n: an integer in 1-32. - * Output : a 32 bit mask. - * Prepares a 32 bit mask with required number of 1 bits on the MSB side. - */ -uint32_t osa_mask32bit(int n) -{ - uint32_t mask = 0x0; - - if (n % 32 == 0) - return 0xffffffff; - - while (n--) - mask = (mask >> 1) ^ 0x80000000; - - return mask; -} - -/*! - * @brief Create integrity cmac t for a given message. - * @param[in] stream_cipher Structure containing various variables to setup encoding - * @param[out] out For EIA2 the output string is 32 bits long - */ -int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]) -{ - osa_snow_3g_context_t snow_3g_context; - uint32_t K[4], IV[4], z[5]; - int i = 0, D; - uint32_t MAC_I = 0; - uint64_t EVAL; - uint64_t V; - uint64_t P; - uint64_t Q; - uint64_t c; - uint64_t M_D_2; - int rem_bits; - uint32_t mask = 0; - uint32_t *message; - - message = (uint32_t *)stream_cipher->message; /* To operate 32 bit message internally. */ - /* Load the Integrity Key for SNOW3G initialization as in section 4.4. */ - memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ - memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ - memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ - K[3] = hton_int32(K[3]); - K[2] = hton_int32(K[2]); - K[1] = hton_int32(K[1]); - K[0] = hton_int32(K[0]); - /* Prepare the Initialization Vector (IV) for SNOW3G initialization as in - section 4.4. */ - IV[3] = (uint32_t)stream_cipher->count; - IV[2] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27); - IV[1] = (uint32_t)(stream_cipher->count) ^ ((uint32_t)(stream_cipher->direction) << 31); - IV[0] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27) ^ ((uint32_t)(stream_cipher->direction & 0x00000001) << 15); - // printf ("K:\n"); - // hexprint(K, 16); - // printf ("K[0]:%08X\n",K[0]); - // printf ("K[1]:%08X\n",K[1]); - // printf ("K[2]:%08X\n",K[2]); - // printf ("K[3]:%08X\n",K[3]); - - // printf ("IV:\n"); - // hexprint(IV, 16); - // printf ("IV[0]:%08X\n",IV[0]); - // printf ("IV[1]:%08X\n",IV[1]); - // printf ("IV[2]:%08X\n",IV[2]); - // printf ("IV[3]:%08X\n",IV[3]); - z[0] = z[1] = z[2] = z[3] = z[4] = 0; - /* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */ - osa_snow3g_initialize(K, IV, &snow_3g_context); - osa_snow3g_generate_key_stream(5, z, &snow_3g_context); - // printf ("z[0]:%08X\n",z[0]); - // printf ("z[1]:%08X\n",z[1]); - // printf ("z[2]:%08X\n",z[2]); - // printf ("z[3]:%08X\n",z[3]); - // printf ("z[4]:%08X\n",z[4]); - P = ((uint64_t)z[0] << 32) | (uint64_t)z[1]; - Q = ((uint64_t)z[2] << 32) | (uint64_t)z[3]; - // printf ("P:%16lX\n",P); - // printf ("Q:%16lX\n",Q); - /* Calculation */ - D = ceil(stream_cipher->blength / 64.0) + 1; - // printf ("D:%d\n",D); - EVAL = 0; - c = 0x1b; - - /* for 0 <= i <= D-3 */ - for (i = 0; i < D - 2; i++) { - V = EVAL ^ ((uint64_t)hton_int32(message[2 * i]) << 32 | (uint64_t)hton_int32(message[2 * i + 1])); - EVAL = OSA_MUL64(V, P, c); - // printf ("Mi: %16X %16X\tEVAL: %16lX\n",hton_int32(message[2*i]),hton_int32(message[2*i+1]), EVAL); - } - - /* for D-2 */ - rem_bits = stream_cipher->blength % 64; - - if (rem_bits == 0) - rem_bits = 64; - - mask = osa_mask32bit(rem_bits % 32); - - if (rem_bits > 32) { - M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) << 32) | (uint64_t)(hton_int32(message[2 * (D - 2) + 1]) & mask); - } else { - M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) & mask) << 32; - } - - V = EVAL ^ M_D_2; - EVAL = OSA_MUL64(V, P, c); - /* for D-1 */ - EVAL ^= stream_cipher->blength; - /* Multiply by Q */ - EVAL = OSA_MUL64(EVAL, Q, c); - MAC_I = (uint32_t)(EVAL >> 32) ^ z[4]; - // printf ("MAC_I:%16X\n",MAC_I); - MAC_I = hton_int32(MAC_I); - memcpy(out, &MAC_I, 4); - return 0; -} - -int stream_compute_integrity_eia2(stream_cipher_t *stream_cipher, uint8_t out[4]) -{ - DevAssert(stream_cipher != NULL); - ; - DevAssert((stream_cipher->blength & 0x7) == 0); - DevAssert(stream_cipher->key_length == 16 && "k_iv.key and stream_cipher mismatch"); - DevAssert(stream_cipher->bearer < 32); - DevAssert(stream_cipher->direction < 2); - - aes_128_t k_iv = {0}; - memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key)); - k_iv.type = AES_INITIALIZATION_VECTOR_8; - - k_iv.iv8.d.bearer = stream_cipher->bearer; - k_iv.iv8.d.direction = stream_cipher->direction; - k_iv.iv8.d.count = htonl(stream_cipher->count); - - const size_t m_length = stream_cipher->blength >> 3; - - uint8_t result[16] = {0}; - byte_array_t msg = {.len = m_length, .buf = stream_cipher->message }; - aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); - - memcpy(out, result, 4); - return 0; -} - -int stream_compute_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t out[4]) -{ - if (algorithm == EIA1_128_ALG_ID) { - LOG_D(OSA, "EIA1 algorithm applied for integrity\n"); - return stream_compute_integrity_eia1(stream_cipher, out); - } else if (algorithm == EIA2_128_ALG_ID) { - LOG_D(OSA, "EIA2 algorithm applied for integrity\n"); - return stream_compute_integrity_eia2(stream_cipher, out); - } - - LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", algorithm); - return -1; -} - -int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t *expected) -{ - uint8_t result[4]; - - if (algorithm != EIA0_ALG_ID) { - if (stream_compute_integrity(algorithm, stream_cipher, result) != 0) { - return -1; - } - - if (memcmp(result, expected, 4) != 0) { - LOG_E(OSA, - "Mismatch found in integrity for algorithm %u,\n" - "\tgot %02x.%02x.%02x.%02x, expecting %02x.%02x.%02x.%02x\n", - algorithm, - result[0], - result[1], - result[2], - result[3], - expected[0], - expected[1], - expected[2], - expected[3]); - return -1; - } - } - - /* Integrity verification succeeded */ - return 0; -} diff --git a/openair3/COMMON/common_types.h b/openair3/COMMON/common_types.h index 80cc20df63..51f1f83391 100644 --- a/openair3/COMMON/common_types.h +++ b/openair3/COMMON/common_types.h @@ -23,8 +23,6 @@ #include "commonDef.h" -#include "security_types.h" - #include "queue.h" #ifndef COMMON_TYPES_H_ diff --git a/openair3/COMMON/security_types.h b/openair3/COMMON/security_types.h index 5494ffd994..d78534e176 100644 --- a/openair3/COMMON/security_types.h +++ b/openair3/COMMON/security_types.h @@ -42,14 +42,6 @@ #define AUTN_LENGTH_BITS (128) #define AUTN_LENGTH_OCTETS (AUTN_LENGTH_BITS/8) -/* Some methods to convert a string to an int64_t */ -/* -#define STRING_TO_64BITS(sTRING, cONTAINER) \ - sscanf(sTRING, "%" SCN64, cONTAINER) -#define STRING_TO_U64BITS(sTRING, cONTAINER) \ - sscanf(sTRING, "%" SCNu64, cONTAINER) -*/ - /* Converts a string to 128 bits gmplib integer holder */ # define STRING_TO_XBITS(sTRING, lENGTH, cONTAINER, rET) \ do { \ @@ -63,18 +55,6 @@ STRING_TO_XBITS(sTRING, 16, cONTAINER, rET) # define STRING_TO_256BITS(sTRING, cONTAINER, rET) \ STRING_TO_XBITS(sTRING, 32, cONTAINER, rET) -# define STRING_TO_RAND STRING_TO_128BITS -# define STRING_TO_AUTH_KEY STRING_TO_128BITS -# define STRING_TO_AUTH_RES STRING_TO_128BITS -# define STRING_TO_AUTN STRING_TO_128BITS -# define STRING_TO_KASME STRING_TO_256BITS -# define STRING_TO_XRES(sTRING, lENGTH, cONTAINER, rET) \ -do { \ - STRING_TO_XBITS(sTRING, lENGTH, (cONTAINER)->data, rET); \ - if (rET != -1) \ - (cONTAINER)->size = lENGTH; \ -} while(0) - /* RES amd XRES can have a variable length of 4-16 octets */ typedef struct { uint8_t size; @@ -107,28 +87,4 @@ typedef struct eutran_vector_s { uint8_t kasme[KASME_LENGTH_OCTETS]; } eutran_vector_t; -#define FC_KASME (0x10) -#define FC_KENB (0x11) -#define FC_NH (0x12) -#define FC_KENB_STAR (0x13) -/* 33401 #A.7 Algorithm for key derivation function. - * This FC should be used for: - * - NAS Encryption algorithm - * - NAS Integrity algorithm - * - RRC Encryption algorithm - * - RRC Integrity algorithm - * - User Plane Encryption algorithm - */ -#define FC_ALG_KEY_DER (0x15) -#define FC_KASME_TO_CK (0x16) - -typedef enum { - NAS_ENC_ALG = 0x01, - NAS_INT_ALG = 0x02, - RRC_ENC_ALG = 0x03, - RRC_INT_ALG = 0x04, - UP_ENC_ALG = 0x05, - UP_INT_ALG = 0x06 -} algorithm_type_dist_t; - #endif /* SECURITY_TYPES_H_ */ diff --git a/openair3/NAS/COMMON/API/NETWORK/nas_message.c b/openair3/NAS/COMMON/API/NETWORK/nas_message.c index 02fa4ad6ca..44c730038c 100644 --- a/openair3/NAS/COMMON/API/NETWORK/nas_message.c +++ b/openair3/NAS/COMMON/API/NETWORK/nas_message.c @@ -53,8 +53,6 @@ Description Defines the layer 3 messages supported by the NAS sublayer #include "secu_defs.h" #include "emmData.h" -//#define DEBUG_NAS_MESSAGE - /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ @@ -1019,7 +1017,8 @@ static int _nas_message_decrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); + /* Decode the first octet (security header type or EPS bearer identity, * and protocol discriminator) */ DECODE_U8(dest, *(uint8_t*)(&header), size); @@ -1054,7 +1053,8 @@ static int _nas_message_decrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); + /* Decode the first octet (security header type or EPS bearer identity, * and protocol discriminator) */ DECODE_U8(dest, *(uint8_t*)(&header), size); @@ -1186,8 +1186,7 @@ static int _nas_message_encrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); - + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); LOG_FUNC_RETURN (length); } @@ -1217,7 +1216,7 @@ static int _nas_message_encrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea2(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA2_128_ALG_ID, &stream_cipher, (unsigned char *)dest); LOG_FUNC_RETURN (length); @@ -1356,10 +1355,8 @@ static uint32_t _nas_message_get_mac( stream_cipher.message = (unsigned char *)buffer; /* length in bits */ stream_cipher.blength = length << 3; + stream_compute_integrity(EIA1_128_ALG_ID, &stream_cipher, mac); - nas_stream_encrypt_eia1( - &stream_cipher, - mac); LOG_TRACE(DEBUG, "NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d", mac[0], mac[1], mac[2],mac[3], @@ -1402,10 +1399,8 @@ static uint32_t _nas_message_get_mac( stream_cipher.message = (unsigned char *)buffer; /* length in bits */ stream_cipher.blength = length << 3; + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); - nas_stream_encrypt_eia2( - &stream_cipher, - mac); LOG_TRACE(DEBUG, "NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d", mac[0], mac[1], mac[2],mac[3], diff --git a/openair3/NAS/COMMON/milenage.h b/openair3/NAS/COMMON/milenage.h index c5762a0d69..c71ad76fe8 100644 --- a/openair3/NAS/COMMON/milenage.h +++ b/openair3/NAS/COMMON/milenage.h @@ -29,10 +29,11 @@ #ifndef MILENAGE_H #define MILENAGE_H + #include +#include "openair3/SECU/aes_128_ecb.h" -#define u8 uint8_t /** milenage_f1 - Milenage f1 and f1* algorithms @opc: OPc = 128-bit value derived from OP and K @@ -45,16 +46,29 @@ Returns: true on success, false on failure */ -void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) { - AES_KEY k; - u8 tmp[16]; - AES_set_encrypt_key(key, 128, &k); - AES_encrypt(in, tmp, &k); +void aes_128_encrypt_block(const uint8_t *key, const uint8_t *in, uint8_t *out) +{ + abort(); + assert(0 != 0 && "Here we are!"); + // Precondition: key, in and out occupy 16 bytes + aes_128_t k_iv = {.type = NONE_INITIALIZATION_VECTOR}; + memcpy(k_iv.key, key, sizeof(k_iv.key)); + + byte_array_t msg = {.buf = (uint8_t *)in, .len = 16}; + uint8_t tmp[16] = {0}; + aes_128_ecb(&k_iv, msg, sizeof(tmp), tmp); memcpy(out, tmp, sizeof(tmp)); } -static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, - const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) { - u8 tmp1[16], tmp2[16], tmp3[16]; + +static bool milenage_f1(const uint8_t *opc, + const uint8_t *k, + const uint8_t *_rand, + const uint8_t *sqn, + const uint8_t *amf, + uint8_t *mac_a, + uint8_t *mac_s) +{ + uint8_t tmp1[16], tmp2[16], tmp3[16]; int i; /* tmp1 = TEMP = E_K(RAND XOR OP_C) */ @@ -62,10 +76,10 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, tmp1[i] = _rand[i] ^ opc[i]; aes_128_encrypt_block(k, tmp1, tmp1); - AES_KEY kTab; - uint8_t cyphered[16]; - AES_set_encrypt_key(k, 128, &kTab); - AES_encrypt(tmp1, cyphered, &kTab); + + uint8_t cyphered[16] = {0}; + aes_128_encrypt_block(k, tmp1, cyphered); + /* tmp2 = IN1 = SQN || AMF || SQN || AMF */ memcpy(tmp2, sqn, 6); memcpy(tmp2 + 6, amf, 2); @@ -97,7 +111,6 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, return true; } - /** milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms @opc: OPc = 128-bit value derived from OP and K @@ -110,9 +123,16 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL Returns: true on success, false on failure */ -static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, - u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) { - u8 tmp1[16], tmp2[16], tmp3[16]; +static bool milenage_f2345(const uint8_t *opc, + const uint8_t *k, + const uint8_t *_rand, + uint8_t *res, + uint8_t *ck, + uint8_t *ik, + uint8_t *ak, + uint8_t *akstar) +{ + uint8_t tmp1[16], tmp2[16], tmp3[16]; int i; /* tmp2 = TEMP = E_K(RAND XOR OP_C) */ @@ -186,7 +206,6 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, return true; } - /** milenage_generate - Generate AKA AUTN,IK,CK,RES @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) @@ -200,11 +219,18 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, @res: Buffer for RES = 64-bit signed response (f2), or %NULL @res_len: Max length for res; set to used length or 0 on failure */ -static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, - const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik, - u8 *ck, u8 *res) { +static bool milenage_generate(const uint8_t *opc, + const uint8_t *amf, + const uint8_t *k, + const uint8_t *sqn, + const uint8_t *_rand, + uint8_t *autn, + uint8_t *ik, + uint8_t *ck, + uint8_t *res) +{ int i; - u8 mac_a[8], ak[6]; + uint8_t mac_a[8], ak[6]; if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) || !milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) @@ -219,7 +245,6 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, return true; } - /** milenage_auts - Milenage AUTS validation @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) @@ -232,10 +257,10 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, #define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5])); // valid code but put in comment as it is not used right now #if 0 -static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts, - u8 *sqn) { - u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ - u8 ak[6], mac_s[8]; +static bool milenage_auts(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, const uint8_t *auts, + uint8_t *sqn) { + uint8_t amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + uint8_t ak[6], mac_s[8]; int i; if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) @@ -262,8 +287,8 @@ static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 @kc: Buffer for Kc = 64-bit Kc Returns: 0 on success, -1 on failure */ -static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) { - u8 res[8], ck[16], ik[16]; +static bool gsm_milenage(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, uint8_t *sres, uint8_t *kc) { + uint8_t res[8], ck[16], ik[16]; int i; if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL)) @@ -298,12 +323,12 @@ static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, @auts: 112-bit buffer for AUTS Returns: 0 on success, -1 on failure, or -2 on synchronization failure */ -static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, - const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len, - u8 *auts) { +static int milenage_check(const uint8_t *opc, const uint8_t *k, const uint8_t *sqn, const uint8_t *_rand, + const uint8_t *autn, uint8_t *ik, uint8_t *ck, uint8_t *res, size_t *res_len, + uint8_t *auts) { int i; - u8 mac_a[8], ak[6], rx_sqn[6]; - const u8 *amf; + uint8_t mac_a[8], ak[6], rx_sqn[6]; + const uint8_t *amf; if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) return -1; @@ -315,7 +340,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_ rx_sqn[i] = autn[i] ^ ak[i]; if (memcmp(rx_sqn, sqn, 6) <= 0) { - u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + uint8_t auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) return -1; @@ -342,7 +367,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_ return 0; } -static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) { +static void milenage_opc_gen(const uint8_t *k, const uint8_t *op, uint8_t *opc) { int i; /* Encrypt OP using K */ aes_128_encrypt_block(k, op, opc); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e57e3800de..4d3078493f 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -40,6 +40,7 @@ #include "aka_functions.h" #include "secu_defs.h" #include "kdf.h" +#include "key_nas_deriver.h" #include "PduSessionEstablishRequest.h" #include "PduSessionEstablishmentAccept.h" #include "RegistrationAccept.h" @@ -50,6 +51,7 @@ #include #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" +#include "openair3/SECU/nas_stream_eia2.h" uint8_t *registration_request_buf; uint32_t registration_request_len; @@ -597,9 +599,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ @@ -702,9 +702,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ @@ -861,9 +859,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ diff --git a/openair3/SECU/aes_128.h b/openair3/SECU/aes_128.h index 7f7e550419..4155c96d7f 100644 --- a/openair3/SECU/aes_128.h +++ b/openair3/SECU/aes_128.h @@ -62,9 +62,10 @@ typedef struct{ }; } iv8_t; -typedef enum{ +typedef enum { AES_INITIALIZATION_VECTOR_8, AES_INITIALIZATION_VECTOR_16, + NONE_INITIALIZATION_VECTOR, AES_INITIALIZATION_VECTOR_END, } iv_e; diff --git a/openair3/SECU/aes_128_ecb.c b/openair3/SECU/aes_128_ecb.c new file mode 100644 index 0000000000..2969166dc1 --- /dev/null +++ b/openair3/SECU/aes_128_ecb.c @@ -0,0 +1,53 @@ +/* + * 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 + */ + +#include "aes_128_ecb.h" +#include "common/utils/assertions.h" +#include +#include +#include + +void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + DevAssert(k_iv->type == NONE_INITIALIZATION_VECTOR); + + // Create and initialise the context + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + DevAssert(ctx != NULL); + + // Initialise the encryption operation. + int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, k_iv->key, NULL); + DevAssert(rc == 1); + + int len_ev = 0; + rc = EVP_EncryptUpdate(ctx, out, &len_ev, msg.buf, msg.len); + DevAssert(!(len_ev > len_out) && "Buffer overflow"); + + // Finalise the encryption. Normally ciphertext bytes may be written at + // this stage, but this does not occur in GCM mode + rc = EVP_EncryptFinal_ex(ctx, out + len_ev, &len_ev); + DevAssert(rc == 1); + + // Get the tag + // rc == EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + EVP_CIPHER_CTX_free(ctx); +} diff --git a/openair3/SECU/aes_128_ecb.h b/openair3/SECU/aes_128_ecb.h new file mode 100644 index 0000000000..254bdac6b9 --- /dev/null +++ b/openair3/SECU/aes_128_ecb.h @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#ifndef AES_128_ECB_OAI_H +#define AES_128_ECB_OAI_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" + +void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +#endif diff --git a/openair3/SECU/key_nas_deriver.c b/openair3/SECU/key_nas_deriver.c index 18cdb3d000..8a7b32ee2f 100644 --- a/openair3/SECU/key_nas_deriver.c +++ b/openair3/SECU/key_nas_deriver.c @@ -19,16 +19,84 @@ * contact@openairinterface.org */ +#include "aes_128.h" +#include "aes_128_cbc_cmac.h" + +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" +#include "kdf.h" +#include "key_nas_deriver.h" +#include "nas_stream_eea1.h" +#include "nas_stream_eea2.h" +#include "nas_stream_eia1.h" +#include "nas_stream_eia2.h" +#include "secu_defs.h" +#include "snow3g.h" +#include +#include +#include #include #include #include #include -#include "security_types.h" -#include "secu_defs.h" -#include "kdf.h" +#define FC_KENB (0x11) +#define FC_NH (0x12) +#define FC_KENB_STAR (0x13) +/* 33401 #A.7 Algorithm for key derivation function. + * This FC should be used for: + * - NAS Encryption algorithm + * - NAS Integrity algorithm + * - RRC Encryption algorithm + * - RRC Integrity algorithm + * - User Plane Encryption algorithm + */ +#define FC_ALG_KEY_DER (0x15) +#define FC_KASME_TO_CK (0x16) + +#define NR_FC_ALG_KEY_DER (0x69) +#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70) + +// #define SECU_DEBUG 1 + +static void derive_key_common(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t FC, uint8_t out[32]) +{ + uint8_t s[7]; +#if defined(SECU_DEBUG) + int i; +#endif + + /* FC */ + s[0] = FC; + + /* P0 = algorithm type distinguisher */ + s[1] = (uint8_t)(alg_type & 0xFF); + + /* L0 = length(P0) = 1 */ + s[2] = 0x00; + s[3] = 0x01; + + /* P1 */ + s[4] = alg_id; + + /* L1 = length(P1) = 1 */ + s[5] = 0x00; + s[6] = 0x01; + +#if defined(SECU_DEBUG) + printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n", __FUNCTION__, FC_ALG_KEY_DER, alg_type, alg_id); + + for (i = 0; i < 7; i ++) { + printf("0x%02x ", s[i]); + } + + printf("\n"); +#endif + + byte_array_t data = {.len = 7, .buf = s}; + kdf(kasme, data, 32, out); +} -#define SECU_DEBUG 1 /*! * @brief Derive the kNASenc from kasme and perform truncate on the generated key to * reduce his size to 128 bits. Definition of the derivation function can @@ -41,50 +109,144 @@ * - 2 for 128-EIA2 AES * @param[in] kasme Key for MME as provided by AUC * @param[out] knas Pointer to reference where output of KDF will be stored. + */ +void derive_key_nas(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t knas[32]) +{ + derive_key_common(alg_type, alg_id, kasme, FC_ALG_KEY_DER, knas); +} + +void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) +{ + uint8_t tmp[32] = {0}; + derive_key_common(alg_type, alg_id, key, NR_FC_ALG_KEY_DER, tmp); + + // Only the last 16 bytes are needed in 5G + memcpy(out, &tmp[16], 16); +} + +/*! + * @brief Derive the keys from key and perform truncate on the generated key to + * reduce his size to 128 bits. Definition of the derivation function can + * be found in 3GPP TS.33401 #A.7 + * @param[in] alg_type Algorithm distinguisher + * @param[in] alg_id Algorithm identifier. + * Possible values are: + * - 0 for EIA0 algorithm (Null Integrity Protection algorithm) + * - 1 for 128-EIA1 SNOW 3G + * - 2 for 128-EIA2 AES + * @param[in] key The top key used to derive other subkeys + * @param[out] out Pointer to reference where output of KDF will be stored. * NOTE: knas is dynamically allocated by the KDF function */ -int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t kasme[32], uint8_t *knas) + +#ifndef NAS_UE +void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) { - uint8_t s[7]; - uint8_t out[32]; -#if defined(SECU_DEBUG) - int i; + uint8_t s[7] = {0}; + + // FC + s[0] = FC_KENB; + // P0 = Uplink NAS count + s[1] = (nas_count & 0xff000000) >> 24; + s[2] = (nas_count & 0x00ff0000) >> 16; + s[3] = (nas_count & 0x0000ff00) >> 8; + s[4] = (nas_count & 0x000000ff); + + // Length of NAS count + s[5] = 0x00; + s[6] = 0x04; + + byte_array_t data = {.buf = s, .len = 7}; + kdf(kasme, data, 32, keNB); +} #endif - /* FC */ - s[0] = FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - s[1] = (uint8_t)(nas_alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - s[2] = 0x00; - s[3] = 0x01; - - /* P1 */ - s[4] = nas_enc_alg_id; - - /* L1 = length(P1) = 1 */ - s[5] = 0x00; - s[6] = 0x01; - -#if defined(SECU_DEBUG) - printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n", - __FUNCTION__, FC_ALG_KEY_DER, nas_alg_type, nas_enc_alg_id); - - for (i = 0; i < 7; i ++) { - printf("0x%02x ", s[i]); +void derive_keNB_star(const uint8_t *kenb_32, + const uint16_t pci, + const uint32_t earfcn_dl, + const bool is_rel8_only, + uint8_t *kenb_star) +{ + // see 33.401 section A.5 KeNB* derivation function + uint8_t s[10] = {0}; + byte_array_t data = {.buf = s}; + // FC = 0x13 + s[0] = FC_KENB_STAR; + // P0 = PCI (target physical cell id) + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); + // L0 = length of PCI (i.e. 0x00 0x02) + s[3] = 0x00; + s[4] = 0x02; + // P1 = EARFCN-DL (target physical cell downlink frequency) + if (is_rel8_only) { + s[5] = (earfcn_dl & 0x0000ff00) >> 8; + s[6] = (earfcn_dl & 0x000000ff); + s[7] = 0x00; + s[8] = 0x02; + data.len = 9; + } else { + s[5] = (earfcn_dl & 0x00ff0000) >> 16; + s[6] = (earfcn_dl & 0x0000ff00) >> 8; + s[7] = (earfcn_dl & 0x000000ff); + s[8] = 0x00; + s[9] = 0x03; + data.len = 10; } - printf("\n"); -#endif + kdf(kenb_32, data, 32, kenb_star); - //kdf(kasme, 32, s, 7, out, 32); - byte_array_t data = {.len = 7, .buf = s}; - kdf(kasme, data, 32, out); + // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between + // 65536 and 262143) NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 + // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This + // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the + // EARFCN-DL. +} - memcpy(knas, &out[31-16+1], 16); +void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) +{ + uint8_t s[10] = {0}; - return 0; + /* FC */ + s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; + + /* P0 = PCI */ + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); + + /* L0 = length(P0) = 2 */ + s[3] = 0x00; + s[4] = 0x02; + + /* P1 = NR ARFCN */ + s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16; + s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8; + s[7] = (nr_arfcn_dl & 0x000000ff); + + /* L1 = length(P1) = 3 */ + s[8] = 0x00; + s[9] = 0x03; + + byte_array_t data = {.buf = s, .len = 10}; + const uint32_t len_key = 32; + kdf(key, data, len_key, key_ng_ran_star); +} + +void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) +{ + uint8_t s[5] = {0}; + + /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ + s[0] = 0x1c; + + /* put sk_counter */ + s[1] = (sk_counter >> 8) & 0xff; + s[2] = sk_counter & 0xff; + + /* put length of sk_counter (2) */ + s[3] = 0x00; + s[4] = 0x02; + + byte_array_t data = {.buf = s, .len = 5}; + kdf(keNB, data, 32, skgNB); } diff --git a/openair3/SECU/key_nas_deriver.h b/openair3/SECU/key_nas_deriver.h new file mode 100644 index 0000000000..4e84c5f3be --- /dev/null +++ b/openair3/SECU/key_nas_deriver.h @@ -0,0 +1,33 @@ +#ifndef KEY_NAS_DERIVER_H +#define KEY_NAS_DERIVER_H + +#include +#include +#include + +typedef enum { + NAS_ENC_ALG = 0x01, + NAS_INT_ALG = 0x02, + RRC_ENC_ALG = 0x03, + RRC_INT_ALG = 0x04, + UP_ENC_ALG = 0x05, + UP_INT_ALG = 0x06 +} algorithm_type_dist_t; + +void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); + +void derive_keNB_star(const uint8_t *kenb_32, + const uint16_t pci, + const uint32_t earfcn_dl, + const bool is_rel8_only, + uint8_t *kenb_star); + +void derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t kasme[32], uint8_t knas[32]); + +void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); + +void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]); + +void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star); + +#endif diff --git a/openair3/SECU/nas_stream_eea0.c b/openair3/SECU/nas_stream_eea0.c new file mode 100644 index 0000000000..e4be5c7508 --- /dev/null +++ b/openair3/SECU/nas_stream_eea0.c @@ -0,0 +1,44 @@ +/* + * 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 + */ + +#include "nas_stream_eea0.h" + +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" + +#include + +void nas_stream_encrypt_eea0(nas_stream_cipher_t const *stream_cipher, uint8_t *out) +{ + DevAssert(stream_cipher != NULL); + DevAssert(out != NULL); + + LOG_D(OSA, + "Entering stream_encrypt_eea0, bits length %u, bearer %u, " + "count %u, direction %s\n", + stream_cipher->blength, + stream_cipher->bearer, + stream_cipher->count, + stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); + + uint32_t byte_length = (stream_cipher->blength + 7) >> 3; + memcpy(out, stream_cipher->message, byte_length); +} diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair3/SECU/nas_stream_eea0.h similarity index 59% rename from openair2/UTIL/OSA/osa_internal.h rename to openair3/SECU/nas_stream_eea0.h index d66a429472..80ada528b5 100644 --- a/openair2/UTIL/OSA/osa_internal.h +++ b/openair3/SECU/nas_stream_eea0.h @@ -19,32 +19,14 @@ * contact@openairinterface.org */ -#ifndef OSA_INTERNAL_H_ -#define OSA_INTERNAL_H_ +#ifndef OAI_NAS_STREAM_EEA0_H +#define OAI_NAS_STREAM_EEA0_H -#define FC_KENB (0x11) -#define FC_NH (0x12) -#define FC_KENB_STAR (0x13) -/* 33401 #A.7 Algorithm for key derivation function. - * This FC should be used for: - * - NAS Encryption algorithm - * - NAS Integrity algorithm - * - RRC Encryption algorithm - * - RRC Integrity algorithm - * - User Plane Encryption algorithm - */ -#define FC_ALG_KEY_DER (0x15) -#define FC_KASME_TO_CK (0x16) +#include "secu_defs.h" -#define NR_FC_ALG_KEY_DER (0x69) -#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70) +#include +#include + +void nas_stream_encrypt_eea0(nas_stream_cipher_t const *stream_cipher, uint8_t *out); -#ifndef hton_int32 -# define hton_int32(x) \ -(((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \ -((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24)) #endif - -// #define SECU_DEBUG - -#endif /* OSA_INTERNAL_H_ */ diff --git a/openair3/SECU/nas_stream_eea1.c b/openair3/SECU/nas_stream_eea1.c index e70d49ea2c..a4e4b84ca4 100644 --- a/openair3/SECU/nas_stream_eea1.c +++ b/openair3/SECU/nas_stream_eea1.c @@ -26,13 +26,10 @@ #include "assertions.h" #include "conversions.h" -#include "secu_defs.h" +#include "nas_stream_eea1.h" #include "snow3g.h" -// #define SECU_DEBUG - - -int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out) +void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out) { snow_3g_context_t snow_3g_context; int n ; @@ -106,6 +103,4 @@ int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out) if (zero_bit > 0) { out[ceil_index - 1] = stream_cipher->message[ceil_index - 1]; } - - return 0; } diff --git a/openair3/SECU/nas_stream_eea1.h b/openair3/SECU/nas_stream_eea1.h new file mode 100644 index 0000000000..d713dc60d3 --- /dev/null +++ b/openair3/SECU/nas_stream_eea1.h @@ -0,0 +1,32 @@ +/* + * 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 + */ + +#ifndef OAI_NAS_STREAM_EEA1_H +#define OAI_NAS_STREAM_EEA1_H + +#include "secu_defs.h" + +#include +#include + +void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out); + +#endif diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 4eeb24b775..dbdc040883 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -28,9 +28,9 @@ #include "aes_128_ctr.h" #include "assertions.h" #include "conversions.h" -#include "secu_defs.h" +#include "nas_stream_eea2.h" -int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) +void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out) { DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->key != NULL); @@ -53,6 +53,4 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) const size_t len_out = byte_lenght; byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght}; aes_128_ctr(&p, msg, len_out, out); - - return 0; } diff --git a/openair2/UTIL/OSA/osa_rijndael.h b/openair3/SECU/nas_stream_eea2.h similarity index 96% rename from openair2/UTIL/OSA/osa_rijndael.h rename to openair3/SECU/nas_stream_eea2.h index fcffac5dbf..c6133c987d 100644 --- a/openair2/UTIL/OSA/osa_rijndael.h +++ b/openair3/SECU/nas_stream_eea2.h @@ -1,3 +1,4 @@ + /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,7 +20,12 @@ * contact@openairinterface.org */ +#ifndef OAI_NAS_STREAM_EEA2_H +#define OAI_NAS_STREAM_EEA2_H + +#include "secu_defs.h" #include + /* Rijndael S-box OSA_SR */ static const uint8_t OSA_SR[256] = { @@ -53,3 +59,7 @@ static const uint8_t OSA_SQ[256] = { 0x04, 0xC8, 0x9D, 0xE7, 0x14, 0xB1, 0x87, 0x9C, 0xDF, 0x6F, 0xF9, 0xDA, 0x2A, 0xC4, 0x59, 0x16, 0x74, 0x91, 0xAB, 0x26, 0x61, 0x76, 0x34, 0x2B, 0xAD, 0x99, 0xFB, 0x72, 0xEC, 0x33, 0x12, 0xDE, 0x98, 0x3B, 0xC0, 0x9B, 0x3E, 0x18, 0x10, 0x3A, 0x56, 0xE1, 0x77, 0xC9, 0x1E, 0x9E, 0x95, 0xA3, 0x90, 0x19, 0xA8, 0x6C, 0x09, 0xD0, 0xF0, 0x86}; + +void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out); + +#endif diff --git a/openair3/SECU/nas_stream_eia1.c b/openair3/SECU/nas_stream_eia1.c index 629d40d612..f080db7aac 100644 --- a/openair3/SECU/nas_stream_eia1.c +++ b/openair3/SECU/nas_stream_eia1.c @@ -25,7 +25,7 @@ #include #include // double ceil(double x); -#include "secu_defs.h" +#include "nas_stream_eia1.h" #include "assertions.h" #include "conversions.h" @@ -33,12 +33,6 @@ #define SECU_DEBUG -uint64_t MUL64x(uint64_t V, uint64_t c); -uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c); -uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c); -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); - - // see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1 /* MUL64x. @@ -49,7 +43,7 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out * function. * See section 4.3.2 for details. */ -uint64_t MUL64x(uint64_t V, uint64_t c) +static uint64_t MUL64x(uint64_t V, uint64_t c) { if ( V & 0x8000000000000000 ) return (V << 1) ^ c; @@ -65,7 +59,7 @@ uint64_t MUL64x(uint64_t V, uint64_t c) function. * See section 4.3.3 for details. */ -uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) +static uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) { if ( i == 0) return V; @@ -81,7 +75,7 @@ uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) * function. * See section 4.3.4 for details. */ -uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) +static uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) { uint64_t result = 0; int i = 0; @@ -99,7 +93,7 @@ uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) * Output : a 32 bit mask. * Prepares a 32 bit mask with required number of 1 bits on the MSB side. */ -uint32_t mask32bit(int n) +static uint32_t mask32bit(int n) { uint32_t mask=0x0; @@ -118,7 +112,7 @@ uint32_t mask32bit(int n) * @param[in] stream_cipher Structure containing various variables to setup encoding * @param[out] out For EIA1 the output string is 32 bits long */ -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) +void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t out[4]) { snow_3g_context_t snow_3g_context; uint32_t K[4],IV[4], z[5]; @@ -218,5 +212,4 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) //printf ("MAC_I:%16X\n",MAC_I); MAC_I = hton_int32(MAC_I); memcpy(out, &MAC_I, 4); - return 0; } diff --git a/openair3/SECU/nas_stream_eia1.h b/openair3/SECU/nas_stream_eia1.h new file mode 100644 index 0000000000..58a7f8be99 --- /dev/null +++ b/openair3/SECU/nas_stream_eia1.h @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#ifndef OAI_NAS_STREAM_EIA1_H +#define OAI_NAS_STREAM_EIA1_H + +#include "secu_defs.h" + +void nas_stream_encrypt_eia1(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]); + +#endif diff --git a/openair3/SECU/nas_stream_eia2.c b/openair3/SECU/nas_stream_eia2.c index 4c7951a0f5..2655c8ad81 100644 --- a/openair3/SECU/nas_stream_eia2.c +++ b/openair3/SECU/nas_stream_eia2.c @@ -25,7 +25,7 @@ #include #include -#include "secu_defs.h" +#include "nas_stream_eia2.h" #include #include "aes_128_cbc_cmac.h" @@ -40,7 +40,7 @@ * @param[out] out For EIA2 the output string is 32 bits long */ -int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) +void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t out[4]) { DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->message != NULL); @@ -49,7 +49,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) DevAssert((stream_cipher->blength & 0x7) == 0); aes_128_t k_iv = {0}; - memcpy(&k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key)); k_iv.type = AES_INITIALIZATION_VECTOR_8; k_iv.iv8.d.bearer = stream_cipher->bearer; k_iv.iv8.d.direction = stream_cipher->direction; @@ -59,8 +59,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) uint8_t result[16] = {0}; byte_array_t msg = {.buf = stream_cipher->message, .len = m_length }; aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); - + memcpy(out, result, 4); - return 0; } diff --git a/openair3/SECU/nas_stream_eia2.h b/openair3/SECU/nas_stream_eia2.h new file mode 100644 index 0000000000..1349408fb7 --- /dev/null +++ b/openair3/SECU/nas_stream_eia2.h @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#ifndef OAI_NAS_STREAM_EIA2_H +#define OAI_NAS_STREAM_EIA2_H + +#include "secu_defs.h" + +void nas_stream_encrypt_eia2(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]); + +#endif diff --git a/openair3/SECU/secu_defs.c b/openair3/SECU/secu_defs.c index 00cf23187e..4a6782de97 100644 --- a/openair3/SECU/secu_defs.c +++ b/openair3/SECU/secu_defs.c @@ -19,78 +19,48 @@ * contact@openairinterface.org */ - #include "secu_defs.h" -#include "kdf.h" -#ifndef NAS_UE -int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" + +#include "nas_stream_eea0.h" +#include "nas_stream_eea1.h" +#include "nas_stream_eea2.h" + +#include "nas_stream_eia1.h" +#include "nas_stream_eia2.h" + +void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t out[4]) { - uint8_t s[7] = {0}; - - // FC - s[0] = FC_KENB; - // P0 = Uplink NAS count - s[1] = (nas_count & 0xff000000) >> 24; - s[2] = (nas_count & 0x00ff0000) >> 16; - s[3] = (nas_count & 0x0000ff00) >> 8; - s[4] = (nas_count & 0x000000ff); - - // Length of NAS count - s[5] = 0x00; - s[6] = 0x04; - - // kdf(kasme, 32, s, 7, keNB, 32); - byte_array_t data = {.buf = s, .len = 7}; - kdf(kasme, data, 32, keNB); - - return 0; -} -#endif - -int derive_keNB_star( - const uint8_t *kenb_32, - const uint16_t pci, - const uint32_t earfcn_dl, - const bool is_rel8_only, - uint8_t *kenb_star) -{ - // see 33.401 section A.5 KeNB* derivation function - uint8_t s[10] = {0}; - byte_array_t data = {.buf = s}; - // FC = 0x13 - s[0] = FC_KENB_STAR; - // P0 = PCI (target physical cell id) - s[1] = (pci & 0x0000ff00) >> 8; - s[2] = (pci & 0x000000ff); - // L0 = length of PCI (i.e. 0x00 0x02) - s[3] = 0x00; - s[4] = 0x02; - // P1 = EARFCN-DL (target physical cell downlink frequency) - if (is_rel8_only) { - s[5] = (earfcn_dl & 0x0000ff00) >> 8; - s[6] = (earfcn_dl & 0x000000ff); - s[7] = 0x00; - s[8] = 0x02; -// kdf (kenb_32, 32, s, 9, kenb_star, 32); - data.len = 9; + if (alg == EIA0_ALG_ID) { + LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg); + } else if (alg == EIA1_128_ALG_ID) { + LOG_D(OSA, "EIA1 algorithm applied for integrity\n"); + nas_stream_encrypt_eia1(stream_cipher, out); + } else if (alg == EIA2_128_ALG_ID) { + LOG_D(OSA, "EIA2 algorithm applied for integrity\n"); + nas_stream_encrypt_eia2(stream_cipher, out); } else { - s[5] = (earfcn_dl & 0x00ff0000) >> 16; - s[6] = (earfcn_dl & 0x0000ff00) >> 8; - s[7] = (earfcn_dl & 0x000000ff); - s[8] = 0x00; - s[9] = 0x03; - //kdf (kenb_32, 32, s, 10, kenb_star, 32); - data.len = 10; + LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg); + DevAssert(0 != 0 && "Unknown Algorithm type"); + } +} + +void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t* out) +{ + if (alg == EEA0_ALG_ID) { + LOG_D(OSA, "EEA0 algorithm applied for encryption\n"); + nas_stream_encrypt_eea0(stream_cipher, out); + } else if (alg == EEA1_128_ALG_ID) { + LOG_D(OSA, "EEA1 algorithm applied for encryption\n"); + nas_stream_encrypt_eea1(stream_cipher, out); + } else if (alg == EEA2_128_ALG_ID) { + LOG_D(OSA, "EEA2 algorithm applied for encryption\n"); + nas_stream_encrypt_eea2(stream_cipher, out); + } else { + LOG_E(OSA, "Provided encrypt algorithm is currently not supported = %u\n", alg); + DevAssert(0 != 0 && "Unknown Algorithm type"); } - - kdf (kenb_32, data, 32, kenb_star); - - // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) - // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 - // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This - // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the - // EARFCN-DL. - return 0; } diff --git a/openair3/SECU/secu_defs.h b/openair3/SECU/secu_defs.h index 7817db30d3..7b96544bd5 100644 --- a/openair3/SECU/secu_defs.h +++ b/openair3/SECU/secu_defs.h @@ -22,47 +22,9 @@ #ifndef SECU_DEFS_H_ #define SECU_DEFS_H_ -#include "security_types.h" #include #include -#define EIA0_ALG_ID 0x00 -#define EIA1_128_ALG_ID 0x01 -#define EIA2_128_ALG_ID 0x02 - -#define EEA0_ALG_ID 0x00 -#define EEA1_128_ALG_ID 0x01 -#define EEA2_128_ALG_ID 0x02 - -#define SECU_DIRECTION_UPLINK 0 -#define SECU_DIRECTION_DOWNLINK 1 - -int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); - -int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, - const bool is_rel8_only, uint8_t * kenb_star); - -int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t kasme[32], uint8_t *knas); - -#define derive_key_nas_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(NAS_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_nas_int(aLGiD, kASME, kNAS) \ - derive_key_nas(NAS_INT_ALG, aLGiD, kASME, kNAS) - -#define derive_key_rrc_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(RRC_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_rrc_int(aLGiD, kASME, kNAS) \ - derive_key_nas(RRC_INT_ALG, aLGiD, kASME, kNAS) - -#define derive_key_up_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(UP_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_up_int(aLGiD, kASME, kNAS) \ - derive_key_nas(UP_INT_ALG, aLGiD, kASME, kNAS) - #define SECU_DIRECTION_UPLINK 0 #define SECU_DIRECTION_DOWNLINK 1 @@ -77,14 +39,34 @@ typedef struct { uint32_t blength; } nas_stream_cipher_t; -int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out); +/*! + * @brief Encrypt/Decrypt a block of data based on the provided algorithm + * @param[in] algorithm Algorithm used to encrypt the data + * Possible values are: + * - EIA0_ALG_ID for NULL encryption + * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) + * - EIA2_128_ALG_ID for 128 bits AES LTE encryption + * @param[in] stream_cipher All parameters used to compute the encrypted block of data + * @param[out] out The encrypted block of data + */ -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); +typedef enum { + EIA0_ALG_ID = 0x00, + EIA1_128_ALG_ID = 0x01, + EIA2_128_ALG_ID = 0x02, + END_EIA0_ALG_ID, +} eia_alg_id_e; -int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out); +void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t out[4]); -int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); +typedef enum { + EEA0_ALG_ID = 0x00, + EEA1_128_ALG_ID = 0x01, + EEA2_128_ALG_ID = 0x02, -#undef SECU_DEBUG + END_EEA_ALG_ID +} eea_alg_id_e; + +void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t *out); #endif /* SECU_DEFS_H_ */ diff --git a/openair3/TEST/test_secu_knas_encrypt_eea1.c b/openair3/TEST/test_secu_knas_encrypt_eea1.c index aa1b57a6ba..03708a9575 100644 --- a/openair3/TEST/test_secu_knas_encrypt_eea1.c +++ b/openair3/TEST/test_secu_knas_encrypt_eea1.c @@ -52,8 +52,7 @@ void eea1_encrypt(uint8_t direction, uint32_t count, nas_cipher->blength = length; nas_cipher->message = message; - if (nas_stream_encrypt_eea1(nas_cipher, result) != 0) - fail("Fail: nas_stream_encrypt_eea1\n"); + stream_compute_encrypt(EEA1_128_ALG_ID, nas_cipher, result); if (compare_buffer(result, byte_length, expected, byte_length) != 0) { fail("Fail: eea1_encrypt\n"); diff --git a/openair3/TEST/test_secu_knas_encrypt_eea2.c b/openair3/TEST/test_secu_knas_encrypt_eea2.c index 78a2b6fecc..e559149f99 100644 --- a/openair3/TEST/test_secu_knas_encrypt_eea2.c +++ b/openair3/TEST/test_secu_knas_encrypt_eea2.c @@ -25,7 +25,6 @@ #include #include "test_util.h" - #include "secu_defs.h" static @@ -52,8 +51,7 @@ void eea2_encrypt(uint8_t direction, uint32_t count, nas_cipher->blength = length; nas_cipher->message = message; - if (nas_stream_encrypt_eea2(nas_cipher, result) != 0) - fail("Fail: nas_stream_encrypt_eea2\n"); + nas_stream_encrypt_eea2(nas_cipher, result); if (compare_buffer(result, byte_length, expected, byte_length) != 0) { fail("Fail: eea2_encrypt\n");