Commit 297e09ea authored by liuyu's avatar liuyu

add udp

parent 090579d4
......@@ -35,3 +35,5 @@
archives
src/oai_rules_result*
test_results_oai_smf.html
.vscode
build
\ No newline at end of file
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.openairinterface.org/?page_id=698
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
SMF =
{
# FQDN = "oai-smf-svc";
INSTANCE = 1; # 0 is the default
PID_DIRECTORY = "/var/run"; # /var/run is the default
LOG_LEVEL = "debug";
INTERFACES :
{
N4 :
{
# SMF binded interface for N4 communication (UPF)
INTERFACE_NAME = "lo"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "127.0.0.100/8";
};
SBI :
{
# SMF binded interface for SBI interface (e.g., communication with AMF, UDM)
INTERFACE_NAME = "ens18"; # YOUR NETWORK CONFIG HERE
IPV4_ADDRESS = "read";
# YOUR NETWORK CONFIG HERE (default: 80)
PORT = 90;
# YOUR NETWORK CONFIG HERE (default: 8080)
HTTP2_PORT = 9090;
# YOUR NETWORK CONFIG HERE (default: v1)
API_VERSION = "v1";
};
};
# DNN configurations with pool of UE assigned IP addresses
# Do not make IP pools overlap
# first IPv4 address X.Y.Z.1 is reserved for GTP network device on UPF
DNN_LIST = (
# PDU_SESSION_TYPE choice in {IPv4, IPv6, IPv4v6}
# DNN IP ADDRESS RANGE format is for example: "12.2.1.2 - 12.2.1.128"
{DNN_NI = "default"; PDU_SESSION_TYPE = "IPv4"; IPV4_RANGE = "192.169.0.3 - 192.169.199.253"; IPV6_PREFIX = "2001:1:2::/64"},
{DNN_NI = "ims"; PDU_SESSION_TYPE = "IPv4v6"; IPV4_RANGE = "192.169.200.2 - 192.169.255.253"; IPV6_PREFIX = "3001:1:2::/64"},
{DNN_NI = "ctnet"; PDU_SESSION_TYPE = "IPv4v6"; IPV4_RANGE = "192.169.0.3 - 192.169.199.253"; IPV6_PREFIX = "4001:1:2::/64"},
{DNN_NI = "internet"; PDU_SESSION_TYPE = "IPv4"; IPV4_RANGE = "192.169.0.3 - 192.169.199.253"; IPV6_PREFIX = "5001:1:2::/64"}
);
# DNS address communicated to UEs
DEFAULT_DNS_IPV4_ADDRESS = "114.114.114.114"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_SEC_IPV4_ADDRESS = "8.8.8.8"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_IPV6_ADDRESS = "2001:4860:4860::8888"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844"; # YOUR DNS CONFIG HERE
#Default P-CSCF server
DEFAULT_CSCF_IPV4_ADDRESS = "127.0.0.1";
DEFAULT_CSCF_IPV6_ADDRESS = "fe80::7915:f408:1787:db8b";
#Default UE MTU
UE_MTU = 1500;
# SUPPORT FEATURES
SUPPORT_FEATURES:
{
# STRING, {"yes", "no"},
# Set to yes if SMF resgisters to an NRF
REGISTER_NRF = "no";
# Set to yes to enable UPF discovery and selection
DISCOVER_UPF = "no";
# Set to yes to enable PCF discovery and selection
DISCOVER_PCF = "no";
# Non standard feature, normally should be set to "no",
# but you may need to set to yes for UE that do not explicitly request a PDN address through NAS signalling
FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS = "no";
# Set to yes if SMF uses local subscription information instead of from an UDM
USE_LOCAL_SUBSCRIPTION_INFO = "yes";
# Set to yes if SMF uses local PCC rules instead of from an PCF
USE_LOCAL_PCC_RULES = "yes";
# Set to yes if AMF/UDM/NRF/UPF will relying on a DNS to resolve FQDN
USE_FQDN_DNS = "no";
# Default: 1
HTTP_VERSION = 1;
# Set yes if UE USAGE REPORTING is to be done at UPF
ENABLE_USAGE_REPORTING = "no"
# Set yes if Downlink PDR is to be included in PFCP session establishment message
ENABLE_DL_PDR_IN_PFCP_SESS_ESTAB = "no"
# Set N3_LOCAL_IPV4_ADDRESS for SD-Fabric UPF
# N3_LOCAL_IPV4_ADDRESS = "0.0.0.0";
}
AMF :
{
IPV4_ADDRESS = "127.0.0.99";
PORT = 8004;
API_VERSION = "v1";
FQDN = "oai-amf"
};
UDM :
{
IPV4_ADDRESS = "192.168.70.137";
PORT = 80;
API_VERSION = "v2";
FQDN = "oai-udm"
};
NRF :
{
IPV4_ADDRESS = "192.168.70.130";
PORT = 80;
API_VERSION = "v1";
FQDN = "oai-nrf"
};
PCF :
{
IPV4_ADDRESS = "0.0.0.0";
PORT = 80;
API_VERSION = "v1";
FQDN = "localhost"
};
UPF_LIST = (
{
IPV4_ADDRESS = "127.0.0.101";
FQDN = "UPF";
NWI_LIST = (
{
DOMAIN_ACCESS = "access.oai.org",
DOMAIN_CORE = "core.oai.org"
}
)
}
);
LOCAL_CONFIGURATION :
{
SESSION_MANAGEMENT_SUBSCRIPTION_LIST = (
{ NSSAI_SST = 1, NSSAI_SD = 0xFFFFFF, DNN = "default", DEFAULT_SESSION_TYPE = "IPv4", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 9, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "1000Mbps", SESSION_AMBR_DL = "1000Mbps"},
{ NSSAI_SST = 1; NSSAI_SD = 0xFFFFFF, DNN = "ims", DEFAULT_SESSION_TYPE = "IPv4v6", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 5, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "100Mbps", SESSION_AMBR_DL = "100Mbps"},
{ NSSAI_SST = 1; NSSAI_SD = 0xFFFFFF, DNN = "ctnet", DEFAULT_SESSION_TYPE = "IPv4v6", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 9, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "1000Mbps", SESSION_AMBR_DL = "1000Mbps"},
{ NSSAI_SST = 1; NSSAI_SD = 0xFFFFFF, DNN = "internet", DEFAULT_SESSION_TYPE = "IPv4", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 9, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "1000Mbps", SESSION_AMBR_DL = "1000Mbps"}
);
};
};
#!/usr/bin/env python3
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the OAI Public License, Version 1.1 (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.openairinterface.org/?page_id=698
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
# contact@openairinterface.org
################################################################################
from jinja2 import Environment, FileSystemLoader
import socket
import os
import sys
CONFIG_FILE = str(os.getenv('CONFIG_FILE','/openair-amf/etc/amf.conf'))
MOUNT_CONFIG = str(os.getenv('MOUNT_CONFIG','no')).lower()
def resolve(hostname):
try:
return socket.gethostbyname(hostname)
except socket.error:
print(f"Not able to resolve {hostname}")
def render(filepath,funcs,values):
env = Environment(loader=FileSystemLoader(os.path.dirname(filepath)))
jinja_template = env.get_template(os.path.basename(filepath))
jinja_template.globals.update(funcs)
template_string = jinja_template.render(env=values)
return template_string
env_variables = dict()
#list of all the environment variables
for name, value in os.environ.items():
env_variables.update({name:value})
if MOUNT_CONFIG != "yes":
output = render(CONFIG_FILE,{"resolve":resolve},env_variables)
with open(CONFIG_FILE, "w") as fh:
fh.write(output)
print(f"Configuration file {CONFIG_FILE} is ready")
if len(sys.argv) == 1:
sys.exit(0)
os.execvp(sys.argv[1], sys.argv[1:]) #important for running the network function it works like exec $@
else:
print("Configuration file is mounted to the network function")
\ No newline at end of file
......@@ -35,6 +35,8 @@
#include <stdlib.h> // srand
#include <unistd.h> // get_pid(), pause()
#include <cooudp.hpp>
using namespace smf;
using namespace util;
using namespace std;
......@@ -131,6 +133,9 @@ int main(int argc, char** argv) {
exit(-EDEADLK);
}
udp_server_coop udp_uplink_("10.103.239.31",20001);
udp_server_coop udp_downlink_("10.103.239.31",20004);
// SMF Pistache API server (HTTP1)
Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*) &smf_cfg.sbi.addr4))),
......
......@@ -22,11 +22,13 @@
include_directories(${SRC_TOP_DIR}/common)
include_directories(${SRC_TOP_DIR}/common/msg)
include_directories(${SRC_TOP_DIR}/common/utils)
include_directories(${SRC_TOP_DIR}/common/utils/bstr)
include_directories(${SRC_TOP_DIR}/itti)
include_directories(${SRC_TOP_DIR}/pfcp)
include_directories(${SRC_TOP_DIR}/udp)
include_directories(${SRC_TOP_DIR}/${MOUNTED_COMMON}/logger)
add_library (UDP STATIC
cooudp.cpp
udp.cpp
)
#include "logger.hpp"
#include "cooudp.hpp"
#include <nlohmann/json.hpp>
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
// #include "amf_sbi.hpp"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <iostream>
#include "cooudp.hpp"
#include <thread>
#include "bstrlib.h"
#include "sstream"
// extern "C" {
// #include "Ngap_InitiatingMessage.h"
// #include "Ngap_NGAP-PDU.h"
// }
void UdpSend(uint8_t buffer[],int n,string ip,int port){
//signal(SIGINT,hand);
int clientSocket;
struct timeval time;
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
clientSocket = socket(AF_INET,SOCK_DGRAM,0);
//2. 创建服务器协议地址簇
struct sockaddr_in cAddr = {0};
const char* ipAddr = ip.c_str();
cAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
cAddr.sin_addr.s_addr = inet_addr(ipAddr); //将字符串转整数
cAddr.sin_port = htons(port); //整数转整数 小端转大端
//3.通信
char temp[256];
int r;
int len = sizeof cAddr;
int sendNum;
sendNum = sendto(clientSocket,buffer,n,0,
(struct sockaddr*)&cAddr,len);
close(clientSocket);
gettimeofday(&time, NULL);
// //收消息
// r = recvfrom(clientSocket,temp,255,0,
// (struct sockaddr*)&cAddr,&len);
// if(r > 0){
// temp[r] = 0;
// printf("服务器发来信息>> %s\n",temp);
// }
}
using namespace std;
udp_server_coop::udp_server_coop(const char* udp_address,uint16_t udp_port_num){
cout<<"start create socket"<<endl;
create_socket(udp_address,udp_port_num);
cout<<"start receive"<<endl;
start_receive(udp_);
}
udp_server_coop::~udp_server_coop(){}
int udp_server_coop::create_socket(const char* udp_address,uint16_t udp_port_num){
//1. 创建socket 参数一: 协议类型(版本) 参数二: 通信媒介 参数三: 保护方式
cout<<"start"<<endl;
serverSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(-1 == serverSocket) printf("创建socket失败:%m\n"),exit(-1);
printf("创建socket成功!\n");
//2. 创建服务器协议地址簇
struct sockaddr_in sAddr = {0};
//uint16_t port = 8000;
//const char* ip_address= "10.103.239.24";
sAddr.sin_family = AF_INET; //协议类型 和socket函数第一个参数一致
sAddr.sin_addr.s_addr = inet_addr(udp_address); //将字符串转整数
sAddr.sin_port = htons(udp_port_num); //整数转整数 小端转大端
//3.绑定
int r = bind(serverSocket,(struct sockaddr*)&sAddr,sizeof sAddr);
if(-1 == r) printf("绑定失败:%m\n"),close(serverSocket),exit(-2);
printf("绑定成功!\n");
return serverSocket;
// struct sockaddr_in addr = {};
// int sd = 0;
// /*
// * Create UDP socket
// */
// if ((sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
// /*
// * Socket creation has failed...
// */
// printf("Socket creation failed (%s)\n", strerror(errno));
// return errno;
// }
// addr.sin_family = AF_INET;
// addr.sin_port = htons(udp_port_num);
// addr.sin_addr.s_addr = inet_addr(udp_address);
// std::string ipv4 = udp_address;
// printf(
// "Creating new listen socket on address %s and port %" PRIu16 " ",
// ipv4.c_str(), udp_port_num);
// if (bind(sd, (struct sockaddr*) &addr, sizeof(struct sockaddr_in)) < 0) {
// /*
// * Bind failed
// */
// printf(
// "Socket bind failed (%s) for address %s and port %" PRIu16 " \n",
// strerror(errno), ipv4.c_str(), udp_port_num);
// close(sd);
// return errno;
// }
}
void udp_server_coop::start_receive(udp_server_coop* udp){
udp_ = udp;
//pthread_create(&udp_thread, NULL, udp_receiver_thread, (void*) this);
//pthread_exit(NULL);
thread_ = std::thread(&udp_server_coop::udp_read_from_socket,this);
thread_.detach();
}
// void* udp_server_coop::udp_receiver_thread(void* arg) {
// udp_server_coop* ptr = (udp_server_coop*) arg;
// //Logger::udp().info("Create pthread to receive udp message");
// ptr->udp_read_from_socket();
// }
int udp_server_coop::getSocket(){
return serverSocket;
}
int udp_server_coop::getPpid(){
return ppid;
}
int udp_server_coop::udp_read_from_socket() {
//4.通信
uint8_t udp_recv[UDP_RECV_BUFFER_SIZE];
//bstring udp_recv;
//struct sockaddr_in cAddr = {0};
//socklen_t len = sizeof(cAddr);
endpoint r_endpoint = {};
//socklen_t addr_len;
int udp_len;
size_t bytes_received = 0;
cout<<"start receive"<<endl;
struct timeval time;
while(1){
r_endpoint.addr_storage_len=sizeof(struct sockaddr_storage);
//如果还需要向客户端发送东西用recvfrom
//udp精髓 向一个协议地址簇发东西
//收消息
//r = recvfrom(serverSocket,udp_recv,udp_len,0,(struct sockaddr*)&cAddr,&len);
bytes_received = recvfrom(serverSocket, (void *)udp_recv, UDP_RECV_BUFFER_SIZE , 0, (struct sockaddr*)&r_endpoint.addr_storage, &r_endpoint.addr_storage_len);
//bytes_received = recvfrom(serverSocket, udp_recv, UDP_RECV_BUFFER_SIZE , 0, (struct sockaddr*)&r_endpoint.addr_storage, &r_endpoint.addr_storage_len);
if(bytes_received > 0){
printf("smf receive udp success from amf\n");
gettimeofday(&time, NULL);
// std::cout<<"receive from plugin, ms: "<<(time.tv_sec*1000 + time.tv_usec/1000)<<std::endl;
// cout<<"bytes"<<bytes_received<<endl;
// cout<<"content:"<<udp_recv<<endl;
// string udp_recv_str(&udp_recv[0],&udp_recv[strlen(udp_recv)]);
// cout<<"content:"<<udp_recv_str<<endl;
// handle_receive_udp(bytes_received,udp_recv);
printf("smf send udp to center amf\n");
UdpSend(udp_recv,bytes_received,"10.103.238.72",20003);
// assoc_id++;
// stream++;
//ngap_app("0",0).handle_receive(udp_recv_str,assoc_id,stream,0,0);
}
}
return 0;
}
vector<string> SplitString(string s, string c){
string::size_type pos1, pos2;
vector<string> v;
pos2 = s.find(c);
pos1 = 0;
while(string::npos != pos2)
{
v.push_back(s.substr(pos1, pos2-pos1));
pos1 = pos2 + c.size();
pos2 = s.find(c, pos1);
}
if(pos1 != s.length())
v.push_back(s.substr(pos1));
return v;
}
void udp_server_coop::handle_receive_udp(int r,uint8_t udp_recv[]){
vector<string> MsgVec;
uint8_t buffer[2048];
//拆分字符串分出连接号
// ngap_msg_stream<<udp_recv;
// ngap_msg_stream>>ngap_msg;
//MsgVec = SplitString(ngap_msg,"|");
//数组赋值
for(int i=0;i<r-2;i++){
buffer[i] = udp_recv[i];
}
int _assoc_id = udp_recv[r-2];
int _stream = udp_recv[r-1];
//打印buffer检查数据
// std::cout<<"buffer: ";
// for(int i = 0; i < r-2; i++)
// {
// std::stringstream data;
// data << std::hex << (int)buffer[i];
// std::cout << data.str();
// }
// std::cout<<std::endl;
bstring payload=blk2bstr(buffer,r-2);
// //bstring udp_recv_bstr=bfromcstr(content.c_str());
// cout<<"data:"<<payload->data<<endl;
// cout<<"slen"<<payload->slen<<endl;
// cout<<"mlen"<<payload->mlen<<endl;
cout<<"start handle"<<endl;
// ngap_app("0",0).handle_receive(payload,assoc_id,stream,0,0);
// Ngap_NGAP_PDU_t* ngap_msg_pdu =
// (Ngap_NGAP_PDU_t*) calloc(1, sizeof(Ngap_NGAP_PDU_t));
// Logger::udp().info("start decode");
// asn_dec_rval_t rc = asn_decode(
// NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_Ngap_NGAP_PDU,
// (void**) &ngap_msg_pdu, bdata(udp_recv_bstr), blength(udp_recv_bstr));
// Logger::udp().debug(
// "Decoded UDP message, procedure code %d, present %d",
// ngap_msg_pdu->choice.initiatingMessage->procedureCode,
// ngap_msg_pdu->present);
// asn_fprint(stderr, &asn_DEF_Ngap_NGAP_PDU, ngap_msg_pdu);
// (*messages_callback[ngap_msg_pdu->choice.initiatingMessage->procedureCode]
// [ngap_msg_pdu->present - 1])(
// assoc_id, stream, ngap_msg_pdu);
}
#ifndef __COOUDP_H
#define __COOUDP_H
#include "conversions.hpp"
#include "endpoint.hpp"
#include "itti.hpp"
#include "thread_sched.hpp"
#include "logger.hpp"
#include <arpa/inet.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <iostream>
#include <map>
#include <memory>
#include <stdint.h>
#include <string>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
#define UDP_RECV_BUFFER_SIZE 8192
using namespace std;
class udp_server_coop{
private:
void* udp_recv;
struct sockaddr_in cAddr = {0};
socklen_t len = sizeof(cAddr);
int udp_len;
uint16_t m_port;
const char* m_address;
int serverSocket;
udp_server_coop* udp_;
pthread_t udp_thread;
uint32_t ppid;
std::thread thread_;
public:
udp_server_coop(const char* address,uint16_t port_num);
virtual ~udp_server_coop();
int create_socket(const char* address,uint16_t port_num);
void start_receive(udp_server_coop* udp);
void handle_receive();
static void* udp_receiver_thread(void* arg);
int udp_read_from_socket();
void handle_receive_udp(int r,uint8_t udp_recv[]);
int getSocket();
int getPpid();
//void SplitString(string s, vector<string>& v, string c);
};
#endif
\ No newline at end of file
cp ./etc/smf.conf ./etc/smf_copy.conf
export CONFIG_FILE=./etc/smf_copy.conf
export MOUNT_CONFIG=NO
export TZ=Europe/Paris
export SMF_INTERFACE_NAME_FOR_N4=eth0
export SMF_INTERFACE_NAME_FOR_SBI=eth0
export DEFAULT_DNS_IPV4_ADDRESS=172.21.3.100
export DEFAULT_DNS_SEC_IPV4_ADDRESS=8.8.8.8
export REGISTER_NRF=yes
export DISCOVER_UPF=yes
export USE_LOCAL_SUBSCRIPTION_INFO=yes
export USE_FQDN_DNS=yes
export AMF_IPV4_ADDRESS=192.168.70.132
export AMF_FQDN=oai-amf
export UDM_IPV4_ADDRESS=192.168.70.137
export UDM_API_VERSION=v2
export UDM_FQDN=oai-udm
export NRF_IPV4_ADDRESS=192.168.70.130
export NRF_FQDN=oai-nrf
export UPF_IPV4_ADDRESS=192.168.70.134
export UPF_FQDN_0=oai-spgwu
export DNN_NI0=oai
export TYPE0=IPv4
export DNN_RANGE0='12.1.1.151 - 12.1.1.253'
export NSSAI_SST0=1
#export NSSAI_SD0=123
export SESSION_AMBR_UL0=200Mbps
export SESSION_AMBR_DL0=400Mbps
./scripts/entrypoint.py
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment