Kubernetes, Near RT-RIC, 5G core, and UE configuration

Infrastructure

The entire O-RAN/AI-RAN testbed is deployed on two high-performance Ubuntu-based infrastructure, providing a stable and scalable foundation for Kubernetes, O-RAN services, and RAN experimentation.

  • Host OS: Ubuntu 24.04.3 LTS (x86_64)
  • CPU: AMD Ryzen 9 9950X3D (32 threads, high clock performance)
  • Memory: 64 GB RAM
  • GPU: NVIDIA RTX 5070ti
  • USRPs: 1x x410, 1x x310, multiple B210
  • Software: OCUDU, srsGUI, srsRAN_4G

We have prepared our forked repositories improving on some of the features for more plottings suitable for ISAC research

Installation

git clone https://github.com/WINGS-UHM/O-RAN.git
cd O-RAN/NearRT-RIC

The following scripts are prepared for installing kubespray and docker based kubernetes cluster for deploying the Near RT-RIC

NEAR-RT-RIC/
├── nginx.sh                            # setup nginx service for hosting dashboards (grafana, kubernetes)
├── kubespray.sh                        # setup a single node kubspray cluster with calico and metallb
├── kube-extra.sh                       # extra setups for setting up dashboard and nfs volumes for influxdb
├── fix-dns.sh                          # fixes dns/internet disconnection if setup breaks nameserver 
├── get-env.sh                          # helper funtion to export import ric-plt ips
└── install_common_templates_to_helm.sh # Modified common templates script to remove root access dependency

NGINX Setup

nginx.sh sets up a installs NGINX and configures a simple reverse proxy with basic authentication to securely expose the Kubernetes dashboard proxy running on the local machine.

The proxy forwards requests from a public port to the local kubectl proxy service. The script uses a default username and password for convenience in closed lab environments. Users may change these credentials if the service is exposed outside the local network.

sudo htpasswd -cb /etc/nginx/htpasswd admin admin123

Kubernetes Cluster Deployment

kubespray.sh script deploys a single-node Kubernetes cluster using Kubespray, with the following components enabled:

  • Calico – Kubernetes networking (CNI)
  • MetalLB – LoadBalancer support for bare-metal environments
  • Helm – Kubernetes package manager
  • Metrics Server – basic cluster metrics

Users Should modify following parameters according to their environment.

  • Add your local Node IP Address in
     NODE_IP="${NODE_IP:-192.168.50.103}"
    
  • Change Ansible username to the username of host pc
     ANSIBLE_USER="${ANSIBLE_USER:-admin}" 
    

    Replace admin with the username of the host machine that will run the deployment.

  • Network Interface for Calico
     CALICO_IFACE="${CALICO_IFACE:-eno1}" 
    

    Interface name should be your internet interface name usually eno1/eth0

  • Metallb IP Pool

    This IP range should be removed from the router’s DHCP allocation to prevent conflicts with other devices on the network. MetalLB assigns addresses from this range to Kubernetes services.

     METALLB_POOL="${METALLB_POOL:-192.168.50.245-192.168.50.246}"
    

Additional Kubernetes Services

kube-extra.sh script installs additional services on top of the Kubernetes cluster, including:

  • a local kubectl proxy system service for dashboard access
  • an admin service account and login token
  • an exported kubeconfig file
  • an optional local Docker registry
  • an optional NFS dynamic storage provisioner
  • the Headlamp Kubernetes UI

