• 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 
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