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