Users should modify the following parameters according to their environment.

  • Local Docker registry

    Leave this enabled only if a local registry is required for storing xApp images. If a registry already exists in the environment, this can be disabled.

     DO_LOCAL_REGISTRY="${DO_LOCAL_REGISTRY:-1}"
     REGISTRY_BIND_IP="${REGISTRY_BIND_IP:-127.0.0.1}"
     REGISTRY_PORT="${REGISTRY_PORT:-5000}"
    

    If registry access is needed from other machines, replace 127.0.0.1 with the host machine IP.

  • NFS Provisioner

    Certain ORAN RIC services require persistent NFS storage access if the system already has a NFS provisoner this can be disabled.

     DO_NFS_PROVISIONER="${DO_NFS_PROVISIONER:-1}"
     NFS_SERVER_IP="${NFS_SERVER_IP:-192.168.50.103}"
     NFS_EXPORT_PATH="${NFS_EXPORT_PATH:-/export/k8s}"
     NFS_MOUNT_OPTIONS="${NFS_MOUNT_OPTIONS:-nfsvers=3}"
    

    If left enabled

    • Set NFS_SERVER_IP to the IP of the Host Machine.

    • Set NFS_EXPORT_PATH to the exported NFS directory.

Installation

After making the modifications, run the scripts in the following order.

sudo chmod +x *.sh
./nginx.sh
./kubespray.sh
./kube-extra.sh

Do not run the scripts as sudo or root.

The scripts internally use sudo only where required. Running them as root may break permissions and prevent access for the normal user.

Headlamp Access Service

To make the Headlamp Kubernetes UI automatically accessible from the host machine, a systemd service is used to maintain a persistent port-forward to the Headlamp service.

This avoids manually running kubectl port-forward after every reboot.

Create the Headlamp systemd service

Create the service file

sudo tee /etc/systemd/system/headlamp-portforward.service > /dev/null << 'EOF'
[Unit]
Description=Start Headlamp Dashboard on reboots
After=network-online.target kubelet.service
Wants=network-online.target kubelet.service

[Service]
Type=simple
User=admin
Environment=HOME=/home/admin
Environment=KUBECONFIG=/home/admin/.kube/config
Environment=PATH=/snap/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/local/bin/kubectl -n headlamp port-forward svc/headlamp 8080:80
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Update system paths as needed. Replace the username admin with your own username and adjust any installation paths if they differ on your system

Enable and start the service

sudo systemctl daemon-reload
sudo systemctl enable headlamp-portforward.service
sudo systemctl start headlamp-portforward.service

Verify status

systemctl status headlamp-portforward.service

Headlamp-Status

Helper command to get login token

Create following script

sudo tee /usr/local/bin/get-headlamp > /dev/null << 'EOF'
#!/usr/bin/env bash

TOKEN_FILE="$HOME/k8s-extra/admin-token.txt"

if ! systemctl is-active --quiet headlamp-portforward; then
    echo "Headlamp service is not running."
    exit 1
fi

if [ ! -f "$TOKEN_FILE" ]; then
    echo "Token file not found at $TOKEN_FILE"
    exit 1
fi

TOKEN=$(cat "$TOKEN_FILE")

echo "Dashboard running at http://localhost:8080"
echo "Login token = $TOKEN"
EOF

sudo chmod +x /usr/local/bin/get-headlamp # Make it executable

The dashboard will be hosted at localhost:8080. Use the login token from

$ get-headlamp

Headlamp-Token

Near RT-RIC deployment

The Near RT-RIC services can be downloaded from the original ric-dep. The original repo assumes root user behaviour for install_common_templates_to_helm.sh script, for a general deployment we have edited it and added sudo command for some of the copy commands you can replace the script with our script for deployment.

git clone https://gerrit.o-ran-sc.org/r/ric-plt/ric-dep
cp ./install_common_templates_to_helm.sh ./ric-dep/bin
cd ric-dep/bin
./install_common_templates_to_helm.sh
version=j   # change variable according to release preference.
./install -f ../RECIPE_EXAMPLE/example_recipe_oran_${version}_release.yaml -c "influxdb jaegeradapter"

The additional flags for influxdb and jaegeradapter are only supported for h-release and later.

E2 Termination logs

To view the output of the RIC E2 termination service, to which RAN nodes connect over SCTP

  kubectl logs -f -n ricplt -l app=ricplt-e2term-alpha

