:::success List the essential information of this chapter. 1. Introduction 2. Build 3. Deployment 4. Testing and Validation ::: --- ### 1. Introduction The following is a diagram of the 5G end-to-end OAI used in this chapter : ![image](https://hackmd.io/_uploads/BkxchyKdT.png) This guide will walk you through the process of build the OAI 5G component and deploy them to form an end-to-end to 5G network. ### 2. Build #### 2.1 Setup Environment ##### 2.1.1 Operating System This is my operating system that i used in this experiment. I used neofetch to see the details of the OS. ![image](https://hackmd.io/_uploads/HJlg85su6.png) ##### 2.1.2 5G Core Network I use the existing open5Gs core network and still active for this end-to-end setup so i cannot build and deploy again from start, with the neccessary parameters are as the following: * AMF Controplane listened on IP `10.30.1.110/24` port `38412` * UPF Userplane listened on IP `10.30.1.110/24` port `2152` * UPF subscribe subnet of `10.45.0.0/16` * Registered PLMN `20899` * The UE simulator IMSI, KI, and OPC registered on the HSS if you want to deploy Open5Gs core network from scratch, you can follow this instructions [Deploy open5Gs core network](https://open5gs.org/open5gs/docs/guide/01-quickstart/). #### 2.2 Build OAI from Source Code 1. Clone Openairinterface5g ``` sudo apt install git cmake build-essentials # Fetch the OpenAirInterface source code git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ``` 2. Build the source code from what you clone ``` cd openairinterface5g # Initialize the necessary environment variables source oaienv cd cmake_targets/ ./build_oai -I --gNB --nrUE -w SIMU ``` 3. Check the compiled binary ``` # Make sure the binaries are exist at ran_build ls ran_build/build/ ``` ![image](https://hackmd.io/_uploads/H14Tj9jO6.png) i use branch 2023.w43 ```= git branch ``` ![image](https://hackmd.io/_uploads/S1Os60-nT.png) ### 3. Deployment Deploy and integrate the RAN components to form an end-to-end 5G. #### 3.1 Setup Environment ##### 3.1.1 CU | Purpose | Interface| IP | Port| | -------- | -------- | -------- |-----| | N1 & N2 | ens33 |10.30.1.85 |38472| | N3 |tun_cu-upf|192.168.34.12 |2152 | | F1 |tun_cu-du |192.168.35.12 | | ##### 3.1.2 DU & RFsim | Purpose | Interface| IP | Port| | -------- | -------- | -------- |-----| | F1 |tun_du-cu |192.168.35.13 | | | RFSIM |tun_rf-ue |192.168.35.14 | | ##### 3.1.2 UE | Purpose | Interface| IP | Port| | -------- | -------- | -------- |-----| | F1 |tun_du-cu |192.168.35.13 | | | RFSIM |tun_rf-ue |192.168.35.14 | | #### 3.2 Configuration ##### 3.2.1 CU Config ``` Active_gNBs = ("gnb-cu-01"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "info"; Num_Threads_PUSCH = 8; gNBs = ( { ////////// Identification parameters: gNB_ID = 0xe01; # cell_type = "CELL_MACRO_GNB"; gNB_name = "gnb-cu-01"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 0xa000; plmn_list = ({ mcc = 208; mnc = 95; mnc_length = 2; snssaiList = ({ sst = 222, sd = 0x7b }) }); nr_cellid = 12345678L; tr_s_preference = "f1"; local_s_if_name = "tun_cu-du"; local_s_address = "192.168.35.12"; remote_s_address = "192.168.35.13"; local_s_portc = 501; local_s_portd = 2153; remote_s_portc = 500; remote_s_portd = 2153; # ------- SCTP definitions SCTP : { # Number of streams to use in input/output SCTP_INSTREAMS = 2; SCTP_OUTSTREAMS = 2; }; ////////// AMF parameters: amf_ip_address = ( { ipv4 = "192.168.70.132"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); NETWORK_INTERFACES : { GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.1"; GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.1"; 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 ="debug"; hw_log_level ="debug"; phy_log_level ="debug"; mac_log_level ="debug"; rlc_log_level ="debug"; pdcp_log_level ="debug"; rrc_log_level ="debug"; f1ap_log_level ="debug"; ngap_log_level ="debug"; }; ``` ##### 3.2.2 DU Config ``` Active_gNBs = ( "gnb-du-02"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; gNBs = ( { ////////// Identification parameters: gNB_ID = 0xe02; # cell_type = "CELL_MACRO_GNB"; gNB_name = "gnb-du-02"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 0xa000; plmn_list = ({ mcc = 208; mnc = 95; mnc_length = 2; snssaiList = ({ sst = 222, sd = 0x7b }) }); 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 = "tun_du-cu"; local_n_address = "192.168.35.13"; remote_n_address = "192.168.35.12"; local_n_portc = 500; local_n_portd = 2153; remote_n_portc = 501; remote_n_portd = 2153; 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 ="debug"; f1ap_log_level ="debug"; ngap_log_level ="debug"; }; ``` ### 4. Testing and Validation #### 1. Run gNB-CU ``` sudo ~/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem -O ./gnb.cu.conf --sa --rfsim --log_config.global_log_options level,nocolor,time ``` The flags that i used is : | Arguments | Remarks | | -------- | ---------------------- | | --rfsim | Use simulated RF Logic | | --sa | Run as Standalone mode | |--log_config| Control the log shown by CU| #### 2. Run gNB-DU & rfSIM ``` sudo ~/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem -O ./gnb.du.conf --sa --rfsim --log_config.global_log_options level,nocolor,time ``` | Arguments | Remarks | | -------- | ---------------------- | | --rfsim | Use simulated RF Logic | | --sa | Run as Standalone mode | |--log_config| Control the log shown by DU| #### 3. Run gNB-UE ``` sudo ~/openairinterface5g/cmake_targets/ran_build/build/nr-uesoftmodem -O etc/nr-ue.conf --sa --rfsim -r 106 --numerology 1 -C 3619200000 --nokrnmod --log_config.global_log_options level nocolor time ``` | Arguments | Remarks | | -------- | ---------------------- | | --rfsim | Use simulated RF Logic | | --sa | Run as Standalone mode | |--log_config| Control the log shown by UE| Testing the RAN connection of signaling and userplane. ![image](https://hackmd.io/_uploads/r1eQSQT_T.png) #### 4.1 Control Plane ##### 4.1.1 Backhaul (NGAP) 1. SCTP Socket: ![image](https://hackmd.io/_uploads/HkVpLPRO6.png) 2. Wireshark ![image](https://hackmd.io/_uploads/HJMXCLMFa.png) ##### 4.1.2 Midhaul (F1AP) 1. SCTP Socket: ![image](https://hackmd.io/_uploads/HkVpLPRO6.png) ##### 4.1.3 Fronthaul This build use simulator mode of the oai/openairinterface5g so one way to make sure that the fronthaul setup is correct is to check the port 4043 is on the LISTEN state and will be used by UE to connect into the gNB. ![image](https://hackmd.io/_uploads/ryYVwwAO6.png) his parameter is configured under the follwing section on `gNB.du.conf`. ``` #... rfsimulator: { serveraddr = "server"; serverport = "4043"; options = (); #("saviq"); or/and "chanmod" modelname = "AWGN"; IQfile = "/tmp/rfsimulator.iqs" } #... ``` ##### 4.1.4 Air Interface ![image](https://hackmd.io/_uploads/HJMjww0O6.png) The air interface connection between UE and RFsim is emulated through tcp socket, that’s why you will have an established tcp connection between the nr-softmodem and nr-uesoftmodem if your RFsim is connected properly with the UEsim. 1. TCP Socket ![image](https://hackmd.io/_uploads/BJM5ywGY6.png) The air interface connection between UE and RFsim is emulated through tcp socket, that’s why you will have an established tcp connection between the nr-softmodem and nr-uesoftmodem if your RFsim is connected properly with the UEsim. 2. UE Attach Request & Response ![image](https://hackmd.io/_uploads/rJo6yPMFT.png) 3. nr-softmodem ![image](https://hackmd.io/_uploads/SJ2ONDGtp.png) #### 4.2 Dataplane ##### 4.2.1 RFsim ![image](https://hackmd.io/_uploads/BJ94_PCda.png) ##### 4.2.2 PDU Session ![image](https://hackmd.io/_uploads/SkyhaIzY6.png) A success attach procedure should shows that the core network successfully finished the UEContextSetupRequest from UE and give UE dataplane IP. ##### 4.2.3 GTP Tunnel Ping test from UE simulator to UPF node through GTP Tunnel. ![image](https://hackmd.io/_uploads/Sk_UaIzY6.png) Captured gtp traffic ![image](https://hackmd.io/_uploads/H1JFaUMYp.png)