目录
前言
本文主要记录了用OpenAirInterface(OAI)项目搭建NR5G基站以及核心网,并实现商用终端接入伪基站进行数据通信的过程。
设备配置:
1)核心网与基站:共用一台电脑
系统:Ubuntu 22.04.5 LTS
硬件:11th Gen Intel® Core™ i7-11700
2)USRP设备:
B210、X310
3)商用终端:
小米10
Ubuntu 18.04 部署OAI教程参考:
OAI gNB安装以及运行问题解决-CSDN博客
OAI 5G核心网安装并连接到gNB_gnb csdn-CSDN博客
手机连接上OAI基站_自己建了一个基站,怎么用手机连接-CSDN博客
OAI项目地址:
基站端:oai / openairinterface5G · GitLab
核心网:oai / cn5g / oai-cn5g-fed · GitLab
一、OAI 5G基站端部署
安装参考:OpenAirKernelMainSetup · Wiki · oai / openairinterface5G · GitLab
doc/BUILD.md · develop · oai / openairinterface5G · GitLab
本章前半部分关于电源设置、CPU频率设置以及低延迟内核设置非必须项,只是为了提高电脑性能以适配OAI和USRP,如果设置失败可以先按第四节内容部署基站。
1、设置低延迟内核
首先,查看当前内核:
uname -sr
下载低延迟内核,低延迟内核版本不一定要用这个:
sudo apt install linux-tools-common linux-tools-lowlatency linux-tools-5.15.0-122-lowlatency
查看所有的内核:
sudo dpkg --get-selections |grep linux-image
内核安装好后就可以在启动界面选择内核进行启动了,如果Ubuntu启动不显示grub界面的话需要进行配置,我这里使用geany来打开文件,用vim或者其他程序打开均可以,打开配置文件:
sudo apt install geany
sudo geany /etc/default/grub
将文件中GRUB_TIMEOUT_STYLE=hidden这一行注释掉,并GRUB_TIMEOUT=0改为其他数值(例如改为10)。
修改完后执行:
sudo update-grub
这样重启后就可以在“Ubuntu高级选项”中选择低延迟内核。
如果想设置默认启动低延迟内核,可以将GRUB_DEFAULT=0进行修改,具体而言目录界面编号是从0开始的,如下:
所以如果想默认启动高级选项下的第五个低延迟内核,就需要改为“1> 4”,引号必须加,>和4之间有空格。4代表的是在Advanced options for Ubutu界面中,低延迟内核为第四个(从0开始数)。
2、设置电源管理
按照OAI部署要求,删除 BIOS 中的所有电源管理功能(睡眠状态,特别是 C 状态)和 CPU 频率缩放 (Intel SpeedStep),具体BIOS的修改方式与主板有关。并在grub文件中修改GRUB_CMDLINE_LINUX_DEFAULT为GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_pstate=disable processor.max_cstate=1 intel_idle.max_cstate=0 idle=poll" ,最后用sudo update-grub更新,并重启电脑。
安装i7z来检查CPU状态,确保均运行在C0状态
sudo apt-get install i7z
sudo i7z
3、设置CPU频率
安装 cpufrequtils:
sudo apt-get install cpufrequtils
然后编辑以下文件(如果不存在,则创建它):
sudo geany /etc/default/cpufrequtils
添加GOVERNOR="performance",并运行:
sudo update-rc.d ondemand disable
如果报错update-rc.d: error: cannot find a LSB script for ondemand 则运行:
sudo /etc/init.d/cpufrequtils restart
systemd reboot
sudo /etc/init.d/cpufrequtils restart
4、安装OAI
如果没有git先安装git:
sudo apt-get install git
在合适文件夹内下载源码:
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
在下载的openairinterface5g文件夹中,确认项目分支为develop:
git checkout develop
构建外部依赖文件
source oaienv
cd cmake_targets
./build_oai -I -w USRP
安装依赖文件成功:
安装UE、eNodeB 和 gNodeB 可执行文件:
./build_oai -w USRP --eNB --UE --nrUE --gNB
安装gNB、eNB、UE成功:
5、运行gNB
连接USRP设备(B210/X310),先运行
uhd_find_devices
如果能显示连接的USRP设备信息,说明前面安装没有问题并且连接成功。更详细的USRP设备信息可以用uhd_usrp_probe来查询。
基站相关的配置文件存在目录openairinterface5g/targets/PROJECTS下,其中5G gNB的配置文件在GENERIC-NR-5GC中。
运行基站需要在openairinterface5g/cmake_targets/ran_build/build/ 文件夹下运行
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.new.conf -E --noS1 --nokrnmod 1 --sa
其中各参数含义如下:
参数 | 解释 |
./nr-softmodem | 运行的是5G gNB基站,所以运行的是nr-softmodem; 如果要运行4G eNB基站,可以运行lte-softmodem |
-O | 表示要传入后面的配置文件 |
../../../targets/PROJECTS /GENERIC-NR-5GC/CONF/ gnb.sa.band41.fr1.106PRB .usrpb210.new.conf | 这是具体使用的配置文件,从名称也可以看出,该配置文件使用的是n41频段,带宽106PRB(40M),使用的设备是B210.具体配置的参数可以在该文件中进行修改 |
-E | 以3/4采样率启动基站,如果是B2XX设备需要添加这个参数,否则会报错 |
--noS1 --nokrnmod 1 | 这两个参数表示在没有核心网的情况下运行基站 |
--sa | 表示基站运行在SA模式下 |
基站成功运行:
6、遇到的问题
在构建依赖文件时发生错误:
其实是版本冲突导致,解决方法:
先查看所有安装的包:
apt list –installed
搜索libuhd,发现已安装的版本为4.7.0。打开 openairinterface5g/cmake_targets/tools路径下的build_helper文件,搜索libuhd,发现文件中安装版本为4.5.0的uhd_host,将4.5.0改为4.7.0,并重新安装./build_oai -I -w USRP即可
二、CN5G 核心网部署
安装参考:README.md · master · oai / cn5g / oai-cn5g-fed · GitLab
1、安装Docker&Docker Compose
docker官网地址:https://hub.docker.com/
使用镜像源安装docker:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
安装完成可以用docker version来查看是否安装成功,之后可以将用户名加入docker组中:
sudo usermod -a -G docker 用户名
安装docker compose是类似的方法:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.29.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
安装完成可以用docker compose version来查看是否安装成功,然后给予权限并建立docker compose的软连接:
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
2、拉取镜像
官网的镜像拉取方法是注册并登陆docker账户,然后直接pull
docker login
#!/bin/bash
docker pull oaisoftwarealliance/oai-amf:v2.1.0
docker pull oaisoftwarealliance/oai-nrf:v2.1.0
docker pull oaisoftwarealliance/oai-upf:v2.1.0
docker pull oaisoftwarealliance/oai-smf:v2.1.0
docker pull oaisoftwarealliance/oai-udr:v2.1.0
docker pull oaisoftwarealliance/oai-udm:v2.1.0
docker pull oaisoftwarealliance/oai-ausf:v2.1.0
docker pull oaisoftwarealliance/oai-upf-vpp:v2.1.0
docker pull oaisoftwarealliance/oai-nssf:v2.1.0
docker pull oaisoftwarealliance/oai-pcf:v2.1.0
docker pull oaisoftwarealliance/oai-lmf:v2.1.0
# Utility image to generate traffic
docker pull oaisoftwarealliance/trf-gen-cn5g:latest
docker logout
但是现在国内的很多镜像源都无了,如果确实找不到合适的镜像源可以用这个github项目搭配阿里云的容器镜像服务进行拉取,有需要也可以私信我获取阿里云的镜像,包含v2.0.1和v2.1.0两个版本:GitHub - tech-shrimp/docker_image_pusher: 使用Github Action将国外的Docker镜像转存到阿里云私有仓库,供国内服务器使用,免费易用使用Github Action将国外的Docker镜像转存到阿里云私有仓库,供国内服务器使用,免费易用 - tech-shrimp/docker_image_pusherhttps://github.com/tech-shrimp/docker_image_pusher
3、部署核心网
首先下载核心网源码,我是使用的v2.1.0版本
git clone --branch v2.1.0 https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git
cd oai-cn5g-fed
git checkout -f v2.1.0
然后同步子模块:
./scripts/syncComponents.sh
结果如下:
4、运行核心网
运行核心网可以在目录下,查看帮助文件:
python3 core-network.py --help
可以看到大体来说是分为basic模式和mini模式,这两个模式的架构图如下:
此外 --scenario 1对应的是有NRF,而--scenario 2为没有NRF,如果没有这项参数则为默认情况--scenario 1,而mini模式只支持没有NRF的--scenario 2。
可以根据需要来选择合适的命令来启动核心网,这里我使用basic模式来启动:
python3 core-network.py --type start-basic
成功启动结果如图:
可以使用docker ls来查看运行中的容器,也可以用ifconfig来查看创建的网口
保存各个网元的log,这样在docker-compose文件夹下会生成log文件:
docker logs oai-amf > amf.log
docker logs oai-smf > smf.log
docker logs oai-nrf > nrf.log
docker logs oai-udr > udr.log
docker logs oai-upf > upf.log
docker logs oai-ausf > ausf.log
docker logs oai-udm > udm.log
关闭核心网,要使用对应的命令:
python3 core-network.py --type stop-basic
5、遇到的问题
在启动核心网的时候,如果之前已经拉取过镜像,但是还要拉取的话,说明配置文件中的镜像名称和现有的镜像名称不一致(尤其是用阿里云容器镜像服务拉取的镜像肯定名称不一致),可以修改配置文件或者给镜像重命名。
1)方法一:镜像重命名
配置文件中默认的AMF镜像名称为oaisoftwarealliance/oai-amf:v2.1.0,因此重命名amf镜像:
docker image tag 现有的镜像名称 oaisoftwarealliance/oai-amf:v2.1.0
此外,其他的网元(smf,upf,udr等)镜像也需要像这样重命名
2)方法二:修改配置文件
首先找到你所用的模式使用的配置文件,具体来说在docker-compose文件夹中的core-network.py文件中找到对应的配置文件,比如我用的basic模式,配置文件为docker-compose-basic-nrf.yaml。在这个文件中就可以修改每个网元对应的镜像名称了,将oaisoftwarealliance/oai-amf:v2.1.0修改为已经拉取的镜像名称。
三、商用设备接入并实现数据通信
(一)小米10
1、白卡烧录
首先需要去淘宝上购买5G白卡、读卡器以及相应的配套软件,软件需要修改的地方主要是需要修改IMSI、OPC、KI以及PLMN,如图:
首先修改的是右半部分5GIMSI、OPC、KI按照需要进行修改,然后删除下面的所有PLMN后,点击右面的Auto,让其自动获取,最后点击左半部分的Same with 5G。完成配置后点击Write Card进行写卡。具体的参数如下表:
IMSI | 001010000000001 |
KI | 0C0A34601D4F07677303652C0462535B |
OPC | 63bfa50ee6523365ff14c1f45f88737d |
2、核心网配置
这次使用的是Basic模式运行核心网,主要配置文件有两个:/docker-compose/文件夹下的docker-compose-basic-nrf.yaml以及/docker-compose/conf/文件夹下的basic_nrf_config.yaml,对应的数据库文件为/docker-compose/database/文件夹下的oai_db2.sql。具体使用的配置文件可以查看core network.py来确定。
首先在数据库中添加订阅信息,在表AuthenticationSubscription中添加在白卡中烧录的信息。其中第一个参数ueid和最后一个参数supi改为白卡中的IMSI的值,中间的则修改为KI和OPC的值,如图:
然后在basic_nrf_config.yaml文件中修改served_guami_list和plmn_support_list,改为白卡中PLMN的值,这里设置为00101。然后修改完整性保护算法,将NIA0注释掉,因为小米10是不支持NIA0的。此外还要修改tac的值,这个值需要与基站一致,这里修改为1.
然后,修改核心网DNN以及nssai,之前测试用oai作为DNN手机会连不到网,所以把DNN和网络切片修改为如图,而相应的文件中nssai也需要修改。
3、基站配置
基站的配置文件在openairinterface5g/targets/PROJECTS文件夹下,我们用的5G基站使用的是其中GENERIC-NR-5GC文件夹中的配置文件。可以看到,基站中以及包含了很多配置文件,覆盖不同频段、不同带宽以及不同的USRP设备,我们这里以B210为例,打开gnb.sa.band78.fr1.106PRB.usrpb210.conf文件。其中要修改内容包括plmn_list,AMF parameters等。
首先plmn_list需要修改为与手机白卡一致,mcc = 001; mnc = 01,而snssaiList需要与上一步NSSAI一致,这里我只用ims的DNN,就修改了一个:
AMF parameters部分要将AMF的IP改为当前AMF的IP地址
当然也可以直接在核心网配置文件中显式设置各个网元的IP地址
此外,配置文件中各项参数均可修改,有些需要按照NR5G协议规定来修改,具体各项参数意义如下:
Active_gNBs = ( "gNB-OAI");
# 定义了活动的gNB列表,这里只有一个gNB,名为"gNB-OAI"
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
# ASN.1解码的详细程度,有三种选项:"none"(不显示)、"info"(显示一些信息)、"annoying"(显示大量信息)
gNBs =
(
{
// Identification parameters: // Identification parameters:
gNB_ID = 0xe00;
# gNB ID,十六进制形式,用于唯一标识基站
gNB_name = "gNB-OAI";
# gNB名称,设置为"gNB-OAI"
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
# 追踪区域代码 (TAC),标识一个移动网络的地理区域
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({sst = 1; sd = 0x1; }) });
# PLMN配置,包含MCC(移动国家码)和MNC(移动网络码)。这里MCC为001,MNC为01,MNC长度为2,支持的切片服务类型SST为1,切片描述符SD为0x1
nr_cellid = 12345678L;
# NR小区标识符,用于唯一标识小区
// Physical parameters: // Physical parameters:
do_CSIRS = 1;
# 是否启用CSI-RS(信道状态信息参考信号)
do_SRS = 1;
# 是否启用SRS(探测参考信号)
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
searchSpaceZero = 0;
}
);
# PDCCH控制信道的配置,定义了资源集和搜索空间
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# 物理小区ID,唯一标识小区
#frequencyInfoDL
# 下行频率信息
absoluteFrequencySSB = 529950;
# SSB(同步信号块)的绝对频率
dl_frequencyBand = 41;
# 下行频率所属频段为41
dl_absoluteFrequencyPointA = 526134;
# PointA的绝对频率,代表PRB 0的中心频率,这里为526134,修改这个参数可以修改下行频点
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# 下行载波偏移量
# subcarrierSpacing
# 子载波间隔(0=15kHz, 1=30kHz, 2=60kHz, 3=120kHz)
dl_subcarrierSpacing = 1;
# 子载波间隔为30kHz
dl_carrierBandwidth = 106;
# 下行载波带宽,单位为PRB,这里为106 PRB,也就是40MHz
#initialDownlinkBWP
#genericParameters
# 初始下行BWP的位置和带宽
initialDLBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
initialDLBWPsubcarrierSpacing = 1;
# 初始BWP的子载波间隔为30kHz
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
# 初始BWP的控制资源集和搜索空间
#uplinkConfigCommon
# 上行频率信息
ul_frequencyBand = 41;
# 上行频率所属频段为41
ul_offstToCarrier = 0;
# 上行载波偏移量
ul_subcarrierSpacing = 1;
# 上行子载波间隔为30kHz
ul_carrierBandwidth = 106;
# 上行载波带宽为106 PRB
pMax = 20;
# 最大上行传输功率,单位为dBm
#initialUplinkBWP
initialULBWPlocationAndBandwidth = 28875;
# 初始上行BWP的位置和带宽
initialULBWPsubcarrierSpacing = 1;
# 初始上行BWP的子载波间隔为30kHz
#rach-ConfigCommon
prach_ConfigurationIndex = 98;
# PRACH(随机接入信道)配置索引,定义随机接入配置
prach_msg1_FDM = 0;
# PRACH消息1的FDM配置,0表示单个频域资源
prach_msg1_FrequencyStart = 0;
# PRACH消息1的频率起始位置
zeroCorrelationZoneConfig = 13;
# 零相关区配置
preambleReceivedTargetPower = -96;
# 前导序列接收的目标功率,单位为dBm
preambleTransMax = 6;
# 前导传输的最大次数,值为6
powerRampingStep = 1;
ra_ResponseWindow = 4;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
# 每个SSB的PRACH前导序列配置
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
# 每个SSB的前导序列数目
ra_ContentionResolutionTimer = 7;
# 竞争解决定时器
rsrp_ThresholdSSB = 19;
# SSB的RSRP门限值
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# PRACH根序列索引配置
msg1_SubcarrierSpacing = 1;
# PRACH消息1的子载波间隔为30kHz
restrictedSetConfig = 0;
# PRACH受限集配置,0表示不受限
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
# PRACH消息3的Delta前导和初始功率配置
pucchGroupHopping = 0;
# PUCCH(物理上行控制信道)组跳频,0表示无跳频
hoppingId = 40;
p0_nominal = -90;
# PUCCH的初始功率设置
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# SSB的发射位置和位图配置
ssb_periodicityServingCell = 2;
# SSB的周期配置,值为2表示20ms周期
dmrs_TypeA_Position = 0;
# DMRS的TypeA位置,0表示pos2
subcarrierSpacing = 1;
# 子载波间隔为30kHz
referenceSubcarrierSpacing = 1;
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
# TDD配置,包括下行和上行的时间分配
}
);
# ------- SCTP definitions
SCTP :
{
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
# SCTP(流控制传输协议)的输入输出流数配置
};
// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } );
# AMF的IPv4和IPv6地址配置,并设置IPv4为优先地址
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152
4、手机端配置与连接至基站
手机端插入白卡后,需要设置接入点APN。具体而言,新增接入点,名称无所谓,APN设置为ims,MCC设置为001,MNC设置为01,APN协议为ipv4/v6,保存APN并使用该接入点:
首先启动核心网,在docker-compose文件夹下中运行
python3 core-network.py --type start-basic
再启动基站,在build文件夹中运行(需要替换为所使用的配置文件)
sudo -E ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf -E --sa
然后手机开启飞行模式,再关闭飞行模式进行初始接入,如果能接入基站就可以实现商用终端的数据通信,如果连接不到基站,小米手机可以在拨号界面输入*#*#4636#*#*,设置首选网络类型为NR only。
5、遇到的问题
1)NGAP报错找不到AMF
如果遇到NGAP报错链接不到gNB,是基站端的AMF的ip地址有问题,可以在核心网成功运行以后查看AMF的ip,并修改基站配置文件。
2)基站显示手机接入,手机显示无信号
这种情况下需要用wireshark进行抓包来分析信令,安装wireshark:
sudo apt install wireshark
安装好后,用管理员权限运行wireshark来抓取demo-oai的端口数据,可以用ngap来进行过滤,筛选出5G信令。下面会列出我在测试的过程中出现的几种报错以及相应的解决方法。
①MAC Failure
这是认证阶段失败,Mac Failure意味着核心网内存储的注册信息和接入手机的信息不一致,需要检查数据库中存储的注册信息是否与烧录的KI和OPC一致。
②Missing or Unknown DNN
这个是DNN配置有问题或者接入设备的APN设置的有问题,这两个需要设置一致,包括APN类型也要一致,这个参数在核心网中需要修改最后dnn参数的pdu_session_type。
3)使用X310做基站
在基站配置文件夹中,有一些x300和x310可以使用的配置文件,分析了一些发现,其与b210的配置文件区别点主要在RUs部分,这是x310配置文件的RUs:
可以发现,x310主要多了sdr_addrs参数,有些文件还会添加type = x300来使用x300系列usrp。此外,在天线配置上,其与b210也有不同,不过我暂时只尝试了单发单收,多天线这方面还没有测试过。其余参数实际上与b210的配置文件差别不大。