To view the output of the RIC E2 manager service, which shows information about connected RAN nodes

kubectl logs -f -n ricplt -l app=ricplt-e2mgr

To view the output of the RIC subscription manager service, which aggregates xApp subscription requests and forwards them to target RAN nodes

 kubectl logs -f -n ricplt -l app=ricplt-submgr

To view the output of the RIC route manager, which manages RMR routes across the RIC components

kubectl logs -f -n ricplt -l app=ricplt-rtmgr

These logs can also be viewed over our deployed Kubernetes Cluster Dashboard.

The headlamp dashboard provides a neat visualization for deployed clusters, you further click on each namespace to see further mapping. Headlamp-Dashboard

From the dashboard page goto the Workloads tab from left pane and click on the specific service deployment you wish to view logs of as shown in image below.

Headlamp-Dashboard

OCUDU Installation

Install the required build tools

sudo apt-get install cmake make gcc g++ pkg-config libmbedtls-dev libsctp-dev libyaml-cpp-dev libgtest-dev

Install ZMQ for simulations

sudo apt-get install libzmq3-dev

Install the OCUDU using the following commands

# Install OCUDU with ZMQ-enabled
git clone https://gitlab.com/ocudu/ocudu.git
cd ocudu
mkdir build
cd build
cmake ../ -DENABLE_EXPORT=ON -DENABLE_ZEROMQ=ON 
make -j $(nproc)
make test -j $(nproc)
sudo make install

Data Plane Development Kit (DPDK) is an optional requirement useful when running 4x4 MIMO configurations or High Bandwidth Configurations. Follow the DPDK installation guide if required.

Deploying Core Network

We deploy the core network using the Docker images provided in the ocudu library from open5gs

cd ocudu/docker
docker compose -f docker-compose.yml up --build 5gc

Additionally you can also launch the grafana dashboard for metrics monitoring using

docker compose -f docker-compose.yml -f docker-compose.ui.yml up --build 5gc

The dashboard will be hosted at localhost:3300 and the WebUI with subscriber database will be at localhost:9999. New subscribers can be added before launching in the open5gs/subscriber_db.csv or from the WebUI after intiating.

Configuration setup

Several of our OTA tested configs are present in the configs folder. OCUDU supports all 3GPP Release 17 bands, the following parameters need to be changed to braodcast at a specific band.

USRP configuration

The ru_sdr block configures the SDR-based radio unit. For USRP-based deployments, OCUDU uses the UHD driver to communicate with the radio hardware. The example below uses an X300/X310-class USRP with a 30.72 MS/s sampling rate.

ru_sdr:
  device_driver: uhd
  device_args: type=x300
  clock: default           # Supported: [default, internal, external, gpsdo].
  sync: default            # Supported: [default, internal, external, gpsdo].
  srate: 30.72
  tx_gain: 25
  rx_gain: 25

The device_args field should match the connected USRP type. For example, X300/X310 radios commonly use type=x300, while other USRP platforms may require different UHD device arguments. The srate value must be compatible with the selected channel bandwidth and numerology.

The clock and sync options control the reference and timing sources used by the USRP. For a single-radio setup, the default or internal clock is usually sufficient. For multi-radio experiments, external synchronization through a 10 MHz reference and PPS source, such as an OctoClock or GPSDO, is recommended to maintain timing and frequency alignment across devices.

The tx_gain and rx_gain values may need tuning depending on the antenna, RF front-end, cable loss, and target coverage area. Very high transmit gain can cause distortion or saturation, while very low gain may result in poor UE attachment or weak received signal strength.

Cell configuration

The transmission band can be changed under the cell_cfg block. Refer to the NR band table at sqimway to verify that the selected band, ARFCN, bandwidth, and subcarrier spacing are valid for the intended deployment.

cell_cfg:
  dl_arfcn: 636666            # Required UINT, sets the Downlink ARFCN.
  band: 78                    # Optional TEXT - auto
  channel_bandwidth_MHz: 30
  common_scs: 30
  plmn: "00101"
  tac: 7
  pci: 1

