Compare commits

...

16 Commits

Author SHA1 Message Date
Surajit Dey
210ddfdd1f Update file BAP_readme.txt 2024-11-15 20:28:37 +00:00
Surajit Dey
be4adbcf96 Update BAP_readme.txt 2024-11-15 20:24:30 +00:00
Surajit Dey
dc510a78f9 Update BAP_readme.txt
Changed spelling error in code path.
2024-11-05 21:48:40 +00:00
Surajit Dey
53e33ba876 Update BAP_readme.txt with minor changes for code and config file locations. 2024-11-05 21:41:31 +00:00
Danny Nsouli
4c626de21d Delete rec_w_bap1.pcap 2024-11-05 17:21:22 +00:00
Danny Nsouli
a9fe6be81c Delete rec_w_bap2.pcap 2024-11-05 17:21:15 +00:00
Danny Nsouli
f2c9e3d670 Delete rec_w_bap_cudu.pcap 2024-11-05 17:21:08 +00:00
Danny Nsouli
ce0cda9b42 Delete BAP_pcap.PNG 2024-11-05 17:20:31 +00:00
Surajit Dey
b04c569355 Update BAP_TODO.md 2024-11-04 19:18:36 +00:00
Danny Nsouli
f90634b49d Delete .DS_Store 2024-11-04 19:03:20 +00:00
Danny Nsouli
9706ae5804 bap layer files (not integrated) and configuration folder added 2024-11-04 11:02:22 -08:00
Danny Nsouli
1afb4dcb05 Add new directory 2024-11-04 18:51:28 +00:00
Surajit Dey
624482aa58 Add new directory for IAB BAP additional code. 2024-11-01 21:39:36 +00:00
Surajit Dey
0c37bd3c76 Update file nr_pdcp_oai_api.c 2024-11-01 21:17:36 +00:00
Surajit Dey
cb32d0106a Update file rrc_gNB.c 2024-10-30 21:59:31 +00:00
Surajit Dey
0d68504e89 Update file nr_pdcp_oai_api.h 2024-10-30 21:11:45 +00:00
18 changed files with 1795 additions and 7 deletions

View File

