> 文章列表 > UE-Ueransim-5GC全链路开发记录

UE-Ueransim-5GC全链路开发记录

UE-Ueransim-5GC全链路开发记录

目录

1. 系统配置

1.1 Ueransim配置

1.2 UE配置

2. 启动 

3. 实际演示

附录 

代理1:ueransim-5gc

 代理2 ue-ueransim

TCPclient

TCPserver


1. 系统配置

1.1 Ueransim配置

  • ueransim的yaml文件如下 
version: '3.8'
services:ueransim2:container_name: ueransimimage: ueransim:latestprivileged: trueenvironment:# GNB Congig Parameters- MCC=208- MNC=95- NCI=0x000000020- TAC=0xa000- LINK_IP=192.168.70.144- NGAP_IP=192.168.70.144- GTP_IP=192.168.72.144- NGAP_PEER_IP=192.168.70.132- SST=222- SD=123- IGNORE_STREAM_IDS=true# UE Config Parameters- NUMBER_OF_UE=1- IMSI=208950000000042- KEY=0C0A34601D4F07677303652C0462535B- OP=63bfa50ee6523365ff14c1f45f88737d- OP_TYPE=OPC- AMF_VALUE=8000- IMEI=356938035643803- IMEI_SV=0035609204079514- GNB_IP_ADDRESS=192.168.70.144- PDU_TYPE=IPv4- APN=default- SST_0=222- SD_0=123- SST_C=222- SD_C=123- SST_D=222- SD_D=123networks:public_net:ipv4_address: 192.168.70.144public_net_access:ipv4_address: 192.168.72.144public_proxy_access: ipv4_address: 192.168.62.144healthcheck:test: /bin/bash -c "ifconfig uesimtun0"interval: 10s
networks:public_net:external:name: demo-oai-public-netpublic_net_access:external:name: oai-public-accesspublic_proxy_access:name:  public_ueransim-accessipam:config:- subnet: 192.168.62.0/24driver_opts:com.docker.network.bridge.name: "ueransim-access"
  • 网络配置

主机网卡及ip

Ueransim 对外接口 ip