The dl_arfcn determines the downlink carrier frequency, while band selects the corresponding NR operating band. The channel_bandwidth_MHz and common_scs fields define the bandwidth and numerology used by the cell. These values must be consistent with the selected NR band and supported by the SDR sampling rate.

O-RAN E2 Connection

The e2 block enables the O-RAN E2 interface between the OCUDU gNB and the near-RT RIC. This allows the gNB to expose RAN information and control interfaces to xApps running on the RIC.

e2:
  enable_du_e2: true               # Enable DU E2 agent (one for each DU instance)
  enable_cu_cp_e2: true            # Enables the CU E2 agent for CU-CP
  enable_cu_up_e2: true            # Enables the CU E2 agent for CU-UP
  e2sm_kpm_enabled: true           # Enable KPM service module
  e2sm_rc_enabled: true            # Enable RC service module
  e2sm_ccc_enabled: true           # Enable CCC service module
  addr: 192.168.50.103             # RIC IP address 
  bind_addr: 192.168.50.38         # A local IP that the E2 agent binds to for traffic from the RIC. ONLY required if running the RIC on a separate machine. 
  port: 32222                      # RIC port

The DU, CU-CP, and CU-UP E2 agents can be enabled depending on which parts of the gNB should communicate with the RIC. The DU E2 agent is commonly used for lower-layer RAN measurements and control, while the CU-CP and CU-UP agents expose control-plane and user-plane related information.

The service model options define which E2 service models are advertised to the RIC. KPM is used for key performance measurements, RC supports RAN control procedures, and CCC enables additional control-related capabilities when supported by the deployment.

The addr field should point to the near-RT RIC E2 termination IP address. The bind_addr should be set to the local interface IP of the machine running OCUDU, especially when the RIC and gNB are deployed on different hosts. The port must match the E2 termination service port exposed by the RIC. On the same host the addr and port field will be the corresponding cluster ip addresses.

Metrics and Packet monitoring

OCUDU supports runtime metrics reporting and packet capture for different protocol layers. These options are controlled directly from the gNB configuration file. To enable monitoring, set the required metric or PCAP flags to true and restart the gNB with the updated configuration.

For metrics, enable JSON reporting and select the layers that should be monitored. The remote_control block exposes the metrics service over the configured IP address and port. For example, setting bind_addr: 0.0.0.0 allows the metrics endpoint to be accessed from other machines on the same network, while port: 8001 defines the service port. This is also the endpoint used by the CN launch with the Grafana dashboard to collect and visualize OCUDU metrics.

metrics:
  autostart_stdout_metrics: false       # Optional BOOLEAN (false). Sets whether or not to autostart stdout metrics reporting. Supported [false, true].
  enable_json: false                    # Optional BOOLEAN (false). Enables JSON metrics reporting.
  enable_log: false                     # Optional BOOLEAN (false). Enables log metrics reporting.
  enable_verbose: false                 # Optional BOOLEAN (false). Enables extended detail metrics reporting.
  layers: 
    enable_app_usage: false             # Optional BOOLEAN (false). Enables application usage metrics.
    enable_ngap: false                  # Optional BOOLEAN (false). Enables NGAP metrics.
    enable_e1ap: false                  # Optional BOOLEAN (false). Enables E1AP metrics.
    enable_pdcp: false                  # Optional BOOLEAN (false). Enables PDCP metrics.
    enable_rrc: false                   # Optional BOOLEAN (false). Enables RRC metrics.
    skip_cu_up_executor: true           # Optional BOOLEAN (true). Whether to skip logging CU-UP executor metrics when executor logging is enabled application wide.
    enable_sched: true                  # Optional BOOLEAN (true). Enables DU scheduler metrics.
    enable_rlc: false                   # Optional BOOLEAN (false). Enables RLC metrics.
    enable_mac: false                   # Optional BOOLEAN (false). Enables MAC metrics.
    enable_executor: false              # Optional BOOLEAN (false). Whether to log application executors metrics.
    enable_du_low: false                # Optional BOOLEAN (false). Enables DU low metrics (upper physical layer).
    enable_ru: false                    # Optional BOOLEAN (false). Enables Radio Unit metrics.
  periodicity: 
    app_usage_report_period: 1000       # Optional UINT (1000). Application resource usage metrics report period in milliseconds.
    cu_cp_report_period: 1000           # Optional UINT (1000). CU-CP metrics report period in milliseconds.
    cu_up_report_period: 1000           # Optional UINT (1000). CU-UP metrics report period in milliseconds.
    du_report_period: 1000              # Optional UINT (1000). DU statistics report period in milliseconds. Supported: [0 - 10485760].
    executors_report_period: 1000       # Optional UINT (1000). Executors metrics report period in milliseconds. Supported: [0 - 10485760].
