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