1 /*
2  * Copyright (C) 2021-2022 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_search_state.h"
17 
18 #include <securec.h>
19 
20 #include "network_search_manager.h"
21 #include "network_search_notify.h"
22 #include "telephony_errors.h"
23 #include "telephony_log_wrapper.h"
24 #include "telephony_ext_wrapper.h"
25 
26 namespace OHOS {
27 namespace Telephony {
NetworkSearchState(const std::weak_ptr<NetworkSearchManager> & networkSearchManager,int32_t slotId)28 NetworkSearchState::NetworkSearchState(const std::weak_ptr<NetworkSearchManager> &networkSearchManager, int32_t slotId)
29     : networkSearchManager_(networkSearchManager), slotId_(slotId)
30 {}
31 
Init()32 bool NetworkSearchState::Init()
33 {
34     TELEPHONY_LOGI("NetworkSearchState Init slotId:%{public}d", slotId_);
35     networkStateOld_ = std::make_unique<NetworkState>();
36     if (networkStateOld_ == nullptr) {
37         TELEPHONY_LOGE("failed to create old networkState slotId:%{public}d", slotId_);
38         return false;
39     }
40     networkState_ = std::make_unique<NetworkState>();
41     if (networkState_ == nullptr) {
42         TELEPHONY_LOGE("failed to create new networkState slotId:%{public}d", slotId_);
43         return false;
44     }
45     imsServiceStatus_ = std::make_unique<ImsServiceStatus>();
46     if (imsServiceStatus_ == nullptr) {
47         TELEPHONY_LOGE("failed to create new imsServiceStatus_ slotId:%{public}d", slotId_);
48         return false;
49     }
50     return true;
51 }
52 
SetOperatorInfo(const std::string & longName,const std::string & shortName,const std::string & numeric,DomainType domainType)53 void NetworkSearchState::SetOperatorInfo(
54     const std::string &longName, const std::string &shortName, const std::string &numeric, DomainType domainType)
55 {
56     std::lock_guard<std::mutex> lock(mutex_);
57     if (networkState_ != nullptr) {
58         networkState_->SetOperatorInfo(longName, shortName, numeric, domainType);
59         TELEPHONY_LOGD("NetworkSearchState::SetOperatorInfo longName : %{public}s, shortName : %{public}s, numeric : "
60                        "%{public}s, slotId:%{public}d",
61             networkState_->GetLongOperatorName().c_str(), networkState_->GetShortOperatorName().c_str(),
62             networkState_->GetPlmnNumeric().c_str(), slotId_);
63     }
64 }
65 
SetEmergency(bool isEmergency)66 void NetworkSearchState::SetEmergency(bool isEmergency)
67 {
68     std::lock_guard<std::mutex> lock(mutex_);
69     if (networkState_ != nullptr) {
70         networkState_->SetEmergency(isEmergency);
71     }
72 }
73 
IsEmergency()74 bool NetworkSearchState::IsEmergency()
75 {
76     std::lock_guard<std::mutex> lock(mutex_);
77     if (networkState_ != nullptr) {
78         return networkState_->IsEmergency();
79     }
80     return false;
81 }
82 
SetNetworkType(RadioTech tech,DomainType domainType)83 void NetworkSearchState::SetNetworkType(RadioTech tech, DomainType domainType)
84 {
85     std::lock_guard<std::mutex> lock(mutex_);
86     if (networkState_ != nullptr) {
87         networkState_->SetNetworkType(tech, domainType);
88     }
89 }
90 
SetNetworkState(RegServiceState state,DomainType domainType)91 void NetworkSearchState::SetNetworkState(RegServiceState state, DomainType domainType)
92 {
93     std::lock_guard<std::mutex> lock(mutex_);
94     if (networkState_ != nullptr) {
95         networkState_->SetNetworkState(state, domainType);
96     }
97 }
98 
SetNetworkStateToRoaming(RoamingType roamingType,DomainType domainType)99 void NetworkSearchState::SetNetworkStateToRoaming(RoamingType roamingType, DomainType domainType)
100 {
101     std::lock_guard<std::mutex> lock(mutex_);
102     if (networkState_ != nullptr) {
103         networkState_->SetRoaming(roamingType, domainType);
104     }
105 }
106 
GetImsStatus(ImsServiceType imsSrvType,ImsRegInfo & info)107 int32_t NetworkSearchState::GetImsStatus(ImsServiceType imsSrvType, ImsRegInfo &info)
108 {
109     std::lock_guard<std::mutex> lock(imsMutex_);
110     bool isRegister = false;
111     switch (imsSrvType) {
112         case ImsServiceType::TYPE_VOICE:
113             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVoice;
114             break;
115         case ImsServiceType::TYPE_VIDEO:
116             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVideo;
117             break;
118         case ImsServiceType::TYPE_UT:
119             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsUt;
120             break;
121         case ImsServiceType::TYPE_SMS:
122             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsSms;
123             break;
124         default:
125             TELEPHONY_LOGE("%{public}d unkunow ims service type!", imsSrvType);
126             return TELEPHONY_ERR_ARGUMENT_INVALID;
127     }
128     info.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
129     info.imsRegTech = imsServiceStatus_->imsRegTech;
130     return TELEPHONY_SUCCESS;
131 }
132 
SetImsStatus(bool imsRegStatus)133 void NetworkSearchState::SetImsStatus(bool imsRegStatus)
134 {
135     std::lock_guard<std::mutex> lock(imsMutex_);
136     bool imsRegStateChanged = imsRegStatus_ != imsRegStatus;
137     if (!imsRegStateChanged) {
138         return;
139     }
140     imsRegStatus_ = imsRegStatus;
141 
142     ImsRegInfo imsRegInfo;
143     bool isRegister = false;
144     imsRegInfo.imsRegTech = imsServiceStatus_->imsRegTech;
145     if (imsServiceStatus_->supportImsVoice) {
146         isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVoice;
147         imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
148         NotifyImsStateChange(ImsServiceType::TYPE_VOICE, imsRegInfo);
149     }
150     if (imsServiceStatus_->supportImsVideo) {
151         isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVideo;
152         imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
153         NotifyImsStateChange(ImsServiceType::TYPE_VIDEO, imsRegInfo);
154     }
155     if (imsServiceStatus_->supportImsUt) {
156         isRegister = imsRegStatus_ && imsServiceStatus_->supportImsUt;
157         imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
158         NotifyImsStateChange(ImsServiceType::TYPE_UT, imsRegInfo);
159     }
160     if (imsServiceStatus_->supportImsSms) {
161         isRegister = imsRegStatus_ && imsServiceStatus_->supportImsSms;
162         imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
163         NotifyImsStateChange(ImsServiceType::TYPE_SMS, imsRegInfo);
164     }
165 }
166 
SetImsServiceStatus(const ImsServiceStatus & imsServiceStatus)167 void NetworkSearchState::SetImsServiceStatus(const ImsServiceStatus &imsServiceStatus)
168 {
169     std::lock_guard<std::mutex> lock(imsMutex_);
170     bool voiceChanged = imsServiceStatus_->supportImsVoice != imsServiceStatus.supportImsVoice;
171     bool videoChanged = imsServiceStatus_->supportImsVideo != imsServiceStatus.supportImsVideo;
172     bool utChanged = imsServiceStatus_->supportImsUt != imsServiceStatus.supportImsUt;
173     bool smsChanged = imsServiceStatus_->supportImsSms != imsServiceStatus.supportImsSms;
174     bool radioTechChanged = imsServiceStatus_->imsRegTech != imsServiceStatus.imsRegTech;
175     if (!voiceChanged && !videoChanged && !utChanged && !smsChanged && !radioTechChanged) {
176         TELEPHONY_LOGD("Nothing need update for slotId:%{public}d", slotId_);
177         return;
178     }
179 
180     *imsServiceStatus_ = imsServiceStatus;
181 
182     if (!imsRegStatus_) {
183         TELEPHONY_LOGI("Nothing need to do since IMS haven't register");
184         return;
185     }
186     ImsRegInfo imsRegInfo;
187     imsRegInfo.imsRegTech = imsServiceStatus.imsRegTech;
188     if (voiceChanged || (radioTechChanged && imsServiceStatus_->supportImsVoice)) {
189         imsRegInfo.imsRegState = GetImsRegState(ImsServiceType::TYPE_VOICE);
190         NotifyImsStateChange(ImsServiceType::TYPE_VOICE, imsRegInfo);
191     }
192     if (videoChanged || (radioTechChanged && imsServiceStatus_->supportImsVideo)) {
193         imsRegInfo.imsRegState = GetImsRegState(ImsServiceType::TYPE_VIDEO);
194         NotifyImsStateChange(ImsServiceType::TYPE_VIDEO, imsRegInfo);
195     }
196     if (utChanged || (radioTechChanged && imsServiceStatus_->supportImsUt)) {
197         imsRegInfo.imsRegState = GetImsRegState(ImsServiceType::TYPE_UT);
198         NotifyImsStateChange(ImsServiceType::TYPE_UT, imsRegInfo);
199     }
200     if (smsChanged || (radioTechChanged && imsServiceStatus_->supportImsSms)) {
201         imsRegInfo.imsRegState = GetImsRegState(ImsServiceType::TYPE_SMS);
202         NotifyImsStateChange(ImsServiceType::TYPE_SMS, imsRegInfo);
203     }
204 }
205 
GetImsRegState(const ImsServiceType type)206 ImsRegState NetworkSearchState::GetImsRegState(const ImsServiceType type)
207 {
208     bool isRegister = false;
209     switch (type) {
210         case ImsServiceType::TYPE_VOICE:
211             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVoice;
212             break;
213         case ImsServiceType::TYPE_VIDEO:
214             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVideo;
215             break;
216         case ImsServiceType::TYPE_UT:
217             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsUt;
218             break;
219         case ImsServiceType::TYPE_SMS:
220             isRegister = imsRegStatus_ && imsServiceStatus_->supportImsSms;
221             break;
222         default:
223             break;
224     }
225     return isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
226 }
227 
GetNetworkStatus()228 std::unique_ptr<NetworkState> NetworkSearchState::GetNetworkStatus()
229 {
230     if (networkState_ == nullptr) {
231         TELEPHONY_LOGE("GetNetworkStatus networkState_ is null slotId:%{public}d", slotId_);
232         return nullptr;
233     }
234     std::lock_guard<std::mutex> lock(mutex_);
235     MessageParcel data;
236     networkState_->Marshalling(data);
237     std::unique_ptr<NetworkState> networkState = std::make_unique<NetworkState>();
238     if (networkState == nullptr) {
239         TELEPHONY_LOGE("failed to create new networkState slotId:%{public}d", slotId_);
240         return nullptr;
241     }
242     networkState->ReadFromParcel(data);
243     return networkState;
244 }
245 
SetInitial()246 void NetworkSearchState::SetInitial()
247 {
248     TELEPHONY_LOGI("NetworkSearchState::SetInitial slotId:%{public}d", slotId_);
249     std::lock_guard<std::mutex> lock(mutex_);
250     if (networkState_ != nullptr) {
251         networkState_->Init();
252     }
253 }
254 
GetLastCfgTech(RadioTech & tech)255 int32_t NetworkSearchState::GetLastCfgTech(RadioTech &tech)
256 {
257     std::lock_guard<std::mutex> lock(mutex_);
258     if (networkState_ == nullptr) {
259         TELEPHONY_LOGE("networkState_ is null, slotId:%{public}d", slotId_);
260         return TELEPHONY_ERR_LOCAL_PTR_NULL;
261     }
262     tech = networkState_->GetLastCfgTech();
263     return TELEPHONY_ERR_SUCCESS;
264 }
265 
GetLastPsRadioTech(RadioTech & tech)266 int32_t NetworkSearchState::GetLastPsRadioTech(RadioTech &tech)
267 {
268     std::lock_guard<std::mutex> lock(mutex_);
269     if (networkState_ == nullptr) {
270         TELEPHONY_LOGE("networkState_ is null, slotId:%{public}d", slotId_);
271         return TELEPHONY_ERR_LOCAL_PTR_NULL;
272     }
273     tech = networkState_->GetLastPsRadioTech();
274     return TELEPHONY_ERR_SUCCESS;
275 }
276 
SetCfgTech(RadioTech tech)277 void NetworkSearchState::SetCfgTech(RadioTech tech)
278 {
279     std::lock_guard<std::mutex> lock(mutex_);
280     if (networkState_ != nullptr) {
281         networkState_->SetCfgTech(tech);
282     }
283 }
284 
SetNrState(NrState state)285 void NetworkSearchState::SetNrState(NrState state)
286 {
287     std::lock_guard<std::mutex> lock(mutex_);
288     if (networkState_ != nullptr) {
289         TELEPHONY_LOGD("nrState_:%{public}d slotId:%{public}d", state, slotId_);
290         networkState_->SetNrState(state);
291     }
292 }
293 
NotifyPsRegStatusChange()294 void NetworkSearchState::NotifyPsRegStatusChange()
295 {
296     std::lock_guard<std::mutex> lock(mutex_);
297     auto networkSearchManager = networkSearchManager_.lock();
298     if (networkSearchManager == nullptr) {
299         TELEPHONY_LOGE("NotifyPsRegStatusChange NetworkSearchManager is null slotId:%{public}d", slotId_);
300         return;
301     }
302     if (networkState_ == nullptr) {
303         TELEPHONY_LOGE("NotifyPsRegStatusChange networkState_ is null slotId:%{public}d", slotId_);
304         return;
305     }
306 
307     if (networkState_->GetPsRegStatus() == RegServiceState::REG_STATE_IN_SERVICE &&
308         (processNetworkState_ || networkStateOld_->GetPsRegStatus() != RegServiceState::REG_STATE_IN_SERVICE)) {
309         networkSearchManager->NotifyPsConnectionAttachedChanged(slotId_);
310     }
311     if (networkState_->GetPsRegStatus() != RegServiceState::REG_STATE_IN_SERVICE &&
312         (processNetworkState_ || networkStateOld_->GetPsRegStatus() == RegServiceState::REG_STATE_IN_SERVICE)) {
313         networkSearchManager->NotifyPsConnectionDetachedChanged(slotId_);
314     }
315 }
316 
NotifyPsRoamingStatusChange()317 void NetworkSearchState::NotifyPsRoamingStatusChange()
318 {
319     std::lock_guard<std::mutex> lock(mutex_);
320     auto networkSearchManager = networkSearchManager_.lock();
321     if (networkSearchManager == nullptr) {
322         TELEPHONY_LOGE("NotifyPsRoamingStatusChange NetworkSearchManager is null slotId:%{public}d", slotId_);
323         return;
324     }
325     if (networkState_ == nullptr) {
326         TELEPHONY_LOGE("NotifyPsRoamingStatusChange networkState_ is null slotId:%{public}d", slotId_);
327         return;
328     }
329     if (networkState_->GetPsRoamingStatus() > RoamingType::ROAMING_STATE_UNKNOWN &&
330         (processNetworkState_ || networkStateOld_->GetPsRoamingStatus() == RoamingType::ROAMING_STATE_UNKNOWN)) {
331         networkSearchManager->NotifyPsRoamingOpenChanged(slotId_);
332     }
333     if ((processNetworkState_ || networkStateOld_->GetPsRoamingStatus() > RoamingType::ROAMING_STATE_UNKNOWN) &&
334         networkState_->GetPsRoamingStatus() == RoamingType::ROAMING_STATE_UNKNOWN) {
335         networkSearchManager->NotifyPsRoamingCloseChanged(slotId_);
336     }
337 }
338 
NotifyPsRadioTechChange()339 void NetworkSearchState::NotifyPsRadioTechChange()
340 {
341     std::lock_guard<std::mutex> lock(mutex_);
342     auto networkSearchManager = networkSearchManager_.lock();
343     if (networkSearchManager == nullptr) {
344         TELEPHONY_LOGE("NotifyPsRadioTechChange NetworkSearchManager is null slotId:%{public}d", slotId_);
345         return;
346     }
347     if (networkState_ == nullptr) {
348         TELEPHONY_LOGE("NotifyPsRadioTechChange networkState_ is null slotId:%{public}d", slotId_);
349         return;
350     }
351 
352     if (processNetworkState_ || networkState_->GetPsRadioTech() != networkStateOld_->GetPsRadioTech()) {
353         networkSearchManager->UpdatePhone(slotId_, networkState_->GetCsRadioTech(), networkState_->GetPsRadioTech());
354         networkSearchManager->SendUpdateCellLocationRequest(slotId_);
355         networkSearchManager->NotifyPsRatChanged(slotId_);
356     }
357 }
358 
NotifyEmergencyChange()359 void NetworkSearchState::NotifyEmergencyChange()
360 {
361     std::lock_guard<std::mutex> lock(mutex_);
362     auto networkSearchManager = networkSearchManager_.lock();
363     if (networkSearchManager == nullptr) {
364         TELEPHONY_LOGE("NotifyEmergencyChange NetworkSearchManager is null slotId:%{public}d", slotId_);
365         return;
366     }
367     if (networkState_ == nullptr) {
368         TELEPHONY_LOGE("NotifyEmergencyChange networkState_ is null slotId:%{public}d", slotId_);
369         return;
370     }
371     if (processNetworkState_ || (networkState_->IsEmergency() != networkStateOld_->IsEmergency())) {
372         if (networkState_->IsEmergency()) {
373             networkSearchManager->NotifyEmergencyOpenChanged(slotId_);
374         } else {
375             networkSearchManager->NotifyEmergencyCloseChanged(slotId_);
376         }
377     }
378 }
379 
NotifyNrStateChange()380 void NetworkSearchState::NotifyNrStateChange()
381 {
382     std::lock_guard<std::mutex> lock(mutex_);
383     auto networkSearchManager = networkSearchManager_.lock();
384     if (networkSearchManager == nullptr) {
385         TELEPHONY_LOGE("NotifyPsRadioTechChange NetworkSearchManager is null slotId:%{public}d", slotId_);
386         return;
387     }
388     if (networkState_ == nullptr) {
389         TELEPHONY_LOGE("NotifyPsRadioTechChange networkState_ is null slotId:%{public}d", slotId_);
390         return;
391     }
392 
393     if (processNetworkState_ || (networkState_->GetNrState() != networkStateOld_->GetNrState())) {
394         networkSearchManager->NotifyNrStateChanged(slotId_);
395     }
396 }
397 
NotifyImsStateChange(ImsServiceType imsSrvType,const ImsRegInfo & info)398 void NetworkSearchState::NotifyImsStateChange(ImsServiceType imsSrvType, const ImsRegInfo &info)
399 {
400     std::lock_guard<std::mutex> lock(mutex_);
401     auto networkSearchManager = networkSearchManager_.lock();
402     if (networkSearchManager == nullptr) {
403         TELEPHONY_LOGE("networkSearchManager is null slotId:%{public}d", slotId_);
404         return;
405     }
406     if (networkState_ == nullptr) {
407         TELEPHONY_LOGE("networkState_ is null slotId:%{public}d", slotId_);
408         return;
409     }
410     networkSearchManager->NotifyImsRegInfoChanged(slotId_, imsSrvType, info);
411 }
412 
NotifyStateChange()413 void NetworkSearchState::NotifyStateChange()
414 {
415     TELEPHONY_LOGI("NetworkSearchState::NotifyStateChange slotId:%{public}d", slotId_);
416     if (networkState_ == nullptr) {
417         TELEPHONY_LOGE("NotifyStateChange networkState_ is null slotId:%{public}d", slotId_);
418         return;
419     }
420 
421     if (TELEPHONY_EXT_WRAPPER.updateNetworkStateExt_ != nullptr) {
422         TELEPHONY_EXT_WRAPPER.updateNetworkStateExt_(slotId_, networkState_);
423     }
424 
425     if (processNetworkState_ || !(*networkState_ == *networkStateOld_)) {
426         TELEPHONY_LOGI(
427             "NetworkSearchState::StateCheck isNetworkStateChange notify to app... slotId:%{public}d", slotId_);
428         sptr<NetworkState> ns = new NetworkState;
429         if (ns == nullptr) {
430             TELEPHONY_LOGE("failed to create networkState slotId:%{public}d", slotId_);
431             return;
432         }
433 
434         MessageParcel data;
435         networkState_->Marshalling(data);
436         ns->ReadFromParcel(data);
437         if (TELEPHONY_EXT_WRAPPER.processStateChangeExt_ != nullptr) {
438             if (TELEPHONY_EXT_WRAPPER.processStateChangeExt_(slotId_, ns)) {
439                 networkState_->Marshalling(data);
440                 networkStateOld_->ReadFromParcel(data);
441                 processNetworkState_ = true;
442                 return;
443             }
444         }
445         // We must Update RadioTech(PhoneType) bebore notifying observers,
446         // otherwise observers may get the wrong phone type
447         CsRadioTechChange();
448 
449         NotifyPsRadioTechChange();
450         NotifyPsRegStatusChange();
451         NotifyPsRoamingStatusChange();
452         NotifyEmergencyChange();
453         NotifyNrStateChange();
454 
455         DelayedSingleton<NetworkSearchNotify>::GetInstance()->NotifyNetworkStateUpdated(slotId_, ns);
456         networkState_->Marshalling(data);
457         networkStateOld_->ReadFromParcel(data);
458     }
459     processNetworkState_ = false;
460 }
461 
CsRadioTechChange()462 void NetworkSearchState::CsRadioTechChange()
463 {
464     TELEPHONY_LOGI("NetworkSearchState::CsRadioTechChange slotId:%{public}d", slotId_);
465     std::lock_guard<std::mutex> lock(mutex_);
466     auto networkSearchManager = networkSearchManager_.lock();
467     if (networkSearchManager == nullptr) {
468         TELEPHONY_LOGE("CsRadioTechChange NetworkSearchManager is null slotId:%{public}d", slotId_);
469         return;
470     }
471     if (networkState_ == nullptr) {
472         TELEPHONY_LOGE("CsRadioTechChange networkState is null slotId:%{public}d", slotId_);
473         return;
474     }
475     if (networkStateOld_ == nullptr) {
476         TELEPHONY_LOGE("CsRadioTechChange networkStateOld_ is null slotId:%{public}d", slotId_);
477         return;
478     }
479 
480     if (processNetworkState_ || networkState_->GetCsRadioTech() != networkStateOld_->GetCsRadioTech()) {
481         networkSearchManager->UpdatePhone(slotId_, networkState_->GetCsRadioTech(), networkState_->GetPsRadioTech());
482     }
483 }
484 
SetLongOperatorName(const std::string & longName,DomainType domainType)485 void NetworkSearchState::SetLongOperatorName(const std::string &longName, DomainType domainType)
486 {
487     std::lock_guard<std::mutex> lock(mutex_);
488     if (networkState_ != nullptr) {
489         networkState_->SetLongOperatorName(longName, domainType);
490         TELEPHONY_LOGD("NetworkSearchState::SetLongOperatorName longName : %{public}s", longName.c_str());
491     }
492 }
493 } // namespace Telephony
494 } // namespace OHOS
495