remote_control:
  bind_addr: 0.0.0.0
  port: 8001
  enabled: true
pcap:
  ngap_filename: /tmp/gnb_ngap.pcap         # Optional TEXT (/tmp/gnb_ngap.pcap). Path for NGAP PCAPs.
  ngap_enable: false                        # Optional BOOLEAN (false). Enable/disable NGAP packet capture. Supported: [false, true].
  n3_filename: /tmp/gnb_n3.pcap             # Optional TEXT (/tmp/gnb_n3.pcap). Path for N3 PCAPs.
  n3_enable: false                          # Optional BOOLEAN (false). Enable/disable N3 packet capture. Supported: [false, true].
  e1ap_filename: /tmp/gnb_e1ap.pcap         # Optional TEXT (/tmp/gnb_e1ap.pcap). Path for E1AP PCAPs.
  e1ap_enable: false                        # Optional BOOLEAN (false). Enable/disable E1AP packet capture. Supported: [false, true].
  e2ap_cu_cp_filename: /tmp/cu_cp_e2ap.pcap # Optional TEXT (/tmp/cu_cp_e2ap.pcap). Path for E2AP CU-CP PCAPs.
  e2ap_cu_up_filename: /tmp/cu_up_e2ap.pcap # Optional TEXT (/tmp/cu_up_e2ap.pcap). Path for E2AP CU-UP PCAPs.
  e2ap_du_filename: /tmp/du_e2ap.pcap       # Optional TEXT (/tmp/du_e2ap.pcap). Path for E2AP CU PCAPs.
  e2ap_enable: false                        # Optional BOOLEAN (false). Enable/disable E2AP packet capture. Supported: [false, true].
  f1ap_filename: /tmp/gnb_f1ap.pcap         # Optional TEXT (/tmp/gnb_f1ap.pcap). Path for F1AP PCAPs.
  f1ap_enable: false                        # Optional BOOLEAN (false). Enable/disable F1AP packet capture. Supported: [false, true].
  f1u_filename: /tmp/gnb_f1u.pcap           # Optional TEXT (/tmp/gnb_f1ap.pcap). Path for F1AP PCAPs.
  f1u_enable: false                         # Optional BOOLEAN (false). Enable/disable F1AP packet capture. Supported: [false, true].
  rlc_filename: /tmp/gnb_rlc.pcap           # Optional TEXT (tmp/gnb_rlc.pcap). Path for RLC PCAPs.
  rlc_rb_type: all                          # Optional TEXT. Sets the RLC PCAP RB type. Supported: [all, srb, drb].
  rlc_enable: false                         # Optional BOOLEAN (false). Enable/disable RLC packet capture. Supported: [false, true].
  mac_filename: /tmp/gnb_mac.pcap           # Optional TEXT (/tmp/gnb_mac.pcap). Path for MAC PCAPs.
  mac_type: udp                             # Optional TEXT (udp). Sets the MAC PCAP pcap type. Supported: [DLT or UDP].
  mac_enable: false                         # Optional BOOLEAN (false). Enable/disable MAC packet capture. Supported: [false, true].

