* Copyright (c) 2025-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* 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.
*/
#include "urspconfig.h"
#include "cellular_data_client.h"
#include "hwnetworkslicemanager.h"
#include "networkslicemanager.h"
#include <parameters.h>
#include <charconv>
namespace OHOS {
namespace NetManagerStandard {
static std::string DEFAULT_NETSLICE_CONFIG_DIR = "/system/profile/";
static std::string URSP_FILENAME1 = "UrspConfig1.xml";
static std::string URSP_FILENAME2 = "UrspConfig2.xml";
const std::string COMMA_SEPARATOR = ",";
const std::string PORT_RANGE_SEPARATOR = "-";
const std::string TAG_UEPOLICY = "uePolicy";
const std::string TAG_PRECONFIGURSP = "preConfigUrsp";
const std::string TAG_TRAFFICDESCRIPTOR = "trafficDescriptor";
const std::string TAG_ROUTESELECTIONDESCRIPTOR = "routeSelectionDescriptor";
const std::string TAG_ROUTESELECTIONDESCRIPTORCONTENTS = "routeSelectionDescriptorContents";
const std::string ATTR_PLMN = "plmn";
const std::string ATTR_URSPPRECEDENCE = "precedence";
const std::string ATTR_TRAFFICDESCRIPTORTYPE = "trafficDescriptorComponentTypeIdentifier";
const std::string ATTR_TRAFFICDESCRIPTORVALUE = "trafficDescriptorComponentValue";
const std::string ATTR_ROUTEPRECEDENCE = "precedenceValueOfRouteSelectionDescriptor";
const std::string ATTR_RSDTYPE = "routeSelectionDescriptorComponentTypeIdentifier";
const std::string ATTR_RSDVALUE = "routeSelectionDescriptorComponentValue";
const std::string NETWORKSLICE_WHITELIST = "networkslice_whitelist";
constexpr int URSPFILE_ID2 = 2;
constexpr int MODEM_ID = 0;
constexpr int BASE_16 = 16;
constexpr int DECODE_FAIL_UNKNOWN_IDENTIFIER = 1;
constexpr int DECODE_SUCCESS = 0;
constexpr int DECODE_FAIL_OTHER = -1;
constexpr int PREFERRED_ACCESS_TYPE_NON_3GPP = 0x10;
constexpr int FIRSTBYTE = 1;
constexpr int SECONDBYTE = 2;
constexpr int THIRDBYTE = 3;
* traffic descriptor component
*/
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_MATCH_ALL = 0x01;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_OS_ID_OS_APP_ID = 0x08;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_IPV4_ADDR = 0x10;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_IPV6_ADDR = 0x21;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_PROTOCOL_ID = 0x30;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_SINGLE_REMOTE_PORT = 0x50;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_REMOTE_PORT_RANGE = 0x51;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_DNN = 0x88;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_CONNECTION_CAPABILITY = 0x90;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_FQDN = 0x91;
constexpr int TRAFFIC_DESCRIPTOR_COMPONENT_OS_APP_ID = 0xA0;
* route selection descriptor
*/
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SSC_MODE_TYPE = 1;
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SNSSAI = 2;
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_DNN = 4;
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PDU_SESSION_TYPE = 8;
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PREFERRED_ACCESS_TYPE = 16;
constexpr int ROUTE_SELECTION_DESCRIPTOR_COMPONENT_NON_3GPP_OFFLOAD = 32;
* protocol pdu session type value
*/
constexpr int PROTOCOL_PDU_SESSION_TYPE_IPV4 = 1;
constexpr int PROTOCOL_PDU_SESSION_TYPE_IPV6 = 2;
constexpr int PROTOCOL_PDU_SESSION_TYPE_IPV4V6 = 3;
constexpr int PROTOCOL_PDU_SESSION_TYPE_UNSTRUCTURED = 4;
constexpr int PROTOCOL_PDU_SESSION_TYPE_ETHERNET = 5;
constexpr int PROTOCOL_PDU_SESSION_TYPE_RESERVED = 7;
* HAL pdu session type value
*/
constexpr int HAL_PDU_SESSION_TYPE_IP = 0;
constexpr int HAL_PDU_SESSION_TYPE_IPV6 = 1;
constexpr int HAL_PDU_SESSION_TYPE_IPV4V6 = 2;
constexpr int HAL_PDU_SESSION_TYPE_NON_IP = 4;
constexpr int HAL_PDU_SESSION_TYPE_UNSTRUCTURED = 5;
constexpr int32_t CONNECTION_CAPABILITY_TYPE_IMS = 1;
constexpr int RSD_MAX_DNN_NUM = 2;
constexpr int RSD_MAX_NSSAI_NUM = 3;
constexpr int RSD_MAX_LIST_NUM = 3;
constexpr int INVALID_VALUE = 0;
constexpr int RSD_MAX_DNN_LEN = 99;
constexpr short IMSA_VERSION = 1;
UrspConfig& UrspConfig::GetInstance()
{
static UrspConfig instance;
return instance;
}
UrspConfig::UrspConfig()
{
NETMGR_EXT_LOG_I("init UrspConfig start");
ParseConfig();
}
void UrspConfig::ParseConfig()
{
NETMGR_EXT_LOG_I("UrspConfig::ParseConfig ");
int urspid = system::GetIntParameter("persist.sys.choose_ursp", 1);
std::string urspName = URSP_FILENAME1;
if (urspid == URSPFILE_ID2) {
urspName = URSP_FILENAME2;
}
std::string path = DEFAULT_NETSLICE_CONFIG_DIR + urspName;
if (path.empty()) {
NETMGR_EXT_LOG_E("config file path is empty!");
return;
}
xmlDocPtr doc = xmlReadFile(path.c_str(), NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
if (doc == NULL) {
NETMGR_EXT_LOG_E("exception parse config file:[%{public}s]! ", path.c_str());
return;
}
xmlNodePtr curNode = xmlDocGetRootElement(doc);
if (curNode == NULL) {
NETMGR_EXT_LOG_E("No root element found in config file!");
xmlFreeDoc(doc);
return;
}
ParseAllUePolicy(doc);
xmlFreeDoc(doc);
}
void UrspConfig::ParseAllUePolicy(xmlDocPtr doc)
{
NETMGR_EXT_LOG_I("UrspConfig::ParseAllUePolicy");
xmlNodePtr curNode = xmlDocGetRootElement(doc);
if (curNode == NULL) {
NETMGR_EXT_LOG_E("No root element found in config file!");
return;
}
std::string curName = std::string(reinterpret_cast<const char*>(curNode->name));
NETMGR_EXT_LOG_I("UrspConfig::ParseAllUePolicy::curName:%{public}s ", curName.c_str());
xmlNodePtr child = curNode->children;
while (child != NULL) {
if (child->type == XML_TEXT_NODE || child->type == XML_COMMENT_NODE) {
std::string childName(reinterpret_cast<const char*>(child->name));
NETMGR_EXT_LOG_I("continue childName:%{public}s ", childName.c_str());
child = child->next;
continue;
}
std::string childName(reinterpret_cast<const char*>(child->name));
NETMGR_EXT_LOG_I("UrspConfig::ParseAllUePolicy::childName:%{public}s ", childName.c_str());
if (child->type == XML_ELEMENT_NODE && childName.compare(TAG_UEPOLICY.c_str()) == 0) {
ParseUePolicy(child);
}
child = child->next;
}
SaveTrafficDescriptorWhiteListToDb();
DumpPreConfigUrspMap();
}
void UrspConfig::ParseUePolicy(xmlNodePtr curNode)
{
NETMGR_EXT_LOG_I("UrspConfig::ParseUePolicy");
std::vector<UrspRule> urspRules;
xmlChar *plmnstr = xmlGetProp(curNode, reinterpret_cast<const xmlChar *>(ATTR_PLMN.c_str()));
std::string plmnStr;
if (plmnstr != nullptr) {
plmnStr = std::string(reinterpret_cast<const char *>(plmnstr));
NETMGR_EXT_LOG_I("UrspConfig::ParseUePolicy::plmnStr = %{public}s", plmnStr.c_str());
xmlFree(plmnstr);
}
xmlNodePtr child = curNode->children;
while (child != NULL) {
if (child->type == XML_TEXT_NODE || child->type == XML_COMMENT_NODE) {
child = child->next;
continue;
}
std::string childName(reinterpret_cast<const char*>(child->name));
if (child->type == XML_ELEMENT_NODE && childName.compare(TAG_PRECONFIGURSP.c_str()) == 0) {
NETMGR_EXT_LOG_I("UrspConfig::ParseUePolicy::childName:%{public}s ", childName.c_str());
UrspRule urspRule = ParsePreConfigUrsp(child);
urspRules.push_back(urspRule);
}
child = child->next;
}
SndPreImsRsdList();
UrspRuleSort(urspRules);
mPreConfigUrspMap[plmnStr] = urspRules;
}
UrspRule UrspConfig::ParsePreConfigUrsp(xmlNodePtr node)
{
NETMGR_EXT_LOG_I("UrspConfig::ParsePreConfigUrsp ");
UrspRule urspRule;
xmlChar *urspprecedence = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_URSPPRECEDENCE.c_str()));
if (urspprecedence != nullptr) {
urspRule.urspPrecedence = atoi(reinterpret_cast<char *>(urspprecedence));
NETMGR_EXT_LOG_I("UrspConfig::ParsePreConfigUrsp::urspPrecedence = %{public}d", urspRule.urspPrecedence);
xmlFree(urspprecedence);
}
xmlNodePtr child = node->children;
while (child != NULL) {
if (child->type == XML_TEXT_NODE || child->type == XML_COMMENT_NODE) {
child = child->next;
continue;
}
std::string childName(reinterpret_cast<const char*>(child->name));
NETMGR_EXT_LOG_I("UrspConfig::ParsePreConfigUrsp::childName = %{public}s", childName.c_str());
if (child->type == XML_ELEMENT_NODE && childName.compare(TAG_TRAFFICDESCRIPTOR.c_str()) == 0) {
ParseTrafficDescriptor(child, urspRule.trafficDescriptor);
} else if (child->type == XML_ELEMENT_NODE && childName.compare(TAG_ROUTESELECTIONDESCRIPTOR.c_str()) == 0) {
ParseRouteSelectionDescriptor(child, urspRule.routeSelectionDescriptors);
}
child = child->next;
}
if (mIsTrafficDescriptorIncludeIms) {
NETMGR_EXT_LOG_I("UrspConfig::ParsePreConfigUrsp IncludeIms");
mImsRsdsMap[urspRule.urspPrecedence] = urspRule.routeSelectionDescriptors;
mIsTrafficDescriptorIncludeIms = false;
}
return urspRule;
}
void UrspConfig::ParseTrafficDescriptor(xmlNodePtr node, TrafficDescriptor &trafficDescriptor)
{
xmlChar *attrvalue = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORTYPE.c_str()));
std::string attrValue;
if (attrvalue != nullptr) {
attrValue = std::string(reinterpret_cast<char *>(attrvalue));
xmlFree(attrvalue);
}
int trafficDescriptorType = 0;
std::from_chars(attrValue.data(), attrValue.data() + attrValue.size(), trafficDescriptorType);
xmlChar *AttrtrafficDescriptorvalue = nullptr;
switch (trafficDescriptorType) {
case TRAFFIC_DESCRIPTOR_COMPONENT_MATCH_ALL:
trafficDescriptor.isMatchAll = true;
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_OS_ID_OS_APP_ID:
ParseOsAppId(node, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_IPV4_ADDR:
ParseIpv4Addr(node, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_IPV6_ADDR:
ParseIpv6Addr(node, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_PROTOCOL_ID:
case TRAFFIC_DESCRIPTOR_COMPONENT_SINGLE_REMOTE_PORT:
case TRAFFIC_DESCRIPTOR_COMPONENT_REMOTE_PORT_RANGE:
case TRAFFIC_DESCRIPTOR_COMPONENT_DNN:
case TRAFFIC_DESCRIPTOR_COMPONENT_FQDN:
case TRAFFIC_DESCRIPTOR_COMPONENT_CONNECTION_CAPABILITY:
ParseTrafficDescriptorEx(node, trafficDescriptor, attrValue);
break;
default:
break;
}
if (AttrtrafficDescriptorvalue != nullptr) {
xmlFree(AttrtrafficDescriptorvalue);
}
}
void UrspConfig::ParseTrafficDescriptorEx(xmlNodePtr node, TrafficDescriptor &trafficDescriptor, std::string attrValue)
{
std::string trafficDescriptorValue;
int trafficDescriptorType = std::stoi(attrValue);
xmlChar *AttrtrafficDescriptorvalue = nullptr;
switch (trafficDescriptorType) {
case TRAFFIC_DESCRIPTOR_COMPONENT_PROTOCOL_ID:
AttrtrafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
trafficDescriptorValue = (std::string)reinterpret_cast<char *>(AttrtrafficDescriptorvalue);
trafficDescriptor.protocolIds.push_back(std::stoi(trafficDescriptorValue));
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_SINGLE_REMOTE_PORT:
AttrtrafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
trafficDescriptorValue = (std::string)reinterpret_cast<char *>(AttrtrafficDescriptorvalue);
trafficDescriptor.singleRemotePorts.push_back(std::stoi(trafficDescriptorValue));
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_REMOTE_PORT_RANGE:
ParseRemotePortRange(node, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_DNN:
AttrtrafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
trafficDescriptorValue = (std::string)reinterpret_cast<char *>(AttrtrafficDescriptorvalue);
if (trafficDescriptorValue == "ims" || trafficDescriptorValue == "IMS") {
mIsTrafficDescriptorIncludeIms = true;
}
trafficDescriptor.dnns.push_back(trafficDescriptorValue);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_FQDN:
AttrtrafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
trafficDescriptorValue = (std::string)reinterpret_cast<char *>(AttrtrafficDescriptorvalue);
trafficDescriptor.fqdns.push_back(trafficDescriptorValue);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_CONNECTION_CAPABILITY:
ParseConnectionCapabilities(node, trafficDescriptor);
break;
}
}
void UrspConfig::ParseRouteSelectionDescriptor(xmlNodePtr node,
std::vector<RouteSelectionDescriptor> &routeSelectionDescriptors)
{
NETMGR_EXT_LOG_I("UrspConfig::ParseRouteSelectionDescriptor ");
xmlChar *attrvalue = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_ROUTEPRECEDENCE.c_str()));
std::string attrValue;
if (attrvalue != nullptr) {
attrValue = std::string(reinterpret_cast<char *>(attrvalue));
xmlFree(attrvalue);
}
NETMGR_EXT_LOG_I("routeSelectionDescriptorPrecedence::%{public}s", attrValue.c_str());
int Precedence = std::stoi(attrValue);
RouteSelectionDescriptor routeSelectionDescriptor;
routeSelectionDescriptor.routePrecedence = Precedence;
xmlNodePtr child = node->children;
while (child != NULL) {
if (child->type == XML_TEXT_NODE || child->type == XML_COMMENT_NODE) {
child = child->next;
continue;
}
std::string childName(reinterpret_cast<const char*>(child->name));
if (child->type == XML_ELEMENT_NODE &&
childName.compare(TAG_ROUTESELECTIONDESCRIPTORCONTENTS.c_str()) == 0) {
ParseRouteRule(child, routeSelectionDescriptor);
}
child = child->next;
}
routeSelectionDescriptors.push_back(routeSelectionDescriptor);
}
void UrspConfig::ParseRouteRule(xmlNodePtr node, RouteSelectionDescriptor &routeSelectionDescriptor)
{
std::string routeRuleValue;
Snssai snssai;
xmlChar *attrvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_RSDTYPE.c_str()));
std::string attrValue;
if (attrvalue != nullptr) {
attrValue = std::string(reinterpret_cast<char *>(attrvalue));
xmlFree(attrvalue);
}
int routeRuleType = std::stoi(attrValue);
NETMGR_EXT_LOG_I("ParseRouteRule routeRuleType = %{public}d", routeRuleType);
xmlChar *AttrrouteRulevalue = nullptr;
switch (routeRuleType) {
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SSC_MODE_TYPE:
AttrrouteRulevalue = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_RSDVALUE.c_str()));
routeRuleValue = (std::string)reinterpret_cast<char *>(AttrrouteRulevalue);
routeSelectionDescriptor.sscMode = static_cast<int>(std::stoi(routeRuleValue));
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SNSSAI:
AttrrouteRulevalue = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_RSDVALUE.c_str()));
routeRuleValue = (std::string)reinterpret_cast<char *>(AttrrouteRulevalue);
snssai.setSnssai(routeRuleValue);
if (sAllowedNssaiConfig_->ParseSnssai(snssai) == false) {
NETMGR_EXT_LOG_E("parseSNssai(sNssai) is false");
break;
}
routeSelectionDescriptor.snssais.push_back(snssai);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_DNN:
AttrrouteRulevalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_RSDVALUE.c_str()));
routeRuleValue = (std::string)reinterpret_cast<char *>(AttrrouteRulevalue);
routeSelectionDescriptor.dnns.push_back(routeRuleValue);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PDU_SESSION_TYPE:
AttrrouteRulevalue = xmlGetProp(node, reinterpret_cast<const xmlChar *>(ATTR_RSDVALUE.c_str()));
routeRuleValue = (std::string)reinterpret_cast<char *>(AttrrouteRulevalue);
routeSelectionDescriptor.pduSessionType = static_cast<int>(std::stoi(routeRuleValue));
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PREFERRED_ACCESS_TYPE:
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_NON_3GPP_OFFLOAD:
break;
default:
break;
}
if (AttrrouteRulevalue != nullptr) {
xmlFree(AttrrouteRulevalue);
}
}
bool UrspConfig::ParseOsAppId(xmlNodePtr node, TrafficDescriptor& trafficDescriptor)
{
xmlChar *trafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
std::string trafficDescriptorValue = (std::string)reinterpret_cast<char *>(trafficDescriptorvalue);
xmlFree(trafficDescriptorvalue);
std::vector<std::string> values;
values = Split(trafficDescriptorValue, COMMA_SEPARATOR);
if (values.size() < SECONDBYTE) {
return false;
}
OsAppId osAppId;
osAppId.setOsId(values[0]);
osAppId.setAppId(values[1]);
trafficDescriptor.osAppIds.push_back(osAppId);
return true;
}
bool UrspConfig::ParseIpv4Addr(xmlNodePtr node, TrafficDescriptor& trafficDescriptor)
{
xmlChar *trafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
std::string trafficDescriptorValue = (std::string)reinterpret_cast<char *>(trafficDescriptorvalue);
xmlFree(trafficDescriptorvalue);
std::vector<std::string> values;
values = Split(trafficDescriptorValue, COMMA_SEPARATOR);
if (values.size() < SECONDBYTE) {
return false;
}
uint32_t ipv4Address = 0;
uint32_t ipv4Mask = 0;
Ipv4Addr ipv4Addr;
ipv4Address = inet_addr(values[0].c_str());
if (ipv4Address == INADDR_NONE) {
return false;
}
ipv4Mask = inet_addr(values[1].c_str());
if (ipv4Mask == INADDR_NONE) {
return false;
}
ipv4Addr.setIpv4Addr(ipv4Address);
ipv4Addr.setIpv4Mask(ipv4Mask);
trafficDescriptor.ipv4Addrs.push_back(ipv4Addr);
return true;
}
bool UrspConfig::ParseIpv6Addr(xmlNodePtr node, TrafficDescriptor& trafficDescriptor)
{
xmlChar *trafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
std::string trafficDescriptorValue = (std::string)reinterpret_cast<char *>(trafficDescriptorvalue);
xmlFree(trafficDescriptorvalue);
std::vector<std::string> values;
values = Split(trafficDescriptorValue, COMMA_SEPARATOR);
if (values.size() < SECONDBYTE) {
return false;
}
struct in6_addr ipv6;
int prefixLen = 0;
Ipv6Addr ipv6Addr;
if (inet_pton(AF_INET6, values[0].c_str(), &ipv6) == 0) {
return false;
}
prefixLen = std::stoi(values[1]);
ipv6Addr.setIpv6Addr(*reinterpret_cast<std::array<uint8_t, BASE_16>*>(ipv6.s6_addr));
ipv6Addr.setIpv6PrefixLen(prefixLen);
trafficDescriptor.ipv6Addrs.push_back(ipv6Addr);
return true;
}
bool UrspConfig::ParseRemotePortRange(xmlNodePtr node, TrafficDescriptor& trafficDescriptor)
{
xmlChar *trafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
std::string trafficDescriptorValue = (std::string)reinterpret_cast<char *>(trafficDescriptorvalue);
xmlFree(trafficDescriptorvalue);
std::vector<std::string> values;
values = Split(trafficDescriptorValue, COMMA_SEPARATOR);
if (values.size() < SECONDBYTE) {
return false;
}
RemotePortRange portRang;
portRang.setPortRangeLowLimit(std::stoi(values[0]));
portRang.setPortRangeHighLimit(std::stoi(values[1]));
trafficDescriptor.remotePortRanges.push_back(portRang);
return true;
}
bool UrspConfig::ParseConnectionCapabilities(xmlNodePtr node, TrafficDescriptor& trafficDescriptor)
{
xmlChar *trafficDescriptorvalue = xmlGetProp(node,
reinterpret_cast<const xmlChar *>(ATTR_TRAFFICDESCRIPTORVALUE.c_str()));
std::string trafficDescriptorValue = (std::string)reinterpret_cast<char *>(trafficDescriptorvalue);
xmlFree(trafficDescriptorvalue);
int connectionCapabilityType = std::stoi(trafficDescriptorValue);
if ((connectionCapabilityType & CONNECTION_CAPABILITY_TYPE_IMS) != 0) {
mIsTrafficDescriptorIncludeIms = true;
}
trafficDescriptor.connectionCapabilities.push_back(connectionCapabilityType);
return true;
}
void UrspConfig::setUrspRules(const std::string& plmn, std::vector<UrspRule>& urspRules)
{
UrspRuleSort(urspRules);
mUePolicyMap[plmn] = urspRules;
}
void UrspConfig::ClearUrspRules()
{
mUePolicyMap.clear();
}
void UrspConfig::SetUrspVersion(int urspVersion)
{
mUrspVersion = urspVersion;
}
void UrspConfig::UrspRuleSort(std::vector<UrspRule>& urspRules)
{
for (auto& urspRule : urspRules) {
std::sort(urspRule.routeSelectionDescriptors.begin(),
urspRule.routeSelectionDescriptors.end(), [](const auto& r1, const auto& r2) {
return r1.routePrecedence < r2.routePrecedence;
});
}
std::sort(urspRules.begin(), urspRules.end(), [](const auto& r1, const auto& r2) {
return r1.urspPrecedence < r2.urspPrecedence;
});
}
void UrspConfig::SaveTrafficDescriptorWhiteListToDb()
{
NETMGR_EXT_LOG_I("SaveTrafficDescriptorWhiteList ");
std::shared_ptr<TrafficDescriptorWhiteList> whiteList = std::make_shared<TrafficDescriptorWhiteList>();
std::vector<UrspRule> urspRules;
std::unordered_map<std::string, std::vector<UrspRule>> uePolicyMap =
mUePolicyMap.empty() ? mPreConfigUrspMap : mUePolicyMap;
for (const auto& entry : uePolicyMap) {
urspRules = entry.second;
FillTrafficDescriptorWhiteList(whiteList, urspRules);
}
if (whiteList != nullptr) {
DelayedSingleton<HwNetworkSliceManager>::GetInstance()->GetTrafficDescriptorWhiteList(*whiteList);
}
}
void UrspConfig::FillTrafficDescriptorWhiteList(std::shared_ptr<TrafficDescriptorWhiteList>& whiteList,
const std::vector<UrspRule>& urspRules)
{
NETMGR_EXT_LOG_I("FillTrafficDescriptorWhiteList ");
for (const auto& urspRule : urspRules) {
const TrafficDescriptor& trafficDescriptor = urspRule.trafficDescriptor;
for (auto& osAppId : trafficDescriptor.osAppIds) {
std::string osAppIdStr = osAppId.getOsId() + "#" + osAppId.getAppId();
if (!whiteList->osAppIds.empty() && whiteList->osAppIds.find(osAppIdStr) != std::string::npos) {
continue;
}
if (!whiteList->osAppIds.empty()) {
whiteList->osAppIds += COMMA_SEPARATOR;
}
whiteList->osAppIds += osAppIdStr;
}
for (const auto& dnn : trafficDescriptor.dnns) {
if (!whiteList->dnns.empty() && whiteList->dnns.find(dnn) != std::string::npos) {
continue;
}
if (!whiteList->dnns.empty()) {
whiteList->dnns += COMMA_SEPARATOR;
}
whiteList->dnns += dnn;
}
for (const auto& fqdn : trafficDescriptor.fqdns) {
if (!whiteList->fqdns.empty() && whiteList->fqdns.find(fqdn) != std::string::npos) {
continue;
}
if (!whiteList->fqdns.empty()) {
whiteList->fqdns += COMMA_SEPARATOR;
}
whiteList->fqdns += fqdn;
}
for (const auto& connectionCapability : trafficDescriptor.connectionCapabilities) {
if (!whiteList->cct.empty() && whiteList->cct.find(connectionCapability) != std::string::npos) {
continue;
}
if (!whiteList->cct.empty()) {
whiteList->cct += COMMA_SEPARATOR;
}
whiteList->cct += std::to_string(connectionCapability);
}
}
}
bool UrspConfig::DecodeUrspRules(int inputLen, int& startIndex,
std::vector<uint8_t> buffer, std::vector<UrspRule>& urspRules)
{
int startIndex_tmp = startIndex;
SetUrspVersion(NetworkSliceCommConfig::URSP_VERSION_1520);
if (DecodeUrspByVersion(inputLen, startIndex, buffer, urspRules, NetworkSliceCommConfig::URSP_VERSION_1520)) {
NETMGR_EXT_LOG_I("decodeUrspRules, success urspVersion is 1520");
sSuccUrspVersion = NetworkSliceCommConfig::URSP_VERSION_1520;
return true;
}
SetUrspVersion(NetworkSliceCommConfig::URSP_VERSION_1510);
if (DecodeUrspByVersion(inputLen, startIndex_tmp, buffer, urspRules, NetworkSliceCommConfig::URSP_VERSION_1510)) {
NETMGR_EXT_LOG_I("decodeUrspRules, success urspVersion is 1510");
sSuccUrspVersion = NetworkSliceCommConfig::URSP_VERSION_1510;
return true;
}
NETMGR_EXT_LOG_E("decodeUrspRules(inputLen, buffer, urspRules) is false");
return false;
}
short UrspConfig::GetSuccUrspVersion()
{
return sSuccUrspVersion;
}
bool UrspConfig::DecodeUrspByVersion(int inputLen, int& startIndex,
std::vector<uint8_t> buffer, std::vector<UrspRule>& urspRules, short version)
{
int subLen;
int len = inputLen;
NETMGR_EXT_LOG_I("version[%{public}d]:startIndex:%{public}d", version, startIndex);
while (len > 0) {
subLen = GetSubLenByversion(startIndex, buffer, version);
if (subLen == DECODE_FAIL_OTHER) {
return false;
}
len = len - GetLenBytesByversion(version) - subLen;
if (((int(buffer.size()) - startIndex) < subLen) || (len < 0)) {
NETMGR_EXT_LOG_E("(buffer.remaining()[%{public}d] < subLen[%{public}d]) || (len[%{public}d] < 0)",
(int(buffer.size()) - startIndex), subLen, len);
return false;
}
if (!DecodeUrspRule(subLen, startIndex, buffer, urspRules, version)) {
urspRules.clear();
ResetImsRsdsMap();
NETMGR_EXT_LOG_E("decodeUrspRule(subLen, buffer, urspRules, verision) is false");
return false;
}
}
return true;
}
void UrspConfig::ResetImsRsdsMap()
{
mIsTrafficDescriptorIncludeIms = false;
mImsRsdsMap.clear();
}
int UrspConfig::GetSubLenByversion(int& startIndex, std::vector<uint8_t> buffer, short version)
{
int subLen;
if (version == NetworkSliceCommConfig::URSP_VERSION_1510) {
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < NetworkSliceCommConfig::LEN_BYTE");
return DECODE_FAIL_OTHER;
}
subLen = ConvertUnsignedShort2Int(buffer[startIndex++]);
} else if (version == NetworkSliceCommConfig::URSP_VERSION_1520) {
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
NETMGR_EXT_LOG_E("buffer.remaining() < NetworkSliceCommConfig::LEN_BYTE");
return DECODE_FAIL_OTHER;
}
short subLen_short = GetShort(startIndex, buffer);
subLen = ConvertUnsignedShort2Int(subLen_short);
} else {
NETMGR_EXT_LOG_E("Ursp version invalid");
return DECODE_FAIL_OTHER;
}
return subLen;
}
int UrspConfig::GetLenBytesByversion(short version)
{
if (version == NetworkSliceCommConfig::URSP_VERSION_1510) {
return NetworkSliceCommConfig::LEN_BYTE;
} else {
return NetworkSliceCommConfig::LEN_SHORT;
}
}
bool UrspConfig::DecodeUrspRule(int inputLen, int& startIndex,
std::vector<uint8_t> buffer, std::vector<UrspRule>& urspRules, short version)
{
NETMGR_EXT_LOG_I("DecodeUrspRule");
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_THREE_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining()[%{public}d] < NetworkSliceCommConfig::LEN_THREE_BYTE",
(int(buffer.size()) - startIndex));
return false;
}
UrspRule urspRule;
urspRule.urspPrecedence = ConvertUnsignedShort2Int(buffer[startIndex++]);
return DecodeUrspRuleExtra(inputLen, startIndex, buffer, urspRule, urspRules, version);
}
bool UrspConfig::DecodeUrspRuleExtra(int inputLen, int& startIndex, std::vector<uint8_t> buffer,
UrspRule& urspRule, std::vector<UrspRule>& urspRules, short version)
{
int trafficDescriptorLen = ConvertUnsignedShort2Int(GetShort(startIndex, buffer));
int len = inputLen;
if (((int(buffer.size()) - startIndex) < trafficDescriptorLen)
|| (len < (NetworkSliceCommConfig::LEN_THREE_BYTE + trafficDescriptorLen))) {
NETMGR_EXT_LOG_E("buffer.remaining() < trafficDescriptorLen");
return false;
}
len = len - NetworkSliceCommConfig::LEN_THREE_BYTE - trafficDescriptorLen;
int ret = DecodeTrafficDescriptor(trafficDescriptorLen, startIndex, buffer, urspRule.trafficDescriptor);
if (ret == DECODE_FAIL_OTHER) {
return false;
}
if (ret == DECODE_FAIL_UNKNOWN_IDENTIFIER) {
if ((int(buffer.size()) - startIndex) < len) {
NETMGR_EXT_LOG_E("buffer.remaining() < len");
return false;
}
std::vector<uint8_t> dsts =std::vector<uint8_t>(len);
std::copy(buffer.begin() + startIndex, buffer.begin() + startIndex + len, dsts.begin());
return true;
}
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
NETMGR_EXT_LOG_E("buffer.remaining() < NetworkSliceCommConfig::LEN_SHORT");
return false;
}
int routeRuleListLen = ConvertUnsignedShort2Int(GetShort(startIndex, buffer));
if (((int(buffer.size()) - startIndex) < routeRuleListLen)
|| (len != NetworkSliceCommConfig::LEN_SHORT + routeRuleListLen)) {
NETMGR_EXT_LOG_E("buffer.remaining[%{public}d] < routeRuleListLen[%{public}d]",
(int(buffer.size()) - startIndex), routeRuleListLen);
return false;
}
ret = DecodeRouteRuleList(routeRuleListLen, startIndex, buffer, urspRule, version);
if (ret == DECODE_FAIL_OTHER) {
return false;
}
if (ret == DECODE_FAIL_UNKNOWN_IDENTIFIER) {
return true;
}
if (mIsTrafficDescriptorIncludeIms) {
NETMGR_EXT_LOG_I("UrspConfig::DecodeUrspRuleExtra IncludeIms");
mImsRsdsMap[urspRule.urspPrecedence] = urspRule.routeSelectionDescriptors;
mIsTrafficDescriptorIncludeIms = false;
}
urspRules.push_back(urspRule);
return true;
}
int UrspConfig::DecodeTrafficDescriptor(int inputLen, int& startIndex,
std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
NETMGR_EXT_LOG_I("DecodeTrafficDescriptor");
int len = inputLen;
int initBufferRemaining = (int(buffer.size()) - startIndex);
while (initBufferRemaining - (int(buffer.size()) - startIndex) < len) {
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Traffic descriptor component type identifier Len");
return DECODE_FAIL_OTHER;
}
int type = static_cast<int>(buffer[startIndex++]);
int ret = DECODE_SUCCESS;
switch (type) {
case TRAFFIC_DESCRIPTOR_COMPONENT_MATCH_ALL:
trafficDescriptor.isMatchAll = true;
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_OS_ID_OS_APP_ID:
ret = DecodeOsIdOsAppId(startIndex, buffer, trafficDescriptor, false);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_IPV4_ADDR:
ret = DecodeIpv4Addr(startIndex, buffer, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_IPV6_ADDR:
ret = DecodeIpv6Addr(startIndex, buffer, trafficDescriptor);
break;
case TRAFFIC_DESCRIPTOR_COMPONENT_PROTOCOL_ID:
ret = DecodeProtocolId(startIndex, buffer, trafficDescriptor);
break;
default:
ret = DecodeTrafficDescriptorExtra(inputLen, startIndex, type,
buffer, trafficDescriptor, initBufferRemaining);
break;
}
if (ret != DECODE_SUCCESS) {
return ret;
}
}
return DECODE_SUCCESS;
}
int UrspConfig::DecodeRouteRuleList(int inputLen, int& startIndex,
std::vector<uint8_t> buffer, UrspRule& urspRule, short version)
{
NETMGR_EXT_LOG_I("DecodeRouteRuleList");
int subLen;
int len = inputLen;
while (len > 0) {
subLen = GetSubLenByversion(startIndex, buffer, version);
if (subLen == DECODE_FAIL_OTHER) {
return DECODE_FAIL_OTHER;
}
len = len - GetLenBytesByversion(version) - subLen;
if ((int(buffer.size()) - startIndex) < subLen || (len < 0)) {
NETMGR_EXT_LOG_E("(buffer.remaining([%{public}d]) < subLen[%{public}d]) || (len[%{public}d] < 0)",
(int(buffer.size()) - startIndex), subLen, len);
return DECODE_FAIL_OTHER;
}
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_THREE_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < NetworkSliceCommConfig::LEN_THREE_BYTE");
return DECODE_FAIL_OTHER;
}
RouteSelectionDescriptor routeRule;
routeRule.routePrecedence = buffer[startIndex++];
int routeRuleLen = ConvertUnsignedShort2Int(GetShort(startIndex, buffer));
if (((int(buffer.size()) - startIndex) < routeRuleLen)
|| (subLen != NetworkSliceCommConfig::LEN_THREE_BYTE + routeRuleLen)) {
NETMGR_EXT_LOG_E("buffer.remaining([%{public}d]) < routeRuleLen[%{public}d], subLen[%{public}d])",
(int(buffer.size()) - startIndex), routeRuleLen, subLen);
return DECODE_FAIL_OTHER;
}
int ret = DecodeRouteRule(startIndex, routeRuleLen, buffer, routeRule);
if (ret == DECODE_FAIL_OTHER) {
return DECODE_FAIL_OTHER;
}
if (ret == DECODE_FAIL_UNKNOWN_IDENTIFIER) {
continue;
}
urspRule.routeSelectionDescriptors.push_back(routeRule);
}
if (urspRule.routeSelectionDescriptors.empty()) {
return DECODE_FAIL_UNKNOWN_IDENTIFIER;
}
return DECODE_SUCCESS;
}
int UrspConfig::DecodeTrafficDescriptorExtra(int inputLen, int& startIndex, int type,
std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor, int initBufferRemaining)
{
int ret = DECODE_SUCCESS;
int len = inputLen;
switch (type) {
case TRAFFIC_DESCRIPTOR_COMPONENT_SINGLE_REMOTE_PORT:
ret = DecodeSingleRemotePort(startIndex, buffer, trafficDescriptor);
return ret;
case TRAFFIC_DESCRIPTOR_COMPONENT_REMOTE_PORT_RANGE:
ret = DecodeRemotePortRange(startIndex, buffer, trafficDescriptor);
return ret;
case TRAFFIC_DESCRIPTOR_COMPONENT_DNN:
ret = DecodeTrafficDescriptorDnn(startIndex, buffer, trafficDescriptor);
return ret;
case TRAFFIC_DESCRIPTOR_COMPONENT_FQDN:
ret = DecodeFqdn(startIndex, buffer, trafficDescriptor);
if (ret == DECODE_FAIL_UNKNOWN_IDENTIFIER) {
int sublen = len - (initBufferRemaining - (int(buffer.size()) - startIndex));
std::vector<uint8_t> dsts = std::vector<uint8_t>(sublen);
for (int i = 0; i < sublen; ++i) {
dsts[i] = buffer[startIndex];
startIndex++;
}
}
return ret;
case TRAFFIC_DESCRIPTOR_COMPONENT_CONNECTION_CAPABILITY:
ret = DecodeConnectionCapabilities(startIndex, buffer, trafficDescriptor);
return ret;
case TRAFFIC_DESCRIPTOR_COMPONENT_OS_APP_ID:
ret = DecodeOsIdOsAppId(startIndex, buffer, trafficDescriptor, true);
return ret;
default:
NETMGR_EXT_LOG_E("decodeTrafficDescriptor failed, invalid Traffic descriptor component type identifier");
int sublen = len - (initBufferRemaining - (int(buffer.size()) - startIndex));
std::vector<uint8_t> dsts = std::vector<uint8_t>(sublen);
for (int i = 0; i < sublen; ++i) {
dsts[i] = buffer[startIndex];
startIndex++;
}
return ret;
}
}
int UrspConfig::DecodeRouteRule(int& startIndex, int inputLen,
std::vector<uint8_t> buffer, RouteSelectionDescriptor& routeRule)
{
int len = inputLen;
int initBufferRemaining = (int(buffer.size()) - startIndex);
while (initBufferRemaining - (int(buffer.size()) - startIndex) < len) {
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Route selection descriptor component type identifier len");
return DECODE_FAIL_OTHER;
}
int type = static_cast<int>(buffer[startIndex++]);
int ret = DECODE_SUCCESS;
switch (type) {
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SSC_MODE_TYPE:
ret = DecodeSscMode(startIndex, buffer, routeRule);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_SNSSAI:
ret = DecodeSnssai(startIndex, buffer, routeRule);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_DNN:
ret = DecodeDnn(startIndex, buffer, routeRule);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PDU_SESSION_TYPE:
ret = DecodePduSessionType(startIndex, buffer, routeRule);
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_PREFERRED_ACCESS_TYPE:
ret = DecodePreferredAccessType(startIndex, buffer, routeRule);
if (ret == DECODE_FAIL_UNKNOWN_IDENTIFIER) {
int sublen = len - (initBufferRemaining - (int(buffer.size()) - startIndex));
std::vector<uint8_t> dsts = std::vector<uint8_t>(sublen);
std::copy(buffer.begin() + startIndex, buffer.begin() + startIndex + sublen, dsts.begin());
startIndex += sublen;
}
break;
case ROUTE_SELECTION_DESCRIPTOR_COMPONENT_NON_3GPP_OFFLOAD:
break;
default:
int sublen = len - (initBufferRemaining - (int(buffer.size()) - startIndex));
std::vector<uint8_t> dsts = std::vector<uint8_t>(sublen);
for (int i = 0; i < sublen; ++i) {
dsts[i] = buffer[startIndex];
startIndex++;
}
ret = DECODE_FAIL_UNKNOWN_IDENTIFIER;
break;
}
if (ret != DECODE_SUCCESS) {
return ret;
}
}
return DECODE_SUCCESS;
}
int UrspConfig::DecodeOsIdOsAppId(int& startIndex, std::vector<uint8_t> buffer,
TrafficDescriptor& trafficDescriptor, bool isAppIdOnly)
{
if ((!isAppIdOnly) && ((int(buffer.size()) - startIndex) < (NetworkSliceCommConfig::LEN_SIXTEEN_BYTE
+ NetworkSliceCommConfig::LEN_BYTE))) {
NETMGR_EXT_LOG_E("buffer.remaining() < osId Len");
return DECODE_FAIL_OTHER;
}
std::string osId = "";
if (!isAppIdOnly) {
for (int i = 0; i < NetworkSliceCommConfig::LEN_SIXTEEN_BYTE; i++) {
osId += ByteToHexStr(buffer[startIndex++]);
}
}
OsAppId osAppId;
osAppId.setOsId(osId);
uint8_t stringLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < stringLen) {
NETMGR_EXT_LOG_E("buffer.remaining() < appId Len");
return DECODE_FAIL_OTHER;
}
std::string stringBuffer = "";
for (int i = 0; i < stringLen; i++) {
stringBuffer += static_cast<char>(buffer[startIndex++]);
}
NETMGR_EXT_LOG_I("DecodeOsId:%{public}s, OsAppId:%{public}s", osId.c_str(), stringBuffer.c_str());
osAppId.setAppId(stringBuffer);
trafficDescriptor.osAppIds.push_back(osAppId);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeIpv4Addr(int& startIndex, std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
std::vector<uint8_t> ipv4(NetworkSliceCommConfig::LEN_INT, 0);
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_EIGHT_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Ipv4Addr Len");
return DECODE_FAIL_OTHER;
}
for (int i = 0; i < NetworkSliceCommConfig::LEN_INT; i++) {
ipv4[i] = buffer[startIndex++];
}
Ipv4Addr ipv4Addr;
ipv4Addr.setIpv4Addr(vectorToUint32(ipv4));
for (int i = 0; i < NetworkSliceCommConfig::LEN_INT; i++) {
ipv4[i] = buffer[startIndex++];
}
ipv4Addr.setIpv4Mask(vectorToUint32(ipv4));
trafficDescriptor.ipv4Addrs.push_back(ipv4Addr);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeIpv6Addr(int& startIndex, std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
std::vector<uint8_t> ipv6(NetworkSliceCommConfig::LEN_SIXTEEN_BYTE, 0);
if ((int(buffer.size()) - startIndex) <
NetworkSliceCommConfig::LEN_SIXTEEN_BYTE + NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Ipv6Addr Len");
return DECODE_FAIL_OTHER;
}
for (int i = 0; i < NetworkSliceCommConfig::LEN_SIXTEEN_BYTE; i++) {
ipv6[i] = buffer[startIndex++];
}
Ipv6Addr ipv6Addr;
ipv6Addr.setIpv6Addr(vectorToIPv6Array(ipv6));
ipv6Addr.setIpv6PrefixLen(static_cast<int>(buffer[startIndex++]));
trafficDescriptor.ipv6Addrs.push_back(ipv6Addr);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeProtocolId(int& startIndex, std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Protocol identifier/next header type Len");
return DECODE_FAIL_OTHER;
}
trafficDescriptor.protocolIds.push_back(static_cast<int>(buffer[startIndex++]));
return DECODE_SUCCESS;
}
int UrspConfig::DecodeSingleRemotePort(int& startIndex, std::vector<uint8_t> buffer,
TrafficDescriptor& trafficDescriptor)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
NETMGR_EXT_LOG_E("buffer.remaining() < Single remote port type Len");
return DECODE_FAIL_OTHER;
}
trafficDescriptor.singleRemotePorts.push_back(ConvertUnsignedShort2Int(GetShort(startIndex, buffer)));
return DECODE_SUCCESS;
}
int UrspConfig::DecodeRemotePortRange(int& startIndex,
std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_INT) {
NETMGR_EXT_LOG_E("buffer.remaining() < Remote port range type Len");
return DECODE_FAIL_OTHER;
}
RemotePortRange portRang;
portRang.setPortRangeLowLimit(ConvertUnsignedShort2Int(GetShort(startIndex, buffer)));
portRang.setPortRangeHighLimit(ConvertUnsignedShort2Int(GetShort(startIndex, buffer)));
trafficDescriptor.remotePortRanges.push_back(portRang);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeTrafficDescriptorDnn(int& startIndex, std::vector<uint8_t> buffer,
TrafficDescriptor& trafficDescriptor)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < LEN_BYTE for dnn type");
return DECODE_FAIL_OTHER;
}
uint8_t stringLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < stringLen) {
NETMGR_EXT_LOG_E("buffer.remaining()[%{public}d] < dnn Len[%{public}d]",
(int(buffer.size()) - startIndex), stringLen);
return DECODE_FAIL_OTHER;
}
std::string stringBuffer = DecodeSubDnns(startIndex, buffer, stringLen);
if (stringBuffer == "") {
return DECODE_FAIL_OTHER;
}
std::string dnn = stringBuffer;
trafficDescriptor.dnns.push_back(dnn);
if ("ims" == dnn || "IMS" == dnn) {
mIsTrafficDescriptorIncludeIms = true;
}
return DECODE_SUCCESS;
}
int UrspConfig::DecodeFqdn(int& startIndex, std::vector<uint8_t> buffer, TrafficDescriptor& trafficDescriptor)
{
if (mUrspVersion == NetworkSliceCommConfig::URSP_VERSION_1510) {
NETMGR_EXT_LOG_E("mUrspVersion = 1510 but Traffic descriptor is FQDN");
return DECODE_FAIL_UNKNOWN_IDENTIFIER;
}
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < LEN_BYTE for fqdn type");
return DECODE_FAIL_OTHER;
}
uint8_t stringLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < stringLen) {
NETMGR_EXT_LOG_E("buffer.remaining() < fqdn Len");
return DECODE_FAIL_OTHER;
}
std::string stringBuffer = DecodeSubDnns(startIndex, buffer, stringLen);
if (stringBuffer == "") {
return DECODE_FAIL_OTHER;
}
trafficDescriptor.fqdns.push_back(stringBuffer);
return DECODE_SUCCESS;
}
std::string UrspConfig::DecodeSubDnns(int& startIndex, std::vector<uint8_t> buffer, uint8_t stringLen)
{
std::string stringBuffer = "";
int cnt = 0;
for (int i = 0; i < (int)stringLen; i++) {
if (cnt == 0) {
cnt = buffer[startIndex++];
if (cnt > stringLen - i - 1) {
NETMGR_EXT_LOG_E("buffer remaining [%{public}d] < sub dnn len [%{public}d]", (stringLen - i), cnt);
return "";
}
if (i > 0) {
stringBuffer += ".";
}
} else {
stringBuffer += static_cast<char>(buffer[startIndex++]);
cnt--;
}
}
if (cnt > 0) {
NETMGR_EXT_LOG_E("can not get full sub dnn [%{public}d]", cnt);
return "";
}
return stringBuffer;
}
int UrspConfig::DecodeConnectionCapabilities(int& startIndex, std::vector<uint8_t> buffer,
TrafficDescriptor& trafficDescriptor)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < LEN_BYTE for Connection capabilities type");
return DECODE_FAIL_OTHER;
}
uint8_t stringLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < stringLen) {
NETMGR_EXT_LOG_E("buffer.remaining() < Connection capabilities type len");
return DECODE_FAIL_OTHER;
}
for (int i = 0; i < stringLen; i++) {
int connCapability = static_cast<int>(buffer[startIndex++]);
trafficDescriptor.connectionCapabilities.push_back(connCapability);
if ((connCapability & CONNECTION_CAPABILITY_TYPE_IMS) != 0) {
mIsTrafficDescriptorIncludeIms = true;
}
}
return DECODE_SUCCESS;
}
int UrspConfig::DecodeSscMode(int& startIndex, std::vector<uint8_t> buffer, RouteSelectionDescriptor &routeRule)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < SSC mode type len");
return DECODE_FAIL_OTHER;
}
* The bits 8 through 4 of the octet shall be spare,
* and the bits 3 through 1 shall be encoded as the value part of the SSC mode
*/
routeRule.sscMode = buffer[startIndex++] & 0x07;
NETMGR_EXT_LOG_I("SSC mode:%{public}d", routeRule.sscMode);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeSnssai(int& startIndex, std::vector<uint8_t> buffer, RouteSelectionDescriptor &routeRule)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < LEN_BYTE for S-NSSAI type");
return DECODE_FAIL_OTHER;
}
uint8_t subLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < subLen) {
NETMGR_EXT_LOG_E("buffer.remaining() < S-NSSAI type len");
return DECODE_FAIL_OTHER;
}
Snssai snssai;
if (!sAllowedNssaiConfig_->DecodeSnssai(startIndex, subLen, buffer, snssai)) {
NETMGR_EXT_LOG_E("AllowedNssaiConfig.decodeSNssai(subLen, buffer, sNssai) is false");
return DECODE_FAIL_OTHER;
}
routeRule.snssais.push_back(snssai);
return DECODE_SUCCESS;
}
int UrspConfig::DecodeDnn(int& startIndex, std::vector<uint8_t> buffer, RouteSelectionDescriptor &routeRule)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < LEN_BYTE for dnn type");
return DECODE_FAIL_OTHER;
}
uint8_t stringLen = buffer[startIndex++];
if ((int(buffer.size()) - startIndex) < stringLen) {
NETMGR_EXT_LOG_E("buffer.remaining()[%{public}d] < dnn Len[%{public}d]",
(int(buffer.size()) - startIndex), stringLen);
return DECODE_FAIL_OTHER;
}
std::string stringBuffer = DecodeSubDnns(startIndex, buffer, stringLen);
if (stringBuffer == "") {
return DECODE_FAIL_OTHER;
}
std::string dnn = stringBuffer;
NETMGR_EXT_LOG_I("DNN:%{public}s", dnn.c_str());
routeRule.dnns.push_back(dnn);
return DECODE_SUCCESS;
}
int UrspConfig::DecodePduSessionType(int& startIndex, std::vector<uint8_t> buffer, RouteSelectionDescriptor &routeRule)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < Preferred access type len");
return DECODE_FAIL_OTHER;
}
* The bits 8 through 4 of the octet shall be spare,
* and the bits 3 through 1 shall be encoded as the value part of the PDU session type
*/
routeRule.pduSessionType = TransferPduSessionTypeToHal(buffer[startIndex++] & 0x07);
NETMGR_EXT_LOG_I("decodePduSessionType pduSessionType = %{public}d", routeRule.pduSessionType);
return DECODE_SUCCESS;
}
int UrspConfig::TransferPduSessionTypeToHal(int pduSessionType)
{
NETMGR_EXT_LOG_I("transferPduSessionTypeToHal pduSessionType = %{public}d", pduSessionType);
switch (pduSessionType) {
case PROTOCOL_PDU_SESSION_TYPE_IPV4:
return HAL_PDU_SESSION_TYPE_IP;
case PROTOCOL_PDU_SESSION_TYPE_IPV6:
return HAL_PDU_SESSION_TYPE_IPV6;
case PROTOCOL_PDU_SESSION_TYPE_IPV4V6:
return HAL_PDU_SESSION_TYPE_IPV4V6;
case PROTOCOL_PDU_SESSION_TYPE_UNSTRUCTURED:
return HAL_PDU_SESSION_TYPE_UNSTRUCTURED;
case PROTOCOL_PDU_SESSION_TYPE_ETHERNET:
return HAL_PDU_SESSION_TYPE_NON_IP;
case PROTOCOL_PDU_SESSION_TYPE_RESERVED:
return HAL_PDU_SESSION_TYPE_IPV4V6;
default:
return HAL_PDU_SESSION_TYPE_IPV4V6;
}
}
int UrspConfig::DecodePreferredAccessType(int& startIndex, std::vector<uint8_t> buffer,
RouteSelectionDescriptor &routeRule)
{
if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_BYTE) {
NETMGR_EXT_LOG_E("buffer.remaining() < PDU session type len");
return DECODE_FAIL_OTHER;
}
if (buffer[startIndex++] == PREFERRED_ACCESS_TYPE_NON_3GPP) {
return DECODE_FAIL_UNKNOWN_IDENTIFIER;
}
return DECODE_SUCCESS;
}
void UrspConfig::SndPreImsRsdList()
{
std::vector<uint8_t> rsdBytes = GetImsRsdList();
if (!rsdBytes.empty()) {
NETMGR_EXT_LOG_I("UrspConfig::SndPreImsRsdList");
Telephony::CellularDataClient::GetInstance().SendImsRsdList(MODEM_ID, rsdBytes);
}
}
std::vector<uint8_t> UrspConfig::GetImsRsdList()
{
if (mImsRsdsMap.empty()) {
return std::vector<uint8_t>();
}
std::vector<uint8_t> rsdBytes = ConvertRsdList2BufferArray(mImsRsdsMap);
ResetImsRsdsMap();
return rsdBytes;
}
std::vector<RouteSelectionDescriptor> UrspConfig::SortRsdsMap(
std::unordered_map<int, std::vector<RouteSelectionDescriptor>> rsdsMap)
{
std::vector<int> keyList;
for (auto& it: rsdsMap) {
keyList.push_back(it.first);
}
std::sort(keyList.begin(), keyList.end(), [](int a, int b) { return a > b;});
std::vector<RouteSelectionDescriptor> rsdList;
for (int& key : keyList) {
std::vector<RouteSelectionDescriptor> outOfOrderList = rsdsMap[key];
std::sort(outOfOrderList.begin(), outOfOrderList.end(), [](auto& r1, auto& r2) {
return r1.routePrecedence < r2.routePrecedence;
});
rsdList.insert(rsdList.end(), outOfOrderList.begin(), outOfOrderList.end());
}
return rsdList;
}
std::vector<uint8_t> UrspConfig::ConvertRsdList2BufferArray(
std::unordered_map<int, std::vector<RouteSelectionDescriptor>> rsdsMap)
{
std::vector<RouteSelectionDescriptor> rsdList = SortRsdsMap(rsdsMap);
for (size_t i = 0; i < rsdList.size(); ++i) {
if (sAllowedNssaiConfig_ == nullptr) {
break;
}
if (rsdList[i].snssais.size() == 0) {
++i;
continue;
}
if (sAllowedNssaiConfig_->FindSnssaiInAllowedNssai(rsdList[i].snssais) != "") {
++i;
continue;
} else {
rsdList.erase(rsdList.begin() + i);
}
}
if (rsdList.size() == 0) {
return NotifyImsaDelRsdInfo();
}
while (rsdList.size() > RSD_MAX_LIST_NUM) {
rsdList.erase(rsdList.begin() + RSD_MAX_LIST_NUM);
}
int dataLen = CalculateRsdListLen();
int rsdNum = rsdList.size();
NETMGR_EXT_LOG_I("convertRsdList2Buffer rsdNum = %{public}d, dataLen = %{public}d", rsdNum, dataLen);
std::vector<uint8_t> rsdBytes;
if (dataLen == INVALID_VALUE) {
NETMGR_EXT_LOG_E("dataLen of rsdList is 0 ");
return rsdBytes;
}
PutShort(rsdBytes, IMSA_VERSION);
PutShort(rsdBytes, static_cast<short>(dataLen));
PutInt(rsdBytes, rsdNum);
PutRsdListInfo(rsdBytes, rsdList);
return rsdBytes;
}
void UrspConfig::PutRsdListInfo(std::vector<uint8_t>& buffer, std::vector<RouteSelectionDescriptor> rsdList)
{
int rsdNum = (int)rsdList.size();
int emptyRsdNum = RSD_MAX_LIST_NUM - rsdNum;
for (RouteSelectionDescriptor rsd : rsdList) {
buffer.push_back(ConvertInt2UnsignedByte(rsd.routePrecedence));
buffer.push_back(0);
buffer.push_back(0);
buffer.push_back(0);
if (rsd.sscMode == 0) {
buffer.push_back(0);
} else {
buffer.push_back(1);
}
buffer.push_back(rsd.sscMode);
buffer.push_back(ConvertInt2UnsignedByte(ConvertPduTypeFromHal2Imsa(rsd.pduSessionType)));
buffer.push_back(0);
buffer.push_back(0);
PutDnnsInfo(buffer, rsd);
PutNssaisInfo(buffer, rsd);
buffer.push_back(0);
buffer.push_back(0);
buffer.push_back(0);
buffer.push_back(0);
}
if (emptyRsdNum > 0) {
int rsdLen = CalculateRsdLen();
int nullLen = rsdLen * emptyRsdNum;
PutInvalidValue(buffer, nullLen);
}
}
void UrspConfig::PutDnnsInfo(std::vector<uint8_t>& buffer, RouteSelectionDescriptor rsd)
{
while (rsd.dnns.size() > RSD_MAX_DNN_NUM) {
rsd.dnns.erase(rsd.dnns.begin() + RSD_MAX_DNN_NUM);
}
int dnnNum = rsd.dnns.size();
int emptyNum = RSD_MAX_DNN_NUM - dnnNum;
PutInt(buffer, dnnNum);
for (std::string dnn : rsd.dnns) {
std::vector<uint8_t> dnnBytes = ConvertstringTouInt8Vector(dnn);
int dnnLen = dnnBytes.size();
int nullNum = RSD_MAX_DNN_LEN - dnnLen;
buffer.push_back(ConvertInt2UnsignedByte(dnnLen));
buffer.insert(buffer.end(), dnnBytes.begin(), dnnBytes.end());
if (nullNum > 0) {
PutInvalidValue(buffer, nullNum);
}
}
if (emptyNum > 0) {
int nullNum = emptyNum * (RSD_MAX_DNN_LEN + NetworkSliceCommConfig::LEN_BYTE);
PutInvalidValue(buffer, nullNum);
}
}
void UrspConfig::PutNssaisInfo(std::vector<uint8_t>& buffer, RouteSelectionDescriptor rsd)
{
for (int i = 0; i < (int)rsd.snssais.size();) {
if (sAllowedNssaiConfig_ == nullptr) {
break;
}
if (sAllowedNssaiConfig_->isSnssaiInAllowedNssai(rsd.snssais[i]) != "") {
i++;
continue;
} else {
rsd.snssais.erase(rsd.snssais.begin() + i);
}
}
while (rsd.snssais.size() > RSD_MAX_NSSAI_NUM) {
rsd.snssais.erase(rsd.snssais.begin() + RSD_MAX_NSSAI_NUM);
}
int snssaiNum = (int)rsd.snssais.size();
int emptyNum = RSD_MAX_NSSAI_NUM - snssaiNum;
PutInt(buffer, snssaiNum);
for (Snssai snssai : rsd.snssais) {
int bitOpt = 0;
if (snssai.getSd() != 0) {
bitOpt = SetBitOpt(bitOpt, FIRSTBYTE);
}
if (snssai.getMappedSst() != 0) {
bitOpt = SetBitOpt(bitOpt, SECONDBYTE);
}
if (snssai.getMappedSd() != 0) {
bitOpt = SetBitOpt(bitOpt, THIRDBYTE);
}
PutInt(buffer, bitOpt);
buffer.push_back(snssai.getSst());
buffer.push_back(snssai.getMappedSst());
buffer.push_back(0);
buffer.push_back(0);
PutInt(buffer, snssai.getSd());
PutInt(buffer, snssai.getMappedSd());
}
if (emptyNum > 0) {
int snssaiLen = (4 + 1 + 1 + 2 + 4 + 4) * NetworkSliceCommConfig::LEN_BYTE;
int nullNum = emptyNum * snssaiLen;
PutInvalidValue(buffer, nullNum);
}
}
int UrspConfig::SetBitOpt(int num, int position)
{
int temp = 1;
temp <<= position - 1;
num = num | temp;
return num;
}
int UrspConfig::ConvertPduTypeFromHal2Imsa(int halPduType)
{
return (halPduType + 1);
}
std::vector<uint8_t> UrspConfig::NotifyImsaDelRsdInfo()
{
std::vector<uint8_t> buffer;
PutShort(buffer, IMSA_VERSION);
PutShort(buffer, 0);
return buffer;
}
void UrspConfig::PutInvalidValue(std::vector<uint8_t>& buffer, int num)
{
for (int i = 0; i < num; i++) {
buffer.push_back(0);
}
}
short UrspConfig::CalculateRsdListLen()
{
short dataLen = 0;
dataLen += NetworkSliceCommConfig::LEN_INT;
dataLen += CalculateRsdLen() * RSD_MAX_LIST_NUM;
return dataLen;
}
short UrspConfig::CalculateRsdLen()
{
short dataLen = 0;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
dataLen += (RSD_MAX_DNN_LEN + NetworkSliceCommConfig::LEN_BYTE) * RSD_MAX_DNN_NUM;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
short snssaiLen = (4 + 1 + 1 + 2 + 4 + 4) * NetworkSliceCommConfig::LEN_BYTE;
dataLen += snssaiLen * RSD_MAX_NSSAI_NUM;
dataLen += 4 * NetworkSliceCommConfig::LEN_BYTE;
return dataLen;
}
bool UrspConfig::SliceNetworkSelection(
SelectedRouteDescriptor& routeRule, std::string plmn, AppDescriptor appDescriptor)
{
NETMGR_EXT_LOG_I("SliceNetworkSelection");
std::unordered_map<std::string, std::vector<UrspRule>> uePolicyMap =
mUePolicyMap.empty() ? mPreConfigUrspMap : mUePolicyMap;
std::vector<UrspRule> urspRules = uePolicyMap.begin()->second;
UrspRule urspRule;
for (size_t i = 0; i < urspRules.size(); i++) {
urspRule = urspRules[i];
if (!isTrafficDescriptorMatch(urspRule.trafficDescriptor, appDescriptor)) {
NETMGR_EXT_LOG_I("!isTrafficDescriptorMatch");
continue;
}
if (!FindAvailableRouteRule(urspRule.routeSelectionDescriptors, routeRule)) {
NETMGR_EXT_LOG_I("Not FindAvailableRouteRule");
continue;
}
routeRule.setUrspPrecedence(static_cast<uint8_t>(urspRule.urspPrecedence));
FillTrafficDescriptor(urspRule.trafficDescriptor, appDescriptor, routeRule);
return true;
}
return false;
}
bool UrspConfig::FindAvailableRouteRule(
const std::vector<RouteSelectionDescriptor>& routeSelectionDescriptors, SelectedRouteDescriptor& routeRule)
{
NETMGR_EXT_LOG_I("FindAvailableRouteRule size = %{public}d", (int)routeSelectionDescriptors.size());
for (size_t i = 0; i < routeSelectionDescriptors.size(); i++) {
routeRule.setPduSessionType(routeSelectionDescriptors[i].pduSessionType);
routeRule.setSscMode(routeSelectionDescriptors[i].sscMode);
if (DelayedSingleton<NetworkSliceManager>::GetInstance()->isRouteRuleInForbiddenList(routeRule)) {
NETMGR_EXT_LOG_I("isRouteRuleInForbiddenList");
continue;
}
if (!routeSelectionDescriptors[i].snssais.empty() && !routeSelectionDescriptors[i].dnns.empty()) {
if (!FindAvailableSnssaiAndDnn(routeSelectionDescriptors[i], routeRule)) {
continue;
}
}
if (!routeSelectionDescriptors[i].snssais.empty() && routeSelectionDescriptors[i].dnns.empty()) {
if (!FindAvailableSnssai(routeSelectionDescriptors[i], routeRule)) {
continue;
}
}
if (routeSelectionDescriptors[i].snssais.empty() && !routeSelectionDescriptors[i].dnns.empty()) {
if (!FindAvailableDnn(routeSelectionDescriptors[i], routeRule)) {
continue;
}
}
return true;
}
return false;
}
bool UrspConfig::FindAvailableSnssaiAndDnn(const RouteSelectionDescriptor& routeSelectionDescriptor,
SelectedRouteDescriptor& routeRule)
{
NETMGR_EXT_LOG_I("FindAvailableSnssaiAndDnn");
for (size_t i = 0; i < routeSelectionDescriptor.snssais.size(); i++) {
if (sAllowedNssaiConfig_ == nullptr) {
continue;
}
Snssai snssai = routeSelectionDescriptor.snssais[i];
std::string stringSnssai = sAllowedNssaiConfig_->isSnssaiInAllowedNssai(snssai);
NETMGR_EXT_LOG_I("FindAvailableSnssaiAndDnn stringSnssai = %{public}s", stringSnssai.c_str());
if (stringSnssai.empty()) {
continue;
}
routeRule.setSnssai(stringSnssai);
for (size_t j = 0; j < routeSelectionDescriptor.dnns.size(); j++) {
std::string dnn = routeSelectionDescriptor.dnns[j];
routeRule.setDnn(dnn);
NETMGR_EXT_LOG_I("FindAvailableDnn:%{public}s", dnn.c_str());
if (DelayedSingleton<NetworkSliceManager>::GetInstance()->isRouteRuleInForbiddenList(routeRule)) {
continue;
}
return true;
}
}
return false;
}
bool UrspConfig::FindAvailableSnssai(const RouteSelectionDescriptor& routeSelectionDescriptor,
SelectedRouteDescriptor& routeRule)
{
for (size_t i = 0; i < routeSelectionDescriptor.snssais.size(); i++) {
if (sAllowedNssaiConfig_ == nullptr) {
continue;
}
Snssai snssai = routeSelectionDescriptor.snssais[i];
NETMGR_EXT_LOG_I("FindAvailableSnssai snssai = %{public}s", snssai.getSnssai().c_str());
std::string stringSnssai = sAllowedNssaiConfig_->isSnssaiInAllowedNssai(snssai);
if (stringSnssai.empty()) {
continue;
}
routeRule.setSnssai(stringSnssai);
if (DelayedSingleton<NetworkSliceManager>::GetInstance()->isRouteRuleInForbiddenList(routeRule)) {
continue;
}
return true;
}
return false;
}
bool UrspConfig::FindAvailableDnn(const RouteSelectionDescriptor& routeSelectionDescriptor,
SelectedRouteDescriptor& routeRule)
{
for (size_t j = 0; j < routeSelectionDescriptor.dnns.size(); j++) {
const auto& dnn = routeSelectionDescriptor.dnns[j];
routeRule.setDnn(dnn);
if (DelayedSingleton<NetworkSliceManager>::GetInstance()->isRouteRuleInForbiddenList(routeRule)) {
continue;
}
return true;
}
return false;
}
* judge if has available ursp rule
*
* @return true: has available ursp rule false: do not have available ursp rule
*/
bool UrspConfig::hasAvailableUrspRule()
{
return (!mUePolicyMap.empty() || !mPreConfigUrspMap.empty());
}
void UrspConfig::FillTrafficDescriptor(TrafficDescriptor urspTrafficDescriptor,
AppDescriptor appDescriptor, SelectedRouteDescriptor& routeRule)
{
NETMGR_EXT_LOG_I("FillTrafficDescriptor");
uint8_t routeBitmap = 0;
if (urspTrafficDescriptor.isMatchAll) {
routeBitmap = static_cast<uint8_t>(routeBitmap | 0x01);
routeRule.setRouteBitmap(routeBitmap);
return;
}
if (!urspTrafficDescriptor.osAppIds.empty()) {
FillOsAppIds(urspTrafficDescriptor, routeRule);
}
if (!urspTrafficDescriptor.ipv4Addrs.empty()) {
FillIpv4Addrs(urspTrafficDescriptor, routeRule);
}
if (!urspTrafficDescriptor.ipv6Addrs.empty()) {
FillIpv6Addrs(urspTrafficDescriptor, routeRule);
}
if (!urspTrafficDescriptor.protocolIds.empty()) {
FillProtocolIds(urspTrafficDescriptor, routeRule);
}
if (!urspTrafficDescriptor.dnns.empty()) {
routeBitmap = static_cast<uint8_t>(routeBitmap | 0x02);
routeRule.setDnn(appDescriptor.getDnn());
}
if (!urspTrafficDescriptor.fqdns.empty()) {
routeBitmap = static_cast<uint8_t>(routeBitmap | 0x04);
}
if (!urspTrafficDescriptor.connectionCapabilities.empty()) {
routeBitmap = static_cast<uint8_t>(routeBitmap | 0x08);
}
routeRule.setRouteBitmap(routeBitmap);
NETMGR_EXT_LOG_I("fillTrafficDescriptor routeBitmap = %{public}d", static_cast<int>(routeBitmap));
FillRemotePorts(urspTrafficDescriptor, routeRule);
}
void UrspConfig::FillOsAppIds(TrafficDescriptor urspTrafficDescriptor,
SelectedRouteDescriptor& routeRule)
{
std::string osAppIdsStr;
for (size_t i = 0; i < urspTrafficDescriptor.osAppIds.size(); ++i) {
std::string combinedOsAppId = urspTrafficDescriptor.osAppIds[i].getOsId()
+ "#" + urspTrafficDescriptor.osAppIds[i].getAppId();
osAppIdsStr += combinedOsAppId;
if (i < urspTrafficDescriptor.osAppIds.size() - 1) {
osAppIdsStr += COMMA_SEPARATOR;
}
}
routeRule.setAppIds(osAppIdsStr);
}
void UrspConfig::FillIpv4Addrs(TrafficDescriptor urspTrafficDescriptor,
SelectedRouteDescriptor& routeRule)
{
uint8_t ipv4Num = static_cast<uint8_t>(urspTrafficDescriptor.ipv4Addrs.size());
std::vector<uint8_t> ipv4AddrAndMask(ipv4Num *
(NetworkSliceCommConfig::LEN_INT + NetworkSliceCommConfig::LEN_INT, 0));
size_t index = 0;
for (const auto& ipv4Addr : urspTrafficDescriptor.ipv4Addrs) {
uint32_t ipv4AddrValues = ipv4Addr.getIpv4Addr();
uint32_t ipv4MaskValues = ipv4Addr.getIpv4Mask();
std::vector<uint8_t> ipv4AddrValue_vec = uInt32ToVector(ipv4AddrValues);
std::vector<uint8_t> ipv4MaskValues_vec = uInt32ToVector(ipv4MaskValues);
for (size_t j = 0; j < NetworkSliceCommConfig::LEN_INT; ++j) {
ipv4AddrAndMask[index++] = ipv4AddrValue_vec[j];
}
for (size_t j = 0; j < NetworkSliceCommConfig::LEN_INT; ++j) {
ipv4AddrAndMask[index++] = ipv4MaskValues_vec[j];
}
}
routeRule.setIpv4Num(ipv4Num);
routeRule.setIpv4AddrAndMask(ipv4AddrAndMask);
}
void UrspConfig::FillIpv6Addrs(TrafficDescriptor urspTrafficDescriptor,
SelectedRouteDescriptor& routeRule)
{
size_t ipv6Num = urspTrafficDescriptor.ipv6Addrs.size();
size_t index = 0;
std::vector<uint8_t> ipv6AddrAndPrefix((NetworkSliceCommConfig::LEN_SIXTEEN_BYTE +
NetworkSliceCommConfig::LEN_BYTE) * ipv6Num, 0);
for (size_t i = 0; i < ipv6Num; i++) {
Ipv6Addr ipv6Addr = urspTrafficDescriptor.ipv6Addrs[i];
std::array<uint8_t, NetworkSliceCommConfig::LEN_IPV6ADDR> ipv6AddrValues_arry = ipv6Addr.getIpv6Addr();
for (size_t j = 0; j < NetworkSliceCommConfig::LEN_SIXTEEN_BYTE; ++j) {
ipv6AddrAndPrefix[index++] = ipv6AddrValues_arry[j];
}
int ipv6PrefixLen = ipv6Addr.getIpv6PrefixLen();
ipv6AddrAndPrefix[index++] = ipv6PrefixLen;
}
routeRule.setIpv6Num(ipv6Num);
routeRule.setIpv6AddrAndPrefix(ipv6AddrAndPrefix);
}
void UrspConfig::FillProtocolIds(TrafficDescriptor urspTrafficDescriptor,
SelectedRouteDescriptor& routeRule)
{
std::string protocolIds = ConvertIntListToString(urspTrafficDescriptor.protocolIds);
routeRule.setProtocolIds(protocolIds);
}
void UrspConfig::FillRemotePorts(TrafficDescriptor urspTrafficDescriptor,
SelectedRouteDescriptor& routeRule)
{
std::string remotePorts = ConvertIntListToString(urspTrafficDescriptor.singleRemotePorts);
if (!urspTrafficDescriptor.remotePortRanges.empty()) {
if (!remotePorts.empty()) {
remotePorts += COMMA_SEPARATOR;
}
RemotePortRange remotePortRange;
for (size_t i = 0; i < urspTrafficDescriptor.remotePortRanges.size(); i++) {
remotePortRange = urspTrafficDescriptor.remotePortRanges[i];
remotePorts += std::to_string(remotePortRange.getPortRangeLowLimit())
+ PORT_RANGE_SEPARATOR + std::to_string(remotePortRange.getPortRangeHighLimit());
if (i < urspTrafficDescriptor.remotePortRanges.size() - 1) {
remotePorts += COMMA_SEPARATOR;
}
}
}
routeRule.setRemotePorts(remotePorts);
}
bool UrspConfig::isTrafficDescriptorMatch(TrafficDescriptor urspTrafficDescriptor,
AppDescriptor appDescriptor)
{
if (urspTrafficDescriptor.isMatchAll) {
NETMGR_EXT_LOG_I("urspTrafficDescriptor.isMatchAll == true");
return true;
}
if (!isOsAppIdMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
if (!isIpv4AddrMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
if (!isIpv6AddrMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
if (!urspTrafficDescriptor.protocolIds.empty()
&& std::find(urspTrafficDescriptor.protocolIds.begin(), urspTrafficDescriptor.protocolIds.end(),
appDescriptor.getProtocolId()) == urspTrafficDescriptor.protocolIds.end()) {
NETMGR_EXT_LOG_I("protocolId not match: %{public}d", appDescriptor.getProtocolId());
return false;
}
if (!urspTrafficDescriptor.dnns.empty()
&& std::find(urspTrafficDescriptor.dnns.begin(), urspTrafficDescriptor.dnns.end(),
appDescriptor.getDnn()) == urspTrafficDescriptor.dnns.end()) {
return false;
}
if (!urspTrafficDescriptor.fqdns.empty()
&& std::find(urspTrafficDescriptor.fqdns.begin(), urspTrafficDescriptor.fqdns.end(),
appDescriptor.getFqdn()) == urspTrafficDescriptor.fqdns.end()) {
NETMGR_EXT_LOG_I("fqdn not match: %{public}s", appDescriptor.getFqdn().c_str());
return false;
}
if (!urspTrafficDescriptor.connectionCapabilities.empty()
&& std::find(urspTrafficDescriptor.connectionCapabilities.begin(),
urspTrafficDescriptor.connectionCapabilities.end(),
appDescriptor.getConnectionCapability()) == urspTrafficDescriptor.connectionCapabilities.end()) {
NETMGR_EXT_LOG_I("connectionCapabilities not match: %{public}d", appDescriptor.getConnectionCapability());
return false;
}
if (!isRemotePortMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
return true;
}
bool UrspConfig::isIpThreeTuplesInWhiteList(std::string plmn, AppDescriptor appDescriptor)
{
std::unordered_map<std::string, std::vector<UrspRule>> uePolicyMap =
mUePolicyMap.empty() ? mPreConfigUrspMap : mUePolicyMap;
if (uePolicyMap.find(plmn) == uePolicyMap.end()) {
NETMGR_EXT_LOG_I("cannot find plmn in sliceNetworkSelection");
return false;
}
std::vector<UrspRule> urspRules = uePolicyMap[plmn];
for (size_t i = 0; i < urspRules.size(); ++i) {
UrspRule urspRule = urspRules[i];
if (isIpThreeTuplesInTrafficDescriptor(urspRule.trafficDescriptor, appDescriptor)) {
return true;
}
}
return false;
}
bool UrspConfig::isIpThreeTuplesInTrafficDescriptor(TrafficDescriptor urspTrafficDescriptor,
AppDescriptor appDescriptor)
{
if (urspTrafficDescriptor.ipv4Addrs.empty()
&& urspTrafficDescriptor.ipv6Addrs.empty()
&& urspTrafficDescriptor.protocolIds.empty()
&& urspTrafficDescriptor.singleRemotePorts.empty()
&& urspTrafficDescriptor.remotePortRanges.empty()) {
return false;
}
if (!isIpv4AddrMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
if (!isIpv6AddrMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
if (!urspTrafficDescriptor.protocolIds.empty()
&& std::find(urspTrafficDescriptor.protocolIds.begin(), urspTrafficDescriptor.protocolIds.end(),
appDescriptor.getProtocolId()) == urspTrafficDescriptor.protocolIds.end()) {
NETMGR_EXT_LOG_I("protocolId not in white list: %{public}d", appDescriptor.getProtocolId());
return false;
}
if (!isRemotePortMatch(urspTrafficDescriptor, appDescriptor)) {
return false;
}
NETMGR_EXT_LOG_I("is IpThreeTuples In TrafficDescriptor");
return true;
}
bool UrspConfig::isOsAppIdMatch(TrafficDescriptor urspTrafficDescriptor, AppDescriptor appDescriptor)
{
if (!urspTrafficDescriptor.osAppIds.empty()) {
size_t i;
for (i = 0; i < urspTrafficDescriptor.osAppIds.size(); i++) {
OsAppId osAppId = urspTrafficDescriptor.osAppIds[i];
if (osAppId.getAppId() == appDescriptor.getOsAppId().getAppId()) {
break;
}
}
if (i == urspTrafficDescriptor.osAppIds.size()) {
NETMGR_EXT_LOG_I("appId not match: %{public}s", appDescriptor.getOsAppId().getAppId().c_str());
return false;
}
NETMGR_EXT_LOG_I("appId match: %{public}s", appDescriptor.getOsAppId().getAppId().c_str());
}
return true;
}
bool UrspConfig::isRemotePortMatch(TrafficDescriptor urspTrafficDescriptor, AppDescriptor appDescriptor)
{
if (!urspTrafficDescriptor.singleRemotePorts.empty()
&& std::find(urspTrafficDescriptor.singleRemotePorts.begin(), urspTrafficDescriptor.singleRemotePorts.end(),
appDescriptor.getRemotePort()) != urspTrafficDescriptor.singleRemotePorts.end()) {
return true;
}
if (!urspTrafficDescriptor.remotePortRanges.empty()) {
RemotePortRange remotePortRange;
size_t i;
for (i = 0; i < urspTrafficDescriptor.remotePortRanges.size(); i++) {
remotePortRange = urspTrafficDescriptor.remotePortRanges[i];
if ((appDescriptor.getRemotePort() >= remotePortRange.getPortRangeLowLimit())
&& (appDescriptor.getRemotePort() <= remotePortRange.getPortRangeHighLimit())) {
break;
}
}
if (i == urspTrafficDescriptor.remotePortRanges.size()) {
return false;
}
}
return true;
}
bool UrspConfig::isIpv4AddrMatch(TrafficDescriptor urspTrafficDescriptor, AppDescriptor appDescriptor)
{
if (urspTrafficDescriptor.ipv4Addrs.empty()) {
return true;
}
size_t i;
bool ipv4match = false;
for (i = 0; i < urspTrafficDescriptor.ipv4Addrs.size(); ++i) {
Ipv4Addr ipv4Addr = urspTrafficDescriptor.ipv4Addrs[i];
uint32_t ipv4AddrValues = ipv4Addr.getIpv4Addr();
uint32_t ipv4MaskValues = ipv4Addr.getIpv4Mask();
uint32_t appAddrValues = appDescriptor.getIpv4Addr();
if ((appAddrValues & ipv4MaskValues) != (ipv4AddrValues & ipv4MaskValues)) {
NETMGR_EXT_LOG_I("ipv4Addr not match");
continue;
}
ipv4match = true;
}
if (ipv4match == false) {
NETMGR_EXT_LOG_I("ipv4Addr not match");
return false;
}
return true;
}
bool UrspConfig::isIpv6AddrMatch(TrafficDescriptor urspTrafficDescriptor, AppDescriptor appDescriptor)
{
if (urspTrafficDescriptor.ipv6Addrs.empty()) {
return true;
}
size_t i;
bool ipv6match = false;
for (i = 0; i < urspTrafficDescriptor.ipv6Addrs.size(); ++i) {
Ipv6Addr ipv6Addr = urspTrafficDescriptor.ipv6Addrs[i];
std::string ipv6AddrValues = transIpv6AddrToStr(ipv6Addr.getIpv6Addr());
std::string appAddrValues = transIpv6AddrToStr(appDescriptor.getIpv6Addr());
if (ipv6AddrValues != appAddrValues) {
NETMGR_EXT_LOG_I("ipv6Addr not match");
continue;
}
ipv6match = true;
}
if (ipv6match == false) {
NETMGR_EXT_LOG_I("ipv6Addr not match");
return false;
}
return true;
}
SelectedRouteDescriptor UrspConfig::GetMatchAllUrspRule(const std::string& plmn)
{
NETMGR_EXT_LOG_I("GetMatchAllUrspRule");
std::unordered_map<std::string, std::vector<UrspRule>> uePolicyMap;
if (mUePolicyMap.empty()) {
uePolicyMap = mPreConfigUrspMap;
} else {
uePolicyMap = mUePolicyMap;
}
SelectedRouteDescriptor routeRule;
if (uePolicyMap.find(plmn) == uePolicyMap.end()) {
NETMGR_EXT_LOG_I("GetMatchAllUrspRule not find plmn");
return routeRule;
}
std::vector<UrspRule> urspRules = uePolicyMap[plmn];
if (urspRules.empty()) {
NETMGR_EXT_LOG_I("GetMatchAllUrspRule urspRules is empty");
return routeRule;
}
uint8_t routeBitmap = 0;
routeBitmap = ConvertInt2UnsignedByte(routeBitmap | 0x08);
UrspRule urspRule = urspRules.back();
if (!urspRule.trafficDescriptor.isMatchAll) {
routeRule.setRouteBitmap(routeBitmap);
NETMGR_EXT_LOG_I("TD is not MatchAll, routeBitmap = %{public}d", routeBitmap);
return routeRule;
}
for (int j = 0; j < (int)urspRule.routeSelectionDescriptors.size(); ++j) {
if (!urspRule.routeSelectionDescriptors[j].snssais.empty()) {
if (sAllowedNssaiConfig_ == nullptr) {
continue;
}
std::vector<Snssai> snssais = urspRule.routeSelectionDescriptors[j].snssais;
std::string snssai = sAllowedNssaiConfig_->FindSnssaiInAllowedNssai(snssais);
if (snssai.empty()) {
continue;
}
routeRule.setSnssai(snssai);
}
routeRule.setPduSessionType(urspRule.routeSelectionDescriptors[j].pduSessionType);
routeRule.setSscMode(urspRule.routeSelectionDescriptors[j].sscMode);
if (!urspRule.routeSelectionDescriptors[j].dnns.empty()) {
routeRule.setDnn(urspRule.routeSelectionDescriptors[j].dnns[0]);
}
routeRule.setUrspPrecedence((uint8_t) urspRule.urspPrecedence);
routeBitmap = ConvertInt2UnsignedByte(routeBitmap | 0x01);
routeRule.setRouteBitmap(routeBitmap);
return routeRule;
}
return routeRule;
}
void UrspConfig::DumpUePolicyMap()
{
NETMGR_EXT_LOG_I("dump UrspConfig.mUePolicyMap begin");
for (const auto& entry : mUePolicyMap) {
NETMGR_EXT_LOG_I("plmn = %{public}s", entry.first.c_str());
const auto& urspRules = entry.second;
NETMGR_EXT_LOG_I("dump UrspConfig: urspRules.size = %{public}d", (int)urspRules.size());
for (size_t i = 0; i < urspRules.size(); ++i) {
const auto& urspRule = urspRules[i];
NETMGR_EXT_LOG_I("urspPrecedence = %{public}d", urspRule.urspPrecedence);
DumptrafficDescriptor(urspRule.trafficDescriptor);
DumpRouteSelectionDescriptors(urspRule.routeSelectionDescriptors);
}
}
NETMGR_EXT_LOG_I("dump end");
}
void UrspConfig::DumpPreConfigUrspMap()
{
NETMGR_EXT_LOG_I("dump UrspConfig.mPreConfigUrspMap begin");
for (const auto& entry : mPreConfigUrspMap) {
NETMGR_EXT_LOG_I("plmn = %{public}s", entry.first.c_str());
const auto& urspRules = entry.second;
NETMGR_EXT_LOG_I("dump UrspConfig: urspRules.size = %{public}d", (int)urspRules.size());
for (size_t i = 0; i < urspRules.size(); ++i) {
const auto& urspRule = urspRules[i];
NETMGR_EXT_LOG_I("urspPrecedence = %{public}d", urspRule.urspPrecedence);
DumptrafficDescriptor(urspRule.trafficDescriptor);
DumpRouteSelectionDescriptors(urspRule.routeSelectionDescriptors);
}
}
NETMGR_EXT_LOG_I("dump end");
}
void UrspConfig::DumptrafficDescriptor(const TrafficDescriptor& trafficDescriptor)
{
NETMGR_EXT_LOG_I("dump trafficDescriptor");
size_t i;
NETMGR_EXT_LOG_I("trafficDescriptor.isMatchAll = %{public}s", trafficDescriptor.isMatchAll ? "true":"false");
for (i = 0; i < trafficDescriptor.osAppIds.size(); ++i) {
NETMGR_EXT_LOG_I("osAppIds.OsId = %{public}s, osAppIds.AppId = %{public}s",
trafficDescriptor.osAppIds[i].getOsId().c_str(), trafficDescriptor.osAppIds[i].getAppId().c_str());
}
for (i = 0; i < trafficDescriptor.ipv4Addrs.size(); ++i) {
NETMGR_EXT_LOG_I("ipv4Addrs.mIpv4Addr = %{public}d, ipv4Addrs.mIpv4Mask = %{public}d",
trafficDescriptor.ipv4Addrs[i].getIpv4Addr(), trafficDescriptor.ipv4Addrs[i].getIpv4Mask());
}
for (i = 0; i < trafficDescriptor.ipv6Addrs.size(); ++i) {
std::string ipv6addr = transIpv6AddrToStr(trafficDescriptor.ipv6Addrs[i].getIpv6Addr());
NETMGR_EXT_LOG_I("ipv6Addrs.mIpv6Addr = %{public}s, ipv6Addrs.mIpv6Prefix = %{public}d",
ipv6addr.c_str(), trafficDescriptor.ipv6Addrs[i].getIpv6PrefixLen());
}
for (i = 0; i < trafficDescriptor.protocolIds.size(); ++i) {
NETMGR_EXT_LOG_I("protocolId = %{public}d", trafficDescriptor.protocolIds[i]);
}
for (i = 0; i < trafficDescriptor.singleRemotePorts.size(); ++i) {
NETMGR_EXT_LOG_I("singleRemotePorts = %{public}d", trafficDescriptor.singleRemotePorts[i]);
}
for (i = 0; i < trafficDescriptor.remotePortRanges.size(); ++i) {
NETMGR_EXT_LOG_I("portRangeLowLimit = %{public}d, portRangeHighLimit = %{public}d",
trafficDescriptor.remotePortRanges[i].getPortRangeLowLimit(),
trafficDescriptor.remotePortRanges[i].getPortRangeHighLimit());
}
for (i = 0; i < trafficDescriptor.dnns.size(); ++i) {
NETMGR_EXT_LOG_I("trafficDescriptor.dnn = %{public}s", trafficDescriptor.dnns[i].c_str());
}
for (i = 0; i < trafficDescriptor.fqdns.size(); ++i) {
NETMGR_EXT_LOG_I("trafficDescriptor.fqdn = %{public}s", trafficDescriptor.fqdns[i].c_str());
}
for (i = 0; i < trafficDescriptor.connectionCapabilities.size(); ++i) {
NETMGR_EXT_LOG_I("trafficDescriptor.connectionCapabilities = %{public}d",
trafficDescriptor.connectionCapabilities[i]);
}
}
void UrspConfig::DumpRouteSelectionDescriptors(const std::vector<RouteSelectionDescriptor>& routeSelectionDescriptors)
{
NETMGR_EXT_LOG_I("dump routeSelectionDescriptors,size = %{public}d", (int)routeSelectionDescriptors.size());
size_t i;
size_t j;
for (i = 0; i < routeSelectionDescriptors.size(); ++i) {
NETMGR_EXT_LOG_I("routeSelectionDescriptor.routePrecedence = %{public}d",
routeSelectionDescriptors[i].routePrecedence);
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sscMode = %{public}d", routeSelectionDescriptors[i].sscMode);
NETMGR_EXT_LOG_I("routeSelectionDescriptor.pduSessionType = %{public}d",
routeSelectionDescriptors[i].pduSessionType);
for (j = 0; j < routeSelectionDescriptors[i].snssais.size(); ++j) {
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sNssai.mSNssaiLen = %{public}d",
routeSelectionDescriptors[i].snssais[j].getSnssaiLen());
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sNssai.mSst = %{public}d",
routeSelectionDescriptors[i].snssais[j].getSst());
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sNssai.mSd = %{public}d",
routeSelectionDescriptors[i].snssais[j].getSd());
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sNssai.mMappedSst = %{public}d",
routeSelectionDescriptors[i].snssais[j].getMappedSst());
NETMGR_EXT_LOG_I("routeSelectionDescriptor.sNssai.mMappedSd = %{public}d",
routeSelectionDescriptors[i].snssais[j].getMappedSd());
}
for (j = 0; j < routeSelectionDescriptors[i].dnns.size(); ++j) {
NETMGR_EXT_LOG_I("routeSelectionDescriptor.dnn = %{public}s", routeSelectionDescriptors[i].dnns[j].c_str());
}
}
}
}
}