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 bool isRegister = false;
187 imsRegInfo.imsRegTech = imsServiceStatus.imsRegTech;
188 if (voiceChanged || (radioTechChanged && imsServiceStatus_->supportImsVoice)) {
189 isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVoice;
190 imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
191 NotifyImsStateChange(ImsServiceType::TYPE_VOICE, imsRegInfo);
192 }
193 if (videoChanged || (radioTechChanged && imsServiceStatus_->supportImsVideo)) {
194 isRegister = imsRegStatus_ && imsServiceStatus_->supportImsVideo;
195 imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
196 NotifyImsStateChange(ImsServiceType::TYPE_VIDEO, imsRegInfo);
197 }
198 if (utChanged || (radioTechChanged && imsServiceStatus_->supportImsUt)) {
199 isRegister = imsRegStatus_ && imsServiceStatus_->supportImsUt;
200 imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
201 NotifyImsStateChange(ImsServiceType::TYPE_UT, imsRegInfo);
202 }
203 if (smsChanged || (radioTechChanged && imsServiceStatus_->supportImsSms)) {
204 isRegister = imsRegStatus_ && imsServiceStatus_->supportImsSms;
205 imsRegInfo.imsRegState = isRegister ? ImsRegState::IMS_REGISTERED : ImsRegState::IMS_UNREGISTERED;
206 NotifyImsStateChange(ImsServiceType::TYPE_SMS, imsRegInfo);
207 }
208 }
209
GetNetworkStatus()210 std::unique_ptr<NetworkState> NetworkSearchState::GetNetworkStatus()
211 {
212 if (networkState_ == nullptr) {
213 TELEPHONY_LOGE("GetNetworkStatus networkState_ is null slotId:%{public}d", slotId_);
214 return nullptr;
215 }
216 std::lock_guard<std::mutex> lock(mutex_);
217 MessageParcel data;
218 networkState_->Marshalling(data);
219 std::unique_ptr<NetworkState> networkState = std::make_unique<NetworkState>();
220 if (networkState == nullptr) {
221 TELEPHONY_LOGE("failed to create new networkState slotId:%{public}d", slotId_);
222 return nullptr;
223 }
224 networkState->ReadFromParcel(data);
225 return networkState;
226 }
227
SetInitial()228 void NetworkSearchState::SetInitial()
229 {
230 TELEPHONY_LOGI("NetworkSearchState::SetInitial slotId:%{public}d", slotId_);
231 std::lock_guard<std::mutex> lock(mutex_);
232 if (networkState_ != nullptr) {
233 networkState_->Init();
234 }
235 }
236
SetCfgTech(RadioTech tech)237 void NetworkSearchState::SetCfgTech(RadioTech tech)
238 {
239 std::lock_guard<std::mutex> lock(mutex_);
240 if (networkState_ != nullptr) {
241 networkState_->SetCfgTech(tech);
242 }
243 }
244
SetNrState(NrState state)245 void NetworkSearchState::SetNrState(NrState state)
246 {
247 std::lock_guard<std::mutex> lock(mutex_);
248 if (networkState_ != nullptr) {
249 networkState_->SetNrState(state);
250 }
251 }
252
NotifyPsRegStatusChange()253 void NetworkSearchState::NotifyPsRegStatusChange()
254 {
255 std::lock_guard<std::mutex> lock(mutex_);
256 auto networkSearchManager = networkSearchManager_.lock();
257 if (networkSearchManager == nullptr) {
258 TELEPHONY_LOGE("NotifyPsRegStatusChange NetworkSearchManager is null slotId:%{public}d", slotId_);
259 return;
260 }
261 if (networkState_ == nullptr) {
262 TELEPHONY_LOGE("NotifyPsRegStatusChange networkState_ is null slotId:%{public}d", slotId_);
263 return;
264 }
265
266 if (networkState_->GetPsRegStatus() == RegServiceState::REG_STATE_IN_SERVICE &&
267 networkStateOld_->GetPsRegStatus() != RegServiceState::REG_STATE_IN_SERVICE) {
268 networkSearchManager->NotifyPsConnectionAttachedChanged(slotId_);
269 }
270 if (networkState_->GetPsRegStatus() != RegServiceState::REG_STATE_IN_SERVICE &&
271 networkStateOld_->GetPsRegStatus() == RegServiceState::REG_STATE_IN_SERVICE) {
272 networkSearchManager->NotifyPsConnectionDetachedChanged(slotId_);
273 }
274 }
275
NotifyPsRoamingStatusChange()276 void NetworkSearchState::NotifyPsRoamingStatusChange()
277 {
278 std::lock_guard<std::mutex> lock(mutex_);
279 auto networkSearchManager = networkSearchManager_.lock();
280 if (networkSearchManager == nullptr) {
281 TELEPHONY_LOGE("NotifyPsRoamingStatusChange NetworkSearchManager is null slotId:%{public}d", slotId_);
282 return;
283 }
284 if (networkState_ == nullptr) {
285 TELEPHONY_LOGE("NotifyPsRoamingStatusChange networkState_ is null slotId:%{public}d", slotId_);
286 return;
287 }
288 if (networkState_->GetPsRoamingStatus() > RoamingType::ROAMING_STATE_UNKNOWN &&
289 networkStateOld_->GetPsRoamingStatus() == RoamingType::ROAMING_STATE_UNKNOWN) {
290 networkSearchManager->NotifyPsRoamingOpenChanged(slotId_);
291 }
292 if (networkStateOld_->GetPsRoamingStatus() > RoamingType::ROAMING_STATE_UNKNOWN &&
293 networkState_->GetPsRoamingStatus() == RoamingType::ROAMING_STATE_UNKNOWN) {
294 networkSearchManager->NotifyPsRoamingCloseChanged(slotId_);
295 }
296 }
297
NotifyPsRadioTechChange()298 void NetworkSearchState::NotifyPsRadioTechChange()
299 {
300 std::lock_guard<std::mutex> lock(mutex_);
301 auto networkSearchManager = networkSearchManager_.lock();
302 if (networkSearchManager == nullptr) {
303 TELEPHONY_LOGE("NotifyPsRadioTechChange NetworkSearchManager is null slotId:%{public}d", slotId_);
304 return;
305 }
306 if (networkState_ == nullptr) {
307 TELEPHONY_LOGE("NotifyPsRadioTechChange networkState_ is null slotId:%{public}d", slotId_);
308 return;
309 }
310
311 if (networkState_->GetPsRadioTech() != networkStateOld_->GetPsRadioTech()) {
312 networkSearchManager->SendUpdateCellLocationRequest(slotId_);
313 networkSearchManager->NotifyPsRatChanged(slotId_);
314 }
315 }
316
NotifyEmergencyChange()317 void NetworkSearchState::NotifyEmergencyChange()
318 {
319 std::lock_guard<std::mutex> lock(mutex_);
320 auto networkSearchManager = networkSearchManager_.lock();
321 if (networkSearchManager == nullptr) {
322 TELEPHONY_LOGE("NotifyEmergencyChange NetworkSearchManager is null slotId:%{public}d", slotId_);
323 return;
324 }
325 if (networkState_ == nullptr) {
326 TELEPHONY_LOGE("NotifyEmergencyChange networkState_ is null slotId:%{public}d", slotId_);
327 return;
328 }
329 if (networkState_->IsEmergency() != networkStateOld_->IsEmergency()) {
330 if (networkState_->IsEmergency()) {
331 networkSearchManager->NotifyEmergencyOpenChanged(slotId_);
332 } else {
333 networkSearchManager->NotifyEmergencyCloseChanged(slotId_);
334 }
335 }
336 }
337
NotifyNrStateChange()338 void NetworkSearchState::NotifyNrStateChange()
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_->GetNrState() != networkStateOld_->GetNrState()) {
352 networkSearchManager->NotifyNrStateChanged(slotId_);
353 }
354 }
355
NotifyImsStateChange(ImsServiceType imsSrvType,const ImsRegInfo & info)356 void NetworkSearchState::NotifyImsStateChange(ImsServiceType imsSrvType, const ImsRegInfo &info)
357 {
358 std::lock_guard<std::mutex> lock(mutex_);
359 auto networkSearchManager = networkSearchManager_.lock();
360 if (networkSearchManager == nullptr) {
361 TELEPHONY_LOGE("networkSearchManager is null slotId:%{public}d", slotId_);
362 return;
363 }
364 if (networkState_ == nullptr) {
365 TELEPHONY_LOGE("networkState_ is null slotId:%{public}d", slotId_);
366 return;
367 }
368 networkSearchManager->NotifyImsRegInfoChanged(slotId_, imsSrvType, info);
369 }
370
NotifyStateChange()371 void NetworkSearchState::NotifyStateChange()
372 {
373 TELEPHONY_LOGI("NetworkSearchState::NotifyStateChange slotId:%{public}d", slotId_);
374 if (networkState_ == nullptr) {
375 TELEPHONY_LOGE("NotifyStateChange networkState_ is null slotId:%{public}d", slotId_);
376 return;
377 }
378
379 // We must Update RadioTech(PhoneType) bebore notifying observers,
380 // otherwise observers may get the wrong phone type
381 CsRadioTechChange();
382
383 NotifyPsRegStatusChange();
384 NotifyPsRoamingStatusChange();
385 NotifyPsRadioTechChange();
386 NotifyEmergencyChange();
387 NotifyNrStateChange();
388
389 if (!(*networkState_ == *networkStateOld_)) {
390 TELEPHONY_LOGI(
391 "NetworkSearchState::StateCheck isNetworkStateChange notify to app... slotId:%{public}d", slotId_);
392 sptr<NetworkState> ns = new NetworkState;
393 if (ns == nullptr) {
394 TELEPHONY_LOGE("failed to create networkState slotId:%{public}d", slotId_);
395 return;
396 }
397
398 MessageParcel data;
399 networkState_->Marshalling(data);
400 ns->ReadFromParcel(data);
401 DelayedSingleton<NetworkSearchNotify>::GetInstance()->NotifyNetworkStateUpdated(slotId_, ns);
402 networkState_->Marshalling(data);
403 networkStateOld_->ReadFromParcel(data);
404 }
405 }
406
CsRadioTechChange()407 void NetworkSearchState::CsRadioTechChange()
408 {
409 TELEPHONY_LOGI("NetworkSearchState::CsRadioTechChange slotId:%{public}d", slotId_);
410 std::lock_guard<std::mutex> lock(mutex_);
411 auto networkSearchManager = networkSearchManager_.lock();
412 if (networkSearchManager == nullptr) {
413 TELEPHONY_LOGE("CsRadioTechChange NetworkSearchManager is null slotId:%{public}d", slotId_);
414 return;
415 }
416 if (networkState_ == nullptr) {
417 TELEPHONY_LOGE("CsRadioTechChange networkState is null slotId:%{public}d", slotId_);
418 return;
419 }
420 if (networkStateOld_ == nullptr) {
421 TELEPHONY_LOGE("CsRadioTechChange networkStateOld_ is null slotId:%{public}d", slotId_);
422 return;
423 }
424
425 if (networkState_->GetCsRadioTech() != networkStateOld_->GetCsRadioTech()) {
426 networkSearchManager->UpdatePhone(slotId_, networkState_->GetCsRadioTech(), networkState_->GetPsRadioTech());
427 }
428 }
429 } // namespace Telephony
430 } // namespace OHOS
431