ueransim-access: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.62.1  netmask 255.255.255.0  broadcast 192.168.62.255inet6 fe80::42:5eff:fe85:8b1  prefixlen 64  scopeid 0x20<link>ether 02:42:5e:85:08:b1  txqueuelen 0  (Ethernet)RX packets 931  bytes 47056 (47.0 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 998  bytes 73591 (73.5 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 Ueransim 容器内部ip

docker exec -it ueransim /bin/bash
root@1dacc8a170b6:/ueransim/bin# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.70.144  netmask 255.255.255.0  broadcast 192.168.70.255ether 02:42:c0:a8:46:90  txqueuelen 0  (Ethernet)RX packets 186  bytes 20087 (20.0 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 144  bytes 12276 (12.2 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.72.144  netmask 255.255.255.0  broadcast 192.168.72.255ether 02:42:c0:a8:48:90  txqueuelen 0  (Ethernet)RX packets 37  bytes 5321 (5.3 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 1  bytes 42 (42.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.62.144  netmask 255.255.255.0  broadcast 192.168.62.255ether 02:42:c0:a8:3e:90  txqueuelen 0  (Ethernet)RX packets 99  bytes 14346 (14.3 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 7  bytes 518 (518.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 3223  bytes 173462 (173.4 KB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 3223  bytes 173462 (173.4 KB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0uesimtun0: flags=369<UP,POINTOPOINT,NOTRAILERS,RUNNING,PROMISC>  mtu 1400inet 12.1.1.2  netmask 255.255.255.255  destination 12.1.1.2unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.2 UE配置

  • 网络配置

工控机网卡及ip

路由设置 

 工控机添加路由(在power shell中添加)

route -p add 192.168.62.1 MASK 255.255.255.1  192.168.12.33

2. 启动 

docker-compose -f docker-compose-basic-vpp-nrf.yaml up -d
docker-compose -f ueransim-yzk-test.yaml up -d
lab@lab-virtual-machine:~/oai-cn5g-fed/docker-compose$ docker ps -a
WARNING: Error loading config file: /home/lab/.docker/config.json: open /home/lab/.docker/config.json: permission denied
CONTAINER ID   IMAGE                                     COMMAND                  CREATED          STATUS                    PORTS                          NAMES
1dacc8a170b6   ueransim:latest                           "/ueransim/bin/entry…"   27 minutes ago   Up 27 minutes (healthy)                                  ueransim
8b2ef5fa8d12   oaisoftwarealliance/oai-smf:v1.5.0        "python3 /openair-sm…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp, 8080/tcp, 8805/udp     oai-smf
133b33b85363   oaisoftwarealliance/oai-amf:v1.5.0        "python3 /openair-am…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp, 9090/tcp, 38412/sctp   oai-amf
b4c318f3ead3   oaisoftwarealliance/oai-ausf:v1.5.0       "python3 /openair-au…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp                         oai-ausf
431965a1ecce   oaisoftwarealliance/oai-udm:v1.5.0        "python3 /openair-ud…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp                         oai-udm
1a4d2d61dfba   oaisoftwarealliance/oai-udr:v1.5.0        "python3 /openair-ud…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp                         oai-udr
b771d01a8186   oaisoftwarealliance/oai-upf-vpp:v1.5.0    "/openair-upf/bin/en…"   29 minutes ago   Up 29 minutes (healthy)   2152/udp, 8085/udp             vpp-upf
58de55946ec2   mysql:8.0                                 "docker-entrypoint.s…"   29 minutes ago   Up 29 minutes (healthy)   3306/tcp, 33060/tcp            mysql
17a5c3649796   oaisoftwarealliance/trf-gen-cn5g:latest   "/bin/bash -c ' ipta…"   29 minutes ago   Up 29 minutes (healthy)                                  oai-ext-dn
d29065bc29b2   oaisoftwarealliance/oai-nrf:v1.5.0        "python3 /openair-nr…"   29 minutes ago   Up 29 minutes (healthy)   80/tcp, 9090/tcp               oai-nrf

 将ueransim-5gc-proxy传输进Ueransim容器中

docker cp /home/lab/oai-cn5g-fed/docker-compose/gNB/ueransim-5gc-proxy.py 1dacc8a170b6:/ueransim/bin
  • Ueransim容器内部命令:
chmod 777 nr-binder
apt-get update
apt-get install -y python3
apt install -y python3-pip
./nr-binder 12.1.1.2 python3 ueransim-5gc-proxy.py
  •  外部命令
python3 ue-ueransim-proxy.py
python3 TCPserve.py
python TCPclient.py

3. 实际演示

  • 主机

  •  工控机

  • 运行状况 

附录 

  • 代理1:ueransim-5gc

#https://www.youtube.com/watch?v=iApNzWZG-10import socket
from threading import Thread
import os
#线程2class Proxy2Server(Thread):#首先设置服务器连接(用_init_方法来构造)#参考https://www.cnblogs.com/ant-colonies/p/6718388.htmldef __init__(self, host, port):super(Proxy2Server,self).__init__()self.game = None #设置为连接用户的套接字,但是该套接字是由Game2Proxy线程创建的self.port = portself.host = host #连接服务器的ip和端口self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.server.connect((host,port))def run(self):while True:data  = self.server.recv(4096)if data:#转发所有数据到用户print("UE <------- Ueransim")self.game.sendall(data)
#线程1(监听用户是否与代理服务器连接)
class Game2Proxy(Thread):def __init__(self,host,port):super(Game2Proxy,self).__init__()self.server = None self.port = portself.host = host #连接用户的ip和端口sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)sock.bind((host,port))sock.listen(1)#这些都是上面官方文档里面调用的例程实现的#等待用户的连接 self.game ,addr = sock.accept() #sock.accept接收套接字#当客户端连接之后我们将获得代理服务器与客户端通信的套接字,并将其分配给self.game,然后在下面的线程中利用永久循环来接收用户端的数据def run(self):while True: #死循环接收用户的数据data = self.game.recv(4096)#最大数据量4kif data:    #如果真的接收到了用户发送过来的数据,那麽我们会尝试将此数据转发到服务器的套接字,即另外一个线程的套接字#转发给服务器print(" UE -------> Ueransim")self.server.sendall(data)#上面的两个线程创建完毕之后,需要为每一个线程提供对另外一个套接字的引用
#为此,我创建了一个更通用的类,命名为Proxy
class Proxy(Thread):def __init__(self,from_host,to_host,port):#如果没有在__init__中初始化对应的实例变量的话,导致后续引用实例变量会出错super(Proxy, self).__init__()self.from_host = from_host self.to_host = to_hostself.port = port def run(self):while True:#print ("[proxy({})] setting up")print ("Initialized, Waitting for connecting...")#用户会连接到下面这个self.g2p = Game2Proxy(self.from_host, self.port) #运行我们创建的这个线程,它等待用户端连接到指定端口#如果代理服务器与用户建立连接之后,另外一个线程将建立到服务器的转发连接self.p2s = Proxy2Server(self.to_host, self.port)print ("proxy connection established")print ("Connected!,Sending...")#现在两个线程都创建了套接字,我们接下来要做的就是交换他们self.g2p.server = self.p2s.server   #将与客户端建立的套接字转发给真实服务器self.p2s.game = self.g2p.game       #将服务器传回的套接字转发到客户端#线程设置完毕,现在我们来真正启动它self.g2p.start()self.p2s.start()#写到这里的时候,唯一缺少的就是创建一个或多个代理线程,我们先从主服务器开始
master_server = Proxy('192.168.62.144', '192.168.70.1', 8088)
#监听自己所有本机端口3333,并将它转发到真实的服务器ip 192.168.178.54
master_server.start()   #启动
  •  代理2 ue-ueransim

#https://www.youtube.com/watch?v=iApNzWZG-10import socket
from threading import Thread
import os
#线程2class Proxy2Server(Thread):#首先设置服务器连接(用_init_方法来构造)#参考https://www.cnblogs.com/ant-colonies/p/6718388.htmldef __init__(self, host, port):super(Proxy2Server,self).__init__()self.game = None #设置为连接用户的套接字,但是该套接字是由Game2Proxy线程创建的self.port = portself.host = host #连接服务器的ip和端口self.server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.server.connect((host,port))def run(self):while True:data  = self.server.recv(4096)if data:#转发所有数据到用户print("UE <------- Ueransim")self.game.sendall(data)
#线程1(监听用户是否与代理服务器连接)
class Game2Proxy(Thread):def __init__(self,host,port):super(Game2Proxy,self).__init__()self.server = None self.port = portself.host = host #连接用户的ip和端口sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)sock.bind((host,port))sock.listen(1)#这些都是上面官方文档里面调用的例程实现的#等待用户的连接 self.game ,addr = sock.accept() #sock.accept接收套接字#当客户端连接之后我们将获得代理服务器与客户端通信的套接字,并将其分配给self.game,然后在下面的线程中利用永久循环来接收用户端的数据def run(self):while True: #死循环接收用户的数据data = self.game.recv(4096)#最大数据量4kif data:    #如果真的接收到了用户发送过来的数据,那麽我们会尝试将此数据转发到服务器的套接字,即另外一个线程的套接字#转发给服务器print(" UE -------> Ueransim")self.server.sendall(data)#上面的两个线程创建完毕之后,需要为每一个线程提供对另外一个套接字的引用
#为此,我创建了一个更通用的类,命名为Proxy
class Proxy(Thread):def __init__(self,from_host,to_host,port):#如果没有在__init__中初始化对应的实例变量的话,导致后续引用实例变量会出错super(Proxy, self).__init__()self.from_host = from_host self.to_host = to_hostself.port = port def run(self):while True:#print ("[proxy({})] setting up")print ("Initialized, Waitting for connecting...")#用户会连接到下面这个self.g2p = Game2Proxy(self.from_host, self.port) #运行我们创建的这个线程,它等待用户端连接到指定端口#如果代理服务器与用户建立连接之后,另外一个线程将建立到服务器的转发连接self.p2s = Proxy2Server(self.to_host, self.port)print ("proxy connection established")print ("Connected!,Sending...")#现在两个线程都创建了套接字,我们接下来要做的就是交换他们self.g2p.server = self.p2s.server   #将与客户端建立的套接字转发给真实服务器self.p2s.game = self.g2p.game       #将服务器传回的套接字转发到客户端#线程设置完毕,现在我们来真正启动它self.g2p.start()self.p2s.start()#写到这里的时候,唯一缺少的就是创建一个或多个代理线程,我们先从主服务器开始
master_server = Proxy('192.168.62.1', '192.168.62.144', 8088)
#监听自己所有本机端口3333,并将它转发到真实的服务器ip 192.168.178.54
master_server.start()   #启动
  • TCPclient

import socket
import time
# 创建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Waitting for connecting...")
# 建立连接
tcp_client_socket.connect(("192.168.62.1", 8088))
print("Connected!")# 发送数据
print("Sending message...")
while 1:tcp_client_socket.send("你好".encode("gb2312"))time.sleep(2)
# 接收数据
recv_data = tcp_client_socket.recv(1024).decode("gb2312")
print(recv_data)# 关闭套接字
tcp_client_socket.close()
  • TCPserver

import socket
from threading import Threaddef new_client_connect(new_client_socket, client_ip_port):while True:# 收发数据recv_data = new_client_socket.recv(1024)if len(recv_data) != 0:recv_text = recv_data.decode("gb2312")print("Connected!")print(" Server from 5GC received [%s]:%s" % (str(client_ip_port), recv_text))else:print("Disconnected!")print("Waitting for connecting...")break# # 关闭连接# new_client_socket.close()  # 表示断开与当前的客户端的通信def main():# 创建套接字tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定端口和iptcp_server_socket.bind(("192.168.70.1", 8088))# 设置套接字为被动监听模式,不能主动发送数据,128为允许接收的最大连接数tcp_server_socket.listen(128)print("Waitting for connecting...")while True:# 接收客户端连接new_client_socket, client_ip_port = tcp_server_socket.accept()t1 = Thread(target=new_client_connect, args=(new_client_socket, client_ip_port))t1.start()# tcp_server_socket.close()  # 表示不再接受新客户端的连接,已经连接的可以继续服务if __name__ == '__main__':main()