• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "network_register.h"
17 
18 #include <cinttypes>
19 
20 #include "core_service_hisysevent.h"
21 #include "hril_modem_parcel.h"
22 #include "i_network_search_callback.h"
23 #include "network_search_manager.h"
24 #include "parameter.h"
25 #include "resource_utils.h"
26 #include "string_ex.h"
27 #include "telephony_errors.h"
28 #include "telephony_log_wrapper.h"
29 
30 namespace OHOS {
31 namespace Telephony {
32 const char *TELEPHONY_NR_CONVERSION_CONFIG_INDEX = "persist.telephony.nr.config.index"; // "A/B/C/D"
33 /**
34  * System configuration format
35  * NOT_SUPPORT:4g,NO_DETECT:4g,CONNECTED_DETECT:4g,IDLE_DETECT:4g,DUAL_CONNECTED:5g,SA_ATTACHED:5g
36  */
37 const char *TELEPHONY_NR_CONVERSION_CONFIG_A = "persist.telephony.nr.config.a";
38 const char *TELEPHONY_NR_CONVERSION_CONFIG_B = "persist.telephony.nr.config.b";
39 const char *TELEPHONY_NR_CONVERSION_CONFIG_C = "persist.telephony.nr.config.c";
40 const char *TELEPHONY_NR_CONVERSION_CONFIG_D = "persist.telephony.nr.config.d";
41 const int32_t SYS_PARAMETER_SIZE = 256;
42 const int32_t NR_STATE_NUM = 6;
43 const int32_t KEY_VALUE_NUM = 2;
44 const int32_t MAX_SIZE = 100;
45 
NetworkRegister(std::shared_ptr<NetworkSearchState> networkSearchState,std::weak_ptr<NetworkSearchManager> networkSearchManager,int32_t slotId)46 NetworkRegister::NetworkRegister(std::shared_ptr<NetworkSearchState> networkSearchState,
47     std::weak_ptr<NetworkSearchManager> networkSearchManager, int32_t slotId)
48     : networkSearchState_(networkSearchState), networkSearchManager_(networkSearchManager), slotId_(slotId)
49 {
50     ResourceUtils::Get().GetValueByName<bool>(ResourceUtils::IS_CS_CAPABLE, isCsCapable_);
51 }
52 
InitNrConversionConfig()53 void NetworkRegister::InitNrConversionConfig()
54 {
55     char prase[SYS_PARAMETER_SIZE] = { 0 };
56     int code = GetParameter(TELEPHONY_NR_CONVERSION_CONFIG_INDEX, "A", prase, SYS_PARAMETER_SIZE);
57     if (code <= 0 || prase[0] > 'D' || prase[0] < 'A') {
58         TELEPHONY_LOGE(
59             "Failed to get system properties %{public}s. err:%{public}d slotId:%{public}d", prase, code, slotId_);
60         return;
61     }
62 
63     switch (prase[0]) {
64         case 'A':
65             code = GetParameter(TELEPHONY_NR_CONVERSION_CONFIG_A, "", prase, SYS_PARAMETER_SIZE);
66             break;
67         case 'B':
68             code = GetParameter(TELEPHONY_NR_CONVERSION_CONFIG_B, "", prase, SYS_PARAMETER_SIZE);
69             break;
70         case 'C':
71             code = GetParameter(TELEPHONY_NR_CONVERSION_CONFIG_C, "", prase, SYS_PARAMETER_SIZE);
72             break;
73         case 'D':
74             code = GetParameter(TELEPHONY_NR_CONVERSION_CONFIG_D, "", prase, SYS_PARAMETER_SIZE);
75             break;
76         default:
77             break;
78     }
79 
80     std::string strNrConfig = "";
81     strNrConfig = prase;
82     if (code <= 0 || strNrConfig.empty()) {
83         TELEPHONY_LOGI("Failed to get system properties err:%{public}d use default config a", code);
84         strNrConfig = "NOT_SUPPORT:4g,NO_DETECT:4g,CONNECTED_DETECT:4g,"
85                       "IDLE_DETECT:4g,DUAL_CONNECTED:5g,SA_ATTACHED:5g";
86     }
87     NrConfigParse(strNrConfig);
88 }
89 
ProcessCsRegister(const AppExecFwk::InnerEvent::Pointer & event) const90 void NetworkRegister::ProcessCsRegister(const AppExecFwk::InnerEvent::Pointer &event) const
91 {
92     auto networkSearchManager = networkSearchManager_.lock();
93     if (networkSearchManager == nullptr) {
94         TELEPHONY_LOGE("NetworkRegister::ProcessCsRegister networkSearchManager is nullptr slotId:%{public}d", slotId_);
95         return;
96     }
97     networkSearchManager->decMsgNum(slotId_);
98     if (event == nullptr) {
99         TELEPHONY_LOGE("NetworkRegister::ProcessCsRegister event is nullptr slotId:%{public}d", slotId_);
100         return;
101     }
102     std::shared_ptr<CsRegStatusInfo> csRegStateResult = event->GetSharedObject<CsRegStatusInfo>();
103     if (csRegStateResult == nullptr) {
104         TELEPHONY_LOGE("NetworkRegister::ProcessCsRegister csRegStateResult is nullptr slotId:%{public}d", slotId_);
105         return;
106     }
107     RilRegister registrationStatus = static_cast<RilRegister>(csRegStateResult->regStatus);
108     RegServiceState regStatus = ConvertRegFromRil(registrationStatus);
109     if (networkSearchState_ == nullptr) {
110         TELEPHONY_LOGE("NetworkRegister::ProcessCsRegister networkSearchState_ is nullptr slotId:%{public}d", slotId_);
111         return;
112     }
113     networkSearchState_->SetNetworkState(regStatus, DomainType::DOMAIN_TYPE_CS);
114     networkSearchState_->SetEmergency((regStatus == RegServiceState::REG_STATE_EMERGENCY_ONLY) && isCsCapable_);
115     RadioTech tech = ConvertTechFromRil(static_cast<HRilRadioTech>(csRegStateResult->radioTechnology));
116     networkSearchState_->SetNetworkType(tech, DomainType::DOMAIN_TYPE_CS);
117     RoamingType roam = RoamingType::ROAMING_STATE_UNKNOWN;
118     if (registrationStatus == RilRegister::REG_STATE_ROAMING) {
119         roam = RoamingType::ROAMING_STATE_UNSPEC;
120     }
121     networkSearchState_->SetNetworkStateToRoaming(roam, DomainType::DOMAIN_TYPE_CS);
122     TELEPHONY_LOGI(
123         "ProcessCsRegister: regStatus= %{public}d radioTechnology=%{public}d roam=%{public}d slotId:%{public}d",
124         registrationStatus, csRegStateResult->radioTechnology, roam, slotId_);
125     networkSearchManager->UpdateCellLocation(
126         slotId_, static_cast<int32_t>(tech), csRegStateResult->cellId, csRegStateResult->lacCode);
127     if (networkSearchManager->CheckIsNeedNotify(slotId_) || networkSearchState_->IsEmergency()) {
128         networkSearchState_->NotifyStateChange();
129     }
130     CoreServiceHiSysEvent::WriteNetworkStateBehaviorEvent(slotId_, static_cast<int32_t>(DomainType::DOMAIN_TYPE_CS),
131         static_cast<int32_t>(tech), static_cast<int32_t>(regStatus));
132 }
133 
ProcessPsRegister(const AppExecFwk::InnerEvent::Pointer & event)134 void NetworkRegister::ProcessPsRegister(const AppExecFwk::InnerEvent::Pointer &event)
135 {
136     auto networkSearchManager = networkSearchManager_.lock();
137     if (networkSearchManager == nullptr) {
138         TELEPHONY_LOGE("NetworkRegister::ProcessPsRegister networkSearchManager is nullptr");
139         return;
140     }
141     networkSearchManager->decMsgNum(slotId_);
142     if (event == nullptr) {
143         TELEPHONY_LOGE("NetworkRegister::ProcessPsRegister event is nullptr slotId:%{public}d", slotId_);
144         return;
145     }
146 
147     std::shared_ptr<PsRegStatusResultInfo> psRegStatusResult = event->GetSharedObject<PsRegStatusResultInfo>();
148     if (psRegStatusResult == nullptr) {
149         TELEPHONY_LOGE("NetworkRegister::ProcessPsRegister psRegStatusResult is nullptr slotId:%{public}d", slotId_);
150         return;
151     }
152     RilRegister registrationStatus = static_cast<RilRegister>(psRegStatusResult->regStatus);
153     RegServiceState regStatus = ConvertRegFromRil(registrationStatus);
154     if (networkSearchState_ == nullptr) {
155         TELEPHONY_LOGE("NetworkRegister::ProcessPsRegister networkSearchState_ is nullptr slotId:%{public}d", slotId_);
156         return;
157     }
158     networkSearchState_->SetNetworkState(regStatus, DomainType::DOMAIN_TYPE_PS);
159     networkSearchState_->SetEmergency((regStatus == RegServiceState::REG_STATE_EMERGENCY_ONLY) && isCsCapable_);
160     RadioTech tech = ConvertTechFromRil(static_cast<HRilRadioTech>(psRegStatusResult->radioTechnology));
161     networkSearchState_->SetNetworkType(tech, DomainType::DOMAIN_TYPE_PS);
162     RoamingType roam = RoamingType::ROAMING_STATE_UNKNOWN;
163     if (registrationStatus == RilRegister::REG_STATE_ROAMING) {
164         roam = RoamingType::ROAMING_STATE_UNSPEC;
165     }
166     networkSearchState_->SetNetworkStateToRoaming(roam, DomainType::DOMAIN_TYPE_PS);
167 
168     endcSupport_ = psRegStatusResult->isEnDcAvailable;
169     dcNrRestricted_ = psRegStatusResult->isDcNrRestricted;
170     nrSupport_ = psRegStatusResult->isNrAvailable;
171     UpdateNrState();
172     UpdateCfgTech();
173 
174     TELEPHONY_LOGI(
175         "ProcessPsRegister: regStatus= %{public}d radioTechnology=%{public}d roam=%{public}d slotId:%{public}d",
176         registrationStatus, psRegStatusResult->radioTechnology, roam, slotId_);
177     if (networkSearchManager->CheckIsNeedNotify(slotId_) || networkSearchState_->IsEmergency()) {
178         networkSearchState_->NotifyStateChange();
179     }
180     CoreServiceHiSysEvent::WriteNetworkStateBehaviorEvent(slotId_, static_cast<int32_t>(DomainType::DOMAIN_TYPE_PS),
181         static_cast<int32_t>(tech), static_cast<int32_t>(regStatus));
182 }
183 
ProcessChannelConfigInfo(const AppExecFwk::InnerEvent::Pointer & event)184 void NetworkRegister::ProcessChannelConfigInfo(const AppExecFwk::InnerEvent::Pointer &event)
185 {
186     std::shared_ptr<ChannelConfigInfoList> channelConfigInfoList = event->GetSharedObject<ChannelConfigInfoList>();
187     if (channelConfigInfoList == nullptr) {
188         TELEPHONY_LOGE(
189             "NetworkRegister::ProcessChannelConfigInfo psRegStatusResult is nullptr slotId:%{public}d", slotId_);
190         return;
191     }
192     int32_t size = channelConfigInfoList->itemNum;
193     TELEPHONY_LOGI("NetworkRegister::ProcessChannelConfigInfo num size:%{public}d slotId:%{public}d", size, slotId_);
194     if (size >= MAX_SIZE) {
195         TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo num over max size");
196         return;
197     }
198     if (channelConfigInfoList->channelConfigInfos.size() > 0 &&
199         static_cast<int32_t>(channelConfigInfoList->channelConfigInfos.size()) == size) {
200         std::vector<PhysicalChannelConfig> &configs = channelConfigInfoList->channelConfigInfos;
201         channelConfigInfos_.clear();
202         channelConfigInfos_.insert(channelConfigInfos_.begin(), configs.begin(), configs.end());
203     } else {
204         TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo data error slotId:%{public}d", slotId_);
205         return;
206     }
207 
208     bool isNrSecondaryCell = false;
209     for (int i = 0; i < size; ++i) {
210         if (static_cast<RadioTech>(channelConfigInfos_[i].ratType) == RadioTech::RADIO_TECHNOLOGY_NR &&
211             static_cast<ConnectServiceCell>(channelConfigInfos_[i].cellConnStatus) ==
212             ConnectServiceCell::CONNECTION_SECONDARY_CELL) {
213             isNrSecondaryCell = true;
214             break;
215         }
216     }
217     NotifyNrFrequencyChanged();
218     if (isNrSecondaryCell_ != isNrSecondaryCell) {
219         isNrSecondaryCell_ = isNrSecondaryCell;
220         UpdateNrState();
221         UpdateCfgTech();
222     }
223 }
224 
NotifyNrFrequencyChanged()225 void NetworkRegister::NotifyNrFrequencyChanged()
226 {
227     auto networkSearchManager = networkSearchManager_.lock();
228     if (networkSearchManager == nullptr) {
229         TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo networkSearchManager is nullptr");
230         return;
231     }
232     bool isFreqChanged = false;
233     FrequencyType curFreqType = FrequencyType::FREQ_TYPE_UNKNOWN;
234 
235     sptr<NetworkSearchCallBackBase> cellularData = networkSearchManager->GetCellularDataCallBack();
236     if (cellularData == nullptr) {
237         TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo cellularData callback is nullptr");
238         return;
239     }
240     ssize_t size = channelConfigInfos_.size();
241     if (size >= MAX_SIZE) {
242         TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo channelConfigInfos_ over max size");
243         return;
244     }
245     for (int i = 0; i < size; ++i) {
246         std::vector<int32_t> &cids = channelConfigInfos_[i].contextIds;
247         if (isFreqChanged) {
248             TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo channelConfigInfos:%{public}d isFreqChanged", i);
249             continue;
250         }
251         for (auto &cid : cids) {
252             if (!cellularData->HasInternetCapability(slotId_, cid)) {
253                 TELEPHONY_LOGE("NetworkRegister::ProcessChannelConfigInfo cid:%{public}d hasNoInternetCapability", cid);
254                 continue;
255             }
256             curFreqType = static_cast<FrequencyType>(channelConfigInfos_[i].freqRange);
257             isFreqChanged = true;
258             break;
259         }
260         if (isFreqChanged) {
261             break;
262         }
263     }
264     if (freqType_ != curFreqType) {
265         freqType_ = curFreqType;
266         networkSearchManager->NotifyNrFrequencyChanged(slotId_);
267         networkSearchManager->SetFrequencyType(slotId_, freqType_);
268     }
269 }
270 
DcPhysicalLinkActiveUpdate(bool isActive)271 void NetworkRegister::DcPhysicalLinkActiveUpdate(bool isActive)
272 {
273     TELEPHONY_LOGI("NetworkRegister::DcPhysicalLinkActiveUpdate isActive:%{public}s slotId:%{public}d",
274         isActive ? "true" : "false", slotId_);
275     isPhysicalLinkActive_ = isActive;
276     UpdateNrState();
277     UpdateCfgTech();
278 }
279 
UpdateNrState()280 void NetworkRegister::UpdateNrState()
281 {
282     auto networkSearchManager = networkSearchManager_.lock();
283     if (networkSearchManager == nullptr || networkSearchState_ == nullptr) {
284         TELEPHONY_LOGE("NetworkRegister::UpdateNrState error slotId:%{public}d", slotId_);
285         return;
286     }
287 
288     // update NR mode and NR state
289     NrMode nrMode = NrMode::NR_MODE_UNKNOWN;
290     nrState_ = NrState::NR_STATE_NOT_SUPPORT;
291     RadioTech rat = networkSearchState_->GetNetworkStatus()->GetPsRadioTech();
292     if (rat == RadioTech::RADIO_TECHNOLOGY_NR) {
293         nrMode = NrMode::NR_MODE_SA_ONLY;
294         nrState_ = NrState::NR_NSA_STATE_SA_ATTACHED;
295     }
296 
297     if (endcSupport_ && (rat == RadioTech::RADIO_TECHNOLOGY_LTE || rat == RadioTech::RADIO_TECHNOLOGY_LTE_CA)) {
298         nrMode = NrMode::NR_MODE_NSA_ONLY;
299 
300         if (dcNrRestricted_) {
301             nrState_ = NrState::NR_STATE_NOT_SUPPORT;
302         }
303         if (!dcNrRestricted_ && !nrSupport_) {
304             nrState_ = NrState::NR_NSA_STATE_NO_DETECT;
305         }
306         if (!dcNrRestricted_ && nrSupport_ && !isPhysicalLinkActive_ && !isNrSecondaryCell_) {
307             nrState_ = NrState::NR_NSA_STATE_IDLE_DETECT;
308         }
309         if (isNrSecondaryCell_ || (!dcNrRestricted_ && nrSupport_ && isPhysicalLinkActive_)) {
310             if (rat == RadioTech::RADIO_TECHNOLOGY_LTE) {
311                 nrState_ = NrState::NR_NSA_STATE_CONNECTED_DETECT;
312             }
313             if (rat == RadioTech::RADIO_TECHNOLOGY_LTE_CA) {
314                 nrState_ = NrState::NR_NSA_STATE_DUAL_CONNECTED;
315             }
316         }
317     }
318     networkSearchManager->SetNrOptionMode(slotId_, nrMode);
319     networkSearchState_->SetNrState(nrState_);
320 }
321 
UpdateCfgTech()322 void NetworkRegister::UpdateCfgTech()
323 {
324     if (nrConfigMap_.find(nrState_) == nrConfigMap_.end()) {
325         TELEPHONY_LOGE("NetworkRegister::UpdateCfgTech not find nr state slotId:%{public}d", slotId_);
326         return;
327     }
328 
329     if (networkSearchState_ == nullptr) {
330         TELEPHONY_LOGE("NetworkRegister::UpdateCfgTech networkSearchState_ is nullptr slotId:%{public}d", slotId_);
331         return;
332     }
333     RadioTech cfgTech = nrConfigMap_[nrState_];
334     if (cfgTech != RadioTech::RADIO_TECHNOLOGY_NR) {
335         cfgTech = networkSearchState_->GetNetworkStatus()->GetPsRadioTech();
336     }
337     networkSearchState_->SetCfgTech(cfgTech);
338 }
339 
ProcessRestrictedState(const AppExecFwk::InnerEvent::Pointer & event) const340 void NetworkRegister::ProcessRestrictedState(const AppExecFwk::InnerEvent::Pointer &event) const {}
341 
ConvertRegFromRil(RilRegister code) const342 RegServiceState NetworkRegister::ConvertRegFromRil(RilRegister code) const
343 {
344     switch (code) {
345         case RilRegister::REG_STATE_SEARCH:
346             return RegServiceState::REG_STATE_SEARCH;
347         case RilRegister::REG_STATE_NOT_REG:
348         case RilRegister::REG_STATE_NO_SERVICE:
349             return RegServiceState::REG_STATE_NO_SERVICE;
350         case RilRegister::REG_STATE_INVALID:
351             return RegServiceState::REG_STATE_UNKNOWN;
352         case RilRegister::REG_STATE_ROAMING:
353         case RilRegister::REG_STATE_HOME_ONLY:
354             return RegServiceState::REG_STATE_IN_SERVICE;
355         case RilRegister::REG_STATE_EMERGENCY_ONLY:
356             return RegServiceState::REG_STATE_EMERGENCY_ONLY;
357         default:
358             return RegServiceState::REG_STATE_NO_SERVICE;
359     }
360 }
361 
ConvertTechFromRil(HRilRadioTech code) const362 RadioTech NetworkRegister::ConvertTechFromRil(HRilRadioTech code) const
363 {
364     switch (code) {
365         case HRilRadioTech::RADIO_TECHNOLOGY_GSM:
366             return RadioTech::RADIO_TECHNOLOGY_GSM;
367         case HRilRadioTech::RADIO_TECHNOLOGY_1XRTT:
368             return RadioTech::RADIO_TECHNOLOGY_1XRTT;
369         case HRilRadioTech::RADIO_TECHNOLOGY_HSPA:
370             return RadioTech::RADIO_TECHNOLOGY_HSPA;
371         case HRilRadioTech::RADIO_TECHNOLOGY_HSPAP:
372             return RadioTech::RADIO_TECHNOLOGY_HSPAP;
373         case HRilRadioTech::RADIO_TECHNOLOGY_WCDMA:
374             return RadioTech::RADIO_TECHNOLOGY_WCDMA;
375         case HRilRadioTech::RADIO_TECHNOLOGY_LTE:
376             return RadioTech::RADIO_TECHNOLOGY_LTE;
377         case HRilRadioTech::RADIO_TECHNOLOGY_EVDO:
378             return RadioTech::RADIO_TECHNOLOGY_EVDO;
379         case HRilRadioTech::RADIO_TECHNOLOGY_EHRPD:
380             return RadioTech::RADIO_TECHNOLOGY_EHRPD;
381         case HRilRadioTech::RADIO_TECHNOLOGY_TD_SCDMA:
382             return RadioTech::RADIO_TECHNOLOGY_TD_SCDMA;
383         case HRilRadioTech::RADIO_TECHNOLOGY_LTE_CA:
384             return RadioTech::RADIO_TECHNOLOGY_LTE_CA;
385         case HRilRadioTech::RADIO_TECHNOLOGY_NR:
386             return RadioTech::RADIO_TECHNOLOGY_NR;
387         default:
388             return RadioTech::RADIO_TECHNOLOGY_UNKNOWN;
389     }
390 }
391 
NrConfigParse(std::string & cfgStr)392 void NetworkRegister::NrConfigParse(std::string &cfgStr)
393 {
394     /**
395      * parse string
396      * NOT_SUPPORT:4g,NO_DETECT:4g,CONNECTED_DETECT:4g,IDLE_DETECT:4g,DUAL_CONNECTED:5g,SA_ATTACHED:5g
397      */
398     std::string strSep = ",";
399     std::vector<std::string> strsRet;
400     SplitStr(cfgStr, strSep, strsRet);
401     if (static_cast<int>(strsRet.size()) != NR_STATE_NUM) {
402         TELEPHONY_LOGE("NetworkRegister::NrConfigParse string error slotId:%{public}d", slotId_);
403         return;
404     }
405 
406     std::string strNrFlag = "";
407     std::vector<std::string> nrStateKv;
408     for (auto &state : strsRet) {
409         strSep = ":";
410         SplitStr(state, strSep, nrStateKv);
411         if (static_cast<int>(nrStateKv.size()) != KEY_VALUE_NUM) {
412             TELEPHONY_LOGE("NetworkRegister::NrConfigParse key value string error slotId:%{public}d", slotId_);
413             return;
414         }
415         NrState nrState = ConvertStringToNrState(nrStateKv[0]);
416         RadioTech tech = RadioTech::RADIO_TECHNOLOGY_NR;
417         if (nrStateKv[1].compare("5g") != 0) {
418             tech = RadioTech::RADIO_TECHNOLOGY_LTE;
419         }
420         nrConfigMap_.insert(std::make_pair(nrState, tech));
421     }
422 }
423 
ConvertStringToNrState(std::string & strState) const424 NrState NetworkRegister::ConvertStringToNrState(std::string &strState) const
425 {
426     if (strState.compare("NOT_SUPPORT") == 0) {
427         return NrState::NR_STATE_NOT_SUPPORT;
428     } else if (strState.compare("NO_DETECT") == 0) {
429         return NrState::NR_NSA_STATE_NO_DETECT;
430     } else if (strState.compare("CONNECTED_DETECT") == 0) {
431         return NrState::NR_NSA_STATE_CONNECTED_DETECT;
432     } else if (strState.compare("IDLE_DETECT") == 0) {
433         return NrState::NR_NSA_STATE_IDLE_DETECT;
434     } else if (strState.compare("DUAL_CONNECTED") == 0) {
435         return NrState::NR_NSA_STATE_DUAL_CONNECTED;
436     } else if (strState.compare("SA_ATTACHED") == 0) {
437         return NrState::NR_NSA_STATE_SA_ATTACHED;
438     } else {
439         return NrState::NR_STATE_NOT_SUPPORT;
440     }
441 }
442 } // namespace Telephony
443 } // namespace OHOS
444