Merge branch 'integration_2024_w17' into 'develop'

Integration `2024.w17`

See merge request oai/openairinterface5g!2702

* !2659 NR bandwidth index fix
* !2693 Harmonize frequency range structures
* !2699 Add support for USRP X410 to run with 200 MHz bandwidth in FR2 at 120 kHz SCS
* !2692 Fix for the overflow issue while processing GPS based timestamp from RU
* !2665 NR UE improvements in handling RRC Release
* !2682 dci11type0
* !2686 CI: Maintenance, fixes, improvements
* !2677 NR UE trigger RA for SR failure
* !2683 Ue small fixes
* !2668 Refactor PDCP Reestablishment and introduce PDCP Suspend at gNB
* Add rhel9.4 to the list of OAI supported distributions
* !2673 speedup integrity computation
* !2706 doc: Update of CI testbenches
This commit is contained in:
Robert Schmidt
2024-04-30 15:38:45 +00:00
95 changed files with 1075 additions and 966 deletions
@@ -25,8 +25,8 @@ allow dynamic UE creation from remote API */
rf_port: 0,
bandwidth: 20,
band: 78,
dl_nr_arfcn:627360,
ssb_nr_arfcn:627360,
dl_nr_arfcn:630048,
ssb_nr_arfcn:630048,
subcarrier_spacing: 30,
n_antenna_dl: N_ANTENNA_DL,
n_antenna_ul: N_ANTENNA_UL,
@@ -39,7 +39,7 @@ allow dynamic UE creation from remote API */
ue_list: [
{
"ue_id" : 1,
"imsi": "208970000000111",
"imsi": "001020000000001",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -54,7 +54,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 2,
"imsi": "208970000000112",
"imsi": "001020000000002",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -69,7 +69,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 3,
"imsi": "208970000000113",
"imsi": "001020000000003",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -84,7 +84,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 4,
"imsi": "208970000000114",
"imsi": "001020000000004",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -99,7 +99,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 5,
"imsi": "208970000000115",
"imsi": "001020000000005",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -114,7 +114,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 6,
"imsi": "208970000000116",
"imsi": "001020000000006",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -129,7 +129,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 7,
"imsi": "208970000000100",
"imsi": "001020000000007",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -144,7 +144,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 8,
"imsi": "208970000000102",
"imsi": "001020000000008",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -159,7 +159,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 9,
"imsi": "208970000000103",
"imsi": "001020000000009",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -174,7 +174,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 10,
"imsi": "208970000000104",
"imsi": "001020000000010",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -189,7 +189,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 11,
"imsi": "208970000000110",
"imsi": "001020000000011",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -204,7 +204,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 12,
"imsi": "208970000000105",
"imsi": "001020000000012",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -219,7 +219,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 13,
"imsi": "208970000000106",
"imsi": "001020000000013",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -234,7 +234,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 14,
"imsi": "208970000000107",
"imsi": "001020000000014",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -249,7 +249,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 15,
"imsi": "208970000000108",
"imsi": "001020000000015",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
@@ -264,7 +264,7 @@ allow dynamic UE creation from remote API */
},
{
"ue_id" : 16,
"imsi": "208970000000109",
"imsi": "001020000000016",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
-280
View File
@@ -1,280 +0,0 @@
/* UE simulator configuration file version 2021-06-17
* LTE / 5G Non StandAlone
* Copyright (C) 2019-2021 Amarisoft
*/
{
#define N_ANTENNA_DL 2
#define TDD 1
log_options: "all.level=warn,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
log_filename: "/tmp/ue.log",
/* Enable remote API and Web interface */
com_addr: "0.0.0.0:9002",
include "rf_driver/1chan.cfg",
/* If true, allow the simulation of several UEs at the same time and
allow dynamic UE creation from remote API */
cell_groups: [{
group_type: "nr",
multi_ue: true,
cells: [{
rf_port: 0,
bandwidth: 20,
band: 78,
dl_nr_arfcn:627360,
ssb_nr_arfcn:627360,
subcarrier_spacing: 30,
n_antenna_dl: N_ANTENNA_DL,
n_antenna_ul: 1,
rx_to_tx_latency:2,
}],
}],
/* UE capabilities */
/* USIM data */
ue_list: [
{
"ue_id" : 1,
"imsi": "208970000000111",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 2,
"imsi": "208970000000112",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 3,
"imsi": "208970000000113",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 4,
"imsi": "208970000000114",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 5,
"imsi": "208970000000115",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 6,
"imsi": "208970000000116",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 7,
"imsi": "208970000000117",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 8,
"imsi": "208970000000118",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 9,
"imsi": "208970000000119",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 10,
"imsi": "208970000000120",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 11,
"imsi": "208970000000121",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 12,
"imsi": "208970000000122",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 13,
"imsi": "208970000000123",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 14,
"imsi": "208970000000124",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 15,
"imsi": "208970000000125",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
{
"ue_id" : 16,
"imsi": "208970000000126",
"K": "fec86ba6eb707ed08905757b1bb44b8f",
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
default_pdu_session_snssai: { sst: 1, },
tun_setup_script: "ue-ifup",
},
],
}
+1 -1
View File
@@ -97,7 +97,7 @@ ltebox-nepes:
amarisoft_ue:
Host: amariue
InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-20897-2x2.cfg &
InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-00102-2x2.cfg &
TermScript: /root/2023-10-27/libs/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
amarisoft_ue_1:
Host: amariue
+48
View File
@@ -44,6 +44,9 @@ 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"
CN_IMAGES = ["mysql", "oai-nrf", "oai-amf", "oai-smf", "oai-upf", "oai-ausf", "oai-udm", "oai-udr", "oai-traffic-server"]
CN_CONTAINERS = ["", "-c nrf", "-c amf", "-c smf", "-c upf", "-c ausf", "-c udm", "-c udr", ""]
def OC_login(cmd, ocUserName, ocPassword, ocProjectName):
if ocUserName == '' or ocPassword == '' or ocProjectName == '':
@@ -65,6 +68,51 @@ def OC_login(cmd, ocUserName, ocPassword, ocProjectName):
def OC_logout(cmd):
cmd.run(f'oc logout')
def OC_deploy_CN(cmd, ocUserName, ocPassword):
logging.debug('OC OAI CN5G: Deploying OAI CN5G on Openshift Cluster')
path = "/opt/oai-cn5g-fed-develop-2024-april-00102"
succeeded = OC_login(cmd, ocUserName, ocPassword, CI_OC_CORE_NAMESPACE)
if not succeeded:
return False, CONST.OC_LOGIN_FAIL
cmd.run('helm uninstall oai5gcn --wait --timeout 60s')
ret = cmd.run(f'helm install --wait --timeout 60s oai5gcn {path}/ci-scripts/charts/oai-5g-basic/.')
if ret.returncode != 0:
logging.error('OC OAI CN5G: Deployment failed')
OC_logout(cmd)
return False, CONST.OC_PROJECT_FAIL
report = cmd.run('oc get pods')
OC_logout(cmd)
return True, report
def OC_undeploy_CN(cmd, ocUserName, ocPassword):
logging.debug('OC OAI CN5G: Terminating CN on Openshift Cluster')
path = "/opt/oai-cn5g-fed-develop-2024-april-00102"
succeeded = OC_login(cmd, ocUserName, ocPassword, CI_OC_CORE_NAMESPACE)
if not succeeded:
return False, CONST.OC_LOGIN_FAIL
cmd.run(f'rm -Rf {path}/logs')
cmd.run(f'mkdir -p {path}/logs')
logging.debug('OC OAI CN5G: Collecting log files to workspace')
cmd.run(f'oc describe pod &> {path}/logs/describe-pods-post-test.log')
cmd.run(f'oc get pods.metrics.k8s &> {path}/logs/nf-resource-consumption.log')
for ii, ci in zip(CN_IMAGES, CN_CONTAINERS):
podName = cmd.run(f"oc get pods | grep {ii} | awk \'{{print $1}}\'").stdout.strip()
if not podName:
logging.debug(f'{ii} pod not found!')
else:
cmd.run(f'oc logs -f {podName} {ci} &> {path}/logs/{ii}.log &')
cmd.run(f'cd {path}/logs && zip -r -qq test_logs_CN.zip *.log')
cmd.copyin(f'{path}/logs/test_logs_CN.zip','test_logs_CN.zip')
ret = cmd.run('helm uninstall --wait --timeout 60s oai5gcn')
if ret.returncode != 0:
logging.error('OC OAI CN5G: Undeployment failed')
cmd.run('helm uninstall --wait --timeout 60s oai5gcn')
OC_logout(cmd)
return False, CONST.OC_PROJECT_FAIL
report = cmd.run('oc get pods')
OC_logout(cmd)
return True, report
class Cluster:
def __init__(self):
self.eNBIPAddress = ""
+4 -4
View File
@@ -129,10 +129,10 @@ def Iperf_analyzeV3BIDIRJson(filename):
with open(filename) as file:
filename = json.load(file)
try:
sender_bitrate_dl = round(filename['end']['streams'][0]['sender']['bits_per_second']/1000000,2)
receiver_bitrate_dl = round(filename['end']['streams'][0]['receiver']['bits_per_second']/1000000,2)
sender_bitrate_ul = round(filename['end']['streams'][1]['sender']['bits_per_second']/1000000,2)
receiver_bitrate_ul = round(filename['end']['streams'][1]['receiver']['bits_per_second']/1000000,2)
sender_bitrate_ul = round(filename['end']['streams'][0]['sender']['bits_per_second']/1000000,2)
receiver_bitrate_ul = round(filename['end']['streams'][0]['receiver']['bits_per_second']/1000000,2)
sender_bitrate_dl = round(filename['end']['streams'][1]['sender']['bits_per_second']/1000000,2)
receiver_bitrate_dl = round(filename['end']['streams'][1]['receiver']['bits_per_second']/1000000,2)
except Exception as e:
return (False, 'Could not compute BIDIR bitrate!')
@@ -204,8 +204,8 @@ MACRLCs = (
bler_target_upper = 20.0;
bler_target_lower = 10.0;
max_ul_rb_index = 27;
puSch10xSnr = 190;
puCch10xSnr = 160;
puSch10xSnr = 250;
puCch10xSnr = 230;
}
);
@@ -224,8 +224,8 @@ RUs = (
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 10
att_rx = 5;
att_tx = 12
att_rx = 0;
bands = [38];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
@@ -204,8 +204,8 @@ MACRLCs = (
bler_target_upper = 20.0;
bler_target_lower = 10.0;
max_ul_rb_index = 27;
puSch10xSnr = 190;
puCch10xSnr = 160;
puSch10xSnr = 280;
puCch10xSnr = 250;
}
);
@@ -224,8 +224,8 @@ RUs = (
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 10
att_rx = 5;
att_tx = 18
att_rx = 0;
bands = [38];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
@@ -167,19 +167,12 @@ gNBs =
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.61.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
amf_ip_address = ({ ipv4 = "192.168.61.132"; });
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.61.129/26";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.61.129/26";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
@@ -164,20 +164,11 @@ gNBs = (
////////// AMF parameters:
amf_ip_address = (
{
ipv4 = "192.168.61.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
amf_ip_address = ({ ipv4 = "192.168.61.132"; });
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.61.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.61.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
}
@@ -13,7 +13,7 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 97; mnc_length = 2; snssaiList = ({sst = 1;}); });
plmn_list = ({ mcc = 001; mnc = 02; mnc_length = 2; snssaiList = ({sst = 1;}); });
nr_cellid = 12345678L
@@ -16,7 +16,7 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 0x1;
plmn_list = ({ mcc = 208; mnc = 97; mnc_length = 2; snssaiList = ({ sst =0x1; }) });
plmn_list = ({ mcc = 001; mnc = 02; mnc_length = 2; snssaiList = ({ sst =0x1; }) });
nr_cellid = 12345678L
@@ -35,10 +35,10 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3410.4 MHz => 301 REs from PointA 25 PRBs + 1 RE
absoluteFrequencySSB = 627360;
absoluteFrequencySSB = 630048;
dl_frequencyBand = 78;
# this is 3410.4 - (51*12*30e-3/2) = 3401.22 MHz
dl_absoluteFrequencyPointA = 626748;
dl_absoluteFrequencyPointA = 629436;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
+12 -58
View File
@@ -298,39 +298,18 @@ class EPCManagement():
html_cell += '(' + res4.group('date') + ')'
html_cell += '\n'
elif re.match('OC-OAI-CN5G', self.Type, re.IGNORECASE):
self.testCase_id = HTML.testCase_id
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 = "/opt/oai-cn5g-fed-develop-2023-04-28-20897"
succeeded = OC.OC_login(mySSH, self.OCUserName, self.OCPassword, OC.CI_OC_CORE_NAMESPACE)
succeeded, report = OC.OC_deploy_CN(mySSH, self.OCUserName, self.OCPassword)
if not succeeded:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
return False
for ii in imageNames:
mySSH.run(f'helm uninstall {ii}', reportNonZero=False)
mySSH.run(f'helm spray {lSourcePath}/ci-scripts/charts/oai-5g-basic/.')
ret = mySSH.run(f'oc get pods', silent=True)
if ret.stdout.count('Running') != 9:
logging.error('\u001B[1m Deploying 5GCN Failed using helm chart on OC Cluster\u001B[0m')
for ii in imageNames:
mySSH.run('helm uninstall '+ ii)
ret = mySSH.run(f'oc get pods')
if re.search('No resources found', ret.stdout):
logging.debug('All pods uninstalled')
OC.OC_logout(mySSH)
mySSH.close()
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_PROJECT_FAIL)
return False
ret = mySSH.run(f'oc get pods', silent=True)
for line in ret.stdout.split('\n')[1:]:
HTML.CreateHtmlTestRow('N/A', 'KO', report)
HTML.CreateHtmlTabFooter(False)
mySSH.close()
sys.exit("OC OAI CN5G: CN deployment failed!")
for line in report.stdout.split('\n')[1:]:
columns = line.strip().split()
name = columns[0]
status = columns[2]
html_cell += status + ' ' + name
html_cell += '\n'
OC.OC_logout(mySSH)
else:
logging.error('This option should not occur!')
mySSH.close()
@@ -562,8 +541,6 @@ class EPCManagement():
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
def Terminate5GCN(self, HTML):
imageNames = ["mysql", "oai-nrf", "oai-amf", "oai-smf", "oai-spgwu-tiny", "oai-ausf", "oai-udm", "oai-udr", "oai-traffic-server"]
containerInPods = ["", "-c nrf", "-c amf", "-c smf", "-c spgwu", "-c ausf", "-c udm", "-c udr", ""]
mySSH = cls_cmd.getConnection(self.IPAddress)
message = ''
if re.match('ltebox', self.Type, re.IGNORECASE):
@@ -598,36 +575,13 @@ class EPCManagement():
mySSH.copyin(f'{self.SourceCodePath}/logs/test_logs_CN.zip','test_logs_CN.zip')
logging.debug(message)
elif re.match('OC-OAI-CN5G', self.Type, re.IGNORECASE):
logging.debug('Terminating OAI CN5G on Openshift Cluster')
lIpAddr = self.IPAddress
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, OC.CI_OC_CORE_NAMESPACE)
succeeded, report = OC.OC_undeploy_CN(mySSH, self.OCUserName, self.OCPassword)
if not succeeded:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OC_LOGIN_FAIL)
return False
mySSH.run(f'oc describe pod &> {lSourcePath}/logs/describe-pods-post-test.log')
mySSH.run(f'oc get pods.metrics.k8s &> {lSourcePath}/logs/nf-resource-consumption.log')
for ii, ci in zip(imageNames, containerInPods):
podName = mySSH.run(f"oc get pods | grep {ii} | awk \'{{print $1}}\'").stdout.strip()
if not podName:
logging.debug(f'{ii} pod not found!')
HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER)
HTML.CreateHtmlTabFooter(False)
mySSH.run(f'oc logs -f {podName} {ci} &> {lSourcePath}/logs/{ii}.log &')
mySSH.run(f'helm uninstall {ii}')
podName = ''
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 {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'
OC.OC_logout(mySSH)
HTML.CreateHtmlTestRow('N/A', 'KO', report)
HTML.CreateHtmlTabFooter(False)
sys.exit("OC OAI CN5G: CN undeployment failed!")
else:
message = report.stdout
else:
logging.error('This should not happen!')
mySSH.close()
@@ -31,15 +31,15 @@
111111
100000
010010
030101
031101
010001
000001
050000
050001
070000
070001
051000
051001
071000
071001
010010
030201
031201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
@@ -65,7 +65,7 @@
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="030101">
<testCase id="031101">
<class>Deploy_Object</class>
<desc>Deploy eNB (TDD/Band38/2.6Ghz/N3XX) in a container</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2</yaml_path>
@@ -85,7 +85,7 @@
<id>up2</id>
</testCase>
<testCase id="050000">
<testCase id="051000">
<class>Ping</class>
<desc>Ping: 20 pings</desc>
<id>up2</id>
@@ -94,7 +94,7 @@
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<testCase id="051001">
<class>Ping</class>
<desc>Ping: 100 pings, size 1024</desc>
<id>up2</id>
@@ -103,7 +103,7 @@
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="070000">
<testCase id="071000">
<class>Iperf</class>
<desc>iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 1M -t 60 -R</iperf_args>
@@ -113,7 +113,7 @@
<iperf_bitrate_threshold>95</iperf_bitrate_threshold>
</testCase>
<testCase id="070001">
<testCase id="071001">
<class>Iperf</class>
<desc>iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile)</desc>
<iperf_args>-u -b 7M -t 60</iperf_args>
@@ -129,7 +129,7 @@
<id>up2</id>
</testCase>
<testCase id="030201">
<testCase id="031201">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2</yaml_path>
@@ -48,9 +48,9 @@
000100
000010
000020
002016
000030
000040
002016
000200
003000
004000
@@ -165,7 +165,7 @@
<testCase id="070003">
<class>Iperf</class>
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -R</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -174,7 +174,7 @@
<testCase id="070004">
<class>Iperf</class>
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -157,7 +157,7 @@
<testCase id="370003">
<class>Iperf</class>
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -R</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -166,7 +166,7 @@
<testCase id="370004">
<class>Iperf</class>
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -189,7 +189,7 @@
<testCase id="170003">
<class>Iperf</class>
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -R</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -198,7 +198,7 @@
<testCase id="170004">
<class>Iperf</class>
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -159,7 +159,7 @@
<testCase id="270003">
<class>Iperf</class>
<desc>iperf (DL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (DL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30 -R</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -168,7 +168,7 @@
<testCase id="270004">
<class>Iperf</class>
<desc>iperf (UL/TCP)(30 sec)(multi-ue profile)</desc>
<desc>iperf (UL/TCP)(30 sec)(single-ue profile)</desc>
<iperf_args>-t 30</iperf_args>
<id>idefix</id>
<svr_id>sabox-nepes</svr_id>
@@ -10,7 +10,7 @@ services:
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3511200000 --sa --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 45 --log_config.global_log_options level,nocolor,time --uicc0.imsi 208970000000111 --uicc0.nssai_sd 16777215
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3511200000 --sa --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 45 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 --uicc0.nssai_sd 16777215
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
@@ -30,7 +30,7 @@ services:
core: -1 # for core dumps
environment:
USE_B2XX: 'yes'
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 0 --L1s.[0].max_ldpc_iterations 20
USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --telnetsrv --telnetsrv.shrmod ci --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 0 --L1s.[0].max_ldpc_iterations 20
volumes:
- ../../conf_files/gnb-du.sa.band1.52prb.usrpb210.conf:/opt/oai-gnb/etc/gnb.conf
- /dev:/dev
+1
View File
@@ -128,6 +128,7 @@ check_supported_distribution() {
"rhel9.1") return 0 ;;
"rhel9.2") return 0 ;;
"rhel9.3") return 0 ;;
"rhel9.4") return 0 ;;
"centos7") return 0 ;;
"centos8") return 0 ;;
"rocky8.7") return 0 ;;
+4 -4
View File
@@ -105,7 +105,6 @@ int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs)
return (-1); // not found
}
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
// Notes:
@@ -179,8 +178,9 @@ const nr_bandentry_t nr_bandtable[] = {
{261,27500040,28350000,27500040,28350000, 2,2070833, 120}
};
int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index)
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb)
{
int bw_index = get_supported_band_index(scs, frequency_range, nb_rb);
if (frequency_range == FR1) {
switch (bw_index) {
case 0 :
@@ -232,8 +232,8 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_
// 38.101-1 section 6.2.2
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
int index = get_nr_table_idx(nr_band, scs);
int bw_index = get_supported_band_index(scs, nr_band > 256 ? FR2 : FR1, nb_ul);
int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, bw_index) * 1000;
int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, nb_ul) * 1000;
float limit = frame_type == TDD ? 0.04 : 0.03;
float rel_bw = (float) (2 * band_size_khz) / (float) (nr_bandtable[index].ul_max + nr_bandtable[index].ul_min);
return rel_bw <= limit;
+11 -7
View File
@@ -79,11 +79,6 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
#define NR_MAX_NB_LAYERS 4 // 8
typedef enum {
nr_FR1 = 0,
nr_FR2
} nr_frequency_range_e;
typedef struct nr_bandentry_s {
int16_t band;
uint64_t ul_min;
@@ -176,7 +171,16 @@ static inline int get_num_dmrs(uint16_t dmrs_mask )
return(num_dmrs);
}
static __attribute__((always_inline)) inline int count_bits_set(uint64_t v)
static inline int count_bits(uint8_t *arr, int sz)
{
AssertFatal(sz % sizeof(int) == 0, "to implement if needed\n");
int ret = 0;
for (uint *ptr = (uint *)arr; (uint8_t *)ptr < arr + sz; ptr++)
ret += __builtin_popcount(*ptr);
return ret;
}
static __attribute__((always_inline)) inline int count_bits64(uint64_t v)
{
return __builtin_popcountll(v);
}
@@ -206,7 +210,7 @@ uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
int get_nb_periods_per_frame(uint8_t tdd_period);
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type);
int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index);
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb);
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
void get_samplerate_and_bw(int mu,
int n_rb,
+10 -8
View File
@@ -9,10 +9,10 @@
| asterix | 172.21.16.127 | CI-Asterix-Usage | *unused* | 172.21.19.14 |
| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2) |
| porcepix | 172.21.16.136 | CI-Porcepix | Executor, EPC, 5GC | -- |
| nrmodule2 | 172.21.16.139 | CI-NrModule2 | Quectel | Quectel module |
| up2 | 172.21.19.68 | CI-UP2-Usage | COTS UE | Quectel RM520N |
| nepes | 172.21.16.137 | CI-Nepes | gNB (n78), EPC/5GC | B200mini (30C51EB) |
| ofqot | 172.21.16.109 | CI-Ofqot | gNB (n78) | B200mini (30C51D4) |
| idefix | 172.21.16.135 | CI-Idefix | Quectel | Quectel module |
| idefix | 172.21.16.135 | CI-Idefix | COTS UE | Quectel RM500Q |
| caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) |
| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator |
| nano | 172.21.18.48 | CI-Nano-Legacy-EPC | Executor, EPC, adb | 2x COTS (adb) |
@@ -23,7 +23,8 @@
| avra | 172.21.16.124 | CI-Avra-Usage | gNB (n78) | AW2S Jaguar (192.168.80.239) |
| orion | 172.21.16.134 | CI-Orion-Build-Sanity-Check-Deploy-Test, CI-Orion-DsTester-Deploy-Test | Build | |
| aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ |
| sphex | 172.21.17.54 | CI-Sphex-Usage | Quectel | Quectel module |
| sphex | 172.21.17.54 | CI-Sphex-Usage | COTS UE | Quectel RM500Q |
| matix | 172.21.19.58 | CI-Matix-Usage | gNB (n77) | N310 |
Note: The available resources, and their current usage, is indicated here:
- [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/):
@@ -154,7 +155,7 @@ information on how the images are built.
- tests OAI 4G for 10 MHz/TM1; known to be unstable
- [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/)
~4G-LTE
- obelix + N310, porcepix, nrmodule2 + Quectel
- obelix + N310, porcepix, up2 + Quectel
- TM1 and TM2 test, IF4p5 fronthaul
- [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/)
~4G-LTE
@@ -191,8 +192,12 @@ information on how the images are built.
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/)
~5G-NR
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 (U22) + Foxconn RU, COTS UE (Quctel RM500Q), OAI CN5G
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on Aerial2 (U22) + Foxconn RU, sphex + COTS UE (Quectel RM500Q), OAI CN5G
- container images for gNB deployment
- [RAN-SA-2x2-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-2x2-Module-CN5G/)
~5G-NR
- matix + N310 (gNB), up2 + COTS UE (Quectel RM520N), OAI 5GC deployed in docker on matix
- NR performance tests: 2x2 configuration, 60 MHz and 100 MHz bandwidth
### RAN-CI-NSA-Trigger
@@ -201,9 +206,6 @@ information on how the images are built.
- [RAN-NSA-2x2-Module-OAIEPC](https://jenkins-oai.eurecom.fr/job/RAN-NSA-2x2-Module-OAIEPC/)
- obelix + N310 (eNB), asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ Magma EPC
- LTE 2x2 and NR 2x2 (non-standalone)
- [RAN-SA-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G/)
- asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ OAI 5GC
- NR 2x2 (standalone)
## How to reproduce CI results
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 56 KiB

+10 -10
View File
@@ -16,16 +16,16 @@
\node[label=above:porcepix] (porcepix)
{\includegraphics[width=1.2cm]{server}};
\node[above right=-0.4cm and 2cm of porcepix, label=above:asterix] (asterix)
\node[above right=-0.4cm and 2cm of porcepix, label=above:matix] (matix)
{\includegraphics[width=1.2cm]{server}}
edge (porcepix);
\node[right=0.3cm of asterix, label=above:N310] (n310a)
{\includegraphics[width=1.5cm]{n310}} edge (asterix);
\node[right=.2cm of n310a, duplexer] (b78o) {n78} edge (n310a);
\node[below right=-0.1cm and 0.35cm of b78o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[right=0.3cm of matix, label=above:N310] (n310a)
{\includegraphics[width=1.5cm]{n310}} edge (matix);
\node[right=.2cm of n310a, duplexer] (b77o) {n77} edge (n310a);
\node[below right=-0.1cm and 0.35cm of b77o.east] (anto1)
{\includegraphics[width=0.3cm]{antenna}} edge (b77o);
\node[above right=-0.1cm and 0.35cm of b77o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b77o);
\node[below right=-0.4cm and 2cm of porcepix, label=above:obelix] (obelix)
{\includegraphics[width=1.2cm]{server}}
@@ -45,7 +45,7 @@
\node[above right=-0.1cm and 0.35cm of b78o.east] (anto2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[above right=-0.5cm and 5.0cm of n310o.east, label=above:RM500Q-GL] (quectel)
\node[above right=-0.5cm and 5.0cm of n310o.east, label=above:RM520N-GL] (quectel)
{\includegraphics[height=1.2cm]{quectel}};
\node[above left=-0.1cm and 0.8cm of quectel.west] (aq2)
{\includegraphics[width=0.3cm]{antenna}} edge (quectel);
@@ -55,7 +55,7 @@
{\includegraphics[width=0.3cm]{antenna}} edge (quectel);
\node[below=-0.2cm of aq3]
{\includegraphics[width=0.3cm]{antenna}} edge (quectel);
\node[right=1cm of quectel, label=above:nrmodule2] (nrmodule2)
\node[right=1cm of quectel, label=above:up2] (up2)
{\includegraphics[width=1.2cm]{server}}
edge (quectel);
+5 -5
View File
@@ -115,10 +115,10 @@ static void tx_func(void *param)
int slot_tx = info->slot;
int frame_rx = info->frame_rx;
int slot_rx = info->slot_rx;
int absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
int absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
int64_t absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
int64_t absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
if (absslot_rx < 0) {
LOG_W(NR_PHY, "Slot ahead %d is larger than absslot_tx %d. Cannot start TX yet.\n", info->gNB->RU_list[0]->sl_ahead, absslot_tx);
LOG_W(NR_PHY, "Slot ahead %d is larger than absslot_tx %ld. Cannot start TX yet.\n", info->gNB->RU_list[0]->sl_ahead, absslot_tx);
return;
}
LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx);
@@ -218,8 +218,8 @@ void rx_func(void *param)
for (; i < gNB->frame_parms.slots_per_subframe / 2; i++)
cumul_samples += gNB->frame_parms.get_samples_per_slot(i, &gNB->frame_parms);
int samples = cumul_samples / i;
int absslot_tx = info->timestamp_tx / samples;
int absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead;
int64_t absslot_tx = info->timestamp_tx / samples;
int64_t absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead;
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.start_L1_RX[rt_prof_idx]);
start_meas(&softmodem_stats_rxtx_sf);
+4 -4
View File
@@ -841,7 +841,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE;
}
if (fp->freq_range == nr_FR2)
if (fp->freq_range == FR2)
flags_gpio = get_gpio_flags(ru, slot);
const int flags = flags_burst | (flags_gpio << 4);
@@ -1108,8 +1108,8 @@ void ru_tx_func(void *param) {
for (; i < fp->slots_per_subframe / 2; i++)
cumul_samples += fp->get_samples_per_slot(i, fp);
int samples = cumul_samples / i;
int absslot_tx = info->timestamp_tx / samples;
int absslot_rx = absslot_tx - ru->sl_ahead;
int64_t absslot_tx = info->timestamp_tx / samples;
int64_t absslot_rx = absslot_tx - ru->sl_ahead;
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]);
// do TX front-end processing if needed (precoding and/or IDFTs)
@@ -1335,7 +1335,7 @@ void *ru_thread( void *param ) {
proc->timestamp_tx += fp->get_samples_per_slot(i % fp->slots_per_frame, fp);
proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame;
proc->frame_tx = proc->tti_rx > proc->tti_tx ? (proc->frame_rx + 1) & 1023 : proc->frame_rx;
int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
int64_t absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]);
LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
+2 -2
View File
@@ -40,7 +40,7 @@ extern "C"
// depth of trace in slots
#define RT_PROF_DEPTH 100
typedef struct {
int absslot_rx[RT_PROF_DEPTH];
int64_t absslot_rx[RT_PROF_DEPTH];
struct timespec return_RU_south_in[RT_PROF_DEPTH];
struct timespec return_RU_feprx[RT_PROF_DEPTH];
struct timespec return_RU_prachrx[RT_PROF_DEPTH];
@@ -50,7 +50,7 @@ typedef struct {
} rt_ru_profiling_t;
typedef struct {
int absslot_ux[RT_PROF_DEPTH];
int64_t absslot_ux[RT_PROF_DEPTH];
struct timespec start_L1_RX[RT_PROF_DEPTH];
struct timespec return_L1_RX[RT_PROF_DEPTH];
struct timespec start_L1_TX[RT_PROF_DEPTH];
+1 -2
View File
@@ -515,8 +515,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
}
fp->threequarter_fs = 0;
int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL);
nr_init_frame_parms(gNB_config, fp);
+6 -6
View File
@@ -252,7 +252,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->get_slot_from_timestamp = &get_slot_from_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? FR1 : FR2;
fp->Ncp = Ncp;
@@ -341,12 +341,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->get_samples_per_slot = &get_samples_per_slot;
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? FR1 : FR2;
uint8_t sco = 0;
if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||
((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) {
if (fp->freq_range == nr_FR1)
if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||
((fp->freq_range == FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) {
if (fp->freq_range == FR1)
sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common;
else
sco = config->ssb_table.ssb_subcarrier_offset;
@@ -379,7 +379,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
frame_parms->numerology_index = mu;
frame_parms->dl_CarrierFreq = downlink_frequency;
frame_parms->ul_CarrierFreq = downlink_frequency + delta_duplex;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? FR1 : FR2;
frame_parms->N_RB_UL = frame_parms->N_RB_DL;
frame_parms->nr_band = nr_band;
+6
View File
@@ -350,6 +350,12 @@ void rx_nr_prach_ru(RU_t *ru,
dftlen = dftlen*6;
break;
case 245760:
// 200 MHz @ 245.76 Ms/s
Ncp <<= 3;
dftlen <<= 3;
break;
default:
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
}
@@ -71,7 +71,7 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
int diff = ue->max_pos_avg >> 15;
if (frame_parms->freq_range==nr_FR2)
if (frame_parms->freq_range == FR2)
sync_offset = 2;
else
sync_offset = 0;
+6
View File
@@ -366,6 +366,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
dftlen = dftlen*6;
break;
case 245760:
// 200 MHz @ 245.76 Ms/s
Ncp <<= 3;
dftlen <<= 3;
break;
default:
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
}
+1 -1
View File
@@ -139,7 +139,7 @@ typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PAR
struct NR_DL_FRAME_PARMS {
/// frequency range
nr_frequency_range_e freq_range;
frequency_range_t freq_range;
// /// Placeholder to replace overlapping fields below
// nfapi_nr_rf_config_t rf_config;
/// Placeholder to replace SSB overlapping fields below
+4 -4
View File
@@ -71,10 +71,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_
// for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the subcarrier spacing provided
// by the higher-layer parameter subCarrierSpacingCommon
const int scs = cfg->ssb_config.scs_common.value;
const int prb_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> scs
: ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> (scs - 2);
const int prb_offset = (fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> scs
: ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> (scs - 2);
const int sc_offset =
(fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset;
(fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset;
fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset);
if (fp->print_ue_help_cmdline_log && get_softmodem_params()->sa) {
@@ -134,7 +134,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_
#endif
// Beam_id is currently used only for FR2
if (fp->freq_range==nr_FR2){
if (fp->freq_range == FR2){
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
for (int j=0;j<fp->symbols_per_slot;j++)
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
+40 -33
View File
@@ -494,19 +494,25 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
// We handle only one CW now
if (!(NR_MAX_NB_LAYERS>4)) {
NR_UE_DLSCH_t *dlsch0 = &dlsch[0];
int harq_pid = dlsch0->dlsch_config.harq_process_nbr;
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlschCfg = &dlsch0->dlsch_config;
int harq_pid = dlschCfg->harq_process_nbr;
// dlsch0_harq contains the previous transmissions data for this harq pid
NR_DL_UE_HARQ_t *dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
uint16_t BWPStart = dlsch0->dlsch_config.BWPStart;
uint16_t pdsch_start_rb = dlsch0->dlsch_config.start_rb;
uint16_t pdsch_nb_rb = dlsch0->dlsch_config.number_rbs;
uint16_t s0 = dlsch0->dlsch_config.start_symbol;
uint16_t s1 = dlsch0->dlsch_config.number_symbols;
AssertFatal(dlsch0->dlsch_config.resource_alloc == 1,
"DLSCH resource allocation type0 not supported at PHY\n");
LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), BWP start %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,BWPStart,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
LOG_D(PHY,
"[UE %d] nr_slot_rx %d, harq_pid %d (%d), BWP start %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask "
"%x, Nl %d\n",
ue->Mod_id,
nr_slot_rx,
harq_pid,
dlsch0_harq->status,
dlschCfg->BWPStart,
dlschCfg->start_rb,
dlschCfg->number_rbs,
dlschCfg->start_symbol,
dlschCfg->number_symbols,
dlschCfg->dlDmrsSymbPos,
dlsch0->Nl);
const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16;
__attribute__((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx * dlsch0->Nl][pdsch_est_size];
@@ -522,25 +528,26 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
__attribute__((aligned(32))) int32_t rxdataF_comp[dlsch[0].Nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT];
memset(rxdataF_comp, 0, sizeof(rxdataF_comp));
for (int m = s0; m < (s0 +s1); m++) {
if (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << m)) {
for (int m = dlschCfg->start_symbol; m < (dlschCfg->start_symbol + dlschCfg->number_symbols); m++) {
if (dlschCfg->dlDmrsSymbPos & (1 << m)) {
for (int nl = 0; nl < dlsch0->Nl; nl++) { //for MIMO Config: it shall loop over no_layers
LOG_D(PHY,"PDSCH Channel estimation layer %d, slot %d, symbol %d\n", nl, nr_slot_rx, m);
nr_pdsch_channel_estimation(ue,
proc,
nl,
get_dmrs_port(nl,dlsch0->dlsch_config.dmrs_ports),
get_dmrs_port(nl, dlschCfg->dmrs_ports),
m,
dlsch0->dlsch_config.nscid,
dlsch0->dlsch_config.dlDmrsScramblingId,
BWPStart,
dlsch0->dlsch_config.dmrsConfigType,
dlsch0->dlsch_config.rb_offset,
ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
pdsch_nb_rb,
dlschCfg->nscid,
dlschCfg->dlDmrsScramblingId,
dlschCfg->BWPStart,
dlschCfg->dmrsConfigType,
dlschCfg->rb_offset,
ue->frame_parms.first_carrier_offset + (dlschCfg->BWPStart + dlschCfg->start_rb) * 12,
dlschCfg->number_rbs,
pdsch_est_size,
pdsch_dl_ch_estimates,
ue->frame_parms.samples_per_slot_wCP, rxdataF);
ue->frame_parms.samples_per_slot_wCP,
rxdataF);
#if 0
///LOG_M: the channel estimation
int nr_frame_rx = proc->frame_rx;
@@ -558,22 +565,22 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
if (ue->chest_time == 1) { // averaging time domain channel estimates
nr_chest_time_domain_avg(&ue->frame_parms,
(int32_t **) pdsch_dl_ch_estimates,
dlsch0->dlsch_config.number_symbols,
dlsch0->dlsch_config.start_symbol,
dlsch0->dlsch_config.dlDmrsSymbPos,
pdsch_nb_rb);
(int32_t **)pdsch_dl_ch_estimates,
dlschCfg->number_symbols,
dlschCfg->start_symbol,
dlschCfg->dlDmrsSymbPos,
dlschCfg->number_rbs);
}
uint16_t first_symbol_with_data = s0;
uint16_t first_symbol_with_data = dlschCfg->start_symbol;
uint32_t dmrs_data_re;
if (dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
dmrs_data_re = 12 - 6 * dlsch0->dlsch_config.n_dmrs_cdm_groups;
if (dlschCfg->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)
dmrs_data_re = 12 - 6 * dlschCfg->n_dmrs_cdm_groups;
else
dmrs_data_re = 12 - 4 * dlsch0->dlsch_config.n_dmrs_cdm_groups;
dmrs_data_re = 12 - 4 * dlschCfg->n_dmrs_cdm_groups;
while ((dmrs_data_re == 0) && (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << first_symbol_with_data))) {
while ((dmrs_data_re == 0) && (dlschCfg->dlDmrsSymbPos & (1 << first_symbol_with_data))) {
first_symbol_with_data++;
}
@@ -582,7 +589,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
int32_t log2_maxh = 0;
start_meas(&ue->rx_pdsch_stats);
for (int m = s0; m < (s1 + s0); m++) {
for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) {
bool first_symbol_flag = false;
if (m == first_symbol_with_data)
first_symbol_flag = true;
+4 -5
View File
@@ -162,8 +162,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
else fp->nr_band = 78;
fp->threequarter_fs= 0;
int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL);
fp->ofdm_offset_divisor = UINT_MAX;
nr_init_frame_parms(gNB_config, fp);
@@ -487,7 +486,7 @@ int main(int argc, char **argv)
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->Nid_cell = Nid_cell;
frame_parms->ssb_type = nr_ssb_type_C;
frame_parms->freq_range = mu<2 ? nr_FR1 : nr_FR2;
frame_parms->freq_range = mu<2 ? FR1 : FR2;
nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
gNB->gNB_config.tdd_table.tdd_period.value = 6;
@@ -620,8 +619,8 @@ int main(int argc, char **argv)
for (i=0; i<frame_parms->Lmax; i++) {
if((SSB_positions >> i) & 0x01) {
const int sc_offset = frame_parms->freq_range == nr_FR1 ? ssb_subcarrier_offset<<mu : ssb_subcarrier_offset;
const int prb_offset = frame_parms->freq_range == nr_FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<<mu : gNB->gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2);
const int sc_offset = frame_parms->freq_range == FR1 ? ssb_subcarrier_offset<<mu : ssb_subcarrier_offset;
const int prb_offset = frame_parms->freq_range == FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<<mu : gNB->gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2);
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset;
+2 -2
View File
@@ -422,7 +422,7 @@ int main(int argc, char **argv){
frame_parms->N_RB_UL = N_RB_UL;
frame_parms->threequarter_fs = threequarter_fs;
frame_parms->frame_type = TDD;
frame_parms->freq_range = (mu != 3 ? nr_FR1 : nr_FR2);
frame_parms->freq_range = (mu != 3 ? FR1 : FR2);
frame_parms->numerology_index = mu;
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
@@ -447,7 +447,7 @@ int main(int argc, char **argv){
frame_parms->Ncp,
frame_parms->samples_per_subframe,
frame_parms->frame_type == FDD ? "FDD" : "TDD",
frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
frame_parms->freq_range == FR1 ? "FR1" : "FR2");
ru->nr_frame_parms = frame_parms;
ru->if_south = LOCAL_RF;
+7
View File
@@ -55,6 +55,12 @@
typedef net_ip_address_t e1ap_net_ip_address_t;
typedef enum BEARER_CONTEXT_STATUS_e {
BEARER_ACTIVE = 0,
BEARER_SUSPEND,
BEARER_RESUME,
} BEARER_CONTEXT_STATUS_t;
typedef struct PLMN_ID_s {
int mcc;
int mnc;
@@ -240,6 +246,7 @@ typedef struct e1ap_bearer_setup_req_s {
char integrityProtectionKey[128];
long ueDlAggMaxBitRate;
PLMN_ID_t servingPLMNid;
BEARER_CONTEXT_STATUS_t bearerContextStatus;
long activityNotificationLevel;
int numPDUSessions;
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
+17 -1
View File
@@ -1192,7 +1192,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id;
/* optional */
/* */
/* c3. E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest;
ieC3->criticality = E1AP_Criticality_reject;
@@ -1230,6 +1230,15 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
}
}
}
/* c4. E1AP_ProtocolIE_ID_id_BearerContextStatusChange */
if (bearerCxt->bearerContextStatus == BEARER_SUSPEND) {
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC4);
ieC4->id = E1AP_ProtocolIE_ID_id_BearerContextStatusChange;
ieC4->criticality = E1AP_Criticality_reject;
ieC4->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange;
/* Bearer Context Status Change */
ieC4->value.choice.BearerContextStatusChange = E1AP_BearerContextStatusChange_suspend;
}
return 0;
}
@@ -1390,6 +1399,13 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
}
break;
case E1AP_ProtocolIE_ID_id_BearerContextStatusChange:
/* Bearer Context Status Change */
DevAssert(ie->criticality == E1AP_Criticality_reject);
DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange);
bearerCxt->bearerContextStatus = (ie->value.choice.BearerContextStatusChange == E1AP_BearerContextStatusChange_suspend) ? BEARER_SUSPEND : BEARER_ACTIVE;
break;
default:
LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
break;
+56 -3
View File
@@ -1694,7 +1694,7 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
if (pointa > 2016666) { //FR2
x = table_6_3_3_2_4_prachConfig_Index[index][2];
s_map = table_6_3_3_2_4_prachConfig_Index[index][5];
*N_RA_sfn += count_bits_set(s_map);
*N_RA_sfn += count_bits64(s_map);
*N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe
*max_association_period = 160/(x * 10);
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
@@ -1721,7 +1721,7 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
if (unpaired) {
x = table_6_3_3_2_3_prachConfig_Index[index][2];
s_map = table_6_3_3_2_3_prachConfig_Index[index][4];
*N_RA_sfn += count_bits_set(s_map);
*N_RA_sfn += count_bits64(s_map);
*N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe
*max_association_period = 160/(x * 10);
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
@@ -1746,7 +1746,7 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
else { // FDD
x = table_6_3_3_2_2_prachConfig_Index[index][2];
s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
*N_RA_sfn += count_bits_set(s_map);
*N_RA_sfn += count_bits64(s_map);
*N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6];
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
@@ -5158,6 +5158,59 @@ uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_rep
return csi_bitlen;
}
bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, long *support_90mhz)
{
if (bw_mhz == 90)
return support_90mhz ? true : false;
switch (supported_BW->present) {
case NR_SupportedBandwidth_PR_fr1 :
switch (supported_BW->choice.fr1) {
case NR_SupportedBandwidth__fr1_mhz5 :
return bw_mhz == 5;
case NR_SupportedBandwidth__fr1_mhz10 :
return bw_mhz == 10;
case NR_SupportedBandwidth__fr1_mhz15 :
return bw_mhz == 15;
case NR_SupportedBandwidth__fr1_mhz20 :
return bw_mhz == 20;
case NR_SupportedBandwidth__fr1_mhz25 :
return bw_mhz == 25;
case NR_SupportedBandwidth__fr1_mhz30 :
return bw_mhz == 30;
case NR_SupportedBandwidth__fr1_mhz40 :
return bw_mhz == 40;
case NR_SupportedBandwidth__fr1_mhz50 :
return bw_mhz == 50;
case NR_SupportedBandwidth__fr1_mhz60 :
return bw_mhz == 60;
case NR_SupportedBandwidth__fr1_mhz80 :
return bw_mhz == 80;
case NR_SupportedBandwidth__fr1_mhz100 :
return bw_mhz == 100;
default :
AssertFatal(false, "Invalid FR1 supported band\n");
}
break;
case NR_SupportedBandwidth_PR_fr2 :
switch (supported_BW->choice.fr2) {
case NR_SupportedBandwidth__fr2_mhz50 :
return bw_mhz == 50;
case NR_SupportedBandwidth__fr2_mhz100 :
return bw_mhz == 100;
case NR_SupportedBandwidth__fr2_mhz200 :
return bw_mhz == 200;
case NR_SupportedBandwidth__fr2_mhz400 :
return bw_mhz == 400;
default :
AssertFatal(false, "Invalid FR2 supported band\n");
}
break;
default :
AssertFatal(false, "Invalid BW type\n");
}
return false;
}
uint16_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length)
{
uint8_t pdu_length = 8; // 2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV
@@ -33,6 +33,7 @@
#include "NR_MIB.h"
#include "NR_CellGroupConfig.h"
#include "NR_UE-NR-Capability.h"
#include "nr_mac.h"
#include "common/utils/nr/nr_common.h"
@@ -316,4 +317,6 @@ uint16_t compute_PDU_length(uint32_t num_TLV, uint16_t total_length);
rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carrier_id);
bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, long *support_90mhz);
#endif
+58 -41
View File
@@ -118,10 +118,9 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL;
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
@@ -140,10 +139,9 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
@@ -262,10 +260,9 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
*scc->ssbSubcarrierSpacing,
@@ -287,10 +284,9 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
long *UL_pointA = NULL;
if (frequencyInfoUL->absoluteFrequencyPointA)
@@ -1426,7 +1422,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
switch (cause) {
case GO_TO_IDLE:
reset_ra(mac, cause);
reset_ra(mac, true);
release_mac_configuration(mac, cause);
nr_ue_init_mac(mac);
nr_ue_mac_default_configs(mac);
@@ -1435,14 +1431,14 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id,
break;
case DETACH:
LOG_A(NR_MAC, "Received detach indication\n");
reset_ra(mac, cause);
reset_ra(mac, true);
reset_mac_inst(mac);
nr_ue_reset_sync_state(mac);
release_mac_configuration(mac, cause);
mac->state = UE_DETACHING;
break;
case T300_EXPIRY:
reset_ra(mac, cause);
reset_ra(mac, false);
reset_mac_inst(mac);
mac->state = UE_SYNC; // still in sync but need to restart RA
break;
@@ -2045,6 +2041,47 @@ static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_Ser
}
}
/// This function implements 38.331 Section 5.3.12: UE actions upon PUCCH/SRS release request
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac)
{
// release PUCCH-CSI-Resources configured in CSI-ReportConfig
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
NR_CSI_MeasConfig_t *meas_config = sc_info->csi_MeasConfig;
if (meas_config && meas_config->csi_ReportConfigToAddModList) {
for (int i = 0; i < meas_config->csi_ReportConfigToAddModList->list.count; i++) {
struct NR_CSI_ReportConfig__reportConfigType *type = &meas_config->csi_ReportConfigToAddModList->list.array[i]->reportConfigType;
switch (type->present) {
case NR_CSI_ReportConfig__reportConfigType_PR_periodic :
for (int j = type->choice.periodic->pucch_CSI_ResourceList.list.count; j > 0 ; j--)
asn_sequence_del(&type->choice.periodic->pucch_CSI_ResourceList.list, j - 1, 1);
break;
case NR_CSI_ReportConfig__reportConfigType_PR_semiPersistentOnPUCCH :
for (int j = type->choice.semiPersistentOnPUCCH->pucch_CSI_ResourceList.list.count; j > 0 ; j--)
asn_sequence_del(&type->choice.semiPersistentOnPUCCH->pucch_CSI_ResourceList.list, j - 1, 1);
break;
case NR_CSI_ReportConfig__reportConfigType_PR_semiPersistentOnPUSCH :
case NR_CSI_ReportConfig__reportConfigType_PR_aperiodic :
// no PUCCH config to release
break;
default :
AssertFatal(false, "Invalid CSI report type\n");
}
}
}
for (int bwp = 0; bwp < mac->ul_BWPs.count; bwp++) {
// release SchedulingRequestResourceConfig instances configured in PUCCH-Config
NR_PUCCH_Config_t *pucch_Config = mac->ul_BWPs.array[bwp]->pucch_Config;
for (int j = pucch_Config->schedulingRequestResourceToAddModList->list.count; j > 0 ; j--)
asn_sequence_del(&pucch_Config->schedulingRequestResourceToAddModList->list, j - 1, 1);
// release SRS-Resource instances configured in SRS-Config
// TODO not clear if only SRS-Resources or also the ResourceSet should be released
NR_SRS_Config_t *srs_Config = mac->ul_BWPs.array[bwp]->srs_Config;
for (int j = srs_Config->srs_ResourceToAddModList->list.count; j > 0 ; j--)
asn_sequence_del(&srs_Config->srs_ResourceToAddModList->list, j - 1, 1);
}
}
void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index)
{
NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[index];
@@ -2139,18 +2176,8 @@ static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t *
NR_FeatureSetDownlinkPerCC_t *fs_dl_cc = fs_dlcc_list->list.array[i];
if (mac->current_DL_BWP->scs != fs_dl_cc->supportedSubcarrierSpacingDL)
continue;
int uecap_bw_index;
if (fs_dl_cc->supportedBandwidthDL.present == NR_SupportedBandwidth_PR_fr1) {
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr1;
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_dl_cc->channelBW_90mhz)
uecap_bw_index++;
}
else
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr2;
int dl_bw_mhz = mac->phy_config.config_req.carrier_config.dl_bandwidth;
if (dl_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
if (!supported_bw_comparison(dl_bw_mhz, &fs_dl_cc->supportedBandwidthDL, fs_dl_cc->channelBW_90mhz))
continue;
if (fs_dl_cc->maxNumberMIMO_LayersPDSCH)
mac->uecap_maxMIMO_PDSCH_layers = 2 << *fs_dl_cc->maxNumberMIMO_LayersPDSCH;
@@ -2162,18 +2189,8 @@ static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t *
NR_FeatureSetUplinkPerCC_t *fs_ul_cc = fs_ulcc_list->list.array[i];
if (mac->current_UL_BWP->scs != fs_ul_cc->supportedSubcarrierSpacingUL)
continue;
int uecap_bw_index;
if (fs_ul_cc->supportedBandwidthUL.present == NR_SupportedBandwidth_PR_fr1) {
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr1;
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_ul_cc->channelBW_90mhz)
uecap_bw_index++;
}
else
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr2;
int ul_bw_mhz = mac->phy_config.config_req.carrier_config.uplink_bandwidth;
if (ul_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
if (!supported_bw_comparison(ul_bw_mhz, &fs_ul_cc->supportedBandwidthUL, fs_ul_cc->channelBW_90mhz))
continue;
if (fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH)
mac->uecap_maxMIMO_PUSCH_layers_nocb = 1 << *fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH;
+1 -4
View File
@@ -140,10 +140,7 @@ static void sl_prepare_phy_config(int module_id,
AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL");
int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing,
sl_band > 256 ? FR2 : FR1,
carriercfg->carrierBandwidth);
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index);
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, carriercfg->subcarrierSpacing, carriercfg->carrierBandwidth);
phycfg->sl_carrier_config.sl_frequency =
from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz
+3 -1
View File
@@ -308,7 +308,7 @@ typedef struct {
/// number of attempt for rach
uint8_t RA_attempt_number;
/// Random-access procedure flag
uint8_t RA_active;
bool RA_active;
/// Random-access preamble index
int ra_PreambleIndex;
// When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
@@ -341,6 +341,8 @@ typedef struct {
/// Msg3 buffer
uint8_t *Msg3_buffer;
bool msg3_C_RNTI;
/// Random-access Contention Resolution Timer
NR_timer_t contention_resolution_timer;
/// Transmitted UE Contention Resolution Identifier
+4 -3
View File
@@ -100,7 +100,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(int nb_inst);
NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id);
void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac);
void reset_ra(NR_UE_MAC_INST_t *nr_mac, NR_UE_MAC_reset_cause_t cause);
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach);
void release_mac_configuration(NR_UE_MAC_INST_t *mac,
NR_UE_MAC_reset_cause_t cause);
@@ -293,7 +293,7 @@ void nr_get_prach_resources(NR_UE_MAC_INST_t *mac,
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack);
void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind);
void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac);
void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac);
void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, int cell_id);
@@ -312,6 +312,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac);
void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id);
void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac);
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max);
@@ -335,7 +336,7 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu);
fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx);
void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt);
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// PUSCH scheduler:
+2 -2
View File
@@ -299,14 +299,14 @@ void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id)
free(nr_mac->ssb_list[bwp_id].tx_ssb);
}
void reset_ra(NR_UE_MAC_INST_t *nr_mac, NR_UE_MAC_reset_cause_t cause)
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
{
RA_config_t *ra = &nr_mac->ra;
if(ra->rach_ConfigDedicated)
asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated);
memset(ra, 0, sizeof(RA_config_t));
if (cause == T300_EXPIRY)
if (!free_prach)
return;
for (int i = 0; i < MAX_NUM_BWP_UE; i++)
+59 -12
View File
@@ -61,7 +61,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
{
mac->state = UE_PERFORMING_RA;
RA_config_t *ra = &mac->ra;
ra->RA_active = 1;
ra->RA_active = true;
ra->ra_PreambleIndex = -1;
ra->RA_usedGroupA = 1;
ra->RA_RAPID_found = 0;
@@ -582,17 +582,25 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
ra->ra_state = nrRA_WAIT_CONTENTION_RESOLUTION;
}
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
static uint8_t *fill_msg3_crnti_pdu(RA_config_t *ra, uint8_t *pdu, uint16_t crnti)
{
// RA triggered by UE MAC with C-RNTI in MAC CE
LOG_D(NR_MAC, "Generating MAC CE with C-RNTI for MSG3 %x\n", crnti);
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_C_RNTI, .R = 0};
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
// C-RNTI MAC CE (2 octets)
uint16_t rnti_pdu = ((crnti & 0xFF) << 8) | ((crnti >> 8) & 0xFF);
memcpy(pdu, &rnti_pdu, sizeof(rnti_pdu));
pdu += sizeof(rnti_pdu);
ra->t_crnti = crnti;
return pdu;
}
static uint8_t *fill_msg3_pdu_from_rlc(NR_UE_MAC_INST_t *mac, uint8_t *pdu, int TBS_max)
{
RA_config_t *ra = &mac->ra;
// we already stored MSG3 in the buffer, we can use that
if (ra->Msg3_buffer) {
buf = ra->Msg3_buffer;
return;
}
uint8_t *pdu = buf;
// regular MSG3 with PDU coming from higher layers
*(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_CCCH};
pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
tbs_size_t len = mac_rlc_data_req(mac->ue_id,
@@ -613,6 +621,25 @@ void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
// We copy from persisted memory to another persisted memory
memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6);
pdu += len;
return pdu;
}
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
{
RA_config_t *ra = &mac->ra;
// we already stored MSG3 in the buffer, we can use that
if (ra->Msg3_buffer) {
memcpy(buf, ra->Msg3_buffer, sizeof(uint8_t) * TBS_max);
return;
}
uint8_t *pdu = buf;
if (ra->msg3_C_RNTI)
pdu = fill_msg3_crnti_pdu(ra, pdu, mac->crnti);
else
pdu = fill_msg3_pdu_from_rlc(mac, pdu, TBS_max);
AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3!\n");
// Padding: fill remainder with 0
LOG_D(NR_MAC, "Remaining %ld bytes, filling with padding\n", pdu - buf);
@@ -657,7 +684,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB
LOG_D(NR_MAC, "[UE %d][%d.%d]: ra_state %d, RA_active %d\n", mac->ue_id, frame, nr_slot_tx, ra->ra_state, ra->RA_active);
if (ra->ra_state > nrRA_UE_IDLE && ra->ra_state < nrRA_SUCCEEDED) {
if (ra->RA_active == 0) {
if (!ra->RA_active) {
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
init_RA(mac, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
@@ -825,7 +852,8 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
}
LOG_D(MAC, "[UE %d] clearing RA_active flag...\n", mac->ue_id);
ra->RA_active = 0;
ra->RA_active = false;
ra->msg3_C_RNTI = false;
ra->ra_state = nrRA_SUCCEEDED;
mac->state = UE_CONNECTED;
free_and_zero(ra->Msg3_buffer);
@@ -875,6 +903,25 @@ void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *pr
}
}
void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac)
{
LOG_W(NR_MAC, "Triggering new RA procedure for UE with RNTI %x\n", mac->crnti);
mac->state = UE_SYNC;
reset_ra(mac, false);
mac->ra.msg3_C_RNTI = true;
// release PUCCH for all Serving Cells;
// release SRS for all Serving Cells;
release_PUCCH_SRS(mac);
// clear any configured downlink assignments and uplink grants;
int scs = mac->current_UL_BWP->scs;
if (mac->dl_config_request)
memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
if (mac->ul_config_request)
clear_ul_config_request(mac, scs);
// clear any PUSCH resources for semi-persistent CSI reporting
// TODO we don't have semi-persistent CSI reporting
}
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
@@ -43,7 +43,7 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
const uint32_t Y)
{
LOG_D(NR_MAC_DCI, "Filling search candidates for DCI\n");
LOG_T(NR_MAC_DCI, "Filling search candidates for DCI\n");
int i = 0;
for (int maxL = 16; maxL > 0; maxL >>= 1) {
@@ -54,7 +54,7 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
maxL);
if (max_number_of_candidates == 0)
continue;
LOG_D(NR_MAC_DCI, "L %d, max number of candidates %d, aggregation %d\n", maxL, max_number_of_candidates, aggregation);
LOG_T(NR_MAC_DCI, "L %d, max number of candidates %d, aggregation %d\n", maxL, max_number_of_candidates, aggregation);
int N_cce_sym = 0; // nb of rbs of coreset per symbol
for (int f = 0; f < 6; f++) {
for (int t = 0; t < 8; t++) {
@@ -66,7 +66,7 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
continue;
for (int j = 0; j < max_number_of_candidates; j++) {
int first_cce = aggregation * ((Y + ((j * N_cces) / (aggregation * max_number_of_candidates)) + 0) % (N_cces / aggregation));
LOG_D(NR_MAC_DCI,
LOG_T(NR_MAC_DCI,
"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n",
j,
max_number_of_candidates,
@@ -79,7 +79,7 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
for (int k = 0; k < i; k++) {
if (rel15->CCE[k] == first_cce && rel15->L[k] == aggregation) {
duplicated = true;
LOG_D(NR_MAC_DCI, "Candidate %d of %d is duplicated\n", j, max_number_of_candidates);
LOG_T(NR_MAC_DCI, "Candidate %d of %d is duplicated\n", j, max_number_of_candidates);
}
}
if (!duplicated) {
@@ -315,7 +315,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac,
#ifdef DEBUG_DCI
for (int i = 0; i < rel15->num_dci_options; i++) {
LOG_D(NR_MAC_DCI,
LOG_T(NR_MAC_DCI,
"[DCI_CONFIG] Configure DCI PDU: rnti_type %d BWPSize %d BWPStart %d rel15->SubcarrierSpacing %d rel15->dci_format %d "
"rel15->dci_length %d sps %d monitoringSymbolsWithinSlot %d \n",
rnti_type,
+41 -17
View File
@@ -293,6 +293,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType0) {
// TS 38.214 subclause 5.1.2.2.1 Downlink resource allocation type 0
dlsch_config_pdu->resource_alloc = 0;
memset(dlsch_config_pdu->rb_bitmap, 0, sizeof(dlsch_config_pdu->rb_bitmap));
int P = getRBGSize(n_RB_DLBWP, pdsch_Config->rbg_Size);
int n_RBG = frequency_domain_assignment.nbits;
int index = 0;
@@ -312,6 +313,23 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
dlsch_config_pdu->rb_bitmap[j / 8] |= bit_rbg << (j % 8);
index += size_RBG;
}
dlsch_config_pdu->number_rbs = count_bits(dlsch_config_pdu->rb_bitmap, sizeofArray(dlsch_config_pdu->rb_bitmap));
// Temporary code to process type0 as type1 when the RB allocation is contiguous
int state = 0;
for (int i = 0; i < sizeof(dlsch_config_pdu->rb_bitmap) * 8; i++) {
int allocated = dlsch_config_pdu->rb_bitmap[i / 8] & (1 << (i % 8));
if (allocated) {
if (state == 0) {
dlsch_config_pdu->start_rb = i;
state = 1;
} else
AssertFatal(state == 1, "non-contiguous RB allocation in RB allocation type 0 not implemented");
} else {
if (state == 1) {
state = 2;
}
}
}
}
else if (pdsch_Config &&
pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_dynamicSwitch)
@@ -2434,7 +2452,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
if(!pucch_Config ||
!pucch_Config->schedulingRequestResourceToAddModList ||
pucch_Config->schedulingRequestResourceToAddModList->list.count==0)
pucch_Config->schedulingRequestResourceToAddModList->list.count == 0)
return false; // SR not configured
int sr_count = 0;
@@ -2458,7 +2476,12 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
pucch->pucch_resource = sr_pucch;
pucch->n_sr = 1;
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
pucch->sr_payload = nr_ue_get_SR(mac, frame, slot, sr_Config->schedulingRequestID);
int ret = nr_ue_get_SR(mac, frame, slot, sr_Config->schedulingRequestID);
if (ret < 0) {
memset(pucch, 0, sizeof(*pucch));
return false;
}
pucch->sr_payload = ret;
sr_count++;
AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n");
}
@@ -2500,18 +2523,18 @@ int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_Schedu
return 1;
}
// TODO
// notify RRC to release PUCCH for all Serving Cells;
// notify RRC to release SRS for all Serving Cells;
// clear any configured downlink assignments and uplink grants;
// clear any PUSCH resources for semi-persistent CSI reporting;
LOG_W(NR_MAC,
"[UE %d] SR not served! SR counter %d reached sr_MaxTransmissions %d\n",
mac->ue_id,
sr_info->counter,
sr_info->maxTransmissions);
// initiate a Random Access procedure (see clause 5.1) on the SpCell and cancel all pending SRs.
LOG_E(NR_MAC, "[UE %d] SR not served. Triggering of new RA procedure not implemented yet.\n", mac->ue_id);
sr_info->pending = false;
sr_info->counter = 0;
nr_timer_stop(&sr_info->prohibitTimer);
return 0;
schedule_RA_after_SR_failure(mac);
return -1;
}
// section 5.2.5 of 38.214
@@ -3511,7 +3534,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
mac_len = 6;
if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) {
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
LOG_I(MAC, "[UE %d]Frame %d Contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
mac->ue_id,
frameP,
pduP[1],
@@ -3523,21 +3546,21 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
bool ra_success = true;
if (!IS_SOFTMODEM_IQPLAYER) { // Control is bypassed when replaying IQs (BMC)
for(int i = 0; i<mac_len; i++) {
if(ra->cont_res_id[i] != pduP[i+1]) {
for(int i = 0; i < mac_len; i++) {
if(ra->cont_res_id[i] != pduP[i + 1]) {
ra_success = false;
break;
}
}
}
if ( (ra->RA_active == 1) && ra_success) {
if (ra->RA_active && ra_success) {
nr_ra_succeeded(mac, gNB_index, frameP, slot);
} else if (!ra_success){
} else if (!ra_success) {
// TODO: Handle failure of RA procedure @ MAC layer
// nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure
ra->ra_state = nrRA_UE_IDLE;
ra->RA_active = 0;
ra->RA_active = false;
}
}
break;
@@ -3978,7 +4001,8 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
if (!ra->cfra) {
ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
rnti = ra->t_crnti;
nr_mac_rrc_msg3_ind(mac->ue_id, rnti, dl_info->gNB_index);
if (!ra->msg3_C_RNTI)
nr_mac_rrc_msg3_ind(mac->ue_id, rnti, dl_info->gNB_index);
}
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
+41 -7
View File
@@ -60,6 +60,17 @@
static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_frame_t slotP);
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs)
{
int slots = nr_slots_per_frame[scs];
for (int i = 0; i < slots ; i++) {
fapi_nr_ul_config_request_t *ul_config = mac->ul_config_request + i;
pthread_mutex_lock(&ul_config->mutex_ul_config);
ul_config->number_pdus = 0;
pthread_mutex_unlock(&ul_config->mutex_ul_config);
}
}
fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type)
{
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
@@ -689,7 +700,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->dfts_ofdm.low_papr_group_number);
}
else {
if (pusch_config_pdu->scid == 0 && NR_DMRS_ulconfig &&
if (pusch_config_pdu->scid == 0 && NR_DMRS_ulconfig && NR_DMRS_ulconfig->transformPrecodingDisabled &&
NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0)
pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0;
if (pusch_config_pdu->scid == 1 && NR_DMRS_ulconfig &&
@@ -1111,6 +1122,19 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info
LOG_E(NR_MAC, "Internal error, no scheduled_response function\n");
}
static bool check_pucchres_for_pending_SR(NR_PUCCH_Config_t *pucch_Config, int target_sr_id)
{
for (int id = 0; id < pucch_Config->schedulingRequestResourceToAddModList->list.count; id++) {
NR_SchedulingRequestResourceConfig_t *sr_Config = pucch_Config->schedulingRequestResourceToAddModList->list.array[id];
if (sr_Config->schedulingRequestID == target_sr_id) {
if (sr_Config->resource) {
return true;
}
}
}
return false;
}
static void nr_update_sr(NR_UE_MAC_INST_t *mac)
{
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
@@ -1153,17 +1177,27 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac)
// if the UL-SCH resources available for a new transmission do not meet the LCP mapping restrictions
// TODO not implemented
// trigger SR
if (lc_info->sr_id < 0 || lc_info->sr_id >= NR_MAX_SR_ID)
LOG_E(NR_MAC, "No SR corresponding to this LCID\n"); // TODO not sure what to do here
else {
nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id];
if (!sr->pending) {
LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id);
sr->pending = true;
sr->counter = 0;
// TODO initiate a Random Access procedure on the SpCell and cancel the pending SR
// if the MAC entity has no valid PUCCH resource configured for the pending SR
NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL;
if (check_pucchres_for_pending_SR(pucch_Config, lc_info->sr_id)) {
// trigger SR
LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id);
sr->pending = true;
sr->counter = 0;
}
else {
// initiate a Random Access procedure on the SpCell and cancel the pending SR
// if the MAC entity has no valid PUCCH resource configured for the pending SR
sr->pending = false;
sr->counter = 0;
nr_timer_stop(&sr->prohibitTimer);
schedule_RA_after_SR_failure(mac);
}
}
}
}
+6 -10
View File
@@ -340,11 +340,9 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
// Carrier configuration
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth.value =
get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, bw_index);
cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary
cfg->num_tlv++;
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value);
@@ -370,11 +368,9 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
}
}
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth.value =
get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, bw_index);
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
cfg->num_tlv++;
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value);
@@ -132,9 +132,14 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
// contention resolution identity MAC ce has a fixed 48 bit size
// this contains the UL CCCH SDU. If UL CCCH SDU is longer than 48 bits,
// it contains the first 48 bits of the UL CCCH SDU
LOG_T(NR_MAC, "[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
LOG_D(NR_MAC,
"[gNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
ue_cont_res_id[0],
ue_cont_res_id[1],
ue_cont_res_id[2],
ue_cont_res_id[3],
ue_cont_res_id[4],
ue_cont_res_id[5]);
// Copying bytes (6 octects) to CEs pointer
mac_ce_size = 6;
memcpy(ce_ptr, ue_cont_res_id, mac_ce_size);
@@ -687,6 +687,12 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
nr_mac_enable_ue_rrc_processing_timer(mac, UE, /* apply_cellGroup = */ true);
NR_SCHED_UNLOCK(&mac->sched_lock);
UE->expect_reconfiguration = false;
/* Re-establish RLC for all remaining bearers */
if (UE->reestablish_rlc) {
for (int i = 1; i < UE->UE_sched_ctrl.dl_lc_num; ++i)
nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, UE->UE_sched_ctrl.dl_lc_ids[i]);
UE->reestablish_rlc = false;
}
}
if (dl_rrc->old_gNB_DU_ue_id != NULL) {
@@ -716,6 +722,11 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
pthread_mutex_unlock(&mac->sched_lock);
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
/* Set flag to trigger RLC re-establishment
* for remaining RBs in next RRCReconfiguration */
UE->reestablish_rlc = true;
/* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */
nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL);
instance_t f1inst = get_f1_gtp_instance();
if (f1inst >= 0) // we actually use F1-U
gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
+2
View File
@@ -683,6 +683,8 @@ typedef struct {
NR_CellGroupConfig_t *CellGroup;
/// CellGroupConfig that is to be activated after the next reconfiguration
bool expect_reconfiguration;
/// reestablishRLC has to be signaled in RRCreconfiguration
bool reestablish_rlc;
NR_CellGroupConfig_t *reconfigCellGroup;
bool apply_cellgroup;
NR_UE_NR_Capability_t *capability;
+8 -3
View File
@@ -2124,9 +2124,12 @@ pdcp_config_set_security(
pdcp_pP->cipheringAlgorithm,
pdcp_pP->integrityProtAlgorithm);
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);
kRRCenc != NULL ? memcpy(pdcp_pP->kRRCenc, kRRCenc+16, 16) : memset(pdcp_pP->kRRCenc, 0, 16);
kRRCint != NULL ? memcpy(pdcp_pP->kRRCint, kRRCint+16, 16) : memset(pdcp_pP->kRRCint, 0, 16);
kUPenc != NULL ? memcpy(pdcp_pP->kUPenc, kUPenc+16, 16) : memset(pdcp_pP->kUPenc, 0, 16);
pdcp_pP->security_container_rrc = stream_security_container_init(pdcp_pP->cipheringAlgorithm, pdcp_pP->integrityProtAlgorithm, pdcp_pP->kRRCenc, pdcp_pP->kRRCint);
pdcp_pP->security_container_up = stream_security_container_init(pdcp_pP->cipheringAlgorithm, 0, pdcp_pP->kUPenc, NULL);
/* Activate security */
pdcp_pP->security_activated = 1;
@@ -2196,6 +2199,8 @@ void rrc_pdcp_config_req (
pdcp_p->last_submitted_pdcp_rx_sn = 4095;
pdcp_p->seq_num_size = 0;
pdcp_p->first_missing_pdu = -1;
stream_security_container_delete(pdcp_p->security_container_rrc);
stream_security_container_delete(pdcp_p->security_container_up);
pdcp_p->security_activated = 0;
h_rc = hashtable_remove(pdcp_coll_p, key);
break;
+6 -3
View File
@@ -181,9 +181,12 @@ typedef struct pdcp_s {
* Control-Plane RRC integrity key
* These keys are configured by RRC layer
*/
uint8_t kUPenc[32];
uint8_t kRRCint[32];
uint8_t kRRCenc[32];
uint8_t kUPenc[16];
uint8_t kRRCint[16];
uint8_t kRRCenc[16];
stream_security_container_t *security_container_rrc;
stream_security_container_t *security_container_up;
uint8_t security_activated;
+16 -13
View File
@@ -112,6 +112,7 @@ pdcp_apply_security(
{
uint8_t *buffer_encrypted = NULL;
nas_stream_cipher_t encrypt_params = {0};
stream_security_container_t *container;
DevAssert(pdcp_pP != NULL);
DevAssert(pdcp_pdu_buffer != NULL);
@@ -122,7 +123,11 @@ pdcp_apply_security(
encrypt_params.direction = (pdcp_pP->is_ue == 1) ? SECU_DIRECTION_UPLINK : SECU_DIRECTION_DOWNLINK;
encrypt_params.bearer = rb_id - 1;
encrypt_params.count = pdcp_get_next_count_tx(pdcp_pP, srb_flagP, current_sn);
encrypt_params.key_length = 16;
if (srb_flagP)
container = pdcp_pP->security_container_rrc;
else
container = pdcp_pP->security_container_up;
if (srb_flagP) {
/* SRBs */
@@ -133,7 +138,7 @@ pdcp_apply_security(
encrypt_params.message = pdcp_pdu_buffer;
encrypt_params.blength = (pdcp_header_len + sdu_buffer_size) << 3;
encrypt_params.key = pdcp_pP->kRRCint + 16; // + 128;
encrypt_params.context = container->integrity_context;
mac_i = &pdcp_pdu_buffer[pdcp_header_len + sdu_buffer_size];
@@ -142,15 +147,13 @@ pdcp_apply_security(
stream_compute_integrity(pdcp_pP->integrityProtAlgorithm,
&encrypt_params,
mac_i);
encrypt_params.key = pdcp_pP->kRRCenc; // + 128 // bit key
} else {
LOG_D(PDCP, "[OSA][RB %ld] %s Applying user-plane security\n",
rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE");
encrypt_params.key = pdcp_pP->kUPenc;// + 128;
}
encrypt_params.context = container->ciphering_context;
encrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
encrypt_params.blength = sdu_buffer_size << 3;
@@ -180,6 +183,7 @@ pdcp_validate_security(
{
uint8_t *buffer_decrypted = NULL;
nas_stream_cipher_t decrypt_params = {0};
stream_security_container_t *container;
DevAssert(pdcp_pP != NULL);
@@ -195,17 +199,17 @@ pdcp_validate_security(
decrypt_params.count = pdcp_get_next_count_rx(pdcp_pP, srb_flagP, hfn, sn);
decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len];
decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3;
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");
decrypt_params.key = pdcp_pP->kRRCenc;// + 128;
container = pdcp_pP->security_container_rrc;
} else {
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;
container = pdcp_pP->security_container_up;
}
/* Uncipher the block */
decrypt_params.context = container->ciphering_context;
stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &decrypt_params, buffer_decrypted);
if (!IS_SOFTMODEM_IQPLAYER) {
@@ -213,7 +217,7 @@ pdcp_validate_security(
/* 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;
decrypt_params.context = container->integrity_context;
if (pdcp_pP->integrityProtAlgorithm != EIA0_ALG_ID) {
uint8_t result[4] = {0};
@@ -221,10 +225,9 @@ pdcp_validate_security(
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",
"[OSA][RB %ld] %s failed to validate MAC-I of incoming PDU\n",
rb_id,
(pdcp_pP->is_ue != 0) ? "UE" : "eNB",
((long long unsigned int *)decrypt_params.key)[0]);
(pdcp_pP->is_ue != 0) ? "UE" : "eNB");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT);
return -1;
}
+6 -4
View File
@@ -261,10 +261,12 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
if (f1inst < 0) // no F1-U?
continue; // nothing to do
in_addr_t addr = {0};
memcpy(&addr, &to_modif->DlUpParamList[0].tlAddress, sizeof(in_addr_t));
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[0].teId);
/* Loop through DL UP Transport Layer params list
* and update GTP tunnel outgoing addr and TEID */
for (int k = 0; k < to_modif->numDlUpParam; k++) {
in_addr_t addr = to_modif->DlUpParamList[k].tlAddress;
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[k].teId);
}
}
}
+37 -2
View File
@@ -57,7 +57,10 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
uint32_t rx_deliv_hfn;
if (entity->entity_suspended) {
LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id);
LOG_W(PDCP,
"PDCP entity (%s) %d is suspended. Quit RX procedure.\n",
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id);
return;
}
@@ -190,6 +193,13 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
count++;
}
entity->rx_deliv = count;
LOG_D(PDCP,
"%s: entity (%s) %d - rx_deliv = %d, rcvd_sn = %d \n",
__func__,
entity->type == NR_PDCP_DRB_AM ? "DRB" : "SRB",
entity->rb_id,
entity->rx_deliv,
rcvd_sn);
}
if (entity->t_reordering_start != 0 && entity->rx_deliv >= entity->rx_reord) {
@@ -220,7 +230,10 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
int dc_bit;
if (entity->entity_suspended) {
LOG_W(PDCP, "PDCP entity %d is suspended. Quit SDU processing.\n", entity->rb_id);
LOG_W(PDCP,
"PDCP entity (%s) %d is suspended. Quit SDU processing.\n",
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id);
return -1;
}
@@ -387,6 +400,14 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
if (entity->t_reordering_start == 0
|| entity->t_current <= entity->t_reordering_start + entity->t_reordering)
return;
LOG_D(PDCP,
"%s: entity (%s) %d: t_reordering_start = %ld, t_current = %ld, t_reordering = %d \n",
__func__,
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id,
entity->t_reordering_start,
entity->t_current,
entity->t_reordering);
/* stop timer */
entity->t_reordering_start = 0;
@@ -450,15 +471,29 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity)
}
}
/**
* @brief PDCP Entity Suspend according to 5.1.4 of 3GPP TS 38.323
* Transmitting PDCP entity shall:
* - set TX_NEXT to the initial value;
* - discard all stored PDCP PDUs (NOTE: PDUs are stored in RLC)
* Receiving PDCP entity shall:
* - if t-Reordering is running:
* a) stop and reset t-Reordering;
* b) deliver all stored PDCP SDUs
* - set RX_NEXT and RX_DELIV to the initial value.
*/
static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
{
/* Transmitting PDCP entity */
entity->tx_next = 0;
/* Receiving PDCP entity */
if (entity->t_reordering_start != 0) {
entity->t_reordering_start = 0;
deliver_all_sdus(entity);
}
entity->rx_next = 0;
entity->rx_deliv = 0;
/* Flag to keep track of PDCP entity status */
entity->entity_suspended = true;
}
+8 -6
View File
@@ -28,6 +28,7 @@
#include "nr_pdcp_sdu.h"
#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h"
#include "openair3/SECU/secu_defs.h"
/* PDCP Formats according to clause 6.2 of 3GPP TS 38.323 */
/* SN Size applicable to SRBs, UM DRBs and AM DRBs */
@@ -151,16 +152,17 @@ typedef struct nr_pdcp_entity_t {
int integrity_algorithm;
unsigned char ciphering_key[16];
unsigned char integrity_key[16];
void *security_context;
void (*cipher)(void *security_context,
stream_security_context_t *security_context;
void (*cipher)(stream_security_context_t *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void (*free_security)(void *security_context);
void *integrity_context;
void (*integrity)(void *integrity_context, unsigned char *out,
void (*free_security)(stream_security_context_t *security_context);
stream_security_context_t *integrity_context;
void (*integrity)(stream_security_context_t *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void (*free_integrity)(void *integrity_context);
void (*free_integrity)(stream_security_context_t *integrity_context);
/* security/integrity algorithms need to know uplink/downlink information
* which is reverse for gnb and ue, so we need to know if this
* pdcp entity is for a gnb or an ue
@@ -28,24 +28,23 @@
#include "openair3/SECU/secu_defs.h"
#include "openair3/SECU/key_nas_deriver.h"
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key)
stream_security_context_t *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key)
{
nas_stream_cipher_t *ret;
ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort();
ret->key = malloc(16); if (ret->key == NULL) abort();
memcpy(ret->key, integrity_key, 16);
ret->key_length = 16; /* unused */
ret->context = malloc(16); if (ret->context == NULL) abort();
memcpy(ret->context, integrity_key, 16);
return ret;
return (stream_security_context_t *)ret;
}
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
void nr_pdcp_integrity_nia1_integrity(stream_security_context_t *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction)
{
nas_stream_cipher_t *ctx = integrity_context;
nas_stream_cipher_t *ctx = (nas_stream_cipher_t *)integrity_context;
ctx->message = buffer;
ctx->count = count;
@@ -56,9 +55,9 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
stream_compute_integrity(EIA1_128_ALG_ID, ctx, out);
}
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context)
void nr_pdcp_integrity_nia1_free_integrity(stream_security_context_t *integrity_context)
{
nas_stream_cipher_t *ctx = integrity_context;
free(ctx->key);
nas_stream_cipher_t *ctx = (nas_stream_cipher_t *)integrity_context;
free(ctx->context);
free(ctx);
}
@@ -22,13 +22,15 @@
#ifndef _NR_PDCP_INTEGRITY_NIA1_H_
#define _NR_PDCP_INTEGRITY_NIA1_H_
void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key);
#include "openair3/SECU/secu_defs.h"
void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
stream_security_context_t *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key);
void nr_pdcp_integrity_nia1_integrity(stream_security_context_t *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context);
void nr_pdcp_integrity_nia1_free_integrity(stream_security_context_t *integrity_context);
#endif /* _NR_PDCP_INTEGRITY_NIA1_H_ */
@@ -30,29 +30,25 @@
#include "openair3/SECU/aes_128.h"
#include "openair3/SECU/aes_128_cbc_cmac.h"
void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16])
stream_security_context_t *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16])
{
// This is a hack. Reduce the 3 functions to just cipher?
// No. The overhead is x8 times more. Don't change before measuring
// return integrity_key;
cbc_cmac_ctx_t* ctx = calloc(1, sizeof(cbc_cmac_ctx_t));
AssertFatal(ctx, "Memory exhausted");
*ctx = init_aes_128_cbc_cmac(integrity_key);
return ctx;
return (stream_security_context_t *)ctx;
}
void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction)
void nr_pdcp_integrity_nia2_integrity(stream_security_context_t *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction)
{
DevAssert(integrity_context != NULL);
DevAssert(out != NULL);
DevAssert(buffer != NULL);
DevAssert(length > -1);
// Strange range: [1-32] instead of [0-31]
DevAssert(bearer > 0 && bearer < 33);
DevAssert(count > -1);
cbc_cmac_ctx_t* ctx = (cbc_cmac_ctx_t*)integrity_context;
cbc_cmac_ctx_t *ctx = (cbc_cmac_ctx_t *)integrity_context;
aes_128_t k_iv = {0};
memcpy(&k_iv.key, ctx->key, sizeof(k_iv.key));
@@ -64,18 +60,13 @@ void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *ou
uint8_t result[16] = {0};
byte_array_t msg = {.buf = buffer, .len = length};
cipher_aes_128_cbc_cmac((cbc_cmac_ctx_t*)integrity_context, &k_iv, msg, sizeof(result), result);
//aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result);
cipher_aes_128_cbc_cmac(ctx, &k_iv, msg, sizeof(result), result);
// AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
// 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
// bit first (so seems to say 33.401 B.2.3)
// Precondition: out should have enough space...
memcpy(out, result, 4);
}
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context)
void nr_pdcp_integrity_nia2_free_integrity(stream_security_context_t *integrity_context)
{
free( ( cbc_cmac_ctx_t*) integrity_context);
free_aes_128_cbc_cmac((cbc_cmac_ctx_t *)integrity_context);
free(integrity_context);
}
@@ -24,13 +24,15 @@
#include <stdint.h>
void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]);
#include "openair3/SECU/secu_defs.h"
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
stream_security_context_t *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]);
void nr_pdcp_integrity_nia2_integrity(stream_security_context_t *integrity_context,
unsigned char *out,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context);
void nr_pdcp_integrity_nia2_free_integrity(stream_security_context_t *integrity_context);
#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */
@@ -29,14 +29,14 @@
#include <stdlib.h>
#include <string.h>
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
stream_security_context_t *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
{
// This is a hack, IMO init, cipher and free functions should be reduced to cipher.
// Test show a ~10% more processing time
return ciphering_key;
return (stream_security_context_t *)ciphering_key;
}
void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer, int length, int bearer, int count, int direction)
void nr_pdcp_security_nea2_cipher(stream_security_context_t *security_context, unsigned char *buffer, int length, int bearer, int count, int direction)
{
DevAssert(security_context != NULL);
DevAssert(buffer != NULL);
@@ -62,7 +62,7 @@ void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer,
memcpy(buffer, out, length);
}
void nr_pdcp_security_nea2_free_security(void *security_context)
void nr_pdcp_security_nea2_free_security(stream_security_context_t *security_context)
{
(void)security_context;
}
@@ -22,12 +22,14 @@
#ifndef _NR_PDCP_SECURITY_NEA2_H_
#define _NR_PDCP_SECURITY_NEA2_H_
void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
#include "openair3/SECU/secu_defs.h"
void nr_pdcp_security_nea2_cipher(void *security_context,
stream_security_context_t *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
void nr_pdcp_security_nea2_cipher(stream_security_context_t *security_context,
unsigned char *buffer, int length,
int bearer, int count, int direction);
void nr_pdcp_security_nea2_free_security(void *security_context);
void nr_pdcp_security_nea2_free_security(stream_security_context_t *security_context);
#endif /* _NR_PDCP_SECURITY_NEA2_H_ */
+6 -7
View File
@@ -650,7 +650,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id)
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
if (rb != NULL) {
LOG_D(RLC, "RB found! (channel ID %d) \n", lc_id);
LOG_D(RLC, "RB found! (channel ID %d), re-establish RLC\n", lc_id);
rb->reestablishment(rb);
} else {
LOG_E(RLC, "no RLC entity found (channel ID %d) for reestablishment\n", lc_id);
@@ -1065,12 +1065,11 @@ bool nr_rlc_update_id(int from_id, int to_id)
}
ue->ue_id = to_id;
LOG_I(RLC, "Update old UE ID %d context to ID %d\n", from_id, to_id);
for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i)
if (ue->srb[i])
ue->srb[i]->reestablishment(ue->srb[i]);
for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i)
if (ue->drb[i])
ue->drb[i]->reestablishment(ue->drb[i]);
/* re-establish RLC for SRB1: according to 5.3.7.4 of TS 38.331 */
if (ue->srb[0]) {
LOG_I(RLC, "Re-establish RLC for SRB 1\n");
ue->srb[0]->reestablishment(ue->srb[0]);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return true;
}
+16 -2
View File
@@ -1059,8 +1059,18 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac,
}
// L2 Abstraction Layer
static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci)
static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac,
unsigned int gNB_index,
frame_t frame,
int slot,
fapi_nr_dci_indication_pdu_t *dci)
{
// if notification of a reception of a PDCCH transmission of the SpCell is received from lower layers
// if the C-RNTI MAC CE was included in Msg3
// consider this Contention Resolution successful
if (mac->ra.msg3_C_RNTI && mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)
nr_ra_succeeded(mac, gNB_index, frame, slot);
return nr_ue_process_dci_indication_pdu(mac, frame, slot, dci);
}
@@ -1156,7 +1166,11 @@ static uint32_t nr_ue_dl_processing(nr_downlink_indication_t *dl_info)
LOG_T(MAC, "[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) {
LOG_T(MAC, ">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n", i, dl_info->dci_ind->number_of_dcis);
nr_dci_format_t dci_format = handle_dci(mac, dl_info->frame, dl_info->slot, dl_info->dci_ind->dci_list + i);
nr_dci_format_t dci_format = handle_dci(mac,
dl_info->gNB_index,
dl_info->frame,
dl_info->slot,
dl_info->dci_ind->dci_list + i);
/* The check below filters out UL_DCIs which are being processed as DL_DCIs. */
if (dci_format != NR_DL_DCI_FORMAT_1_0 && dci_format != NR_DL_DCI_FORMAT_1_1) {
+19 -21
View File
@@ -526,18 +526,12 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig,
NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL;
if (fs) {
const int bw_index = get_supported_band_index(scs, freq_range, bw_size);
AssertFatal(bw_index >= 0, "BW corresponding to %d PRBs not found\n", bw_size);
const int bw_mhz = get_supported_bw_mhz(freq_range, scs, bw_size);
// go through UL feature sets and look for one with current SCS
for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) {
NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i];
long supported_bw;
if (freq_range == FR1)
supported_bw = dl_fs->supportedBandwidthDL.choice.fr1;
else
supported_bw = dl_fs->supportedBandwidthDL.choice.fr2;
if (scs == dl_fs->supportedSubcarrierSpacingDL &&
bw_index == supported_bw &&
supported_bw_comparison(bw_mhz, &dl_fs->supportedBandwidthDL, dl_fs->channelBW_90mhz) &&
dl_fs->maxNumberMIMO_LayersPDSCH) {
long ue_supported_layers = (2 << *dl_fs->maxNumberMIMO_LayersPDSCH);
*pdsch_servingcellconfig->ext1->maxMIMO_Layers = NR_MAX_SUPPORTED_DL_LAYERS < ue_supported_layers ? NR_MAX_SUPPORTED_DL_LAYERS : ue_supported_layers;
@@ -776,38 +770,42 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
int numerology,
int rbsize,
int mcs_table_dl,
int mcs_table_ul) {
int mcs_table_ul)
{
NR_Phy_Parameters_t *phy_Parameters = &cap->phy_Parameters;
int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
NR_BandNR_t *nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t));
NR_BandNR_t *nr_bandnr = calloc(1, sizeof(NR_BandNR_t));
nr_bandnr->bandNR = band;
asn1cSeqAdd(&cap->rf_Parameters.supportedBandListNR.list,
nr_bandnr);
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[0];
if (mcs_table_ul == 1) {
bandNRinfo->pusch_256QAM = CALLOC(1,sizeof(*bandNRinfo->pusch_256QAM));
bandNRinfo->pusch_256QAM = calloc(1,sizeof(*bandNRinfo->pusch_256QAM));
*bandNRinfo->pusch_256QAM = NR_BandNR__pusch_256QAM_supported;
}
if (mcs_table_dl == 1) {
const frequency_range_t freq_range = band < 257 ? FR1 : FR2;
int bw = get_supported_band_index(numerology, freq_range, rbsize);
if (freq_range == FR2) {
bandNRinfo->pdsch_256QAM_FR2 = CALLOC(1,sizeof(*bandNRinfo->pdsch_256QAM_FR2));
bandNRinfo->pdsch_256QAM_FR2 = calloc(1, sizeof(*bandNRinfo->pdsch_256QAM_FR2));
*bandNRinfo->pdsch_256QAM_FR2 = NR_BandNR__pdsch_256QAM_FR2_supported;
}
else{
phy_Parameters->phy_ParametersFR1 = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFR1));
phy_Parameters->phy_ParametersFR1 = calloc(1, sizeof(*phy_Parameters->phy_ParametersFR1));
NR_Phy_ParametersFR1_t *phy_fr1 = phy_Parameters->phy_ParametersFR1;
phy_fr1->pdsch_256QAM_FR1 = CALLOC(1,sizeof(*phy_fr1->pdsch_256QAM_FR1));
phy_fr1->pdsch_256QAM_FR1 = calloc(1, sizeof(*phy_fr1->pdsch_256QAM_FR1));
*phy_fr1->pdsch_256QAM_FR1 = NR_Phy_ParametersFR1__pdsch_256QAM_FR1_supported;
}
cap->featureSets = CALLOC(1,sizeof(*cap->featureSets));
cap->featureSets = calloc(1, sizeof(*cap->featureSets));
NR_FeatureSets_t *fs=cap->featureSets;
fs->featureSetsDownlinkPerCC = CALLOC(1,sizeof(*fs->featureSetsDownlinkPerCC));
NR_FeatureSetDownlinkPerCC_t *fs_cc = CALLOC(1,sizeof(NR_FeatureSetDownlinkPerCC_t));
fs->featureSetsDownlinkPerCC = calloc(1, sizeof(*fs->featureSetsDownlinkPerCC));
NR_FeatureSetDownlinkPerCC_t *fs_cc = calloc(1, sizeof(*fs_cc));
fs_cc->supportedSubcarrierSpacingDL = numerology;
int bw = get_supported_band_index(numerology, freq_range, rbsize);
if (bw == 10) // 90MHz
fs_cc->channelBW_90mhz = calloc(1, sizeof(*fs_cc->channelBW_90mhz));
if (bw == 11) // 100MHz
bw--;
if(freq_range == FR2) {
fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr2;
fs_cc->supportedBandwidthDL.choice.fr2 = bw;
@@ -816,12 +814,12 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr1;
fs_cc->supportedBandwidthDL.choice.fr1 = bw;
}
fs_cc->supportedModulationOrderDL = CALLOC(1,sizeof(*fs_cc->supportedModulationOrderDL));
fs_cc->supportedModulationOrderDL = calloc(1, sizeof(*fs_cc->supportedModulationOrderDL));
*fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256;
asn1cSeqAdd(&fs->featureSetsDownlinkPerCC->list, fs_cc);
}
phy_Parameters->phy_ParametersFRX_Diff = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFRX_Diff));
phy_Parameters->phy_ParametersFRX_Diff = calloc(1, sizeof(*phy_Parameters->phy_ParametersFRX_Diff));
phy_Parameters->phy_ParametersFRX_Diff->pucch_F0_2WithoutFH = NULL;
}
+24 -7
View File
@@ -227,8 +227,7 @@ static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_
else
AssertFatal(false, "Invalid absoluteFrequencyPointA: %u\n", dl_arfcn);
int bw_index = get_supported_band_index(scs, band > 256 ? FR2 : FR1, get_dl_bw(cell_info));
int band_size_hz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, bw_index) * 1000 * 1000;
int band_size_hz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, scs, get_dl_bw(cell_info)) * 1000 * 1000;
uint32_t ssb_arfcn = to_nrarfcn(band, freqssb, scs, band_size_hz);
LOG_D(NR_RRC,
@@ -370,6 +369,9 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP)
return tmp;
}
/**
* @brief Create srb-ToAddModList for RRCSetup and RRCReconfiguration messages
*/
static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
{
if (!ue->Srb[1].Active) {
@@ -381,6 +383,7 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
if (ue->Srb[i].Active) {
asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
srb->srb_Identity = i;
/* Set reestablishPDCP only for SRB2 */
if (reestablish && i == 2) {
asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true);
}
@@ -1018,13 +1021,11 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
/* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) {
if (ue_p->Srb[srb_id].Active) {
if (ue_p->Srb[srb_id].Active)
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
}
/* PDCP Reestablishment over E1 */
cuup_notify_reestablishment(rrc, ue_p);
/* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */
nr_pdcp_reestablishment(ue_p->rrc_ue_id, 1, true);
/* F1AP DL RRC Message Transfer */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
@@ -1075,12 +1076,28 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
for (i = 1; i < ue_p->masterCellGroup->rlc_BearerToAddModList->list.count; ++i)
asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, ue_p->masterCellGroup->rlc_BearerToAddModList->list.array[i]);
/*
* At this stage, PDCP entity are re-established and reestablishRLC is flagged
* with RRCReconfiguration to complete RLC re-establishment of remaining bearers
*/
for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
asn1cCallocOne(cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC,
NR_RLC_BearerConfig__reestablishRLC_true);
}
/* Re-establish SRB2 according to clause 5.3.5.6.3 of 3GPP TS 38.331
* (SRB1 is re-established with RRCReestablishment message)
*/
int srb_id = 2;
if (ue_p->Srb[srb_id].Active) {
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
/* PDCP Reestablishment of DRBs according to 5.3.5.6.5 of 3GPP TS 38.331 (over E1) */
cuup_notify_reestablishment(rrc, ue_p);
/* Create srb-ToAddModList */
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
/* Create drb-ToAddModList */
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
+45 -8
View File
@@ -1623,15 +1623,14 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
} break;
case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
LOG_I(NR_RRC, "Received rrcResume on DL-DCCH-Message\n");
LOG_E(NR_RRC, "Received rrcResume on DL-DCCH-Message -> Not handled\n");
break;
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
LOG_I(NR_RRC, "[UE %ld] Received RRC Release (gNB %d)\n", rrc->ue_id, gNB_indexP);
// TODO properly implement procedures in 5.3.8.3 of 38.331
NR_Release_Cause_t cause = OTHER;
if (rrc->detach_after_release)
rrc->nrRrcState = RRC_STATE_DETACH_NR;
nr_rrc_going_to_IDLE(rrc, cause, dl_dcch_msg->message.choice.c1->choice.rrcRelease);
// delay the actions 60 ms from the moment the RRCRelease message was received
UPDATE_IE(rrc->RRCRelease, dl_dcch_msg->message.choice.c1->choice.rrcRelease, NR_RRCRelease_t);
nr_timer_setup(&rrc->release_timer, 60, 10); // 10ms step
nr_timer_start(&rrc->release_timer);
break;
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
@@ -1930,13 +1929,11 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
for (int i = 1; i < 4; i++) {
if (rrc->Srb[i] == RB_ESTABLISHED) {
rrc->Srb[i] = RB_SUSPENDED;
nr_pdcp_suspend_srb(rrc->ue_id, i);
}
}
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
if (get_DRB_status(rrc, i) == RB_ESTABLISHED) {
set_DRB_status(rrc, i, RB_SUSPENDED);
nr_pdcp_suspend_drb(rrc->ue_id, i);
}
}
// release the MCG SCell(s), if configured
@@ -2136,6 +2133,46 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
}
}
void handle_RRCRelease(NR_UE_RRC_INST_t *rrc)
{
NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
// stop timer T380, if running
nr_timer_stop(&tac->T380);
// stop timer T320, if running
nr_timer_stop(&tac->T320);
if (rrc->detach_after_release)
rrc->nrRrcState = RRC_STATE_DETACH_NR;
const struct NR_RRCRelease_IEs *rrcReleaseIEs = rrc->RRCRelease ? rrc->RRCRelease->criticalExtensions.choice.rrcRelease : NULL;
if (!rrc->as_security_activated) {
// ignore any field included in RRCRelease message except waitTime
// perform the actions upon going to RRC_IDLE as specified in 5.3.11 with the release cause 'other'
// upon which the procedure ends
NR_Release_Cause_t cause = OTHER;
nr_rrc_going_to_IDLE(rrc, cause, rrc->RRCRelease);
asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease);
return;
}
bool suspend = false;
if (rrcReleaseIEs) {
if (rrcReleaseIEs->redirectedCarrierInfo)
LOG_E(NR_RRC, "redirectedCarrierInfo in RRCRelease not handled\n");
if (rrcReleaseIEs->cellReselectionPriorities)
LOG_E(NR_RRC, "cellReselectionPriorities in RRCRelease not handled\n");
if (rrcReleaseIEs->deprioritisationReq)
LOG_E(NR_RRC, "deprioritisationReq in RRCRelease not handled\n");
if (rrcReleaseIEs->suspendConfig) {
suspend = true;
// procedures to go in INACTIVE state
AssertFatal(false, "Inactive State not supported\n");
}
}
if (!suspend) {
NR_Release_Cause_t cause = OTHER;
nr_rrc_going_to_IDLE(rrc, cause, rrc->RRCRelease);
}
asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease);
}
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
NR_Release_Cause_t release_cause,
NR_RRCRelease_t *RRCRelease)
+5 -4
View File
@@ -159,6 +159,7 @@ typedef struct NR_UE_Timers_Constants_s {
NR_timer_t T320;
NR_timer_t T321;
NR_timer_t T325;
NR_timer_t T380;
NR_timer_t T390;
// counters
uint32_t N310_cnt;
@@ -217,10 +218,10 @@ typedef struct NR_UE_RRC_INST_s {
long keyToUse;
bool as_security_activated;
bool detach_after_release;
long selected_plmn_identity;
Rrc_State_NR_t nrRrcState;
as_nas_info_t initialNasMsg;
NR_timer_t release_timer;
NR_RRCRelease_t *RRCRelease;
long selected_plmn_identity;
Rrc_State_NR_t nrRrcState;
//Sidelink params
NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
+1 -1
View File
@@ -86,7 +86,7 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id,
void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
NR_Release_Cause_t release_cause,
NR_RRCRelease_t *RRCRelease);
void handle_RRCRelease(NR_UE_RRC_INST_t *rrc);
void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success);
void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, int gnb_id);
void set_rlf_sib1_timers_and_constants(NR_UE_Timers_Constants_t *tac, NR_SIB1_t *sib1);
@@ -119,6 +119,10 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc)
{
NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
bool release_timer_expired = nr_timer_tick(&rrc->release_timer);
if (release_timer_expired)
handle_RRCRelease(rrc);
bool t300_expired = nr_timer_tick(&timers->T300);
if(t300_expired) {
LOG_W(NR_RRC, "Timer T300 expired! No timely response to RRCSetupRequest\n");
+7 -13
View File
@@ -1009,8 +1009,7 @@ static int _nas_message_decrypt(
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
count);
stream_cipher.key = emm_security_context->knas_enc.value;
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
stream_cipher.context = emm_security_context->security_container->ciphering_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
@@ -1045,15 +1044,14 @@ static int _nas_message_decrypt(
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
count);
stream_cipher.key = emm_security_context->knas_enc.value;
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
stream_cipher.context = emm_security_context->security_container->ciphering_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
stream_cipher.message = (unsigned char *)src;
/* length in bits */
stream_cipher.blength = length << 3;
stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
stream_compute_encrypt(EEA2_128_ALG_ID, &stream_cipher, (unsigned char *)dest);
/* Decode the first octet (security header type or EPS bearer identity,
* and protocol discriminator) */
@@ -1178,8 +1176,7 @@ static int _nas_message_encrypt(
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
count);
stream_cipher.key = emm_security_context->knas_enc.value;
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
stream_cipher.context = emm_security_context->security_container->ciphering_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
@@ -1208,8 +1205,7 @@ static int _nas_message_encrypt(
(direction == SECU_DIRECTION_UPLINK) ? "UPLINK":"DOWNLINK",
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
count);
stream_cipher.key = emm_security_context->knas_enc.value;
stream_cipher.key_length = AUTH_KNAS_ENC_SIZE;
stream_cipher.context = emm_security_context->security_container->ciphering_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
@@ -1347,8 +1343,7 @@ static uint32_t _nas_message_get_mac(
fflush(stderr);
#endif
stream_cipher.key = emm_security_context->knas_int.value;
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
stream_cipher.context = emm_security_context->security_container->integrity_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
@@ -1391,8 +1386,7 @@ static uint32_t _nas_message_get_mac(
(direction == SECU_DIRECTION_UPLINK) ? emm_security_context->ul_count.seq_num:emm_security_context->dl_count.seq_num,
count);
stream_cipher.key = emm_security_context->knas_int.value;
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
stream_cipher.context = emm_security_context->security_container->integrity_context;
stream_cipher.count = count;
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
stream_cipher.direction = direction;
+8 -12
View File
@@ -515,6 +515,10 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *buf)
{
derive_ue_keys(buf, nas);
/* todo: as of now, nia2 is hardcoded in derive_ue_keys(), remove this hardcoding, use NAS signalling for getting proper algorithm */
/* todo: deal with ciphering for this stream_security_container_init() (handle ciphering in general) */
/* todo: stream_security_container_delete() is not called anywhere, deal with that */
nas->security_container = stream_security_container_init(0, 2 /* hardcoded: nia2 */, NULL, nas->security.knas_int);
OctetString res;
res.length = 16;
res.value = calloc(1,16);
@@ -598,8 +602,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
stream_cipher.key = nas->security.knas_int;
stream_cipher.key_length = 16;
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.mm_counter++;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
@@ -642,8 +645,6 @@ static void decodeRegistrationAccept(const uint8_t *buf, int len, nr_ue_nas_t *n
static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer)
{
//wait send RRCReconfigurationComplete and InitialContextSetupResponse
sleep(1);
int length = 0;
int size = 0;
fgs_nas_message_t nas_msg;
@@ -701,8 +702,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
}
initialNasMsg->length = length;
stream_cipher.key = nas->security.knas_int;
stream_cipher.key_length = 16;
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.mm_counter++;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
@@ -764,8 +764,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg->length = security_header_len + mm_msg_encode(&sp_msg->plain.mm_msg, (uint8_t *)(initialNasMsg->data + security_header_len), size - security_header_len);
nas_stream_cipher_t stream_cipher = {
.key = nas->security.knas_int,
.key_length = 16,
.context = nas->security_container->integrity_context,
.count = nas->security.mm_counter++,
.bearer = 1,
.direction = 0,
@@ -781,8 +780,6 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, nas_pdu_session_req_t *pdu_req)
{
//wait send RegistrationComplete
usleep(100*150);
int size = 0;
fgs_nas_message_t nas_msg={0};
@@ -857,8 +854,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len);
stream_cipher.key = nas->security.knas_int;
stream_cipher.key_length = 16;
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.mm_counter++;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
+2
View File
@@ -41,6 +41,7 @@
#include "as_message.h"
#include "FGSUplinkNasTransport.h"
#include <openair3/UICC/usim_interface.h>
#include "secu_defs.h"
#define PLAIN_5GS_MSG 0b0000
#define INTEGRITY_PROTECTED 0b0001
@@ -98,6 +99,7 @@ typedef struct {
typedef struct {
uicc_t *uicc;
ue_sa_security_key_t security;
stream_security_container_t *security_container;
Guti5GSMobileIdentity_t *guti;
bool termination_procedure;
} nr_ue_nas_t;
@@ -258,6 +258,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
LOG_TRACE(INFO,
"EMM-PROC - Update Current security context");
/* Release non-current security context */
stream_security_container_delete(user->emm_data->security->security_container);
_security_release(user->emm_data->security);
user->emm_data->security = user->emm_data->non_current;
/* Reset the uplink NAS COUNT counter */
@@ -265,6 +266,12 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
user->emm_data->security->ul_count.seq_num = 0;
/* Set new security context indicator */
security_context_is_new = true;
/* create contexts */
user->emm_data->security->security_container = stream_security_container_init(
seea,
seia,
user->emm_data->non_current->knas_enc.value,
user->emm_data->non_current->knas_int.value);
}
}
+2
View File
@@ -42,6 +42,7 @@ Description Defines internal private data handled by EPS Mobility
#include "commonDef.h"
#include "networkDef.h"
#include "securityDef.h"
#include "openair3/SECU/secu_defs.h"
#include "OctetString.h"
#include "nas_timer.h"
@@ -138,6 +139,7 @@ typedef struct emm_security_context_s {
//OctetString ksgsn; /* SGSN security key (mapped context) */
OctetString knas_enc; /* NAS cyphering key */
OctetString knas_int; /* NAS integrity key */
stream_security_container_t *security_container; /* container for NAS security */
struct count_s{
uint32_t spare:8;
uint32_t overflow:16;
+53 -132
View File
@@ -31,101 +31,56 @@
// code for version 3.0 or greater
#include <openssl/core_names.h>
static
const char *propq = NULL;
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
{
OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new();
DevAssert(library_context != NULL);
/* Fetch the CMAC implementation */
EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq);
DevAssert(mac != NULL);
/* Create a context for the CMAC operation */
EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac);
DevAssert(mctx != NULL);
// The underlying cipher to be used
char cipher_name[] = "aes128";
OSSL_PARAM params[2] = {0};
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
sizeof(cipher_name));
params[1] = OSSL_PARAM_construct_end();
/* Initialise the CMAC operation */
int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params);
DevAssert(rc != 0);
size_t sz_iv = 0;
uint8_t* iv = NULL;
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
sz_iv = 8;
iv = (uint8_t*)k_iv->iv8.iv;
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
sz_iv = 16;
iv = (uint8_t*)k_iv->iv16.iv;
} else {
DevAssert(0!=0 && "Unknwon Initialization vector");
}
/* Make one or more calls to process the data to be authenticated */
rc = EVP_MAC_update(mctx, iv, sz_iv);
DevAssert(rc != 0);
/* Make one or more calls to process the data to be authenticated */
rc = EVP_MAC_update(mctx, msg.buf, msg.len);
DevAssert(rc != 0);
/* Make a call to the final with a NULL buffer to get the length of the MAC */
size_t out_len = 0;
rc = EVP_MAC_final(mctx, out, &out_len, len_out);
DevAssert(rc != 0);
EVP_MAC_CTX_free(mctx);
EVP_MAC_free(mac);
OSSL_LIB_CTX_free(library_context);
}
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16])
cbc_cmac_ctx_t init_aes_128_cbc_cmac(const uint8_t key[16])
{
DevAssert(key != NULL);
OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new();
DevAssert(library_context != NULL);
/* Fetch the CMAC implementation */
EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq);
DevAssert(mac != NULL);
EVP_MAC *mac_implementation = EVP_MAC_fetch(NULL, "CMAC", NULL);
DevAssert(mac_implementation != NULL);
cbc_cmac_ctx_t ctx = {.lib_ctx = library_context, .mac = mac };
/* Create a context for the CMAC operation */
EVP_MAC_CTX* mac_context = EVP_MAC_CTX_new(mac_implementation);
DevAssert(mac_context != NULL);
assert(16 == sizeof(ctx.key));
cbc_cmac_ctx_t ctx = { .mac_implementation = mac_implementation, .mac_context = mac_context };
memcpy(ctx.key, key, 16);
return ctx;
// The underlying cipher to be used
char cipher_name[] = "aes128";
OSSL_PARAM params[2] = {0};
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
sizeof(cipher_name));
params[1] = OSSL_PARAM_construct_end();
/* Initialise the CMAC operation */
int rc = EVP_MAC_init(mac_context, key, 16, params);
DevAssert(rc != 0);
return ctx;
}
void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
{
DevAssert(ctx != NULL);
DevAssert(k_iv != NULL);
/* Create a context for the CMAC operation */
EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(ctx->mac);
DevAssert(mctx != NULL);
// The underlying cipher to be used
char cipher_name[] = "aes128";
OSSL_PARAM params[2] = {0};
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name,
sizeof(cipher_name));
params[1] = OSSL_PARAM_construct_end();
/* Initialise the CMAC operation */
int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params);
/* reset the CMAC */
/* There is a bug with version <= 3.0.2 of OpenSSL for which we must
* pass the key to reset. (Some Ubuntu version provide this version.)
* Passing the key has some impact on performance.
* todo: drop support for old versions of openssl.
*/
#if OPENSSL_VERSION_NUMBER <= 0x30000020
/* todo: when/if we remove this code, don't forget to check use of k_iv->key
* somewhere else in the codebase.
* If not used, remove from aes_128_t*
*/
int rc = EVP_MAC_init(ctx->mac_context, k_iv->key, 16, NULL);
#else
int rc = EVP_MAC_init(ctx->mac_context, NULL, 0, NULL);
#endif
DevAssert(rc != 0);
size_t sz_iv = 0;
@@ -141,74 +96,41 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
}
/* Make one or more calls to process the data to be authenticated */
rc = EVP_MAC_update(mctx, iv, sz_iv);
rc = EVP_MAC_update(ctx->mac_context, iv, sz_iv);
DevAssert(rc != 0);
/* Make one or more calls to process the data to be authenticated */
rc = EVP_MAC_update(mctx, msg.buf, msg.len);
rc = EVP_MAC_update(ctx->mac_context, msg.buf, msg.len);
DevAssert(rc != 0);
/* Make a call to the final with a NULL buffer to get the length of the MAC */
size_t out_len = 0;
rc = EVP_MAC_final(mctx, out, &out_len, len_out);
rc = EVP_MAC_final(ctx->mac_context, out, &out_len, len_out);
DevAssert(rc != 0);
EVP_MAC_CTX_free(mctx);
}
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx)
{
DevAssert(ctx != NULL);
EVP_MAC_free(ctx->mac);
OSSL_LIB_CTX_free(ctx->lib_ctx);
EVP_MAC_CTX_free(ctx->mac_context);
EVP_MAC_free(ctx->mac_implementation);
}
#else
// code for 1.1.x or lower
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out])
{
DevAssert(k_iv != NULL);
CMAC_CTX *ctx = CMAC_CTX_new();
DevAssert(ctx != NULL);
CMAC_Init(ctx, k_iv->key, sizeof(k_iv->key), EVP_aes_128_cbc(), NULL);
size_t sz_iv = 0;
uint8_t* iv = NULL;
if(k_iv->type == AES_INITIALIZATION_VECTOR_8){
sz_iv = 8;
iv = (uint8_t*)k_iv->iv8.iv;
} else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) {
sz_iv = 16;
iv = (uint8_t*)k_iv->iv16.iv;
} else {
AssertFatal(0 != 0, "Unknwon Initialization vector");
}
CMAC_Update(ctx, iv, sz_iv);
CMAC_Update(ctx, msg.buf, msg.len);
size_t len_res = 0;
CMAC_Final(ctx, out, &len_res);
DevAssert(len_res <= len_out);
CMAC_CTX_free(ctx);
}
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16])
cbc_cmac_ctx_t init_aes_128_cbc_cmac(const uint8_t key[16])
{
DevAssert(key != NULL);
cbc_cmac_ctx_t ctx = {.lib_ctx = NULL, .mac = NULL };
cbc_cmac_ctx_t ctx = {.mac_implementation = NULL, .mac_context = NULL };
ctx.mac = CMAC_CTX_new();
DevAssert(ctx.mac != NULL);
ctx.mac_context = CMAC_CTX_new();
DevAssert(ctx.mac_context != NULL);
//assert(16 == sizeof(ctx.key));
memcpy(ctx.key, key, 16); //sizeof(ctx.key));
CMAC_Init(ctx.mac, ctx.key, 16, EVP_aes_128_cbc(), NULL);
CMAC_Init(ctx.mac_context, ctx.key, 16, EVP_aes_128_cbc(), NULL);
return ctx;
}
@@ -218,11 +140,11 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
DevAssert(k_iv != NULL);
//From https://man.openbsd.org/CMAC_Init.3
//If ctx is already initialized, CMAC_Init() can be called again with key,
//cipher, and impl all set to NULL and key_len set to 0. In that case, any
//data already processed is discarded and ctx is re-initialized to start
//If ctx is already initialized, CMAC_Init() can be called again with key,
//cipher, and impl all set to NULL and key_len set to 0. In that case, any
//data already processed is discarded and ctx is re-initialized to start
//reading data anew.
CMAC_Init(ctx->mac, NULL, 0, NULL, NULL);
CMAC_Init(ctx->mac_context, NULL, 0, NULL, NULL);
size_t sz_iv = 0;
uint8_t* iv = NULL;
@@ -236,19 +158,18 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
AssertFatal(0 != 0, "Unknwon Initialization vector");
}
CMAC_Update(ctx->mac, iv, sz_iv);
CMAC_Update(ctx->mac_context, iv, sz_iv);
CMAC_Update(ctx->mac, msg.buf, msg.len);
CMAC_Update(ctx->mac_context, msg.buf, msg.len);
size_t len_res = 0;
CMAC_Final(ctx->mac, out, &len_res);
CMAC_Final(ctx->mac_context, out, &len_res);
DevAssert(len_res <= len_out);
}
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx)
{
DevAssert(ctx != NULL);
CMAC_CTX_free(ctx->mac);
CMAC_CTX_free(ctx->mac_context);
}
#endif
+3 -7
View File
@@ -31,17 +31,13 @@
#include <stdlib.h>
typedef struct {
void* lib_ctx;
void* mac;
void *mac_implementation;
void *mac_context;
uint8_t key[16];
} cbc_cmac_ctx_t ;
void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]);
cbc_cmac_ctx_t init_aes_128_cbc_cmac(const uint8_t key[16]);
void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx);
#endif
+22 -12
View File
@@ -38,10 +38,9 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
//uint32_t byte_length;
uint32_t *KS;
uint32_t K[4],IV[4];
uint8_t *key = (uint8_t *)stream_cipher->context;
DevAssert(stream_cipher != NULL);
DevAssert(stream_cipher->key != NULL);
DevAssert(stream_cipher->key_length == 16);
DevAssert(out != NULL);
n = ( stream_cipher->blength + 31 ) / 32;
@@ -50,22 +49,20 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
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
/* Load the confidentiality key for SNOW 3G initialization as in section 3.4. */
memcpy(K+3,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*/
memcpy(K+2,key+4,4); /*K[2] = key[1];*/
memcpy(K+1,key+8,4); /*K[1] = key[2];*/
memcpy(K+0,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. */
/* 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];
@@ -104,3 +101,16 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
out[ceil_index - 1] = stream_cipher->message[ceil_index - 1];
}
}
stream_security_context_t *stream_ciphering_init_eea1(const uint8_t *ciphering_key)
{
void *ret = calloc(1, 16);
AssertFatal(ret != NULL, "out of memory\n");
memcpy(ret, ciphering_key, 16);
return (stream_security_context_t *)ret;
}
void stream_ciphering_free_eea1(stream_security_context_t *ciphering_context)
{
free(ciphering_context);
}
+3
View File
@@ -29,4 +29,7 @@
void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out);
stream_security_context_t *stream_ciphering_init_eea1(const uint8_t *ciphering_key);
void stream_ciphering_free_eea1(stream_security_context_t *ciphering_context);
#endif
+14 -3
View File
@@ -33,15 +33,13 @@
void nas_stream_encrypt_eea2(nas_stream_cipher_t const *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);
aes_128_t p = {0};
memcpy(p.key, stream_cipher->key, stream_cipher->key_length);
memcpy(p.key, stream_cipher->context, 16);
p.type = AES_INITIALIZATION_VECTOR_16;
p.iv16.d.count = htonl(stream_cipher->count);
p.iv16.d.bearer = stream_cipher->bearer;
@@ -54,3 +52,16 @@ void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *
byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght};
aes_128_ctr(&p, msg, len_out, out);
}
stream_security_context_t *stream_ciphering_init_eea2(const uint8_t *ciphering_key)
{
void *ret = calloc(1, 16);
AssertFatal(ret != NULL, "out of memory\n");
memcpy(ret, ciphering_key, 16);
return (stream_security_context_t *)ret;
}
void stream_ciphering_free_eea2(stream_security_context_t *ciphering_context)
{
free(ciphering_context);
}
+3 -34
View File
@@ -26,40 +26,9 @@
#include "secu_defs.h"
#include <stdint.h>
/* Rijndael S-box OSA_SR */
static const uint8_t OSA_SR[256] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};
/* S-box OSA_SQ */
static const uint8_t OSA_SQ[256] = {
0x25, 0x24, 0x73, 0x67, 0xD7, 0xAE, 0x5C, 0x30, 0xA4, 0xEE, 0x6E, 0xCB, 0x7D, 0xB5, 0x82, 0xDB, 0xE4, 0x8E, 0x48, 0x49,
0x4F, 0x5D, 0x6A, 0x78, 0x70, 0x88, 0xE8, 0x5F, 0x5E, 0x84, 0x65, 0xE2, 0xD8, 0xE9, 0xCC, 0xED, 0x40, 0x2F, 0x11, 0x28,
0x57, 0xD2, 0xAC, 0xE3, 0x4A, 0x15, 0x1B, 0xB9, 0xB2, 0x80, 0x85, 0xA6, 0x2E, 0x02, 0x47, 0x29, 0x07, 0x4B, 0x0E, 0xC1,
0x51, 0xAA, 0x89, 0xD4, 0xCA, 0x01, 0x46, 0xB3, 0xEF, 0xDD, 0x44, 0x7B, 0xC2, 0x7F, 0xBE, 0xC3, 0x9F, 0x20, 0x4C, 0x64,
0x83, 0xA2, 0x68, 0x42, 0x13, 0xB4, 0x41, 0xCD, 0xBA, 0xC6, 0xBB, 0x6D, 0x4D, 0x71, 0x21, 0xF4, 0x8D, 0xB0, 0xE5, 0x93,
0xFE, 0x8F, 0xE6, 0xCF, 0x43, 0x45, 0x31, 0x22, 0x37, 0x36, 0x96, 0xFA, 0xBC, 0x0F, 0x08, 0x52, 0x1D, 0x55, 0x1A, 0xC5,
0x4E, 0x23, 0x69, 0x7A, 0x92, 0xFF, 0x5B, 0x5A, 0xEB, 0x9A, 0x1C, 0xA9, 0xD1, 0x7E, 0x0D, 0xFC, 0x50, 0x8A, 0xB6, 0x62,
0xF5, 0x0A, 0xF8, 0xDC, 0x03, 0x3C, 0x0C, 0x39, 0xF1, 0xB8, 0xF3, 0x3D, 0xF2, 0xD5, 0x97, 0x66, 0x81, 0x32, 0xA0, 0x00,
0x06, 0xCE, 0xF6, 0xEA, 0xB7, 0x17, 0xF7, 0x8C, 0x79, 0xD6, 0xA7, 0xBF, 0x8B, 0x3F, 0x1F, 0x53, 0x63, 0x75, 0x35, 0x2C,
0x60, 0xFD, 0x27, 0xD3, 0x94, 0xA5, 0x7C, 0xA1, 0x05, 0x58, 0x2D, 0xBD, 0xD9, 0xC7, 0xAF, 0x6B, 0x54, 0x0B, 0xE0, 0x38,
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);
stream_security_context_t *stream_ciphering_init_eea2(const uint8_t *ciphering_key);
void stream_ciphering_free_eea2(stream_security_context_t *ciphering_context);
#endif
+19 -5
View File
@@ -126,16 +126,17 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
uint64_t M_D_2;
int rem_bits;
uint32_t mask = 0;
uint32_t *message;
uint32_t *message;
uint8_t *key = (uint8_t *)stream_cipher->context;
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
memcpy(K+3,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
memcpy(K+2,key+4,4); /*K[2] = key[1];*/
memcpy(K+1,key+8,4); /*K[1] = key[2];*/
memcpy(K+0,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]);
@@ -213,3 +214,16 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
MAC_I = hton_int32(MAC_I);
memcpy(out, &MAC_I, 4);
}
stream_security_context_t *stream_integrity_init_eia1(const uint8_t *integrity_key)
{
void *ret = calloc(1, 16);
AssertFatal(ret != NULL, "out of memory\n");
memcpy(ret, integrity_key, 16);
return (stream_security_context_t *)ret;
}
void stream_integrity_free_eia1(stream_security_context_t *integrity_context)
{
free(integrity_context);
}
+3
View File
@@ -26,4 +26,7 @@
void nas_stream_encrypt_eia1(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]);
stream_security_context_t *stream_integrity_init_eia1(const uint8_t *integrity_key);
void stream_integrity_free_eia1(stream_security_context_t *integrity_context);
#endif
+16 -3
View File
@@ -45,11 +45,11 @@ void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t o
DevAssert(stream_cipher != NULL);
DevAssert(stream_cipher->message != NULL);
DevAssert(stream_cipher->bearer < 32);
DevAssert(stream_cipher->key_length == 16);
DevAssert((stream_cipher->blength & 0x7) == 0);
cbc_cmac_ctx_t *ctx = (cbc_cmac_ctx_t *)stream_cipher->context;
aes_128_t k_iv = {0};
memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key));
memcpy(&k_iv.key, ctx->key, 16);
k_iv.type = AES_INITIALIZATION_VECTOR_8;
k_iv.iv8.d.bearer = stream_cipher->bearer;
k_iv.iv8.d.direction = stream_cipher->direction;
@@ -58,8 +58,21 @@ void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t o
size_t const m_length = stream_cipher->blength >> 3;
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);
cipher_aes_128_cbc_cmac(ctx, &k_iv, msg, sizeof(result), result);
memcpy(out, result, 4);
}
stream_security_context_t *stream_integrity_init_eia2(const uint8_t *integrity_key)
{
cbc_cmac_ctx_t *ret = calloc(1, sizeof(cbc_cmac_ctx_t));
AssertFatal(ret != NULL, "out of memory\n");
*ret = init_aes_128_cbc_cmac(integrity_key);
return (stream_security_context_t *)ret;
}
void stream_integrity_free_eia2(stream_security_context_t *integrity_context)
{
free_aes_128_cbc_cmac((cbc_cmac_ctx_t *)integrity_context);
free(integrity_context);
}
+3
View File
@@ -26,4 +26,7 @@
void nas_stream_encrypt_eia2(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]);
stream_security_context_t *stream_integrity_init_eia2(const uint8_t *integrity_key);
void stream_integrity_free_eia2(stream_security_context_t *integrity_context);
#endif
+67
View File
@@ -64,3 +64,70 @@ void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const* stream_
}
}
stream_security_context_t *stream_integrity_init(int integrity_algorithm, const uint8_t *integrity_key)
{
switch (integrity_algorithm) {
case EEA0_ALG_ID: return NULL;
case EEA1_128_ALG_ID: return stream_integrity_init_eia1(integrity_key);
case EEA2_128_ALG_ID: return stream_integrity_init_eia2(integrity_key);
default: AssertFatal(0, "unsupported integrity algorithm\n");
}
}
void stream_integrity_free(int integrity_algorithm, stream_security_context_t *integrity_context)
{
switch (integrity_algorithm) {
case EEA0_ALG_ID: return;
case EEA1_128_ALG_ID: return stream_integrity_free_eia1(integrity_context);
case EEA2_128_ALG_ID: return stream_integrity_free_eia2(integrity_context);
default: AssertFatal(0, "unsupported integrity algorithm\n");
}
}
stream_security_context_t *stream_ciphering_init(int ciphering_algorithm, const uint8_t *ciphering_key)
{
switch (ciphering_algorithm) {
case EEA0_ALG_ID: return NULL;
case EEA1_128_ALG_ID: return stream_ciphering_init_eea1(ciphering_key);
case EEA2_128_ALG_ID: return stream_ciphering_init_eea2(ciphering_key);
default: AssertFatal(0, "unsupported ciphering algorithm\n");
}
}
void stream_ciphering_free(int ciphering_algorithm, stream_security_context_t *ciphering_context)
{
switch (ciphering_algorithm) {
case EEA0_ALG_ID: return;
case EEA1_128_ALG_ID: return stream_ciphering_free_eea1(ciphering_context);
case EEA2_128_ALG_ID: return stream_ciphering_free_eea2(ciphering_context);
default: AssertFatal(0, "unsupported ciphering algorithm\n");
}
}
stream_security_container_t *stream_security_container_init(int ciphering_algorithm,
int integrity_algorithm,
const uint8_t *ciphering_key,
const uint8_t *integrity_key)
{
stream_security_container_t *container = calloc(1, sizeof(*container));
AssertFatal(container != NULL, "out of memory\n");
container->integrity_algorithm = integrity_algorithm;
container->ciphering_algorithm = ciphering_algorithm;
container->integrity_context = stream_integrity_init(integrity_algorithm, integrity_key);
container->ciphering_context = stream_ciphering_init(ciphering_algorithm, ciphering_key);
return container;
}
void stream_security_container_delete(stream_security_container_t *container)
{
/* passing NULL is accepted */
if (container == NULL)
return;
stream_integrity_free(container->integrity_algorithm, container->integrity_context);
stream_ciphering_free(container->ciphering_algorithm, container->ciphering_context);
free(container);
}
+32 -3
View File
@@ -28,17 +28,46 @@
#define SECU_DIRECTION_UPLINK 0
#define SECU_DIRECTION_DOWNLINK 1
/* stream_security_context_t is an opaque structure.
* It is different for each integrity and ciphering algorithm in use.
* Defined as a struct to have compilation time type checking
* (the "context" field is never actually used).
*/
typedef struct {
uint8_t *key;
uint32_t key_length;
void *context;
} stream_security_context_t;
/* stream_security_container_t contains the current configuration
* of integrity and ciphering. It is used by PDCP and NAS.
*/
typedef struct {
int integrity_algorithm;
int ciphering_algorithm;
stream_security_context_t *ciphering_context;
stream_security_context_t *integrity_context;
} stream_security_container_t;
typedef struct {
stream_security_context_t *context;
uint32_t count;
uint8_t bearer;
uint8_t direction;
uint8_t *message;
/* length in bits */
uint32_t blength;
uint32_t blength;
} nas_stream_cipher_t;
stream_security_context_t *stream_integrity_init(int integrity_algorithm, const uint8_t *integrity_key);
stream_security_context_t *stream_ciphering_init(int ciphering_algorithm, const uint8_t *ciphering_key);
void stream_integrity_free(int integrity_algorithm, stream_security_context_t *integrity_context);
void stream_ciphering_free(int ciphering_algorithm, stream_security_context_t *ciphering_context);
stream_security_container_t *stream_security_container_init(int ciphering_algorithm,
int integrity_algorithm,
const uint8_t *ciphering_key,
const uint8_t *integrity_key);
void stream_security_container_delete(stream_security_container_t *container);
/*!
* @brief Encrypt/Decrypt a block of data based on the provided algorithm
* @param[in] algorithm Algorithm used to encrypt the data
+12 -4
View File
@@ -1220,12 +1220,20 @@ extern "C" {
LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
switch ((int)openair0_cfg[0].sample_rate) {
case 245760000:
// from usrp_time_offset
// openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 15; // to be checked
openair0_cfg[0].tx_bw = 200e6;
openair0_cfg[0].rx_bw = 200e6;
break;
case 184320000:
// from usrp_time_offset
//openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 15; //to be checked
openair0_cfg[0].tx_bw = 100e6;
openair0_cfg[0].rx_bw = 100e6;
// openair0_cfg[0].samples_per_packet = 2048;
openair0_cfg[0].tx_sample_advance = 15; // to be checked
openair0_cfg[0].tx_bw = 100e6;
openair0_cfg[0].rx_bw = 100e6;
break;
case 122880000: