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
16 #include "nrunsolicitedmsgparser.h"
17 #include "cellular_data_client.h"
18 #include "core_service_client.h"
19 #include "networkslicemanager.h"
20 #include "state_utils.h"
21
22 namespace OHOS {
23 namespace NetManagerStandard {
24 static constexpr int MODEM_ID = 0;
25 static constexpr uint8_t MSG_MANAGE_UE_POLICY_COMMAND = 1;
26 static constexpr uint8_t MSG_MANAGE_UE_POLICY_COMPLETE = 0;
27 static constexpr uint8_t MSG_MANAGE_UE_POLICY_COMMAND_REJECT = 1;
28 static constexpr uint8_t MSG_UE_STATE_INDICATION = 2;
29 static constexpr uint8_t SPACELENGTH = 4;
30 static constexpr uint8_t NSSAI_TYPE_DEFAULT_CONFIGURED_REJECT_CONFIGURED_ALLOWED_NSSAI = 3;
31 static constexpr uint8_t UE_POLICY_PART_TYPE_URSP = 1;
32 static std::string REPORTURSP_PATH = "/system/profile/reportUrsp.json";
33 static std::string DEFAULT_PLMN = "00101";
34
GetInstance()35 NrUnsolicitedMsgParser& NrUnsolicitedMsgParser::GetInstance()
36 {
37 static NrUnsolicitedMsgParser instance;
38 return instance;
39 }
40
NrUnsolicitedMsgParser()41 NrUnsolicitedMsgParser::NrUnsolicitedMsgParser()
42 {
43 NETMGR_EXT_LOG_I("init NrUnsolicitedMsgParser start");
44 if (sUrspConfig_ == nullptr) {
45 NETMGR_EXT_LOG_E("NrUnsolicitedMsgParser sUrspConfig_ = nullptr");
46 sUrspConfig_ = std::make_shared<UrspConfig>(UrspConfig::GetInstance());
47 }
48 GetSubscriberIdAndUrspFromFile();
49 NETMGR_EXT_LOG_I("init NrUnsolicitedMsgParser end");
50 }
51
52
GetSubscriberIdAndUrspFromFile()53 void NrUnsolicitedMsgParser::GetSubscriberIdAndUrspFromFile()
54 {
55 NETMGR_EXT_LOG_I("nrunsolicited:Enter getSubscriberIdAndUrspFromFile");
56 if (mSubscriberId.empty()) {
57 NETMGR_EXT_LOG_E("imsi null");
58 return;
59 }
60 std::unordered_map<std::string, UePolicy> uePolicyMaptmp = ReadObjectFromJsonFile(REPORTURSP_PATH);
61 if (uePolicyMaptmp.empty()) {
62 NETMGR_EXT_LOG_I("nrunsolicited:read ue policy from file failed");
63 WriteObjectToJsonFile(REPORTURSP_PATH, uePolicyMap);
64 SendUePolicySectionIdentifier();
65 return;
66 }
67 uePolicyMap = uePolicyMaptmp;
68 if (uePolicyMap.empty()) {
69 return;
70 }
71 UpdateUrspRules();
72 }
73
HandleSimStateChanged()74 void NrUnsolicitedMsgParser::HandleSimStateChanged()
75 {
76 NETMGR_EXT_LOG_E("enter handleSimStateChanged isAllowedNssaiSync = %{public}d", isAllowedNssaiSync);
77 SyncSubscriberId();
78 if (!isAllowedNssaiSync) {
79 GetNetworkSliceAllowedNssai();
80 }
81 GetNetworkSliceEhplmn();
82 }
83
SyncSubscriberId()84 void NrUnsolicitedMsgParser::SyncSubscriberId()
85 {
86 int32_t slotId = StateUtils::GetPrimarySlotId();
87 NETMGR_EXT_LOG_I("NrUnsolicitedMsgParser slotId = %{public}d", slotId);
88 std::u16string imsi;
89 Telephony::CoreServiceClient::GetInstance().GetIMSI(slotId, imsi);
90 if (imsi.empty()) {
91 NETMGR_EXT_LOG_E("syncSubscriberId fail, imsi null");
92 return;
93 }
94 std::string imsistr = Str16ToStr8(imsi);
95 std::string encryptImsi = GetSha256Str(imsistr);
96 if (mSubscriberId.empty()) {
97 mSubscriberId = encryptImsi;
98 return;
99 }
100 if (mSubscriberId == encryptImsi) {
101 return;
102 }
103 mSubscriberId = encryptImsi;
104 uePolicyMap = std::unordered_map<std::string, UePolicy>(NetworkSliceCommConfig::HASH_MAP_DEFAULT_CAPACITY);
105 WriteObjectToJsonFile(REPORTURSP_PATH, uePolicyMap);
106 SendUePolicySectionIdentifier();
107 UpdateUrspRules();
108 SendUrspUpdate();
109 auto networkSliceManager = DelayedSingleton<NetworkSliceManager>::GetInstance();
110 if (networkSliceManager != nullptr) {
111 networkSliceManager->onUrspAvailableStateChanged();
112 }
113 }
114
GetNetworkSliceAllowedNssai()115 void NrUnsolicitedMsgParser::GetNetworkSliceAllowedNssai()
116 {
117 NETMGR_EXT_LOG_E("GetNetworkSliceAllowedNssai");
118 int32_t slotId = StateUtils::GetPrimarySlotId();
119 std::u16string operatorNumeric;
120 Telephony::CoreServiceClient::GetInstance().GetSimOperatorNumeric(slotId, operatorNumeric);
121 std::string plmn = Str16ToStr8(operatorNumeric);
122 if (plmn == "") {
123 NETMGR_EXT_LOG_E("GetPlmn fail");
124 return;
125 }
126 NETMGR_EXT_LOG_E("NrUnsolicitedMsgParser GetNetworkSliceAllowedNssai plmn = %{public}s", plmn.c_str());
127 std::vector<uint8_t> plmns = ConvertstringTouInt8Vector(plmn);
128 std::vector<uint8_t> buffer;
129 buffer.push_back(plmns.size());
130 for (size_t i = 0; i < plmns.size(); ++i) {
131 buffer.push_back(plmns[i]);
132 }
133 buffer.push_back(NSSAI_TYPE_DEFAULT_CONFIGURED_REJECT_CONFIGURED_ALLOWED_NSSAI);
134 Telephony::CellularDataClient::GetInstance().GetNetworkSliceAllowedNssai(MODEM_ID, buffer);
135 isAllowedNssaiSync = true;
136 }
137
GetNetworkSliceEhplmn()138 void NrUnsolicitedMsgParser::GetNetworkSliceEhplmn()
139 {
140 NETMGR_EXT_LOG_I("GetNetworkSliceEhplmn");
141 Telephony::CellularDataClient::GetInstance().GetNetworkSliceEhplmn(MODEM_ID);
142 }
143
WriteObjectToJsonFile(const std::string & fileName,std::unordered_map<std::string,UePolicy> & obj)144 void NrUnsolicitedMsgParser::WriteObjectToJsonFile(const std::string& fileName,
145 std::unordered_map<std::string, UePolicy>& obj)
146 {
147 if (fileName.empty()) {
148 return;
149 }
150 NETMGR_EXT_LOG_I("WriteObjectToJsonFile:%{public}s", fileName.c_str());
151 nlohmann::json j = nlohmann::json::object();
152 for (const auto& pair : obj) {
153 std::string plmn = pair.first;
154 NETMGR_EXT_LOG_I("WriteObjectToJsonFile plmn = %{public}s", plmn.c_str());
155 UePolicy uePolicy = pair.second;
156 nlohmann::json uePolicyJson = uePolicy.to_json();
157 j[plmn] = uePolicyJson;
158 }
159
160 std::fstream f;
161 f.open(fileName, std::ios::out);
162 if (!f.is_open()) {
163 NETMGR_EXT_LOG_E("file not opened! ");
164 } else {
165 f << j.dump(SPACELENGTH);
166 f.close();
167 }
168 }
169
ReadObjectFromJsonFile(const std::string & fileName)170 std::unordered_map<std::string, UePolicy> NrUnsolicitedMsgParser::ReadObjectFromJsonFile(const std::string& fileName)
171 {
172 std::ifstream file(fileName);
173 if (!file.is_open()) {
174 NETMGR_EXT_LOG_E("failed to open file ");
175 return {};
176 }
177 NETMGR_EXT_LOG_I("ReadObjectFromJsonFile");
178 nlohmann::json j;
179 file >> j;
180 if (j.empty()) {
181 return {};
182 }
183 std::unordered_map<std::string, UePolicy> uePolicies;
184 for (const auto& item : j.items()) {
185 const std::string& plmn = item.key();
186 const nlohmann::json& policyJson = item.value();
187
188 UePolicy uePolicy;
189 uePolicy.from_json(policyJson);
190 uePolicies[plmn] = uePolicy;
191 }
192 if (file.is_open()) {
193 file.close();
194 }
195 return uePolicies;
196 }
197
198
UpdateUrspRules()199 void NrUnsolicitedMsgParser::UpdateUrspRules()
200 {
201 if (sUrspConfig_ == nullptr) {
202 NETMGR_EXT_LOG_E("sUrspConfig == null");
203 return;
204 }
205 NETMGR_EXT_LOG_I("UpdateUrspRules");
206 std::string plmn;
207 UePolicy uePolicy;
208 PolicyInstruction policyInstruction;
209 sUrspConfig_->ClearUrspRules();
210 for (const auto& entry : uePolicyMap) {
211 std::string plmn = entry.first;
212 const UePolicy& uePolicy = entry.second;
213 std::vector<UrspRule> urspRules;
214 for (const auto& instructionEntry : uePolicy.policyInstructionMap) {
215 PolicyInstruction policyInstruction = instructionEntry.second;
216 for (size_t i = 0; i < policyInstruction.urspRules.size(); ++i) {
217 urspRules.push_back(policyInstruction.urspRules[i]);
218 }
219 }
220 sUrspConfig_->setUrspRules(plmn, urspRules);
221 }
222 sUrspConfig_->DumpUePolicyMap();
223 sUrspConfig_->SaveTrafficDescriptorWhiteListToDb();
224 }
225
SendUrspUpdate()226 void NrUnsolicitedMsgParser::SendUrspUpdate()
227 {
228 if (sUrspConfig_ == nullptr) {
229 NETMGR_EXT_LOG_E("sendUrspUpdate, mUrspConfig == null");
230 return;
231 }
232 std::string plmn = GetHplmn();
233 NETMGR_EXT_LOG_I("SendUrspUpdate GetHplmn = %{public}s", plmn.c_str());
234 SelectedRouteDescriptor routeRule = sUrspConfig_->GetMatchAllUrspRule(plmn);
235 std::map<std::string, std::string> data;
236 data["routeBitmap"] = std::to_string(routeRule.getRouteBitmap());
237 NETMGR_EXT_LOG_I("SendUrspUpdate routeBitmap = %{public}s", data["routeBitmap"].c_str());
238 if ((routeRule.getRouteBitmap() & 0x01) == 0x01) {
239 data["sscMode"] = std::to_string(routeRule.getSscMode());
240 if (routeRule.getPduSessionType() != -1) {
241 data["pduSessionType"] = std::to_string(routeRule.getPduSessionType());
242 }
243 data["sNssai"] = routeRule.getSnssai();
244 data["dnn"] = routeRule.getDnn();
245 data["urspPrecedence"] = std::to_string(routeRule.getUrspPrecedence());
246 }
247 std::shared_ptr<std::map<std::string, std::string>> msg =
248 std::make_shared<std::map<std::string, std::string>>(data);
249 Singleton<NetworkSliceMsgCenter>::GetInstance().Publish(EVENT_URSP_CHANGED, msg);
250 }
251
GetHplmn()252 std::string NrUnsolicitedMsgParser::GetHplmn()
253 {
254 return (mEhplmns.size() > 0) ? mEhplmns[0] : DEFAULT_PLMN;
255 }
256
GetAllowedNssaiFromUnsolData(std::vector<uint8_t> buffer)257 void NrUnsolicitedMsgParser::GetAllowedNssaiFromUnsolData(std::vector<uint8_t> buffer)
258 {
259 sAllowedNssaiConfig_->DecodeAllowedNssai(buffer);
260 }
261
GetEhplmnFromUnsolData(std::vector<uint8_t> buffer)262 void NrUnsolicitedMsgParser::GetEhplmnFromUnsolData(std::vector<uint8_t> buffer)
263 {
264 if (buffer.empty()) {
265 NETMGR_EXT_LOG_E("GetEhplmnFromUnsolData failed, invalid buffer");
266 return;
267 }
268 NETMGR_EXT_LOG_I("start GetEhplmnFromUnsolData");
269 int inputLen = (int)buffer.size();
270 mEhplmns.clear();
271 std::string ehplmn = "";
272 std::vector<std::string> values;
273 int i;
274 for (i = 0; i < inputLen; ++i) {
275 ehplmn += static_cast<char>(buffer[i]);
276 }
277 values = Split(ehplmn, ",");
278 for (i = 0; i < (int)values.size(); ++i) {
279 mEhplmns.push_back(values[i]);
280 }
281 for (i = 0; i < (int)mEhplmns.size(); ++i) {
282 NETMGR_EXT_LOG_I("mEhplmn[%{public}d] = %{public}s", i, mEhplmns[i].c_str());
283 }
284 }
285
GetUrspFromUnsolData(std::vector<uint8_t> buffer)286 void NrUnsolicitedMsgParser::GetUrspFromUnsolData(std::vector<uint8_t> buffer)
287 {
288 if (buffer.empty()) {
289 NETMGR_EXT_LOG_E("getUrspFromUnsolData failed, invalid buffer");
290 return;
291 }
292 if (buffer.size() < NetworkSliceCommConfig::LEN_THREE_BYTE) {
293 return;
294 }
295 int startIndex = 0;
296 const uint8_t pti = buffer[startIndex++];
297 const uint8_t segmentNum = buffer[startIndex++];
298 if (segmentNum < 1) {
299 return;
300 }
301 const uint8_t segmentIndex = buffer[startIndex++];
302 if (segmentNum == 1) { /* one segment buffer, directly decode buffer */
303 DecodeUrspFromUnsolData(startIndex, buffer);
304 return;
305 }
306 if (mMultipleBufferMap.find(pti) == mMultipleBufferMap.end()) { /* first segment of this pti */
307 MultipleBuffer multipleBuffer;
308 multipleBuffer.segmentNum = segmentNum;
309 multipleBuffer.bufferSegmentMap[segmentIndex] = buffer;
310 multipleBuffer.totalBufferLen += (int(buffer.size()) - startIndex);
311 mMultipleBufferMap[pti] = multipleBuffer;
312 } else {
313 MultipleBuffer multipleBuffer = mMultipleBufferMap[pti];
314 if (segmentNum != multipleBuffer.segmentNum || segmentIndex > segmentNum || segmentIndex <= 0) {
315 NETMGR_EXT_LOG_E("segmentNum or segmentIndex invalid");
316 return;
317 }
318 if (multipleBuffer.bufferSegmentMap.find(segmentIndex) != multipleBuffer.bufferSegmentMap.end()) {
319 NETMGR_EXT_LOG_E("segmentIndex already exist");
320 return;
321 }
322 multipleBuffer.bufferSegmentMap[segmentIndex] = buffer;
323 multipleBuffer.totalBufferLen += (int(buffer.size()) - startIndex);
324 if (multipleBuffer.bufferSegmentMap.size() == segmentNum) { /* all segment is received */
325 std::vector<uint8_t> combinationBuffer(multipleBuffer.totalBufferLen);
326 for (int index = 1; index <= segmentNum; ++index) {
327 std::vector<uint8_t> tmpvec = multipleBuffer.bufferSegmentMap[static_cast<uint8_t>(index)];
328 combinationBuffer.insert(combinationBuffer.end(), tmpvec.begin(), tmpvec.end());
329 }
330 startIndex = 0;
331 DecodeUrspFromUnsolData(startIndex, combinationBuffer);
332 mMultipleBufferMap.erase(pti);
333 }
334 }
335 }
336
DecodeUrspFromUnsolData(int & startIndex,std::vector<uint8_t> buffer)337 void NrUnsolicitedMsgParser::DecodeUrspFromUnsolData(int& startIndex, std::vector<uint8_t> buffer)
338 {
339 if (sUrspConfig_ == nullptr) {
340 NETMGR_EXT_LOG_E("DecodeUrspFromUnsolData, sUrspConfig_ == nullptr");
341 return;
342 }
343 if (buffer.empty()) {
344 NETMGR_EXT_LOG_E("getursp failed, invalid buffer");
345 return;
346 }
347 NETMGR_EXT_LOG_I("start decode ursp, buffer.remaining() = [%{public}d]", (int)buffer.size());
348 int inputLen = (int(buffer.size()) - startIndex);
349 if (inputLen < NetworkSliceCommConfig::LEN_SHORT) {
350 NETMGR_EXT_LOG_E("inputLen < NetworkSliceCommConfig::LEN_SHORT");
351 return;
352 }
353 short version = GetShort(startIndex, buffer, true);
354 NETMGR_EXT_LOG_I("ursp version = [%{public}d]", version);
355 if (version == NetworkSliceCommConfig::URSP_VERSION_1510
356 || version == NetworkSliceCommConfig::URSP_VERSION_1520) {
357 sUrspConfig_->SetUrspVersion(version);
358 } else {
359 NETMGR_EXT_LOG_E("version is invalid = %{public}d", version);
360 return;
361 }
362 inputLen -= NetworkSliceCommConfig::LEN_SHORT;
363 if (inputLen < NetworkSliceCommConfig::LEN_INT) {
364 /* LEN_INT = PTI + message type + Length of contents */
365 NETMGR_EXT_LOG_E("inputLen < NetworkSliceCommConfig::LEN_INT");
366 return;
367 }
368 /* PTI */
369 uint8_t pti = buffer[startIndex++];
370 inputLen -= NetworkSliceCommConfig::LEN_BYTE;
371
372 /* UE policy delivery service message type */
373 if (buffer[startIndex++] != MSG_MANAGE_UE_POLICY_COMMAND) {
374 NETMGR_EXT_LOG_E("buffer.get() != MSG_MANAGE_UE_POLICY_COMMAND");
375 return;
376 }
377 inputLen -= NetworkSliceCommConfig::LEN_BYTE;
378 std::unordered_map<std::string, UePolicy> decodeUePolicyMap;
379 if (!DecodePolicySectionList(inputLen, startIndex, buffer, decodeUePolicyMap)) {
380 return;
381 }
382 NETMGR_EXT_LOG_I("end decode ursp = [%{public}d]", pti);
383 HandleDecodeResult(pti, decodeUePolicyMap);
384 }
385
HandleDecodeResult(uint8_t pti,std::unordered_map<std::string,UePolicy> & decodeUePolicyMap)386 void NrUnsolicitedMsgParser::HandleDecodeResult(uint8_t pti,
387 std::unordered_map<std::string, UePolicy>& decodeUePolicyMap)
388 {
389 NETMGR_EXT_LOG_I("HandleDecodeResult");
390 UePolicyRejectMsg uePolicyRejectMsg;
391 if (!isUePolicyLegal(decodeUePolicyMap, uePolicyRejectMsg)) {
392 NETMGR_EXT_LOG_I("NrUnsolicitedMsgParser::ue policy illegal");
393 SndManageUePolicyCommandReject(pti, uePolicyRejectMsg);
394 return;
395 }
396 SndManageUePolicyComplete(pti);
397 AddNewUePolicy(decodeUePolicyMap);
398 SendUePolicySectionIdentifier();
399 SendImsRsdList();
400 WriteObjectToJsonFile(REPORTURSP_PATH, uePolicyMap);
401 UpdateUrspRules();
402 SendUrspUpdate();
403 DelayedSingleton<NetworkSliceManager>::GetInstance()->onUrspAvailableStateChanged();
404 }
405
SndManageUePolicyComplete(uint8_t pti)406 void NrUnsolicitedMsgParser::SndManageUePolicyComplete(uint8_t pti)
407 {
408 NETMGR_EXT_LOG_I("SndManageUePolicyComplete, ModemID:%{public}d, MSGID:%{public}d",
409 MODEM_ID, MSG_MANAGE_UE_POLICY_COMPLETE);
410 std::vector<uint8_t> buffer;
411 buffer.push_back(pti);
412 buffer.push_back(MSG_MANAGE_UE_POLICY_COMPLETE);
413 Telephony::CellularDataClient::GetInstance().SendUrspDecodeResult(MODEM_ID, buffer);
414 }
415
SndManageUePolicyCommandReject(uint8_t pti,UePolicyRejectMsg uePolicyRejectMsg)416 void NrUnsolicitedMsgParser::SndManageUePolicyCommandReject(uint8_t pti,
417 UePolicyRejectMsg uePolicyRejectMsg)
418 {
419 NETMGR_EXT_LOG_I("SndManageUePolicyCommandReject");
420 std::vector<uint8_t> buffer;
421 int32_t startlen = 0;
422 /* put pti */
423 buffer.push_back(pti);
424 startlen++;
425 /* put UE policy delivery service message type */
426 buffer.push_back(MSG_MANAGE_UE_POLICY_COMMAND_REJECT);
427 startlen++;
428 /* put UE policy section management result information element */
429 PutShort(buffer, uePolicyRejectMsg.totalLen);
430 startlen += NetworkSliceCommConfig::LEN_SHORT;
431 for (int i = 0; i < (int)uePolicyRejectMsg.uePolicyRejects.size(); ++i) {
432 /* put Number of results */
433 buffer.push_back(static_cast<uint8_t>(uePolicyRejectMsg.uePolicyRejects.size()));
434 startlen++;
435 /* put plmn */
436 for (int j = 0; j < PLMN_LEN; ++j) {
437 buffer.push_back(uePolicyRejectMsg.uePolicyRejects[i].plmn[j]);
438 startlen++;
439 }
440
441 /* put UE policy section management result contents */
442 std::vector<UePolicyResult> uePolicyResults = uePolicyRejectMsg.uePolicyRejects[i].uePolicyResult;
443 for (int j = 0; j < (int)uePolicyResults.size(); ++j) {
444 PutShort(buffer, uePolicyResults[j].upsc);
445 startlen += NetworkSliceCommConfig::LEN_SHORT;
446 PutShort(buffer, uePolicyResults[j].failedInstructionOrder);
447 startlen += NetworkSliceCommConfig::LEN_SHORT;
448 buffer.push_back(uePolicyResults[j].cause);
449 startlen++;
450 }
451 }
452 Telephony::CellularDataClient::GetInstance().SendUrspDecodeResult(MODEM_ID, buffer);
453 }
454
SendUePolicySectionIdentifier()455 void NrUnsolicitedMsgParser::SendUePolicySectionIdentifier()
456 {
457 if (sUrspConfig_ == nullptr) {
458 NETMGR_EXT_LOG_E("SendUePolicySectionIdentifier sUrspConfig_ == nullptr ");
459 return;
460 }
461 short upsiListLen = 0;
462 for (const auto& entry : uePolicyMap) {
463 const UePolicy& uePolicy = entry.second;
464 upsiListLen = (short)(upsiListLen + NetworkSliceCommConfig::LEN_SHORT + PLMN_LEN
465 + NetworkSliceCommConfig::LEN_SHORT * uePolicy.policyInstructionMap.size());
466 }
467 uint16_t allocateLen = NetworkSliceCommConfig::LEN_BYTE + NetworkSliceCommConfig::LEN_BYTE
468 + NetworkSliceCommConfig::LEN_SHORT + upsiListLen
469 + NetworkSliceCommConfig::LEN_BYTE + NetworkSliceCommConfig::LEN_BYTE + NetworkSliceCommConfig::LEN_SHORT;
470 std::vector<uint8_t> buffer;
471 int32_t startlen = 0;
472 buffer.push_back(0); /* put pti, use 0 */
473 startlen++;
474 buffer.push_back(MSG_UE_STATE_INDICATION); /* put UE policy delivery service message type */
475 startlen++;
476 PutShort(buffer, upsiListLen); /* put upsi */
477 startlen += NetworkSliceCommConfig::LEN_SHORT;
478 for (const auto& entry : uePolicyMap) {
479 const UePolicy& uePolicy = entry.second;
480 uint8_t upsiSublistLen = (uint8_t)(PLMN_LEN
481 + NetworkSliceCommConfig::LEN_SHORT * uePolicy.policyInstructionMap.size());
482 PutShort(buffer, upsiSublistLen); /* put upsi sublist len */
483 startlen += NetworkSliceCommConfig::LEN_SHORT;
484 for (int i = 0; i < PLMN_LEN; ++i) { /* put plmn */
485 buffer.push_back(uePolicy.plmn[i]);
486 startlen++;
487 }
488 for (const auto& instructionEntry : uePolicy.policyInstructionMap) { /* put upsc list */
489 PutShort(buffer, instructionEntry.first);
490 startlen += NetworkSliceCommConfig::LEN_SHORT;
491 }
492 }
493 buffer.push_back(1); /* put Length of Policy information contents */
494 startlen++;
495 buffer.push_back(0); /* put UE policy classmark, 0 means ANDSP not supported by the UE */
496 startlen++;
497 PutShort(buffer, sUrspConfig_->GetSuccUrspVersion()); /* put ursp version */
498 startlen += NetworkSliceCommConfig::LEN_SHORT;
499 Telephony::CellularDataClient::GetInstance().SendUePolicySectionIdentifier(MODEM_ID, buffer);
500 }
501
SendImsRsdList()502 void NrUnsolicitedMsgParser::SendImsRsdList()
503 {
504 if (sUrspConfig_ == nullptr) {
505 NETMGR_EXT_LOG_E("SendImsRsdList sUrspConfig_ == nullptr ");
506 return;
507 }
508 if (!sUrspConfig_->mImsRsdsMap.empty()) {
509 NETMGR_EXT_LOG_I("GetImsRsdList mImsRsdsMap is not empty");
510 }
511 std::vector<uint8_t> rsdBytes = sUrspConfig_->GetImsRsdList();
512 if (!rsdBytes.empty()) {
513 NETMGR_EXT_LOG_I("NrUnsolicitedMsgParser::SendImsRsdList");
514 Telephony::CellularDataClient::GetInstance().SendImsRsdList(MODEM_ID, rsdBytes);
515 }
516 }
517
AddNewUePolicy(std::unordered_map<std::string,UePolicy> & decodeUePolicyMap)518 void NrUnsolicitedMsgParser::AddNewUePolicy(std::unordered_map<std::string, UePolicy>& decodeUePolicyMap)
519 {
520 NETMGR_EXT_LOG_I("AddNewUePolicy");
521 /*
522 * Upon receipt of the MANAGE UE POLICY COMMAND message,
523 * for each instruction included in the UE policy section management list IE,
524 * the UE shall:
525 * a)store the received UE policy section of the instruction,
526 * if the UE has no stored UE policy section associated with the same UPSI
527 * as the UPSI associated with the instruction;
528 * b)replace the stored UE policy section with the received UE policy section of the instruction,
529 * if the UE has a stored UE policy section associated with the same UPSI as the UPSI associated
530 * with the instruction; or
531 * c)delete the stored UE policy section, if the UE has a stored UE policy section associated with
532 * the same UPSI as the UPSI associated with the instruction and the UE policy section contents of
533 * the instruction is empty.
534 */
535 for (const auto& entry : decodeUePolicyMap) {
536 std::string plmn = entry.first;
537 NETMGR_EXT_LOG_I("AddNewUePolicy plmn = %{public}s", plmn.c_str());
538 UePolicy uePolicy = entry.second;
539 if (uePolicyMap.find(plmn) == uePolicyMap.end()) {
540 uePolicyMap[plmn] = uePolicy;
541 continue;
542 }
543
544 std::unordered_map<short, PolicyInstruction>& oldUePolicy = uePolicyMap[plmn].policyInstructionMap;
545
546 for (const auto& instructionEntry : uePolicy.policyInstructionMap) {
547 short upsc = instructionEntry.first;
548 if (oldUePolicy.find(upsc) == oldUePolicy.end()) {
549 oldUePolicy[upsc] = instructionEntry.second;
550 continue;
551 }
552
553 if (!instructionEntry.second.hasUrspType) {
554 oldUePolicy.erase(upsc);
555 continue;
556 }
557
558 oldUePolicy.erase(upsc);
559 oldUePolicy[upsc] = instructionEntry.second;
560 }
561
562 if (oldUePolicy.empty()) {
563 uePolicyMap.erase(plmn);
564 }
565 }
566 }
567
isUePolicyLegal(std::unordered_map<std::string,UePolicy> & decodeUePolicyMap,UePolicyRejectMsg & uePolicyRejectMsg)568 bool NrUnsolicitedMsgParser::isUePolicyLegal(std::unordered_map<std::string, UePolicy>& decodeUePolicyMap,
569 UePolicyRejectMsg& uePolicyRejectMsg)
570 {
571 for (const auto& entry : decodeUePolicyMap) {
572 const std::string& plmn = entry.first;
573 if (isPlmnInHplmn(plmn)) {
574 continue;
575 }
576 const UePolicy& uePolicy = entry.second;
577 UePolicyReject uePolicyReject;
578 std::copy(uePolicy.plmn.begin(), uePolicy.plmn.begin() + PLMN_LEN, std::back_inserter(uePolicyReject.plmn));
579 for (const auto& instructionEntry : uePolicy.instructionOrderMap) {
580 UePolicyResult uePolicyResult;
581 uePolicyResult.upsc = instructionEntry.second;
582 uePolicyResult.failedInstructionOrder = instructionEntry.first;
583 uePolicyResult.cause = CAUSE_PROTOCOL_ERROR;
584 uePolicyReject.uePolicyResult.push_back(uePolicyResult);
585 uePolicyRejectMsg.totalLen += RESULT_LEN;
586 }
587 uePolicyRejectMsg.uePolicyRejects.push_back(uePolicyReject);
588 uePolicyRejectMsg.totalLen += NetworkSliceCommConfig::LEN_BYTE + PLMN_LEN;
589 }
590 if (!uePolicyRejectMsg.uePolicyRejects.empty()) {
591 return false;
592 }
593 return true;
594 }
595
isPlmnInHplmn(std::string plmn)596 bool NrUnsolicitedMsgParser::isPlmnInHplmn(std::string plmn)
597 {
598 if (mEhplmns.empty()) {
599 mEhplmns.push_back(DEFAULT_PLMN);
600 }
601 if (mEhplmns.empty()) {
602 NETMGR_EXT_LOG_I("mEhplmns == null");
603 return false;
604 }
605 NETMGR_EXT_LOG_I("mEhplmns.size() = %{public}d", (int)mEhplmns.size());
606 if (mEhplmns.size() > 0 && plmn == mEhplmns[0]) {
607 return true;
608 }
609 return false;
610 }
611
DecodePolicySectionList(int inputLen,int & startIndex,std::vector<uint8_t> buffer,std::unordered_map<std::string,UePolicy> & decodeUePolicyMap)612 bool NrUnsolicitedMsgParser::DecodePolicySectionList(int inputLen, int& startIndex, std::vector<uint8_t> buffer,
613 std::unordered_map<std::string, UePolicy>& decodeUePolicyMap)
614 {
615 NETMGR_EXT_LOG_I("DecodePolicySectionList");
616 int len = inputLen;
617 short subLen_short = GetShort(startIndex, buffer);
618 len -= NetworkSliceCommConfig::LEN_SHORT;
619 if (ConvertUnsignedShort2Int(subLen_short) != len) {
620 NETMGR_EXT_LOG_E("buffer.getShort() != len, %{public}d != %{public}d",
621 ConvertUnsignedShort2Int(subLen_short), len);
622 return false;
623 }
624 while (len > 0) {
625 if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
626 NETMGR_EXT_LOG_E("buffer.remaining() is not enough when get sublist length");
627 return false;
628 }
629 subLen_short = GetShort(startIndex, buffer);
630 int subLen = ConvertUnsignedShort2Int(subLen_short);
631 if (((int(buffer.size()) - startIndex) < subLen) ||
632 (len < (NetworkSliceCommConfig::LEN_SHORT + subLen))) {
633 NETMGR_EXT_LOG_I("size = %{public}d, subLen = %{public}d, Len = %{public}d",
634 (int(buffer.size()) - startIndex), subLen, len);
635 NETMGR_EXT_LOG_E("buffer.remaining() or len is not enough when decode policy section list");
636 return false;
637 }
638 len = len - NetworkSliceCommConfig::LEN_SHORT - subLen;
639 if (!DecodePolicySection(subLen, startIndex, buffer, decodeUePolicyMap)) {
640 NETMGR_EXT_LOG_E("decodePolicySection(subLen, buffer) is false");
641 return false;
642 }
643 }
644 return true;
645 }
646
DecodePolicySection(int inputLen,int & startIndex,std::vector<uint8_t> buffer,std::unordered_map<std::string,UePolicy> & decodeUePolicyMap)647 bool NrUnsolicitedMsgParser::DecodePolicySection(int inputLen, int& startIndex, std::vector<uint8_t> buffer,
648 std::unordered_map<std::string, UePolicy>& decodeUePolicyMap)
649 {
650 std::vector<uint8_t> plmns;
651 int len = inputLen;
652 if (len < NetworkSliceCommConfig::LEN_THREE_BYTE) { /* plmn */
653 NETMGR_EXT_LOG_E("len < NetworkSliceCommConfig::LEN_THREE_BYTE");
654 return false;
655 }
656 plmns.push_back(buffer[startIndex]);
657 plmns.push_back(buffer[startIndex + ARRAY_INDEX_1]);
658 plmns.push_back(buffer[startIndex + ARRAY_INDEX_2]);
659 startIndex += NetworkSliceCommConfig::LEN_THREE_BYTE;
660 len -= NetworkSliceCommConfig::LEN_THREE_BYTE;
661 std::string plmn = PlmnToString(plmns);
662 NETMGR_EXT_LOG_I("DecodePolicySection::PLMN = %{public}s", plmn.c_str());
663 if (plmn == "") {
664 return false;
665 }
666 UePolicy uePolicy;
667 if (decodeUePolicyMap.find(plmn) != decodeUePolicyMap.end()) {
668 uePolicy = decodeUePolicyMap[plmn];
669 } else {
670 uePolicy.plmn = plmns;
671 }
672 short instructionOrder = 0;
673 while (len > 0) {
674 if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
675 NETMGR_EXT_LOG_E("buffer.remaining() < NetworkSliceCommConfig::LEN_SHORT");
676 return false;
677 }
678 short subLen_short = GetShort(startIndex, buffer);
679 int subLen = ConvertUnsignedShort2Int(subLen_short);
680 if ((int(buffer.size()) - startIndex) < subLen || (len < (NetworkSliceCommConfig::LEN_SHORT + subLen))) {
681 NETMGR_EXT_LOG_E("(buffer.remaining() < subLen) || (len < (NetworkSliceCommConfig::LEN_SHORT + subLen))");
682 return false;
683 }
684 len = len - NetworkSliceCommConfig::LEN_SHORT - subLen;
685 instructionOrder++;
686 if (!DecodeInstruction(subLen, startIndex, buffer, uePolicy, instructionOrder)) {
687 NETMGR_EXT_LOG_E("decodeInstruction(subLen, buffer, uePolicy) is false");
688 return false;
689 }
690 }
691 if (decodeUePolicyMap.find(plmn) == decodeUePolicyMap.end()) {
692 decodeUePolicyMap[plmn] = uePolicy;
693 }
694 if (uePolicy.policyInstructionMap.empty()) {
695 decodeUePolicyMap.erase(plmn);
696 }
697 return true;
698 }
699
DecodeInstruction(int inputLen,int & startIndex,std::vector<uint8_t> buffer,UePolicy & uePolicy,short instructionOrder)700 bool NrUnsolicitedMsgParser::DecodeInstruction(int inputLen, int& startIndex, std::vector<uint8_t> buffer,
701 UePolicy& uePolicy, short instructionOrder)
702 {
703 NETMGR_EXT_LOG_I("DecodeInstruction");
704 PolicyInstruction policyInstruction;
705 int len = inputLen;
706
707 /* upsc */
708 if (len < NetworkSliceCommConfig::LEN_SHORT) {
709 NETMGR_EXT_LOG_E("len < NetworkSliceCommConfig::LEN_SHORT");
710 return false;
711 }
712 short upsc = GetShort(startIndex, buffer);
713 len -= NetworkSliceCommConfig::LEN_SHORT;
714 NETMGR_EXT_LOG_E("upsc = %{public}d, len = %{public}d", upsc, len);
715 if (uePolicy.policyInstructionMap.find(upsc) != uePolicy.policyInstructionMap.end()) {
716 policyInstruction = uePolicy.policyInstructionMap[upsc];
717 policyInstruction.hasUrspType = false;
718 policyInstruction.urspRules.clear();
719 } else {
720 PolicyInstruction newPolicyInstruction;
721 newPolicyInstruction.hasUrspType = false;
722 uePolicy.policyInstructionMap[upsc] = newPolicyInstruction;
723 }
724
725 while (len > 0) {
726 /* UE policy part contents length */
727 if ((int(buffer.size()) - startIndex) < NetworkSliceCommConfig::LEN_SHORT) {
728 NETMGR_EXT_LOG_E("buffer.size() < NetworkSliceCommConfig::LEN_SHORT");
729 return false;
730 }
731 short subLen_short = GetShort(startIndex, buffer);
732 int subLen = ConvertUnsignedShort2Int(subLen_short);
733 if (((int(buffer.size()) - startIndex) < subLen) || (len < (NetworkSliceCommConfig::LEN_SHORT + subLen))) {
734 NETMGR_EXT_LOG_I("size = %{public}d, subLen = %{public}d, Len = %{public}d",
735 (int(buffer.size()) - startIndex), subLen, len);
736 NETMGR_EXT_LOG_E("(buffer.size() < subLen) || (len < (NetworkSliceCommConfig::LEN_SHORT + subLen))");
737 return false;
738 }
739 len = len - NetworkSliceCommConfig::LEN_SHORT - subLen;
740 if (!DecodeUePolicyPart(subLen, startIndex, buffer, policyInstruction)) {
741 NETMGR_EXT_LOG_E("decodeUePolicyPart(subLen, buffer, policyInstruction.urspRules) is false");
742 return false;
743 }
744 }
745
746 uePolicy.policyInstructionMap[upsc] = policyInstruction;
747 if (policyInstruction.hasUrspType) {
748 uePolicy.instructionOrderMap[instructionOrder] = upsc;
749 }
750 return true;
751 }
752
DecodeUePolicyPart(int inputLen,int & startIndex,std::vector<uint8_t> buffer,PolicyInstruction & policyInstruction)753 bool NrUnsolicitedMsgParser::DecodeUePolicyPart(int inputLen, int& startIndex,
754 std::vector<uint8_t> buffer, PolicyInstruction& policyInstruction)
755 {
756 NETMGR_EXT_LOG_I("DecodeUePolicyPart");
757 uint8_t uePolicyType;
758 std::vector<uint8_t> dsts;
759 int len = inputLen;
760 /* ue policy part type */
761 if (len < NetworkSliceCommConfig::LEN_BYTE) {
762 NETMGR_EXT_LOG_E("len < NetworkSliceCommConfig::LEN_BYTE");
763 return false;
764 }
765 /* use low 4 bits for ue policy type, high 4 bits reserved */
766 uePolicyType = buffer[startIndex] & 0x0F;
767 startIndex += NetworkSliceCommConfig::LEN_BYTE;
768 len -= NetworkSliceCommConfig::LEN_BYTE;
769 if (uePolicyType != UE_POLICY_PART_TYPE_URSP) {
770 NETMGR_EXT_LOG_I("uePolicyType != UE_POLICY_PART_TYPE_URSP, %{public}d != %{public}d",
771 uePolicyType, UE_POLICY_PART_TYPE_URSP);
772 /* not ursp type */
773 dsts = std::vector<uint8_t>(len);
774 for (int i = 0; i < len; ++i) {
775 dsts[i] = buffer[startIndex];
776 startIndex++;
777 }
778 return true;
779 }
780 policyInstruction.hasUrspType = true;
781 if (sUrspConfig_ == nullptr) {
782 NETMGR_EXT_LOG_E("mUrspConfig == null");
783 return false;
784 }
785 if (!sUrspConfig_->DecodeUrspRules(len, startIndex, buffer, policyInstruction.urspRules)) {
786 NETMGR_EXT_LOG_E("mUrspConfig->decodeUrspRules(subLen, buffer, urspRules) is false");
787 return false;
788 }
789 return true;
790 }
791
PlmnToString(const std::vector<uint8_t> & plmns)792 std::string NrUnsolicitedMsgParser::PlmnToString(const std::vector<uint8_t>& plmns)
793 {
794 std::string plmn;
795 std::string firstByte = ByteToHexStr(plmns[ARRAY_INDEX_0] & CONVERT_INT_AND_BYTE);
796 plmn += std::to_string(std::stoi(firstByte) % RADIX);
797 plmn += std::to_string(std::stoi(firstByte) / RADIX);
798 std::string secondByte = ByteToHexStr(plmns[ARRAY_INDEX_1] & CONVERT_INT_AND_BYTE);
799 bool isThreeDigitsForMnc = true;
800 if (secondByte.find("f") == 0) {
801 secondByte = "0" + secondByte.substr(1);
802 isThreeDigitsForMnc = false;
803 }
804 plmn += std::to_string(std::stoi(secondByte) % RADIX);
805 std::string thirdByte = ByteToHexStr(plmns[ARRAY_INDEX_2] & CONVERT_INT_AND_BYTE);
806 plmn += std::to_string(std::stoi(thirdByte) % RADIX);
807 plmn += std::to_string(std::stoi(thirdByte) / RADIX);
808 if (isThreeDigitsForMnc) {
809 plmn += std::to_string(std::stoi(secondByte) / RADIX);
810 }
811 NETMGR_EXT_LOG_I("NrUnsolicitedMsgParser::PlmnToString is %{public}s", plmn.c_str());
812 return plmn;
813 }
814
815 } // namespace NetManagerStandard
816 } // namespace OHOS
817