• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2026 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "allowednssaiconfig.h"
16 #include "networksliceutil.h"
17 #include "state_utils.h"
18 
19 namespace OHOS {
20 namespace NetManagerStandard {
21 const std::string SST_AND_SD_SEPARATOR = ".";
22 constexpr int SNSSAI_LEN_1_SST = 1;
23 constexpr int SNSSAI_LEN_2_SST_MAPPED_SST = 2;
24 constexpr int SNSSAI_LEN_4_SST_SD = 4;
25 constexpr int SNSSAI_LEN_5_SST_SD_MAPPED_SST = 5;
26 constexpr int SNSSAI_LEN_8_SST_SD_MAPPED_SST_MAPPED_SD = 8;
27 constexpr int RADIX = 16;
28 
29 std::shared_ptr<AllowedNssaiConfig> sAllowedNssaiConfig_ =
30     std::make_shared<AllowedNssaiConfig>(AllowedNssaiConfig::GetInstance());
31 
GetInstance()32 AllowedNssaiConfig& AllowedNssaiConfig::GetInstance()
33 {
34     static AllowedNssaiConfig instance;
35     return instance;
36 }
37 
ParseSnssai(Snssai & snssai)38 bool AllowedNssaiConfig::ParseSnssai(Snssai& snssai)
39 {
40     std::vector<std::string> values;
41     std::vector<std::string> snssaiValues;
42     if (snssai.getSnssai().empty()) {
43         NETMGR_EXT_LOG_E("invalid snssai to parse");
44         return false;
45     }
46 
47     values = Split(snssai.getSnssai(), ";");
48     NETMGR_EXT_LOG_I("valuessize = %{public}d", (int)values.size());
49     if (values.size() != 1 && values.size() != NetworkSliceCommConfig::LEN_SHORT) {
50         NETMGR_EXT_LOG_E("values.length invalid, values.length = [%{public}d]", (int)values.size());
51         return false;
52     }
53     snssaiValues = Split(values[0], SST_AND_SD_SEPARATOR);
54     NETMGR_EXT_LOG_I("snssaiValuessize = %{public}d", (int)snssaiValues.size());
55     for (size_t i = 0; i < snssaiValues.size(); ++i) {
56         NETMGR_EXT_LOG_I("snssaiValues[%{public}s]", snssaiValues[i].c_str());
57     }
58     if (snssaiValues.size() == 1) {
59         snssai.setSst(ConvertInt2UnsignedByte((std::stoi(snssaiValues[0], nullptr, RADIX))));
60         NETMGR_EXT_LOG_I("size = 1, Sst = %{public}d", snssai.getSst());
61         snssai.setSnssaiLen(1);
62     } else if (snssaiValues.size() == NetworkSliceCommConfig::LEN_SHORT) {
63         snssai.setSst(ConvertInt2UnsignedByte((std::stoi(snssaiValues[0], nullptr, RADIX))));
64         snssai.setSd(std::stoi(snssaiValues[1], nullptr, RADIX));
65         NETMGR_EXT_LOG_I("size = 2, Sst = %{public}d, Sd = %{public}d", snssai.getSst(), snssai.getSd());
66         snssai.setSnssaiLen(NetworkSliceCommConfig::LEN_INT);
67     } else {
68         NETMGR_EXT_LOG_E("values[0].snssaiValues.length invalid, snssaiValues.length = [%{public}d]",
69             (int)snssaiValues.size());
70         return false;
71     }
72 
73     if (values.size() == NetworkSliceCommConfig::LEN_SHORT) {
74         snssaiValues = Split(values[1], SST_AND_SD_SEPARATOR);
75         if (snssaiValues.size() == 1) {
76             snssai.setMappedSst(ConvertInt2UnsignedByte((std::stoi(snssaiValues[0], nullptr, RADIX))));
77             snssai.setSnssaiLen(snssai.getSnssaiLen() + 1);
78         } else if (snssaiValues.size() == NetworkSliceCommConfig::LEN_SHORT) {
79             snssai.setMappedSst(ConvertInt2UnsignedByte((std::stoi(snssaiValues[0], nullptr, RADIX))));
80             snssai.setMappedSd(std::stoi(snssaiValues[1], nullptr, RADIX));
81             snssai.setSnssaiLen(snssai.getSnssaiLen() + NetworkSliceCommConfig::LEN_INT);
82         } else {
83             NETMGR_EXT_LOG_E("values[1].snssaiValues.length invalid, snssaiValues.length = [%{public}d]",
84                 (int)snssaiValues.size());
85             return false;
86         }
87     }
88     return true;
89 }
90 
DecodeAllowedNssai(std::vector<uint8_t> buffer)91 void AllowedNssaiConfig::DecodeAllowedNssai(std::vector<uint8_t> buffer)
92 {
93     if (buffer.empty()) {
94         NETMGR_EXT_LOG_I("getAllowedNssai failed, invalid buffer");
95         return;
96     }
97     NETMGR_EXT_LOG_I("start decode AllowedNssai");
98     int inputLen = buffer.size();
99     mAllowedNssais.clear();
100     std::string nssai = "";
101     std::vector<std::string> values;
102     for (int i = 0; i < inputLen; ++i) {
103         nssai += static_cast<char>(buffer[i]);
104     }
105     values = Split(nssai, ":");
106     for (int i = 0; i < (int)values.size(); i++) {
107         NETMGR_EXT_LOG_I("start decode AllowedNssai %{public}s", values[i].c_str());
108         Snssai snssai;
109         snssai.setSnssai(values[i]);
110         if (!ParseSnssai(snssai)) {
111             NETMGR_EXT_LOG_I("parseSNssai(sNssai) is false");
112             continue;
113         }
114         mAllowedNssais.push_back(snssai);
115     }
116     NETMGR_EXT_LOG_I("end decode AllowedNssai");
117     DumpAllowedNssai();
118     return;
119 }
120 
DecodeSnssai(int & startIndex,uint8_t len,std::vector<uint8_t> buffer,Snssai & snssai)121 bool AllowedNssaiConfig::DecodeSnssai(int& startIndex, uint8_t len, std::vector<uint8_t> buffer, Snssai& snssai)
122 {
123     int msd = 0;
124     int mappedsd = 0;
125     switch (len) {
126         case SNSSAI_LEN_1_SST: /* Length of S-NSSAI contents = 1, SST */
127             snssai.setSnssaiLen(SNSSAI_LEN_1_SST);
128             snssai.setSst(buffer[startIndex++]);
129             break;
130         case SNSSAI_LEN_2_SST_MAPPED_SST: /* Length of S-NSSAI contents = 2, SST and mapped HPLMN SST */
131             snssai.setSnssaiLen(SNSSAI_LEN_2_SST_MAPPED_SST);
132             snssai.setSst(buffer[startIndex++]);
133             snssai.setMappedSst(buffer[startIndex++]);
134             break;
135         case SNSSAI_LEN_4_SST_SD: /* Length of S-NSSAI contents = 4, SST and SD */
136             snssai.setSnssaiLen(SNSSAI_LEN_4_SST_SD);
137             snssai.setSst(buffer[startIndex++]);
138             msd = buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_16;
139             msd += buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_8;
140             msd += buffer[startIndex++];
141             snssai.setSd(msd);
142             break;
143         case SNSSAI_LEN_5_SST_SD_MAPPED_SST: /* Length of S-NSSAI contents = 5, SST, SD and mapped HPLMN SST */
144             snssai.setSnssaiLen(SNSSAI_LEN_5_SST_SD_MAPPED_SST);
145             snssai.setSst(buffer[startIndex++]);
146             msd = buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_16;
147             msd += buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_8;
148             msd += buffer[startIndex++];
149             snssai.setSd(msd);
150             snssai.setMappedSst(buffer[startIndex++]);
151             break;
152         case SNSSAI_LEN_8_SST_SD_MAPPED_SST_MAPPED_SD:
153             /* Length of S-NSSAI contents = 8, SST, SD, mapped HPLMN SST and mapped HPLMN SD */
154             snssai.setSnssaiLen(SNSSAI_LEN_8_SST_SD_MAPPED_SST_MAPPED_SD);
155             snssai.setSst(buffer[startIndex++]);
156             msd = buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_16;
157             msd += buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_8;
158             msd += buffer[startIndex++];
159             snssai.setSd(msd);
160             snssai.setMappedSst(buffer[startIndex++]);
161             mappedsd = buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_16;
162             mappedsd += buffer[startIndex++] << NetworkSliceCommConfig::BIT_MOVE_8;
163             mappedsd += buffer[startIndex++];
164             snssai.setMappedSd(mappedsd);
165             break;
166         default:
167             NETMGR_EXT_LOG_E("Length of S-NSSAI contents invalid, len = %{public}d", len);
168             return false;
169         }
170     return true;
171 }
172 
173 
DumpAllowedNssai()174 void AllowedNssaiConfig::DumpAllowedNssai()
175 {
176     NETMGR_EXT_LOG_I("dump AllowedNssaiConfig.mAllowedNssais begin");
177     int i;
178     for (i = 0; i < (int)mAllowedNssais.size(); i++) {
179         std::string snssai = mAllowedNssais[i].getSnssai();
180         NETMGR_EXT_LOG_I("mSnssaiLen = %{public}d, mSst = %{public}d, mSd = %{public}d, "
181             "mMappedSst = %{public}d, mMappedSd = %{public}d, mSnssai = %{public}s ",
182             mAllowedNssais[i].getSnssaiLen(), mAllowedNssais[i].getSst(), mAllowedNssais[i].getSd(),
183             mAllowedNssais[i].getMappedSst(), mAllowedNssais[i].getMappedSd(), snssai.c_str());
184     }
185     NETMGR_EXT_LOG_I("dump end");
186 }
187 
FindSnssaiInAllowedNssai(const std::vector<Snssai> & snssais)188 std::string AllowedNssaiConfig::FindSnssaiInAllowedNssai(const std::vector<Snssai>& snssais)
189 {
190     int slotId = StateUtils::GetPrimarySlotId();
191     if (StateUtils::IsRoaming(slotId)) {
192         /* currently donot consider roaming situation */
193         return "";
194     }
195     for (const auto& snssai : snssais) {
196         auto it = std::find_if(mAllowedNssais.begin(), mAllowedNssais.end(), [&snssai](const Snssai& nssai) {
197             return snssai.getSnssaiLen() == nssai.getSnssaiLen() &&
198                    snssai.getSst() == nssai.getSst() &&
199                    snssai.getSd() == nssai.getSd() &&
200                    snssai.getMappedSst() == nssai.getMappedSst() &&
201                    snssai.getMappedSd() == nssai.getMappedSd();
202         });
203         if (it != mAllowedNssais.end()) {
204             return it->getSnssai();
205         }
206     }
207     return "";
208 }
209 
isSnssaiInAllowedNssai(Snssai snssai)210 std::string AllowedNssaiConfig::isSnssaiInAllowedNssai(Snssai snssai)
211 {
212     int slotId = StateUtils::GetPrimarySlotId();
213     if (StateUtils::IsRoaming(slotId)) {
214         /* currently donot consider roaming situation */
215         NETMGR_EXT_LOG_I("isSnssaiInAllowedNssai IsRoaming");
216         return "";
217     }
218     NETMGR_EXT_LOG_I("mAllowedNssais size = %{public}d", (int)mAllowedNssais.size());
219     for (int j = 0; j < (int)mAllowedNssais.size(); ++j) {
220         NETMGR_EXT_LOG_I("snssai Len = %{public}d, AllowedNssais Len = %{public}d",
221             snssai.getSnssaiLen(), mAllowedNssais[j].getSnssaiLen());
222         NETMGR_EXT_LOG_I("snssai Sst = %{public}d, AllowedNssais Sst = %{public}d",
223             snssai.getSst(), mAllowedNssais[j].getSst());
224         NETMGR_EXT_LOG_I("snssai Sd = %{public}d, AllowedNssais Sd = %{public}d",
225             snssai.getSd(), mAllowedNssais[j].getSd());
226         NETMGR_EXT_LOG_I("snssai MapSst = %{public}d, AllowedNssais MapSst = %{public}d",
227             snssai.getMappedSst(), mAllowedNssais[j].getMappedSst());
228         NETMGR_EXT_LOG_I("snssai MapSd = %{public}d, AllowedNssais MapSd = %{public}d",
229             snssai.getMappedSd(), mAllowedNssais[j].getMappedSd());
230             if (snssai.getSnssaiLen() == mAllowedNssais[j].getSnssaiLen() &&
231                    snssai.getSst() == mAllowedNssais[j].getSst() &&
232                    snssai.getSd() == mAllowedNssais[j].getSd() &&
233                    snssai.getMappedSst() == mAllowedNssais[j].getMappedSst() &&
234                    snssai.getMappedSd() == mAllowedNssais[j].getMappedSd()) {
235                 return mAllowedNssais[j].getSnssai();
236             }
237         };
238     return "";
239 }
240 
241 }
242 }
243