Deploy an LTE Environment using USRP and Magma - caprivm/virtualization GitHub Wiki

caprivm ([email protected]) jhonny9211 ([email protected])

Updated: January 12, 2023

Description

This page explains all the steps required to connect the USRP B200 (mini) to a vEPC based on Magma (https://www.magmacore.org/). The RAN controller was tested on a single-machine with the next considerations:

Feature Value
OS Used Ubuntu 20.04 LTS (Desktop)
vCPU 4
RAM (GB) 6
Disk (GB) 40
Home user caprivm
Mosaic5G branch or tag master

The Core was tested on the ARM device: HawkEyeTech HK-6050 Series.

RAN configuration

The configuration used for RAN in this experiment is as follows. Adjust it based on your environment:

Feature Value
USRP Version USRP b200 mini
UDH Version UHD_3.15.0.0-2build5

Core Configuration

The configuration used for Core in this experiment is as follows. Adjust it based on your environment:

Feature Value
MME IP 10.0.2.1
MCC 01
MNC 901
MNC Lenght 2

UE Configuration

The configuration used for UE in this experiment is as follows. Adjust it based on your environment:

Feature Value
OPC 8e27b6af0e692e750f32667a3b14605d
Key 8baf473f2f8fd09487cccbd7097c6862
IMSI 208930100001102
Model Motorola g5 plus
SIM Card sysmocom

Prerequisites

Before starting this guide, you should have installed the following tools. You can check the adjacent links if you haven't already:

Verifying CPU Compatibility

For the USRP to be able to radiate, the CPU must support AVX. Checking this is simple:

cat /proc/cpuinfo | grep --color flags | grep --color avx
# flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave ------>avx<------ lahf_lm epb pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts md_clear flush_l1d
# flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave ------>avx<------ lahf_lm epb pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts md_clear flush_l1d
# flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave ------>avx<------ lahf_lm epb pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts md_clear flush_l1d
# flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave ------>avx<------ lahf_lm epb pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts md_clear flush_l1d

Another very important aspect to validate is that USRPs use CPU times to emulate the radiation frequency. In CPUs that are old (in my case, I tested <2011), they usually have a drawback at the time of radiating (when executing sudo oai-ran.enb) that manifests itself with the error: Illegal instruction (core dumped) error. Consider executing the following command:

sudo lshw | grep -i -A 3 -B 3 -i cpu
#           size: 128KiB
#           capacity: 2496KiB
#           capabilities: pci pnp upgrade shadowing escd cdboot bootselect socketedrom edd int13floppy360 int13floppy1200 int13floppy720 int5printscreen int9keyboard int14serial int17printer int10video acpi usb ls120boot smartbattery biosbootspecification netboot
#      *-cpu
#           description: CPU
#           product: Intel(R) Core(TM) i3-2330M CPU @ 2.20GHz
#           vendor: Intel Corp.
#           physical id: 2e
#           bus info: cpu@0
#           version: Intel(R) Core(TM) i3-2330M CPU @ 2.20GHz
#           serial: Not Supported by CPU
#           slot: CPU
#           size: 820MHz
#           capacity: 2200MHz
#           width: 64 bits
#           clock: 100MHz
#           capabilities: x86-64 fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave avx lahf_lm epb pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid xsaveopt dtherm arat pln pts md_clear flush_l1d cpufreq
#           configuration: cores=2 enabledcores=2 threads=4
#         *-cache:0
#              description: L1 cache

Compare this information with that provided in this issue: https://github.com/facebookresearch/demucs/issues/134

Also, you can use the following links to understand the root cause of a Illegal instruction (core dumped) problem:

Prepare the USRP

The first thing is to prepare the USRP. Although it may seem simple, the USRP needs specific drivers for connection to a computer. Please note the Software and Hardware configurations described at the beginning and follow the instructions below:

sudo add-apt-repository ppa:ettusresearch/uhd
sudo apt-add-repository universe
sudo apt-get update

Select an specific UHD version to manage the USRP. You can list the version using:

sudo apt-cache policy uhd-host
# uhd-host:
#   Installed: 3.15.0.0-2build5
#   Candidate: 4.1.0.4-0ubuntu1~focal1
#   Version table:
#      4.1.0.4-0ubuntu1~focal1 500
#         500 http://ppa.launchpad.net/ettusresearch/uhd/ubuntu focal/main amd64 Packages
#  *** 3.15.0.0-2build5 500
#         500 http://co.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
#         100 /var/lib/dpkg/status

In this case, the 3.15.0.0-2build5 version is selected. So, this version is installed:

sudo apt-get install -y libuhd3.15.0=3.15.0.0-2build5
sudo apt-get install -y libuhd-dev=3.15.0.0-2build5
sudo apt-get install -y uhd-host=3.15.0.0-2build5
cd /usr/lib/uhd/utils/
./utils/uhd_images_downloader.py

Next, identify the USRP:

export UHD_IMAGES_DIR='/usr/share/uhd/images/'
uhd_usrp_probe
uhd_find_devices
# [INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_3.15.0.0-2build5-release
# --------------------------------------------------
# -- UHD Device 0
# --------------------------------------------------
# Device Address:
#     serial: 31E1B52
#     name: B200mini
#     product: B200mini
#     type: b200

Building and Installing UHD from source

Reference: https://files.ettus.com/manual/page_build_guide.html

You can install the USRP dependencies from its source code. This way, if you make any changes to the code, you can regenerate it here. However, this procedure is more time-consuming and usually has a higher degree of complexity:

sudo apt-get install autoconf automake build-essential ccache cmake cpufrequtils doxygen ethtool g++ git inetutils-tools libboost-all-dev libncurses5 libncurses5-dev libusb-1.0-0 libusb-1.0-0-dev libusb-dev python3-dev python3-mako python3-numpy python3-requests python3-scipy python3-setuptools python3-ruamel.yaml
git clone https://github.com/EttusResearch/uhd.git ~/uhd-git
cd ~/uhd-git
git checkout v3.15.0.0 -b release-3.15.0.0
cd ~/uhd-git/host; mkdir build; cd build
cmake -DCMAKE_INSTALL_PREFIX=/opt/uhd ../
make
make test           # This step is optional
sudo make install
export LD_LIBRARY_PATH=~/uhd-git/host/build/lib/
sudo ldconfig

Setup Udev for USB (Linux)

Reference: https://files.ettus.com/manual/page_transport.html#transport_usb_udev

On Linux, Udev handles USB plug and unplug events. The following commands install a Udev rule so that non-root users may access the device:

cd ~/uhd-git/host/utils/
sudo cp uhd-usrp.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger

Test the USRP

Reference: This link is used as main reference: https://kb.ettus.com/Verifying_the_Operation_of_the_USRP_Using_UHD_and_GNU_Radio

You can test the operation of the USRP with some test commands:

cd /usr/lib/uhd/examples/
# Benchmarks interface with device
./benchmark_rate --rx_rate 10e6 --tx_rate 10e6
# Saves samples to file
./rx_samples_to_file --freq 98e6 --rate 5e6 --gain 20 --duration 10 usrp_samples.dat
# Transmits samples from file
./tx_samples_from_file --freq 915e6 --rate 5e6 --gain 10 usrp_samples.dat

Configure USRP to connect to Magma

To connect the URSP to Magma, it is necessary to have a RAN manager that handles the USRP as a radio unit (RU). For this scenario, Mosaic5G (https://gitlab.eurecom.fr/mosaic5g/mosaic5g) is used.

Installing the RAN

Reference: This link is used as main reference: https://gitlab.eurecom.fr/mosaic5g/mosaic5g/-/wikis/tutorials/oai-ran

Clone the repository and use the build_m5g script to install the OAI RAN snaps::

cd ~ && git clone https://gitlab.eurecom.fr/mosaic5g/mosaic5g.git
./mosaic5g/build_m5g -R

Before being able to run OAI-RAN, you have to grant some permissions (see oai-ran.info):

sudo snap connect oai-ran:log-observe
sudo snap connect oai-ran:network-control
sudo snap connect oai-ran:netlink-connector
sudo snap connect oai-ran:process-control
sudo snap connect oai-ran:cpu-control
sudo snap connect oai-ran:raw-usb

This installs three deployment possibilities for the RAN:

  • oai-ran.enb as the monolithic case.
  • oai-ran.cudu for a disaggregrated eNodeB.
  • oai-ran.rru for a monolithic or disaggregated RRU with split option 2.

In this case the monolithic is used. To get additional help type sudo oai-ran.help.

Configure the RAN

To configure the RAN, get the configuration file using the oai-ran.enb-conf-get command, then use an editor with sudo rights:

sudo oai-ran.enb-conf-get
# /var/snap/oai-ran/59/enb.band7.tm1.50PRB.usrpb210.conf

There is another configuration files:

cd /var/snap/oai-ran/current
ls | grep usrpb                 # See the configuration files options for usrpb
# enb.band7.tm1.25PRB.usrpb210.replay.conf
# enb.band7.tm1.50PRB.usrpb210.conf
# enb.band7.tm1.50PRB.usrpb210-d2d.conf
# enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
# enb.band7.tm1.fr1.25PRB.usrpb210.conf
# gnb.band78.106PRB.30kHz,usrpb2x0.conf
# gnb.band78.106PRB.30kHz.usrpb2x0.conf
# gnb.band78.tm1.106PRB.usrpb210.conf
# gnb.band78.tm1.fr1.106PRB.usrpb210.conf
# oaiL1.nfapi.usrpb210.conf

For this case the configuration file will be used: enb.band7.tm1.50PRB.usrpb210.conf. Edit it according to your network configuration and then validate that the edit is correct.

sudo cp /var/snap/oai-ran/current/enb.band7.tm1.50PRB.usrpb210.conf ~/enb.band7.tm1.50PRB.usrpb210.conf.backup    # Make a backup
sudo vim /var/snap/oai-ran/current/enb.band7.tm1.50PRB.usrpb210.conf

Made the next changes:

# Line 34
- downlink_frequency                                    = 2685000000L;
+ downlink_frequency                                    = 2625000000L;
# Line 37
- N_RB_DL                                               = 50;
+ N_RB_DL                                               = 25;
# Line 43
- rx_gain                                            = 125;
+ rx_gain                                            = 115;
# Line 175
- mme_ip_address      = ( { ipv4       = "127.0.1.1";
+ mme_ip_address      = ( { ipv4       = "10.0.2.1";
# Line 182
- enable_measurement_reports = "no";
+ enable_measurement_reports = "yes";
# Line 191 to 194
- ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
- ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.1.3/23";
- ENB_INTERFACE_NAME_FOR_S1U               = "lo";
- ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.14.3/23";
+ ENB_INTERFACE_NAME_FOR_S1_MME            = "enp3s0";
+ ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.0.2.244/24";
+ ENB_INTERFACE_NAME_FOR_S1U               = "enp3s0";
+ ENB_IPV4_ADDRESS_FOR_S1U                 = "10.0.2.244/24";
# Line 197
- ENB_IPV4_ADDRESS_FOR_X2C                 = "127.0.15.1/24";
+ ENB_IPV4_ADDRESS_FOR_X2C                 = "10.0.2.244/24";
# Line 255
- att_tx         = 0
+ att_tx         = 3
# Line 259
- max_rxgain                    = 125;
+ max_rxgain                    = 110;
# Line 278
- parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+ parallel_config    = "PARALLEL_SINGLE_THREAD";

Validate that the configuration was correctly applied to the configuration file with the command sudo oai-ran.enb-conf-show. Once the RAN is configured, it can be started in the two following ways:

sudo oai-ran.enb        # Manually, stop with Ctrl-C
sudo oai-ran.enb-start  # As a daemon

In daemon mode you can see the status and logs with sudo oai-ran.enb-status and sudo oai-ran.enb-journal respectively. Stop the daemon with:

sudo oai-ran.enb-stop
⚠️ **GitHub.com Fallback** ⚠️