@@ -0,0 +1,67 @@
# BAP TODO List
NOTICE
This software was produced for the U. S. Government
under Basic Contract No. W56KGU-18-D-0004, and is
subject to the Rights in Noncommercial Computer Software
and Noncommercial Computer Software Documentation
Clause 252.227-7014 (FEB 2014)
(C) 2024 The MITRE Corporation.
### Author Information:
- Developer: Surajit Dey (MITRE)
- Developer: Danny Nsouli (MITRE)
### File Descriptions:
All figures can be referenced in the [Backhaul Adaptation Protocol (BAP) 3GPP Specification TS 38.340.](https://www.etsi.org/deliver/etsi_ts/138300_138399/138340/16.04.00_60/ts_138340v160400p.pdf)
#### 1. Integrate BAP Control PDU for Flow Control Feedback Polling (Figure 6.2.3.2-1)
- It was determined that a new function (i.e. `int bap_fc_polling_pdu(rntiP, tb_sizeP)`) could be written to assemble the aforementioned polling control PDU in `openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c`.
- A global variable, `char BAP_FC_POLLING_PDU`, could be created to initialize the variable, `buffer_pP`, a pointer to a buffer that is used to store the MAC PDU (Protocol Data Unit) data. This new variable is necessary as a different value is required for the assembly of this specific PDU, hence why `MAC_PDU_SIZE` could be replaced.
- Within `radio/rfsimulator/simulator.c`, a thread may be required to both control and avoid rapid erroneous PDU polling activity. Therefore, it was determined that a BAP polling thread could be created within `bool flushInput(*t, timeout, nsamps_for_initial)`. A new worker function (i.e. `void *worker2`) should be added to assist the thread's creation as a required parameter (i.e. `threadCreate(&th, worker2, NULL, "BAP polling", -1, OAI_PRIORITY_RT_LOW);`).
#### 2. Integrate BAP Control PDU format for flow control feedback per BAP routing ID (Figure 6.2.3.1-2)
- `bap_cpdu_routing.c` contains a function that can assemble the BAP header for the aforementioned PDU.
- It has not been determined how this functionality should be integrated whether it be in an existing OAI file or a new one.
#### 3. Integrate BAP Control PDU format for flow control feedback per BH RLC channel (Figure 6.2.3.1-1)
- `bap_cpdu.c` contains a function that can assemble the BAP header for the aforementioned PDU.
- It has not been determined how this functionality should be integrated whether it be in an existing OAI file or a new one.
#### 4. Integrate BAP Control PDU format for BH RLF indication (Figure 6.2.3.3-1)
- `bap_control_indic.c` contains a function that can assemble the BAP header for the aforementioned PDU.
- It has not been determined how this functionality should be integrated whether it be in an existing OAI file or a new one.
#### 5. Integrate BAP Control PDU format for BH RLF detection indication (Figure 6.2.3.4-1)
- `bap_control_detec.c` contains a function that can assemble the BAP header for the aforementioned PDU.
- It has not been determined how this functionality should be integrated whether it be in an existing OAI file or a new one.
#### 6. Integrate BAP Control PDU format for BH RLF recovery indication (Figure 6.2.3.5-1)
- `bap_control_recov.c` contains a function that can assemble the BAP header for the aforementioned PDU.
- It has not been determined how this functionality should be integrated whether it be in an existing OAI file or a new one.
Each of the mentioned c files from points 2-6 resides in: `oai5g/bap_and_oai_modified_files_NOV2023/bap_files_not_integrated/
#### 7. Integrate all control PDUs in OAI code and test for the following functions:
- Flow control per backhaul RLC channel
- Flow control per BAP routing ID
- Flow control feedback polling
- Backhaul Radio Link Failure indication
- Backhaul Radio Link Failure detection indication
- Backhaul Radio Link Failure recovery indication
#### 8. Make BAP ID and path (routing ID) dynamic.
- In the current version BAP ID and path are hard coded for the prototype test. Those need to be configured dynamically using RRC messages.
- Process RRC signaling from donor-CU-CP to get the BAP ID and path or routing ID. Use those parameters in the BAP data PDU header for communicating to the next hop IAB node.
#### 9. Test for performance with max bandwidth to compare the impact of BAP layer addition in the user plane traffic throughput and latency.

View File

@@ -0,0 +1,125 @@
# OAI File Modification Documentation:
NOTICE
This software was produced for the U. S. Government
under Basic Contract No. W56KGU-18-D-0004, and is
subject to the Rights in Noncommercial Computer Software
and Noncommercial Computer Software Documentation
Clause 252.227-7014 (FEB 2014)
(C) 2024 The MITRE Corporation.
#### Author Information:
- Developer: Surajit Dey (MITRE)
- Developer: Danny Nsouli (MITRE)
#### Modified Code Files Documentation:
All figures can be referenced in the [Backhaul Adaptation Protocol (BAP) Specification TS 38.340](https://www.etsi.org/deliver/etsi_ts/138300_138399/138340/16.04.00_60/ts_138340v160400p.pdf). The following are files modified in November 2023 in an attempt to integrate a BAP layer:
`openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h`
- Added BAP data structure (`struct bap_data`), BAP Data PDU (Figure 6.2.2-1) assembly function declarations: `int bap_pdu_func(dest, path)`
`openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c`
- Integrated BAP Data PDU (Figure 6.2.2-1) assembly function (`int bap_pdu_func(dest, path)`). `dest` is a 10-bit field that identifies the destination BAP address, which could be the address of an IAB-node or IAB-donor-DU. `path` carries a 10-bit path identity that is used for routing the BAP Data PDU.
- deliver_pdu_drb() was modified to insert the BAP data PDU header in the transmit direction of user plane in both UE and gNB.
- deliver_pdu_srb_rlc() was modified to insert the BAP data PDU header in the transmit direction of signaling plane in both UE and gNB.
- do_pdcp_data_ind() was modified to remove the BAP data PDU header in the receive direction of user plane in both UE and gNB.
- deliver_sdu_srb() was modified to remove the BAP data PDU header in the receive direction of signaling plane in both UE and gNB.
`openair2/RRC/NR/rrc_gNB.c`
- DURecvCb() was modified to insert the BAP data PDU header in the transmit direction of signaling plane in both UE and gNB.
- rrc_DU_process_ue_context_setup_request() was modified to insert the BAP data PDU header in the transmit direction of signaling plane in both UE and gNB.
#### New Non-Integrated Code Files:
The following files were tested with various edge cases in a local environment seperate from the OAI codebase. They contain assembly functions for each of the BAP Data and Control PDU formats:
`bap_pdu.c`
- Assembles Figure 6.2.2-1: BAP Data PDU format
`bap_cpdu_routing.c`
- Assembles Figure 6.2.3.1-2: BAP Control PDU format for flow control feedback per BAP routing ID
`bap_cpdu.c:`
- Assembles Figure 6.2.3.1-1: BAP Control PDU format for flow control feedback per BH RLC channel
`bap_control_detec.c`
- Assembles Figure 6.2.3.4-1: BAP Control PDU format for BH RLF detection indication
`bap_control_indic.c`
- Assembles Figure 6.2.3.3-1: BAP Control PDU format for BH RLF indication
`bap_control_polling.c`
- Assembles Figure 6.2.3.2-1: BAP Control PDU format for flow control feedback polling
`bap_control_recov.c`
- Assembles Figure 6.2.3.5-1: BAP Control PDU format for BH RLF recovery indication
Each of these c files resides in: openair2/LAYER2/BAP_code_not_integrated/bap_files_not_integrated/
Backhaul Adaptation Protocol (BAP) layer code has been added using 2023.w16 tag of the OAI develop branch.
BAP data PDU is added in the control plane and user plane of gNB/IAB-DU and UE.
Packet structure of BAP data PDU is taken from 3GPP spec TS 38.340 section 6.2.2.
Verified BAP data PDU header insertion and removal in gNB & UE using RF simulation feature of Open Air Interface. UE, gNB and core all were simulated in one Ubuntu host machine running 20.04 Ubuntu.
Verified BAP layer functionality with CU-DU split architecture of gNB (using RF simulator).
How to run BAP code:
Start 5G core simulator first:
Use the following link to download core container images.
https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/develop/ci-scripts/yaml_files/5g_rfsimulator
Start only the core NFs. Remove or comment out the gNB and UE sections in the docker-compose.yaml file.
The docker-compose file is located in:
~/ci-scripts/yaml_files/5g_rfsimulator directory.
$ cd ci-scripts/yaml_files/5g_rfsimulator
$ sudo docker-compose up -d
CU-DU split:
Start CU:
sudo RFSIMULATOR=server ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_CU.conf
DU:
sudo RFSIMULATOR=server BAP=yes ./nr-softmodem --rfsim --sa -O ../../../ci-scripts/conf_files/gNB_SA_DU.conf
UE:
sudo RFSIMULATOR=IAB-DU_IP_addr BAP=yes ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --nokrnmod -O ~/conf-files/ue1.conf
Note: The "BAP" environment variable was used for testing the BAP functionality in UE/IAB-MT and DU.
Example configuration files for CU, DU and UE can be found in Config-files directory.
Use ping or iperf in UE and rfsim5g-oai-ext-dn for end to end data test.
Monitor traffic with wireshark on rfsim5g-public interface with filters set to "udp or sctp".
Pcap files from lab test are available in this website:
https://dnsouli.wixsite.com/mitre-oai-docs/file-share/9cbba17c-8b7f-46d2-9dbc-3a06e2b3ab8d
A png file is also available at the same site. The png shows an example of how BAP header (3 bytes with known pattern 0x8eafcd) are added in the uplink direction.
Note 1: MITRE did end to end test with moderate amount of traffic. Stress test or performance test was not done under full bandwidth scenarios.
Note 2: RF simulator airlink data is sent between UE and gNB as TCP payload. In order to dissect the headers below IP layer - PDCP/RLC/MAC, the following procedure was used.
To run gNB with T tracer, use this option with nr-softmodem:
--T_stdout 2
cd to common/utils/T/tracer and run
./macpdu2wireshark -d ../T_messages.txt -live
Capture required data in pcap file:
sudo tcpdump -n -iany "udp port 9999 or udp port 2152 or sctp or port 38462 or port 38472 or port 38412 or port 2153" -w /tmp/rec.pcap
Open the pcap file on wireshark.
https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/common/utils/T/DOC/T/wireshark.md
https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/common/utils/T/DOC/T/basic.md

View File

@@ -0,0 +1,182 @@
version: '3.8'
services:
oai-nrf:
container_name: "rfsim5g-oai-nrf"
image: oaisoftwarealliance/oai-nrf:v1.5.0
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- TZ=Europe/Paris
networks:
public_net:
ipv4_address: 192.168.71.130
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
volumes:
- ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v1.5.0
environment:
- TZ=Europe/paris
- MCC=208
- MNC=99
- REGION_ID=128
- AMF_SET_ID=1
- SERVED_GUAMI_MCC_0=208
- SERVED_GUAMI_MNC_0=99
- SERVED_GUAMI_REGION_ID_0=128
- SERVED_GUAMI_AMF_SET_ID_0=1
- SERVED_GUAMI_MCC_1=460
- SERVED_GUAMI_MNC_1=11
- SERVED_GUAMI_REGION_ID_1=10
- SERVED_GUAMI_AMF_SET_ID_1=1
- PLMN_SUPPORT_MCC=208
- PLMN_SUPPORT_MNC=99
- PLMN_SUPPORT_TAC=0x0001
# Only one slice is defined (1, 0xFFFFFF).
- SST_0=1
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
- AMF_INTERFACE_NAME_FOR_N11=eth0
# One single SMF instance
- SMF_INSTANCE_ID_0=1
- SMF_FQDN_0=oai-smf
- SMF_IPV4_ADDR_0=192.168.71.133
- SELECTED_0=true
# mysql definition in AMF is mandatory in mini deployment.
- MYSQL_SERVER=192.168.71.131
- MYSQL_USER=root
- MYSQL_PASS=linux
- MYSQL_DB=oai_db
# NF registration
- NRF_IPV4_ADDRESS=192.168.71.130
- NRF_FQDN=oai-nrf
- NF_REGISTRATION=yes
- SMF_SELECTION=yes
- USE_FQDN_DNS=yes
- USE_HTTP2=no
depends_on:
- oai-nrf
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v1.5.0
environment:
- TZ=Europe/Paris
- SMF_INTERFACE_NAME_FOR_N4=eth0
- SMF_INTERFACE_NAME_FOR_SBI=eth0
- DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
- DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
- AMF_IPV4_ADDRESS=192.168.71.132
- AMF_FQDN=oai-amf
- UPF_IPV4_ADDRESS=192.168.71.134
- UPF_FQDN_0=oai-spgwu
- NRF_IPV4_ADDRESS=192.168.71.130
- NRF_FQDN=oai-nrf
- REGISTER_NRF=yes
- DISCOVER_UPF=yes
- USE_FQDN_DNS=yes
- USE_LOCAL_SUBSCRIPTION_INFO=yes
- UE_MTU=1500
# Only one slice is defined (1, 0xFFFFFF)
- DNN_NI0=oai
- TYPE0=IPv4
- DNN_RANGE0=12.1.1.2 - 12.1.1.127
- NSSAI_SST0=1
- SESSION_AMBR_UL0=200Mbps
- SESSION_AMBR_DL0=400Mbps
- DEFAULT_CSCF_IPV4_ADDRESS=127.0.0.1
- ENABLE_USAGE_REPORTING=no
depends_on:
- oai-nrf
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-spgwu:
container_name: "rfsim5g-oai-spgwu"
image: oaisoftwarealliance/oai-spgwu-tiny:v1.5.0
environment:
- TZ=Europe/Paris
- SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
- SGW_INTERFACE_NAME_FOR_SX=eth0
- PGW_INTERFACE_NAME_FOR_SGI=eth0
- NETWORK_UE_NAT_OPTION=yes
- NETWORK_UE_IP=12.1.1.0/24
- ENABLE_5G_FEATURES=yes
- REGISTER_NRF=yes
- USE_FQDN_NRF=yes
- UPF_FQDN_5G=oai-spgwu
- NRF_IPV4_ADDRESS=192.168.71.130
- NRF_FQDN=oai-nrf
# Only one slice is defined (1, 0xFFFFFF)
- NSSAI_SST_0=1
- NSSAI_SD_0=0xffffff
- DNN_0=oai
depends_on:
- oai-nrf
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
traffic_net:
ipv4_address: 192.168.72.134
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-spgwu
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"

View File

@@ -0,0 +1,218 @@
Active_gNBs = ( "gNB-Eurecom-CU");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8;
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-CU";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
nr_cellid = 12345678L;
force_256qam_off = 1;
tr_s_preference = "f1";
local_s_if_name = "lo";
local_s_address = "127.0.0.4";
remote_s_address = "127.0.0.3";
local_s_portc = 501;
local_s_portd = 2152;
remote_s_portc = 500;
remote_s_portd = 2152;
min_rxtxtime = 6;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.71.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "rfsim5g-public";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "rfsim5g-public";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="debug";
pdcp_log_level ="info";
rrc_log_level ="info";
f1ap_log_level ="info";
ngap_log_level ="debug";
};

View File

@@ -0,0 +1,239 @@
Active_gNBs = ( "gNB-Eurecom-DU");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
# cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-DU";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
nr_cellid = 12345678L;
////////// Physical parameters:
min_rxtxtime = 6;
force_256qam_off = 1;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 641280;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640008;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=27,L=48 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "f1";
local_n_if_name = "lo";
local_n_address = "127.0.0.3";
remote_n_address = "127.0.0.4";
local_n_portc = 500;
local_n_portd = 2152;
remote_n_portc = 501;
remote_n_portd = 2152;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 1;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
pucch0_dtx_threshold = 150;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
rfsimulator: {
serveraddr = "server";
serverport = "4043";
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs"
}
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
f1ap_log_level ="info";
ngap_log_level ="debug";
};

View File

@@ -0,0 +1,19 @@
uicc0 = {
//imsi = "208990100001124";
//imsi = "208990200000001";
//imsi = "208990100001135";
imsi = "208990100001100";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "c42449363bbad02b66d16bc975d77cc1";
//dnn= "internet";
dnn= "oai";
nssai_sst=1;
nssai_sd=0xFFFFFF;
}
//telnetsrv = {
// listenport = 9091
// histfile = "~/history.telnetsrv"
//}
//@include "channelmod_rfsimu.conf"

View File

@@ -0,0 +1,72 @@
/*! \file bap_control_detec.c
* \brief BAP Control PDU format for BH RLF detection indication
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// BAP header
struct bap_control_detec {
unsigned char oct1;
};
// Flow control fields
unsigned char PDU_Type = 0b0100;
uint64_t bap_control_detec_func() {
struct bap_control_detec bap_cd;
// Set header fields
bap_cd.oct1 = 0;
bap_cd.oct1 |= (PDU_Type << 3);
// DC=0, PDU Type=0100
printf("Oct 1 0x%x\n", bap_cd.oct1);
unsigned char controlPDU[1];
memcpy(&controlPDU[0], (unsigned char *) &bap_cd, sizeof(bap_cd));
// Print assembled PDU
for(int i=0; i<6; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= bap_cd.oct1;
return octets;
}
uint64_t main(int argc, char *argv[]){
if (argc != 1) {
printf("Please pass in exactly two arguments\n");
return 1;
}
uint64_t octets = bap_control_detec_func();
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,72 @@
/*! \file bap_control_indic.c
* \brief BAP Control PDU format for BH RLF indication
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// BAP header
struct bap_control_indic {
unsigned char oct1;
};
// Flow control fields
unsigned char PDU_Type = 0b0011;
uint64_t bap_control_indic_func() {
struct bap_control_indic bap_ci;
// Set header fields
bap_ci.oct1 = 0;
bap_ci.oct1 |= (PDU_Type << 3);
// DC=0, PDU Type=0011
printf("Oct 1 0x%x\n", bap_ci.oct1);
unsigned char controlPDU[1];
memcpy(&controlPDU[0], (unsigned char *) &bap_ci, sizeof(bap_ci));
// Print assembled PDU
for(int i=0; i<6; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= bap_ci.oct1;
return octets;
}
uint64_t main(int argc, char *argv[]){
if (argc != 1) {
printf("Please pass in exactly two arguments\n");
return 1;
}
uint64_t octets = bap_control_indic_func();
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,73 @@
/*! \file bap_control_polling.c
* \brief BAP Control PDU format for flow control feedback polling
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// BAP header
struct bap_control_polling {
unsigned char oct1;
};
// Flow control fields
unsigned char PDU_Type = 0b0010;
uint64_t bap_control_polling_func() {
struct bap_control_polling bap_cp;
// Set header fields
bap_cp.oct1 = 0;
bap_cp.oct1 |= (PDU_Type << 3);
// bapc.oct1 = 0x01; // DC=0, PDU Type=0010
printf("Oct 1 0x%x\n", bap_cp.oct1);
unsigned char controlPDU[1];
memcpy(&controlPDU[0], (unsigned char *) &bap_cp, sizeof(bap_cp));
// Print assembled PDU
for(int i=0; i<6; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= bap_cp.oct1;
return octets;
}
uint64_t main(int argc, char *argv[]){
int i;
if (argc != 1) {
printf("Please pass in exactly two arguments\n");
return 1;
}
uint64_t octets = bap_control_polling_func();
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,73 @@
/*! \file bap_control_recov.c
* \brief BAP Control PDU format for BH RLF recovery indication
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// BAP header
struct bap_control_recov {
unsigned char oct1;
};
// Flow control fields
unsigned char PDU_Type = 0b0101;
uint64_t bap_control_recov_func() {
struct bap_control_recov bap_cr;
// Set header fields
bap_cr.oct1 = 0;
bap_cr.oct1 |= (PDU_Type << 3);
// DC=0, PDU Type=0101
printf("Oct 1 0x%x\n", bap_cr.oct1);
unsigned char controlPDU[1];
memcpy(&controlPDU[0], (unsigned char *) &bap_cr, sizeof(bap_cr));
// Print assembled PDU
for(int i=0; i<6; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= bap_cr.oct1;
return octets;
}
uint64_t main(int argc, char *argv[]){
int i;
if (argc != 1) {
printf("Please pass in exactly two arguments\n");
return 1;
}
uint64_t octets = bap_control_recov_func();
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,107 @@
/*! \file bap_cpdu.c
* \brief BAP Control PDU per RLC channel
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// BAP header
struct bap_control {
unsigned char oct1;
unsigned char oct2;
unsigned char oct3;
unsigned char oct4;
unsigned char oct5;
unsigned char oct6;
};
uint64_t bap_control_func(unsigned short bh_rlc_ch_id, unsigned int avail_buffer_size) {
struct bap_control bapc;
// Set header fields
bapc.oct1 = 0;
printf("Oct 1 0x%x\n", bapc.oct1);
bapc.oct2 = (bh_rlc_ch_id >> 8) & 0xFF;
bapc.oct3 = (bh_rlc_ch_id) & 0xFF;
printf("Oct 2 0x%X\n", bapc.oct2);
printf("Oct 3 0x%X\n", bapc.oct3);
bapc.oct4 = (avail_buffer_size >> 16) & 0xFF;
bapc.oct5 = (avail_buffer_size >> 8) & 0xFF;
bapc.oct6 = (avail_buffer_size) & 0xFF;
printf("Oct 4 0x%X\n", bapc.oct4);
printf("Oct 5 0x%X\n", bapc.oct5);
printf("Oct 6 0x%X\n", bapc.oct6);
unsigned char controlPDU[6];
memcpy(&controlPDU[0], (unsigned char *) &bapc, sizeof(bapc));
// Print assembled PDU
for(int i=0; i<6; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= ((uint64_t)bapc.oct6 << 40);
octets |= ((uint64_t)bapc.oct5 << 32);
octets |= ((uint64_t)bapc.oct4 << 24);
octets |= ((uint64_t)bapc.oct3 << 16);
octets |= ((uint64_t)bapc.oct2 << 8);
octets |= bapc.oct1;
return octets;
}
uint64_t main(int argc, char *argv[]){
int i;
if (argc != 3) {
printf("Please pass in exactly two arguments\n");
return 1;
}
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
short bh_rlc_ch_id = (short)strtol(argv[1], NULL, 16);
int avail_buffer_size = (int)strtol(argv[2], NULL, 16);
printf("bh_rlc_ch_id: %d\n", bh_rlc_ch_id);
printf("avail_buffer_size: %d\n", avail_buffer_size);
if (bh_rlc_ch_id < 0 || bh_rlc_ch_id > 0xFFFF || avail_buffer_size < 0 || avail_buffer_size > 0xFFFFFF) {
printf("ERROR: One or both inputted values is out of range.\n");
return -1;
}
uint64_t octets = bap_control_func(bh_rlc_ch_id, avail_buffer_size);
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,116 @@
/*! \file bap_cpdu_routing.c
* \brief BAP Control PDU per BAP Routing ID
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <stdio.h>
#include <stdint.h>
// BAP header
struct bap_control {
unsigned char oct1;
unsigned char oct2;
unsigned char oct3;
unsigned char oct4;
unsigned char oct5;
unsigned char oct6;
unsigned char oct7;
};
unsigned char PDU_Type = 0b0001;
uint64_t bap_control_routing_func(unsigned int bap_routing_id, unsigned int avail_buffer_size) {
struct bap_control bapc;
// Set header fields
bapc.oct1 = 0;
bapc.oct1 |= (PDU_Type << 3);
// bapc.oct1 = 0x01; // DC=0, PDU Type=0001
printf("Oct 1 0x%X\n", bapc.oct1);
bapc.oct2 = (bap_routing_id >> 12) & 0xFF;
bapc.oct3 = (bap_routing_id >> 4) & 0xFF;
//Takes into account the 4 reserved bits
bapc.oct4 = (bap_routing_id) & 0xF;
bapc.oct4 = (bapc.oct4 << 4) & 0xF0;
printf("Oct 2 0x%X\n", bapc.oct2);
printf("Oct 3 0x%X\n", bapc.oct3);
printf("Oct 4 0x%X\n", bapc.oct4);
bapc.oct5 = (avail_buffer_size >> 16) & 0xFF;
bapc.oct6 = (avail_buffer_size >> 8) & 0xFF;
bapc.oct7 = (avail_buffer_size) & 0xFF;
printf("Oct 5 0x%X\n", bapc.oct5);
printf("Oct 6 0x%X\n", bapc.oct6);
printf("Oct 7 0x%X\n", bapc.oct7);
unsigned char controlPDU[7];
memcpy(&controlPDU[0], (unsigned char *) &bapc, sizeof(bapc));
// Print assembled PDU
for(int i=0; i<7; i++) {
printf("%02X ", controlPDU[i]);
}
printf("\n");
uint64_t octets = 0;
octets |= ((uint64_t)bapc.oct7 << 56);
octets |= ((uint64_t)bapc.oct6 << 48);
octets |= ((uint64_t)bapc.oct5 << 40);
octets |= ((uint64_t)bapc.oct4 << 32);
octets |= ((uint64_t)bapc.oct3 << 24);
octets |= ((uint64_t)bapc.oct2 << 16);
octets |= ((uint64_t)bapc.oct1 << 8);
return octets;
}
uint64_t main(int argc, char *argv[]){
int i;
if (argc != 3) {
printf("Please pass in exactly two arguments\n");
return 1;
}
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
int bap_routing_id = (int)strtol(argv[1], NULL, 16);;
int avail_buffer_size = (int)strtol(argv[2], NULL, 16);
printf("bap_routing_id: %d\n", bap_routing_id);
printf("avail_buffer_size: %d\n", avail_buffer_size);
if (bap_routing_id < 0 || bap_routing_id > 0xFFFFF || avail_buffer_size < 0 || avail_buffer_size > 0xFFFFFF) {
printf("ERROR: One or both inputted values is out of range.\n");
return -1;
}
uint64_t octets = bap_control_routing_func(bap_routing_id, avail_buffer_size);
printf("Octets: 0x%llX\n", octets);
return octets;
}

View File

@@ -0,0 +1,163 @@
/*! \file bap_pdu.c
* \brief BAP PDU
* \author Surajit Dey, Danny Nsouli, Michael Bundas
* \date NOV 2023
* \version 1.0
* \company MITRE
* \email: sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*
* NOTICE
*
* This software was produced for the U. S. Government
* under Basic Contract No. W56KGU-18-D-0004, and is
* subject to the Rights in Noncommercial Computer Software
* and Noncommercial Computer Software Documentation
* Clause 252.227-7014 (FEB 2014)
*
* (C) 2024 The MITRE Corporation.
*/
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
/****************************************
ipv4 packet structure
****************************************/
struct ipv4_packet {
struct iphdr iph;
struct tcphdr tcph;
void *data;
};
/****************************************
BAP Data PDU
****************************************/
struct bap_data
{
unsigned char oct1;
unsigned char oct2;
unsigned char oct3;
// void *data;
};
int bap_pdu_func(unsigned short dest, unsigned short path) {
struct bap_data bapd;
unsigned short dest_high, dest_low;
unsigned char dest_high_char, dest_low_char;
unsigned short path_high, path_low;
unsigned char path_high_char, path_low_char;
unsigned char packet[2048];
char buffer[1024] = "ABCDEFGH";
int i, len=8;
unsigned char* cp;
unsigned char bapx[3];
/* Prepare BAP header */
/* 1st octet */
bapd.oct1 = 0;
bapd.oct1 |= 0x80; /* D/C bit 7=1 for data, 3 R bits 4-6 = 0 */
dest_high = dest & 0x03C0; /* bits 6-9 of destination=dest high */
dest_high = dest_high >> 6;
dest_high_char = (unsigned char) dest_high;
bapd.oct1 |= (dest_high_char & 0x0F); /* bits 0-3 of oct 1 = dest high */
printf("Oct 1 0x%x\n", bapd.oct1);
/* 2nd octet */
bapd.oct2 = 0;
dest_low = dest & 0x003F; /* bits 0-5 of destination=dest low */
dest_low = dest_low << 2;
dest_low_char = (unsigned char) dest_low;
bapd.oct2 |= (dest_low_char & 0xFC); /* bits 2-7 of oct 2 = dest low */
path_high = path & 0x0300; /* bits 8,9 of path = path high */
path_high = path_high >> 8;
path_high_char = (unsigned char) path_high;
bapd.oct2 |= (path_high_char & 0x03); /* bits 0-1 of oct 2 = path high */
printf("Oct 2 0x%x\n", bapd.oct2);
/* 3rd octet */
path_low = path & 0x00FF; /* bits 0-7 of oct 3 = path low */
path_low_char = (unsigned char) path_low;
bapd.oct3 = path_low_char;
printf("Oct 3 0x%x\n", bapd.oct3);
/*Assemble packet*/
memcpy(&packet[0], (unsigned char *) &bapd, sizeof(bapd));
printf("Packet 1 BAP hdr len=%d\n", sizeof(bapd));
cp = &packet[0];
for ( ; *cp != '\0'; ++cp )
{
printf("%x", *cp);
}
memcpy(packet + sizeof(bapd), buffer, len);
printf("\nPacket 2 BAP hdr + data len=%d\n", (sizeof(bapd)+len));
cp = &packet[0];
for ( ; *cp != '\0'; ++cp )
{
printf("%x", *cp);
}
printf("\n");
int octets = 0;
octets = (bapd.oct3 << 16) | (bapd.oct2 << 8) | bapd.oct1;
return octets;
}
int main (int argc, char *argv[] ) {
int i;
if (argc != 3) {
printf("Please pass in exactly two arguments\n");
return 1;
}
printf("The following arguments were passed to main(): ");
for(i=1; i<argc; i++) printf("%s ", argv[i]);
printf("\n");
short dest = (short)strtol(argv[1], NULL, 16);;
short path = (short)strtol(argv[2], NULL, 16);
printf("dest: %d\n", dest);
printf("path: %d\n", path);
if (dest < 0 || dest > 0x03FF || path < 0 || path > 0x03FF) {
printf("ERROR: One or both inputted values is out of range.\n");
return -1;
}
int octets = bap_pdu_func(dest, path);
printf("Octets: 0x%x\n", octets);;
return octets;
}

View File

@@ -18,7 +18,13 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
* Modified by Surajit Dey, Danny Nsouli, Michael Bundas
* MITRE Corporation
* Add BAP layer code
* November 2023
* sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
@@ -118,6 +124,10 @@ static void *rlc_data_req_thread(void *_)
i = q.start;
if (pthread_mutex_unlock(&q.m) != 0) abort();
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0) {
LOG_I(PDCP, "BAP rlc_data_req_thread: count %d len %d\n", i, q.q[i].sdu_sizeP);
}
rlc_data_req(&q.q[i].ctxt_pP,
q.q[i].srb_flagP,
q.q[i].MBMS_flagP,
@@ -276,7 +286,14 @@ static void do_pdcp_data_ind(
}
if (rb != NULL) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
// Remove BAP data PDU header - 3 bytes if it matches known pattern 1st octet=0x8e, 3rd octet=0xcd
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0 &&
*(sdu_buffer->data+sdu_buffer_size-3) == 0x8e && *(sdu_buffer->data+sdu_buffer_size-1) == 0xcd) {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size-3);
}
else {
rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size);
}
} else {
LOG_E(PDCP, "%s:%d:%s: no RB found (rb_id %ld, srb_flag %d)\n",
__FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP);
@@ -284,6 +301,11 @@ static void do_pdcp_data_ind(
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0 &&
*(sdu_buffer->data+sdu_buffer_size-3) == 0x8e && *(sdu_buffer->data+sdu_buffer_size-1) == 0xcd) {
LOG_I(PDCP, "BAP PDU rcvd at PDCP, removing BAP hdr\n");
}
free_mem_block(sdu_buffer, __FUNCTION__);
}
@@ -299,6 +321,10 @@ static void *pdcp_data_ind_thread(void *_)
i = pq.start;
if (pthread_mutex_unlock(&pq.m) != 0) abort();
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0) {
LOG_I(PDCP, "BAP pdcp_data_ind_thread count %d len %d\n", i, pq.q[i].sdu_buffer_size);
}
do_pdcp_data_ind(&pq.q[i].ctxt_pP,
pq.q[i].srb_flagP,
pq.q[i].MBMS_flagP,
@@ -623,6 +649,51 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
return pdcp_optmask ;
}
// Function to construct BAP data PDU header
// Inputs: BAP data PDU destination (10 bits) and path (10 bits)
// Output: BAP data PDU header (lower 3 bytes)
int bap_pdu_func(unsigned short dest, unsigned short path)
{
struct bap_data bapd;
unsigned short dest_high, dest_low;
unsigned char dest_high_char, dest_low_char;
unsigned short path_high, path_low;
unsigned char path_high_char, path_low_char;
/* Prepare BAP data PDU header */
/* 1st octet */
bapd.oct1 = 0;
bapd.oct1 |= 0x80; /* D/C bit 7=1 for data, 3 R bits 4-6 = 0 */
dest_high = dest & 0x03C0; /* bits 6-9 of destination=dest high */
dest_high = dest_high >> 6;
dest_high_char = (unsigned char) dest_high;
bapd.oct1 |= (dest_high_char & 0x0F); /* bits 0-3 of oct 1 = dest high */
/* 2nd octet */
bapd.oct2 = 0;
dest_low = dest & 0x003F; /* bits 0-5 of destination=dest low */
dest_low = dest_low << 2;
dest_low_char = (unsigned char) dest_low;
bapd.oct2 |= (dest_low_char & 0xFC); /* bits 2-7 of oct 2 = dest low */
path_high = path & 0x0300; /* bits 8,9 of path = path high */
path_high = path_high >> 8;
path_high_char = (unsigned char) path_high;
bapd.oct2 |= (path_high_char & 0x03); /* bits 0-1 of oct 2 = path high */
/* 3rd octet */
path_low = path & 0x00FF; /* bits 0-7 of oct 3 = path low */
path_low_char = (unsigned char) path_low;
bapd.oct3 = path_low_char;
// Copy 3 octets in lower 3 bytes of the (int) octets
int octets = 0;
octets = (bapd.oct3 << 16) | (bapd.oct2 << 8) | bapd.oct1;
return octets;
}
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size)
{
@@ -656,6 +727,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
char *buf, int size, int sdu_id)
{
struct bap_data bapd;
unsigned short dest;
unsigned short path;
int octets;
DevAssert(deliver_pdu_data == NULL);
protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id };
@@ -679,6 +754,52 @@ static void deliver_pdu_drb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
__func__, rb_id, size);
extern instance_t CUuniqInstance;
itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p);
}
else if (node_type == -1) { // UE
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0)
{
// Add BAP data pdu here for IAB-MT data plane Tx side.
// BAP data pdu: hdr 3 octets, data variable.
// BAP hdr = 0x8eafcd
//bapd.oct1=0x8e; // dest=0x03AB, path=0x03CD
//bapd.oct2=0xaf;
//bapd.oct3=0xcd;
dest = 0x03AB;
path = 0x03CD;
octets = bap_pdu_func(dest, path);
bapd.oct1 = octets & 0xFF;
bapd.oct2 = (octets >> 8) & 0xFF;
bapd.oct3 = (octets >> 16) & 0xFF;
mem_block_t *memblock = get_free_mem_block(size+3, __FUNCTION__);
memcpy(memblock->data, buf, size);
memcpy(memblock->data+size, (unsigned char *) &bapd, sizeof(bapd));
LOG_I(PDCP, "BAP UE %s(): (drb %d) calling rlc_data_req size %d bap2 hdr %x\n", __func__, rb_id, size, bapd.oct2);
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size+3, memblock);
}
}
else { // DU
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0)
{
// Add BAP data pdu here for IAB-DU data plane Tx side.
//bapd.oct1=0x8e; // dest=0x03AA, path=0x03CD
//bapd.oct2=0xab; // Note: path same as UE/IAB-MT
//bapd.oct3=0xcd;
dest = 0x03AA;
path = 0x03CD;
octets = bap_pdu_func(dest, path);
bapd.oct1 = octets & 0xFF;
bapd.oct2 = (octets >> 8) & 0xFF;
bapd.oct3 = (octets >> 16) & 0xFF;
mem_block_t *memblock = get_free_mem_block(size+3, __FUNCTION__);
memcpy(memblock->data, buf, size);
memcpy(memblock->data+size, (unsigned char *) &bapd, sizeof(bapd));
LOG_I(PDCP, "BAP DU %s(): (drb %d) calling rlc_data_req size %d bap2 hdr %x\n", __func__, rb_id, size, bapd.oct2);
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size+3, memblock);
}
} else {
mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
@@ -711,6 +832,16 @@ srb_found:
MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE);
AssertFatal(message_p != NULL, "OUT OF MEMORY\n");
f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p);
// Code to remove BAP data PDU header in control plane of gNB Rx side
// if it matches known pattern - 1st octet=0x8e, 3rd octet=0xcd
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0) {
if(*(buf+size-3) == 0x8e && *(buf+size-1) == 0xcd) {
LOG_I(PDCP, "gNB BAP PDU rcvd at PDCP, removing BAP hdr\n");
size -= 3;
}
}
ul_rrc->rnti = ue->rntiMaybeUEid;
ul_rrc->srb_id = srb_id;
ul_rrc->rrc_container = malloc(size);
@@ -719,6 +850,14 @@ srb_found:
ul_rrc->rrc_container_length = size;
itti_send_msg_to_task(TASK_RRC_GNB, 0, message_p);
} else {
// Code to remove BAP data PDU header in control plane of UE Rx side
// if it matches known pattern - 1st octet=0x8e, 3rd octet=0xcd
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0) {
if(*(buf+size-3) == 0x8e && *(buf+size-1) == 0xcd) {
LOG_I(PDCP, "UE BAP PDU rcvd at PDCP, removing BAP hdr\n");
size -= 3;
}
}
uint8_t *rrc_buffer_p = itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size);
AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY\n");
memcpy(rrc_buffer_p, buf, size);
@@ -735,10 +874,40 @@ srb_found:
void deliver_pdu_srb_rlc(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,
char *buf, int size, int sdu_id)
{
struct bap_data bapd;
unsigned short dest;
unsigned short path;
int octets;
protocol_ctxt_t ctxt = { .enb_flag = 1, .rntiMaybeUEid = ue_id };
mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
// Add BAP data PDU header in control plane - Tx side
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0)
{
if (node_type == -1) { // UE
dest = 0x03AB;
}
else // gNB
{
dest = 0x03AA;
}
path = 0x03CD;
octets = bap_pdu_func(dest, path);
bapd.oct1 = octets & 0xFF;
bapd.oct2 = (octets >> 8) & 0xFF;
bapd.oct3 = (octets >> 16) & 0xFF;
LOG_I(PDCP, "BAP node %d %s(): (srb %d) size %d bap2 hdr %x\n", node_type, __func__, srb_id, size, bapd.oct2);
mem_block_t *memblock = get_free_mem_block(size+3, __FUNCTION__);
memcpy(memblock->data, buf, size);
memcpy(memblock->data+size, (unsigned char *) &bapd, sizeof(bapd));
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size+3, memblock);
}
else {
mem_block_t *memblock = get_free_mem_block(size, __FUNCTION__);
memcpy(memblock->data, buf, size);
enqueue_rlc_data_req(&ctxt, 1, MBMS_FLAG_NO, srb_id, sdu_id, 0, size, memblock);
}
}
void deliver_pdu_srb_f1(void *deliver_pdu_data, ue_id_t ue_id, int srb_id,

View File

@@ -18,6 +18,13 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
* Modified by Surajit Dey, Danny Nsouli, Michael Bundas
* MITRE Corporation
* Add BAP layer code
* November 2023
* sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
*/
#ifndef NR_PDCP_OAI_API_H
#define NR_PDCP_OAI_API_H
@@ -108,4 +115,14 @@ nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager();
const bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out);
struct bap_data
{
unsigned char oct1;
unsigned char oct2;
unsigned char oct3;
// void *data;
};
int bap_pdu_func(unsigned short dest, unsigned short path);
#endif /* NR_PDCP_OAI_API_H */

View File

@@ -27,6 +27,14 @@
* \company Eurecom, NTUST
* \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr, kroempa@gmail.com
*/
/*
31 * Modified by Surajit Dey, Danny Nsouli, Michael Bundas
32 * MITRE Corporation
33 * Add BAP layer code
34 * November 2023
35 * sdey@mitre.org, dnsouli@mitre.org, mbundas@mitre.org
36 */
#define RRC_GNB_C
#define RRC_GNB_C
@@ -122,10 +130,44 @@ bool DURecvCb(protocol_ctxt_t *ctxt_pP,
const pdcp_transmission_mode_t modeP,
const uint32_t *sourceL2Id,
const uint32_t *destinationL2Id) {
struct bap_data bapd;
unsigned short dest;
unsigned short path;
int octets;
ngran_node_t node_type = get_node_type();
// Add BAP header (3 bytes)
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0)
{
if (node_type == -1) { // UE
dest = 0x03AB;
}
else // gNB
{
dest = 0x03AA;
}
path = 0x03CD;
octets = bap_pdu_func(dest, path);
bapd.oct1 = octets & 0xFF;
bapd.oct2 = (octets >> 8) & 0xFF;
bapd.oct3 = (octets >> 16) & 0xFF;
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP+3, __func__);
memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP);
memcpy(sdu->data+sdu_buffer_sizeP, (unsigned char *) &bapd, sizeof(bapd));
du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP,muiP, confirmP, sdu_buffer_sizeP+3, sdu);
LOG_I(NR_RRC, "BAP node %d %s(): (srb %d) size %d bap2 hdr %x\n", node_type, __func__, rb_idP, sdu_buffer_sizeP, bapd.oct2);
}
else {
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__);
memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP);
du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP,muiP, confirmP, sdu_buffer_sizeP, sdu);
}
return true;
}
@@ -2535,6 +2577,10 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
uint32_t incoming_teid = 0;
struct bap_data bapd;
unsigned short dest;
unsigned short path;
int octets;
if(req->cu_to_du_rrc_information!=NULL){
if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){
@@ -2686,11 +2732,41 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_
fill_mastercellGroupConfig(cellGroupConfig, UE->masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
apply_macrlc_config(rrc, ue_context_p, &ctxt);
ngran_node_t node_type = get_node_type();
mem_block_t *pdcp_pdu_p;
if(req->rrc_container_length > 0){
mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__);
// Add BAP header (3 bytes)
if (getenv("BAP") != NULL && strcmp(getenv("BAP"),"yes") == 0)
{
if (node_type == -1) { // UE
dest = 0x03AB;
}
else // gNB
{
dest = 0x03AA;
}
path = 0x03CD;
octets = bap_pdu_func(dest, path);
bapd.oct1 = octets & 0xFF;
bapd.oct2 = (octets >> 8) & 0xFF;
bapd.oct3 = (octets >> 16) & 0xFF;
pdcp_pdu_p = get_free_mem_block(req->rrc_container_length+3, __func__);
memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length);
memcpy(&pdcp_pdu_p->data[0]+req->rrc_container_length, (unsigned char *) &bapd, sizeof(bapd));
du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length+3, pdcp_pdu_p);
LOG_I(NR_RRC, "BAP node %d %s(): size %d bap2 hdr %x\n", node_type, __func__, req->rrc_container_length, bapd.oct2);
}
else {
*pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__);
memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length);
du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p);
}
LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n");
for (int j=0; j<req->rrc_container_length; j++){
printf("%02x ", pdcp_pdu_p->data[j]);