GNB Deployment

After changing the relevant parameters execute the gNB

sudo gnb -c <path-to-your-config>
# e.g. sudo gnb -c gnb_x310_n78_TDD_30Mhz.yml

gnb-deploy

Private cellular transmissions may be regulated in your region. Use low-power indoor deployments for testing, and avoid high transmit power or outdoor operation unless authorized, as this may interfere with licensed networks.

Expert Configuration

OCUDU fills many omitted configuration parameters with built-in defaults, so most basic deployments only require the main radio, cell, core network, and E2 settings. This keeps the configuration lightweight for standard testbed bring-up.

For more advanced experiments, OCUDU also supports detailed control over scheduler behavior, slicing policies, slot allocation, TDD patterns, and other RAN parameters. These options are useful when tuning the gNB for specific traffic profiles, uplink/downlink balance, latency requirements, or controlled research experiments.

For the full list of supported parameters and default values, refer to the complete OCUDU Configuration Reference.

Under construction

Under construction

srsRAN UE

The USRP-based UE setup is included here mainly for PoC validation and initial testing. It can be useful for basic bring-up checks, RF sanity testing, and early experimentation, but it should not be treated as the preferred UE option for complete 5G SA testbed operation.

Much of the USRP UE development was originally tied to the older srsRAN 4G stack, and 5G SA support remains limited. As noted in the official OCUDU documentation, COTS UEs or commercial UE solutions such as Amarisoft are preferred for more complete and reliable 5G SA testing.

Limitations

The current srsUE implementation has several limitations when running in 5G SA mode:

  • Limited to 15 kHz subcarrier spacing, which means only FDD bands can be used.
  • Limited to 5, 10, 15, or 20 MHz channel bandwidth.
  • Handover is not supported.

Due to these constraints, the USRP-based UE path is best viewed as a lightweight experimental option, while COTS UE and Amarisoft-based setups are better suited for full testbed validation.

Installation

Install the required build dependencies:

sudo apt-get install build-essential cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev

Install srsGUI

srsGUI provides real-time channel quality visualization. The WINGS-UHM fork includes updated dependency support for the current testbed setup.

git clone https://github.com/WINGS-UHM/srsGUI.git
cd srsGUI
mkdir build
cd build
cmake ../
make 

Install srsRAN 4G

The WINGS-UHM srsRAN_4G fork is used for 5G-SA visualization support in this setup.

git clone https://github.com/WINGS-UHM/srsRAN_4G.git
cd srsRAN_4G
mkdir build
cd build
cmake ../
make
make test

Install the built binaries and generate the default user configuration files:

sudo make install
srsran_install_configs.sh user

Deploying srsUE

Due to limitations only FDD bands can be used you can download the config here.

RF configuration

Update the [rf] section to configure the USRP radio parameters according to your SDR. If an external reference is used, set the corresponding clock source in device_args.

[rf]
freq_offset = 0
tx_gain = 50
rx_gain = 40
srate = 23.04e6
nof_antennas = 1

device_name = uhd
device_args = clock=external    # Supported [default, internal, external, gpsdo]
time_adv_nsamples = auto

Disable LTE carrier

In the [rat.eutra] section, disable the LTE carrier so that the UE operates only with the 5G NR carrier.

[rat.eutra]
dl_earfcn = 2850
nof_carriers = 0

Configure NR carrier

Configure the [rat.nr] section for 5G SA operation. The NR band, ARFCN, and PRB values should match the gNB configuration.

[rat.nr]
bands = 3
nof_carriers = 1
max_nof_prb = 106
nof_prb = 106

The max_nof_prb and nof_prb values must be selected according to the configured channel bandwidth:

BW PRBs
   

Physical SIM/ISIM setup

cots-ue

For COTS UE testing, a programmable SIM/USIM is required so that the UE credentials match the subscriber profile configured in the 5G core. The SIM can be programmed using a compatible smart-card reader, a programmable USIM card, and the SIM programming tool.

The subscriber information is stored in a CSV file using the following format:

Name,IMSI,Key,OP_Type,OP/OPc,AMF,QCI,IP_alloc

For a basic testbed setup, each UE should have a unique Name, IMSI, and IP_alloc. The remaining authentication values can be kept the same across entries. The current csv currently consists of two rows for the UEs we have tested with a Commericial Android Phone and a SixFab 5G Development Kit.

Name,IMSI,K,OP_Type,OPc,AMF,SQN,UE_IP
S23U,001010123456780,00112233445566778899AABBCCDDEEFF,opc,63BFA50EE6523365FF14C1F45F88737D,8000,9,10.45.1.2
A22,001010123456781,00112233445566778899AABBCCDDEEFF,opc,63BFA50EE6523365FF14C1F45F88737D,8000,9,10.45.1.3

For the sim card we used a sysmoISIM-SJA5-9FV SIM and a HID OMNIKEY 3121 sim reader/programming tool.

Reading/Writing to SIM

sysmocom SIM cards support programming sim values through their python library. Install the pySim library

git clone https://github.com/osmocom/pysim
cd pysim
sudo apt-get install --no-install-recommends \
    pcscd libpcsclite-dev \
    python3 \
    python3-setuptools \
    python3-pyscard \
    python3-pip
pip3 install -r requirements.txt

Check the current ISIM configuration:

./pySim-read.py -p0 # may need to be ran with sudo on some devices

Writing the values according to your csv row.

./pySim-prog.py -p0 -s <ICCID> --mcc=<MCC> --mnc=<MNC> -a <ADM-KEY> --imsi=<IMSI> -k <KI> --opc=<OPC>

e.g.

./pySim-prog.py -p0 -s <ICCID> --mcc=001 --mnc=01 -a <ADM-KEY> \
  --imsi=001010123456781 \
  -k 00112233445566778899AABBCCDDEEFF \
  --opc=63BFA50EE6523365FF14C1F45F88737D

The following values will be provided by your individual sim card.

  • <ICCID> = SIM card ICCID
  • <ADM-KEY> = programmable SIM admin key

Smartphone Setup

Insert the sim card in your test smartphone and navigate to the the sim cards Access Point Name settings and add a new APN as shown in image:

APN-Setting

SixFab 5G development kit

The SixFab 5G Development Kit provides a Raspberry Pi-based modem UE platform with a 5G HAT, Quectel M.2 modem, SIM interface, antennas, USB connectivity, and external power support for private 5G/O-RAN testbed experiments.

Modem Manager

Many Linux distributions have ModemManager preinstalled. They must uninstall it before starting the tutorial. They can be easily uninstalled through the package manager.

sudo apt purge modemmanager -y

Install the required serial communication program such as minicom.

sudo apt install minicom -y

Open the serial communication for /dev/ttyUSB2 device port with 115200 baudrate using minicom

APN Setup

sudo minicom -D /dev/ttyUSB2 -b 115200  

Configure the modem for ECM mode. The response should be OK.

AT+QCFG="usbnet",1

Add our srsapn to connect and restart.

AT+CGDCONT=1,"IP","srsapn"
AT+CFUN=1,1

Check the allocated IP address it should match our entry in subscriber_db.csv

AT+CGPADDR=1

apn-setup

Close the minicom interface by pressing ctrl+A and Z. This completes the APN setup.

Internet Connectivity

We can now check internet connectivity through a speedtest-cli. Install the speedtest-cli

sudo apt install speedtest-cli

Check the IPv4 address assigned to the modem interface. For the SixFab 5G Development Kit, the interface is typically named usb0. Run the speedtest.

speedtest-cli --source <usb0 IPV4>
# e.g. speedtest-cli --source 192.168.225.24

speedtest-cli