1 /*
2  * Copyright (C) 2021-2024 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 "cell_info.h"
17 #include "telephony_log_wrapper.h"
18 #include "network_search_manager.h"
19 #include "network_search_notify.h"
20 
21 namespace OHOS {
22 namespace Telephony {
23 constexpr int32_t ZERO_VALUE = 0;
24 constexpr int32_t SIGNAL_LEVEL_INVALID = 0;
25 constexpr int32_t SIGNAL_RSSI_MAXIMUM = -1;
26 constexpr int32_t SIGNAL_FOUR_BARS = 4;
27 constexpr int32_t SIGNAL_FIVE_BARS = 5;
28 const int32_t *GSM_SIGNAL_THRESHOLD = SignalInformation::GSM_SIGNAL_THRESHOLD_5BAR;
29 const int32_t *CDMA_SIGNAL_THRESHOLD = SignalInformation::CDMA_SIGNAL_THRESHOLD_5BAR;
30 const int32_t *LTE_SIGNAL_THRESHOLD = SignalInformation::LTE_SIGNAL_THRESHOLD_5BAR;
31 const int32_t *WCDMA_SIGNAL_THRESHOLD = SignalInformation::WCDMA_SIGNAL_THRESHOLD_5BAR;
32 const int32_t *TD_SCDMA_SIGNAL_THRESHOLD = SignalInformation::TD_SCDMA_SIGNAL_THRESHOLD_5BAR;
33 const int32_t *NR_SIGNAL_THRESHOLD = SignalInformation::NR_SIGNAL_THRESHOLD_5BAR;
34 int32_t CellInfo::signalBar_ = SIGNAL_FIVE_BARS;
35 
36 const std::map<TelRilRatType, CellInfo::CallInfoFunc> CellInfo::memberFuncMap_ = {
37     { TelRilRatType::NETWORK_TYPE_GSM,
__anon967be80e0102() 38         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellGsm(cellInfo); } },
39     { TelRilRatType::NETWORK_TYPE_CDMA,
__anon967be80e0202() 40         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellCdma(cellInfo); } },
41     { TelRilRatType::NETWORK_TYPE_WCDMA,
__anon967be80e0302() 42         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellWcdma(cellInfo); } },
43     { TelRilRatType::NETWORK_TYPE_TDSCDMA,
__anon967be80e0402() 44         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellTdscdma(cellInfo); } },
45     { TelRilRatType::NETWORK_TYPE_LTE,
__anon967be80e0502() 46         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellLte(cellInfo); } },
47     { TelRilRatType::NETWORK_TYPE_NR,
__anon967be80e0602() 48         [](CellInfo *ci, CellNearbyInfo *cellInfo) { return ci->ProcessNeighboringCellNr(cellInfo); } }
49 };
50 
CellInfo(std::weak_ptr<NetworkSearchManager> networkSearchManager,int32_t slotId)51 CellInfo::CellInfo(std::weak_ptr<NetworkSearchManager> networkSearchManager, int32_t slotId)
52     : networkSearchManager_(networkSearchManager), slotId_(slotId)
53 {
54     InitCellSignalBar();
55 }
56 
InitCellSignalBar(const int32_t bar)57 void CellInfo::InitCellSignalBar(const int32_t bar)
58 {
59     if (bar == SIGNAL_FOUR_BARS) {
60         GSM_SIGNAL_THRESHOLD = SignalInformation::GSM_SIGNAL_THRESHOLD_4BAR;
61         CDMA_SIGNAL_THRESHOLD = SignalInformation::CDMA_SIGNAL_THRESHOLD_4BAR;
62         LTE_SIGNAL_THRESHOLD = SignalInformation::LTE_SIGNAL_THRESHOLD_4BAR;
63         WCDMA_SIGNAL_THRESHOLD = SignalInformation::WCDMA_SIGNAL_THRESHOLD_4BAR;
64         TD_SCDMA_SIGNAL_THRESHOLD = SignalInformation::TD_SCDMA_SIGNAL_THRESHOLD_4BAR;
65         NR_SIGNAL_THRESHOLD = SignalInformation::NR_SIGNAL_THRESHOLD_4BAR;
66         signalBar_ = SIGNAL_FOUR_BARS;
67     } else {
68         GSM_SIGNAL_THRESHOLD = SignalInformation::GSM_SIGNAL_THRESHOLD_5BAR;
69         CDMA_SIGNAL_THRESHOLD = SignalInformation::CDMA_SIGNAL_THRESHOLD_5BAR;
70         LTE_SIGNAL_THRESHOLD = SignalInformation::LTE_SIGNAL_THRESHOLD_5BAR;
71         WCDMA_SIGNAL_THRESHOLD = SignalInformation::WCDMA_SIGNAL_THRESHOLD_5BAR;
72         TD_SCDMA_SIGNAL_THRESHOLD = SignalInformation::TD_SCDMA_SIGNAL_THRESHOLD_5BAR;
73         NR_SIGNAL_THRESHOLD = SignalInformation::NR_SIGNAL_THRESHOLD_5BAR;
74         signalBar_ = SIGNAL_FIVE_BARS;
75     }
76 }
77 
ProcessNeighboringCellInfo(const AppExecFwk::InnerEvent::Pointer & event)78 void CellInfo::ProcessNeighboringCellInfo(const AppExecFwk::InnerEvent::Pointer &event)
79 {
80     TELEPHONY_LOGD("CellInfo::ProcessNeighboringCellInfo cell info start...... slotId:%{public}d", slotId_);
81     std::lock_guard<std::mutex> lock(mutex_);
82     if (event == nullptr) {
83         TELEPHONY_LOGE("CellInfo::ProcessNeighboringCellInfo event is nullptr slotId:%{public}d", slotId_);
84         return;
85     }
86 
87     CellListNearbyInfo *cellInfo = event->GetSharedObject<CellListNearbyInfo>().get();
88     if (cellInfo == nullptr) {
89         TELEPHONY_LOGE("CellInfo::ProcessNeighboringCellInfo rssi is nullptr slotId:%{public}d", slotId_);
90         return;
91     }
92 
93     int32_t cellSize = cellInfo->itemNum >= CellInformation::MAX_CELL_NUM ? CellInformation::MAX_CELL_NUM :
94                                                                             cellInfo->itemNum;
95     if (cellSize > 0) {
96         currentCellInfo_ = nullptr;
97         cellInfos_.clear();
98     } else {
99         return;
100     }
101 
102     TELEPHONY_LOGI(
103         "CellInfo::ProcessNeighboringCellInfo cell size:%{public}d, cur size:%{public}zu slotId:%{public}d",
104         cellInfo->itemNum, cellInfos_.size(), slotId_);
105     std::vector<CellNearbyInfo> cell = cellInfo->cellNearbyInfo;
106     for (int32_t i = 0; i < cellSize; ++i) {
107         int32_t type = cell[i].ratType;
108         auto itFunc = memberFuncMap_.find(static_cast<TelRilRatType>(type));
109         if (itFunc != memberFuncMap_.end()) {
110             auto memberFunc = itFunc->second;
111             if (memberFunc != nullptr) {
112                 memberFunc(this, &cell[i]);
113             }
114         }
115     }
116 }
117 
ProcessCurrentCellInfo(const AppExecFwk::InnerEvent::Pointer & event)118 void CellInfo::ProcessCurrentCellInfo(const AppExecFwk::InnerEvent::Pointer &event)
119 {
120     ClearCellInfoList();
121     std::lock_guard<std::mutex> lock(mutex_);
122     if (event == nullptr) {
123         TELEPHONY_LOGE("CellInfo::ProcessCurrentCellInfo event is nullptr slotId:%{public}d", slotId_);
124         return;
125     }
126     CellListCurrentInformation *cellInfoList = event->GetSharedObject<CellListCurrentInformation>().get();
127     if (cellInfoList == nullptr) {
128         TELEPHONY_LOGE("CellInfo::ProcessCurrentCellInfo cellInfoList is nullptr slotId:%{public}d", slotId_);
129         return;
130     }
131 
132     int32_t cellSize = cellInfoList->itemNum >= CellInformation::MAX_CELL_NUM ? CellInformation::MAX_CELL_NUM :
133                                                                                 cellInfoList->itemNum;
134     if (cellSize <= 0) {
135         TELEPHONY_LOGE("CellInfo::ProcessCurrentCellInfo cellSize:%{public}d error, slotId:%{public}d",
136             cellSize, slotId_);
137         return;
138     }
139 
140     TELEPHONY_LOGI("CellInfo::ProcessCurrentCellInfo cell size:%{public}d, slotId:%{public}d",
141         cellInfoList->itemNum, slotId_);
142     std::vector<CurrentCellInformation> cell = cellInfoList->cellCurrentInfo;
143     for (int32_t i = 0; i < cellSize; ++i) {
144         CurrentCellInformation currentCell = cell[i];
145         ProcessCurrentCell(&currentCell);
146     }
147     NotifyCellInfoUpdated();
148 }
149 
NotifyCellInfoUpdated() const150 void CellInfo::NotifyCellInfoUpdated() const
151 {
152     if (cellInfos_.size() > 0) {
153         DelayedSingleton<NetworkSearchNotify>::GetInstance()->NotifyCellInfoUpdated(slotId_, cellInfos_);
154     } else {
155         TELEPHONY_LOGI("CellInfo::NotifyCellInfoUpdated no notify slotId:%{public}d", slotId_);
156     }
157 }
158 
UpdateCellLocation(int32_t techType,int32_t cellId,int32_t lac)159 void CellInfo::UpdateCellLocation(int32_t techType, int32_t cellId, int32_t lac)
160 {
161     CellInformation::CellType type = ConvertTechToCellType(static_cast<RadioTech>(techType));
162     if (type == CellInformation::CellType::CELL_TYPE_NONE) {
163         TELEPHONY_LOGE("CellInfo::UpdateCellLocation type error");
164         return;
165     }
166 
167     for (auto &cell : cellInfos_) {
168         if (cell->GetNetworkType() == type) {
169             if (ProcessCellLocation(cell, type, cellId, lac)) {
170                 UpdateSignalLevel(cell, type);
171                 NotifyCellInfoUpdated();
172                 cell->SetIsCamped(true);
173                 currentCellInfo_ = cell;
174             }
175             break;
176         }
177     }
178 }
179 
ProcessCellLocation(sptr<CellInformation> & cell,CellInformation::CellType type,int32_t cellId,int32_t lac)180 bool CellInfo::ProcessCellLocation(
181     sptr<CellInformation> &cell, CellInformation::CellType type, int32_t cellId, int32_t lac)
182 {
183     switch (type) {
184         case CellInformation::CellType::CELL_TYPE_GSM: {
185             GsmCellInformation *gsm = reinterpret_cast<GsmCellInformation *>(cell.GetRefPtr());
186             if (gsm->GetCellId() != cellId || gsm->GetLac() != lac) {
187                 gsm->UpdateLocation(cellId, lac);
188                 return true;
189             }
190             break;
191         }
192         case CellInformation::CellType::CELL_TYPE_LTE: {
193             LteCellInformation *lte = reinterpret_cast<LteCellInformation *>(cell.GetRefPtr());
194             if (lte->GetCellId() != cellId || lte->GetTac() != lac) {
195                 lte->UpdateLocation(cellId, lac);
196                 return true;
197             }
198             break;
199         }
200         case CellInformation::CellType::CELL_TYPE_WCDMA: {
201             WcdmaCellInformation *wcdma = reinterpret_cast<WcdmaCellInformation *>(cell.GetRefPtr());
202             if (wcdma->GetCellId() != cellId || wcdma->GetLac() != lac) {
203                 wcdma->UpdateLocation(cellId, lac);
204                 return true;
205             }
206             break;
207         }
208         case CellInformation::CellType::CELL_TYPE_TDSCDMA: {
209             TdscdmaCellInformation *tdscdma = reinterpret_cast<TdscdmaCellInformation *>(cell.GetRefPtr());
210             if (tdscdma->GetCellId() != cellId || tdscdma->GetLac() != lac) {
211                 tdscdma->UpdateLocation(cellId, lac);
212                 return true;
213             }
214             break;
215         }
216         case CellInformation::CellType::CELL_TYPE_NR: {
217             NrCellInformation *nr = reinterpret_cast<NrCellInformation *>(cell.GetRefPtr());
218             if (nr->GetCellId() != cellId || nr->GetTac() != lac) {
219                 nr->UpdateLocation(cellId, lac);
220                 return true;
221             }
222             break;
223         }
224         default:
225             TELEPHONY_LOGE("CellInfo::ProcessCellLocation type error");
226             break;
227     }
228     return false;
229 }
230 
UpdateSignalLevel(sptr<CellInformation> & cell,CellInformation::CellType cellType)231 void CellInfo::UpdateSignalLevel(sptr<CellInformation> &cell, CellInformation::CellType cellType)
232 {
233     if (cellType == CellInformation::CellType::CELL_TYPE_NONE || cell->GetNetworkType() != cellType) {
234         TELEPHONY_LOGE("CellInfo::UpdateSignalLevel type error");
235         return;
236     }
237 
238     std::shared_ptr<NetworkSearchManager> nsm = networkSearchManager_.lock();
239     if (nsm == nullptr) {
240         TELEPHONY_LOGE("CellInfo::UpdateSignalLevel nsm is nullptr slotId:%{public}d", slotId_);
241         return;
242     }
243 
244     std::vector<sptr<SignalInformation>> signals;
245     nsm->GetSignalInfoList(slotId_, signals);
246     int32_t signalLevel = 0;
247     int32_t signalIntensity = 0;
248     for (const auto &v : signals) {
249         if (ConvertToCellType(v->GetNetworkType()) == cellType) {
250             TELEPHONY_LOGI("CellInfo::UpdateSignalLevel signal level %{public}d slotId:%{public}d",
251                 v->GetSignalLevel(), slotId_);
252             signalLevel = v->GetSignalLevel();
253             signalIntensity = v->GetSignalIntensity();
254             break;
255         }
256     }
257     cell->SetSignalLevel(signalLevel);
258     cell->SetSignalIntensity(signalIntensity);
259 }
260 
ConvertToCellType(SignalInformation::NetworkType signalType) const261 CellInformation::CellType CellInfo::ConvertToCellType(SignalInformation::NetworkType signalType) const
262 {
263     switch (signalType) {
264         case SignalInformation::NetworkType::GSM:
265             return CellInformation::CellType::CELL_TYPE_GSM;
266         case SignalInformation::NetworkType::WCDMA:
267             return CellInformation::CellType::CELL_TYPE_WCDMA;
268         case SignalInformation::NetworkType::LTE:
269             return CellInformation::CellType::CELL_TYPE_LTE;
270         case SignalInformation::NetworkType::CDMA:
271             return CellInformation::CellType::CELL_TYPE_CDMA;
272         case SignalInformation::NetworkType::TDSCDMA:
273             return CellInformation::CellType::CELL_TYPE_TDSCDMA;
274         case SignalInformation::NetworkType::NR:
275             return CellInformation::CellType::CELL_TYPE_NR;
276         default:
277             return CellInformation::CellType::CELL_TYPE_NONE;
278     }
279 }
280 
ConvertRatToCellType(int ratType) const281 CellInformation::CellType CellInfo::ConvertRatToCellType(int ratType) const
282 {
283     switch (ratType) {
284         case TelRilRatType::NETWORK_TYPE_GSM:
285             return CellInformation::CellType::CELL_TYPE_GSM;
286         case TelRilRatType::NETWORK_TYPE_WCDMA:
287             return CellInformation::CellType::CELL_TYPE_WCDMA;
288         case TelRilRatType::NETWORK_TYPE_LTE:
289             return CellInformation::CellType::CELL_TYPE_LTE;
290         case TelRilRatType::NETWORK_TYPE_CDMA:
291             return CellInformation::CellType::CELL_TYPE_CDMA;
292         case TelRilRatType::NETWORK_TYPE_TDSCDMA:
293             return CellInformation::CellType::CELL_TYPE_TDSCDMA;
294         case TelRilRatType::NETWORK_TYPE_NR:
295             return CellInformation::CellType::CELL_TYPE_NR;
296         default:
297             return CellInformation::CellType::CELL_TYPE_NONE;
298     }
299 }
300 
ConvertTechToCellType(RadioTech techType) const301 CellInformation::CellType CellInfo::ConvertTechToCellType(RadioTech techType) const
302 {
303     switch (techType) {
304         case RadioTech::RADIO_TECHNOLOGY_GSM:
305             return CellInformation::CellType::CELL_TYPE_GSM;
306         case RadioTech::RADIO_TECHNOLOGY_WCDMA:
307         case RadioTech::RADIO_TECHNOLOGY_HSPAP:
308         case RadioTech::RADIO_TECHNOLOGY_HSPA:
309             return CellInformation::CellType::CELL_TYPE_WCDMA;
310         case RadioTech::RADIO_TECHNOLOGY_LTE:
311         case RadioTech::RADIO_TECHNOLOGY_LTE_CA:
312             return CellInformation::CellType::CELL_TYPE_LTE;
313         case RadioTech::RADIO_TECHNOLOGY_TD_SCDMA:
314             return CellInformation::CellType::CELL_TYPE_TDSCDMA;
315         case RadioTech::RADIO_TECHNOLOGY_1XRTT:
316         case RadioTech::RADIO_TECHNOLOGY_EVDO:
317         case RadioTech::RADIO_TECHNOLOGY_EHRPD:
318             return CellInformation::CellType::CELL_TYPE_CDMA;
319         case RadioTech::RADIO_TECHNOLOGY_NR:
320             return CellInformation::CellType::CELL_TYPE_NR;
321         default:
322             return CellInformation::CellType::CELL_TYPE_NONE;
323     }
324 }
325 
ProcessCurrentCell(CurrentCellInformation * cellInfo)326 bool CellInfo::ProcessCurrentCell(CurrentCellInformation *cellInfo)
327 {
328     bool ret = false;
329     switch (cellInfo->ratType) {
330         case TelRilRatType::NETWORK_TYPE_GSM: {
331             ret = ProcessCurrentCellGsm(cellInfo);
332             break;
333         }
334         case TelRilRatType::NETWORK_TYPE_LTE: {
335             ret = ProcessCurrentCellLte(cellInfo);
336             break;
337         }
338         case TelRilRatType::NETWORK_TYPE_WCDMA: {
339             ret = ProcessCurrentCellWcdma(cellInfo);
340             break;
341         }
342         case TelRilRatType::NETWORK_TYPE_TDSCDMA: {
343             ret = ProcessCurrentCellTdscdma(cellInfo);
344             break;
345         }
346         case TelRilRatType::NETWORK_TYPE_CDMA: {
347             ret = ProcessCurrentCellCdma(cellInfo);
348             break;
349         }
350         case TelRilRatType::NETWORK_TYPE_NR: {
351             ret = ProcessCurrentCellNr(cellInfo);
352             break;
353         }
354         default: {
355             TELEPHONY_LOGI("CellInfo::ProcessCurrentCell error rat type:%{public}d slotId:%{public}d",
356                 cellInfo->ratType, slotId_);
357             return false;
358         }
359     }
360     if (!ret) {
361         TELEPHONY_LOGI(
362             "CellInfo::ProcessCurrentCell currentCellInfo is null or cell info no change slotId:%{public}d",
363             slotId_);
364         return false;
365     }
366     return true;
367 }
368 
ProcessNeighboringCellGsm(CellNearbyInfo * cellInfo)369 bool CellInfo::ProcessNeighboringCellGsm(CellNearbyInfo *cellInfo)
370 {
371     bool ret = false;
372     if (cellInfo == nullptr) {
373         TELEPHONY_LOGE("cellInfo is nullptr");
374         return ret;
375     }
376     sptr<GsmCellInformation> cell = new GsmCellInformation;
377     if (cell != nullptr) {
378         int32_t &arfcn = cellInfo->ServiceCellParas.gsm.arfcn;
379         int32_t &cellId = cellInfo->ServiceCellParas.gsm.cellId;
380         int32_t &bsic = cellInfo->ServiceCellParas.gsm.bsic;
381         int32_t &lac = cellInfo->ServiceCellParas.gsm.lac;
382         cell->Init(0, 0, cellId);
383         cell->SetGsmParam(bsic, lac, arfcn);
384         cellInfos_.emplace_back(cell);
385         TELEPHONY_LOGI("CellInfo::ProcessNeighboringCellGsm arfcn:%{private}d cellId:%{private}d"
386             "bsic:%{private}d lac:%{private}d slotId:%{public}d",
387             arfcn, cellId, bsic, lac, slotId_);
388         ret = true;
389     }
390     return ret;
391 }
392 
ProcessNeighboringCellLte(CellNearbyInfo * cellInfo)393 bool CellInfo::ProcessNeighboringCellLte(CellNearbyInfo *cellInfo)
394 {
395     bool ret = false;
396     if (cellInfo == nullptr) {
397         TELEPHONY_LOGE("cellInfo is nullptr");
398         return ret;
399     }
400     sptr<LteCellInformation> cell = new LteCellInformation;
401     if (cell != nullptr) {
402         int32_t &arfcn = cellInfo->ServiceCellParas.lte.arfcn;
403         int32_t pci = cellInfo->ServiceCellParas.lte.pci;
404         cell->Init(0, 0, 0);
405         cell->SetLteParam(pci, 0, arfcn);
406         cellInfos_.emplace_back(cell);
407         TELEPHONY_LOGI("CellInfo::ProcessLte arfcn:%{private}d pci:%{private}d slotId:%{public}d", arfcn, pci, slotId_);
408         ret = true;
409     }
410     return ret;
411 }
412 
ProcessNeighboringCellWcdma(CellNearbyInfo * cellInfo)413 bool CellInfo::ProcessNeighboringCellWcdma(CellNearbyInfo *cellInfo)
414 {
415     bool ret = false;
416     if (cellInfo == nullptr) {
417         TELEPHONY_LOGE("cellInfo is nullptr");
418         return ret;
419     }
420     sptr<WcdmaCellInformation> cell = new WcdmaCellInformation;
421     if (cell != nullptr) {
422         int32_t &arfcn = cellInfo->ServiceCellParas.wcdma.arfcn;
423         int32_t psc = cellInfo->ServiceCellParas.wcdma.psc;
424         cell->Init(0, 0, 0);
425         cell->SetWcdmaParam(psc, 0, arfcn);
426         cellInfos_.emplace_back(cell);
427         TELEPHONY_LOGI(
428             "CellInfo::ProcessWcdma arfcn:%{private}d psc:%{private}d slotId:%{public}d", arfcn, psc, slotId_);
429         ret = true;
430     }
431     return ret;
432 }
433 
ProcessNeighboringCellCdma(CellNearbyInfo * cellInfo)434 bool CellInfo::ProcessNeighboringCellCdma(CellNearbyInfo *cellInfo)
435 {
436     bool ret = false;
437     if (cellInfo == nullptr) {
438         TELEPHONY_LOGE("cellInfo is nullptr");
439         return ret;
440     }
441     sptr<CdmaCellInformation> cell = new CdmaCellInformation;
442     if (cell != nullptr) {
443         int32_t &baseId = cellInfo->ServiceCellParas.cdma.baseId;
444         int32_t &longitude = cellInfo->ServiceCellParas.cdma.longitude;
445         int32_t &latitude = cellInfo->ServiceCellParas.cdma.latitude;
446         int32_t &networkId = cellInfo->ServiceCellParas.cdma.networkId;
447         int32_t &systemId = cellInfo->ServiceCellParas.cdma.systemId;
448         cell->Init(0, 0, 0);
449         cell->SetCdmaParam(baseId, latitude, longitude, networkId, systemId);
450         cellInfos_.emplace_back(cell);
451         TELEPHONY_LOGI(
452             "CellInfo::ProcessCdma baseId:%{private}d psc:%{private}d slotId:%{public}d", baseId, systemId, slotId_);
453         ret = true;
454     }
455     return ret;
456 }
457 
ProcessNeighboringCellTdscdma(CellNearbyInfo * cellInfo)458 bool CellInfo::ProcessNeighboringCellTdscdma(CellNearbyInfo *cellInfo)
459 {
460     bool ret = false;
461     if (cellInfo == nullptr) {
462         TELEPHONY_LOGE("cellInfo is nullptr");
463         return ret;
464     }
465     sptr<TdscdmaCellInformation> cell = new TdscdmaCellInformation;
466     if (cell != nullptr) {
467         int32_t &arfcn = cellInfo->ServiceCellParas.tdscdma.arfcn;
468         int32_t &cpid = cellInfo->ServiceCellParas.tdscdma.cpid;
469         int32_t &lac = cellInfo->ServiceCellParas.tdscdma.lac;
470         cell->Init(0, 0, 0);
471         cell->SetTdscdmaParam(cpid, lac, arfcn);
472         cellInfos_.emplace_back(cell);
473         TELEPHONY_LOGI(
474             "CellInfo::ProcessTdscdma arfcn:%{private}d psc:%{private}d slotId:%{public}d", arfcn, cpid, slotId_);
475         ret = true;
476     }
477     return ret;
478 }
479 
ProcessNeighboringCellNr(CellNearbyInfo * cellInfo)480 bool CellInfo::ProcessNeighboringCellNr(CellNearbyInfo *cellInfo)
481 {
482     bool ret = false;
483     if (cellInfo == nullptr) {
484         TELEPHONY_LOGE("cellInfo is nullptr");
485         return ret;
486     }
487     sptr<NrCellInformation> cell = new NrCellInformation;
488     if (cell != nullptr && cellInfo != nullptr) {
489         int32_t &nrArfcn = cellInfo->ServiceCellParas.nr.nrArfcn;
490         int32_t &pci = cellInfo->ServiceCellParas.nr.pci;
491         int32_t &tac = cellInfo->ServiceCellParas.nr.tac;
492         int64_t &nci = cellInfo->ServiceCellParas.nr.nci;
493         cell->Init(0, 0, 0);
494         cell->SetNrParam(nrArfcn, pci, tac, nci);
495         cellInfos_.emplace_back(cell);
496         TELEPHONY_LOGI("CellInfo::ProcessNeighboringCellNr arfcn:%{private}d pci:%{private}d slotId:%{public}d",
497             nrArfcn, pci, slotId_);
498         ret = true;
499     }
500     return ret;
501 }
502 
ProcessCurrentCellGsm(CurrentCellInformation * cellInfo)503 bool CellInfo::ProcessCurrentCellGsm(CurrentCellInformation *cellInfo)
504 {
505     bool ret = false;
506     if (cellInfo == nullptr) {
507         TELEPHONY_LOGE("cellInfo is nullptr");
508         return ret;
509     }
510     sptr<GsmCellInformation> cell = new GsmCellInformation;
511     if (cell != nullptr) {
512         int32_t &arfcn = cellInfo->ServiceCellParas.gsm.arfcn;
513         int32_t &cellId = cellInfo->ServiceCellParas.gsm.cellId;
514         int32_t &bsic = cellInfo->ServiceCellParas.gsm.bsic;
515         int32_t &lac = cellInfo->ServiceCellParas.gsm.lac;
516         int32_t &rxlev = cellInfo->ServiceCellParas.gsm.rxlev;
517         rxlev = ZERO_VALUE - rxlev;
518         cell->Init(cellInfo->mcc, cellInfo->mnc, cellId);
519         cell->SetGsmParam(bsic, lac, arfcn);
520         cell->SetSignalIntensity(rxlev);
521         cell->SetIsCamped(true);
522         int32_t level = GetCurrentSignalLevelGsm(rxlev);
523         cell->SetSignalLevel(level);
524         currentCellInfo_ = cell;
525         cellInfos_.emplace_back(cell);
526         TELEPHONY_LOGI(
527             "CellInfo::ProcessCurrentCellGsm arfcn:%{private}d cellId:%{private}d"
528             "bsic:%{private}d lac:%{private}d rxlev:%{public}d slotId:%{public}d",
529             arfcn, cellId, bsic, lac, rxlev, slotId_);
530         ret = true;
531     }
532     return ret;
533 }
534 
ProcessCurrentCellLte(CurrentCellInformation * cellInfo)535 bool CellInfo::ProcessCurrentCellLte(CurrentCellInformation *cellInfo)
536 {
537     bool ret = false;
538     if (cellInfo == nullptr) {
539         TELEPHONY_LOGE("cellInfo is nullptr");
540         return ret;
541     }
542     sptr<LteCellInformation> cell = new LteCellInformation;
543     if (cell != nullptr) {
544         int32_t &arfcn = cellInfo->ServiceCellParas.lte.arfcn;
545         int32_t &pci = cellInfo->ServiceCellParas.lte.pci;
546         int32_t &cellId = cellInfo->ServiceCellParas.lte.cellId;
547         int32_t &tac = cellInfo->ServiceCellParas.lte.tac;
548         int32_t &rsrp = cellInfo->ServiceCellParas.lte.rsrp;
549         rsrp = ZERO_VALUE - rsrp;
550         cell->Init(cellInfo->mcc, cellInfo->mnc, cellId);
551         cell->SetLteParam(pci, tac, arfcn);
552         cell->SetSignalIntensity(rsrp);
553         cell->SetIsCamped(true);
554         int32_t level = GetCurrentSignalLevelLte(rsrp);
555         cell->SetSignalLevel(level);
556         currentCellInfo_ = cell;
557         cellInfos_.emplace_back(cell);
558         TELEPHONY_LOGI(
559             "CellInfo::ProcessCurrentCellLte arfcn:%{private}d pci:%{private}d rsrp:%{public}d slotId:%{public}d",
560             arfcn, pci, rsrp, slotId_);
561         ret = true;
562     }
563     return ret;
564 }
565 
ProcessCurrentCellWcdma(CurrentCellInformation * cellInfo)566 bool CellInfo::ProcessCurrentCellWcdma(CurrentCellInformation *cellInfo)
567 {
568     bool ret = false;
569     if (cellInfo == nullptr) {
570         TELEPHONY_LOGE("cellInfo is nullptr");
571         return ret;
572     }
573     sptr<WcdmaCellInformation> cell = new WcdmaCellInformation;
574     if (cell != nullptr) {
575         int32_t &arfcn = cellInfo->ServiceCellParas.wcdma.arfcn;
576         int32_t &psc = cellInfo->ServiceCellParas.wcdma.psc;
577         int32_t &cellId = cellInfo->ServiceCellParas.wcdma.cellId;
578         int32_t &lac = cellInfo->ServiceCellParas.wcdma.lac;
579         int32_t &rscp = cellInfo->ServiceCellParas.wcdma.rscp;
580         rscp = ZERO_VALUE - rscp;
581         cell->Init(cellInfo->mcc, cellInfo->mnc, cellId);
582         cell->SetWcdmaParam(psc, lac, arfcn);
583         cell->SetSignalIntensity(rscp);
584         cell->SetIsCamped(true);
585         int32_t level = GetCurrentSignalLevelWcdma(rscp);
586         cell->SetSignalLevel(level);
587         currentCellInfo_ = cell;
588         cellInfos_.emplace_back(cell);
589         TELEPHONY_LOGI(
590             "CellInfo::ProcessCurrentCellWcdma arfcn:%{private}d psc:%{private}d rscp:%{public}d", arfcn, psc, rscp);
591         ret = true;
592     }
593     return ret;
594 }
595 
ProcessCurrentCellCdma(CurrentCellInformation * cellInfo)596 bool CellInfo::ProcessCurrentCellCdma(CurrentCellInformation *cellInfo)
597 {
598     bool ret = false;
599     if (cellInfo == nullptr) {
600         TELEPHONY_LOGE("cellInfo is nullptr");
601         return ret;
602     }
603     sptr<CdmaCellInformation> cell = new CdmaCellInformation;
604     if (cell != nullptr) {
605         int32_t &baseId = cellInfo->ServiceCellParas.cdma.baseId;
606         int32_t &longitude = cellInfo->ServiceCellParas.cdma.longitude;
607         int32_t &latitude = cellInfo->ServiceCellParas.cdma.latitude;
608         int32_t &networkId = cellInfo->ServiceCellParas.cdma.networkId;
609         int32_t &systemId = cellInfo->ServiceCellParas.cdma.systemId;
610         int32_t &pilotStrength = cellInfo->ServiceCellParas.cdma.pilotStrength;
611         pilotStrength = ZERO_VALUE - pilotStrength;
612         cell->Init(cellInfo->mcc, cellInfo->mnc, baseId);
613         cell->SetCdmaParam(baseId, latitude, longitude, networkId, systemId);
614         cell->SetSignalIntensity(pilotStrength);
615         cell->SetIsCamped(true);
616         int32_t level = GetCurrentSignalLevelCdma(pilotStrength);
617         cell->SetSignalLevel(level);
618         currentCellInfo_ = cell;
619         cellInfos_.emplace_back(cell);
620         TELEPHONY_LOGI(
621             "CellInfo::ProcessCurrentCellCdma baseId:%{private}d networkId:%{private}d pilotStrength:%{public}d",
622             baseId, networkId, pilotStrength);
623         ret = true;
624     }
625     return ret;
626 }
627 
ProcessCurrentCellTdscdma(CurrentCellInformation * cellInfo)628 bool CellInfo::ProcessCurrentCellTdscdma(CurrentCellInformation *cellInfo)
629 {
630     bool ret = false;
631     if (cellInfo == nullptr) {
632         TELEPHONY_LOGE("cellInfo is nullptr");
633         return ret;
634     }
635     sptr<TdscdmaCellInformation> cell = new TdscdmaCellInformation;
636     if (cell != nullptr) {
637         int32_t &arfcn = cellInfo->ServiceCellParas.tdscdma.arfcn;
638         int32_t &cpid = cellInfo->ServiceCellParas.tdscdma.cpid;
639         int32_t &cellId = cellInfo->ServiceCellParas.tdscdma.cellId;
640         int32_t &lac = cellInfo->ServiceCellParas.tdscdma.lac;
641         int32_t &rscp = cellInfo->ServiceCellParas.tdscdma.rscp;
642         rscp = ZERO_VALUE - rscp;
643         cell->Init(cellInfo->mcc, cellInfo->mnc, cellId);
644         cell->SetTdscdmaParam(cpid, lac, arfcn);
645         cell->SetSignalIntensity(rscp);
646         cell->SetIsCamped(true);
647         int32_t level = GetCurrentSignalLevelTdscdma(rscp);
648         cell->SetSignalLevel(level);
649         currentCellInfo_ = cell;
650         cellInfos_.emplace_back(cell);
651         TELEPHONY_LOGI("CellInfo::ProcessCurrentCellTdscdma arfcn:%{private}d pci:%{private}d slotId:%{public}d", arfcn,
652             cpid, slotId_);
653         ret = true;
654     }
655     return ret;
656 }
657 
ProcessCurrentCellNr(CurrentCellInformation * cellInfo)658 bool CellInfo::ProcessCurrentCellNr(CurrentCellInformation *cellInfo)
659 {
660     bool ret = false;
661     if (cellInfo == nullptr) {
662         TELEPHONY_LOGE("cellInfo is nullptr");
663         return ret;
664     }
665     sptr<NrCellInformation> cell = new NrCellInformation;
666     if (cell != nullptr && cellInfo != nullptr) {
667         int32_t &nrArfcn = cellInfo->ServiceCellParas.nr.nrArfcn;
668         int32_t &pci = cellInfo->ServiceCellParas.nr.pci;
669         int32_t &tac = cellInfo->ServiceCellParas.nr.tac;
670         int64_t &nci = cellInfo->ServiceCellParas.nr.nci;
671         int32_t &rsrp = cellInfo->ServiceCellParas.nr.rsrp;
672         int32_t &rsrq = cellInfo->ServiceCellParas.nr.rsrq;
673         rsrp = ZERO_VALUE - rsrp;
674         rsrq = ZERO_VALUE - rsrq;
675         cell->Init(cellInfo->mcc, cellInfo->mnc, 0);
676         cell->SetNrParam(nrArfcn, pci, tac, nci);
677         cell->SetNrSignalParam(rsrp, rsrq);
678         cell->SetSignalIntensity(rsrp);
679         cell->SetIsCamped(true);
680         int32_t level = GetCurrentSignalLevelNr(rsrp);
681         cell->SetSignalLevel(level);
682         currentCellInfo_ = cell;
683         cellInfos_.emplace_back(cell);
684 
685         TELEPHONY_LOGI(
686             "CellInfo::ProcessCurrentCellNr arfcn:%{private}d pci:%{private}d slotId:%{public}d rsrp:%{public}d "
687             "rsrq:%{public}d", nrArfcn, pci, slotId_, rsrp, rsrq);
688         ret = true;
689     }
690     return ret;
691 }
692 
GetCurrentSignalLevelGsm(int32_t rxlev)693 int32_t CellInfo::GetCurrentSignalLevelGsm(int32_t rxlev)
694 {
695     int32_t level = SIGNAL_LEVEL_INVALID;
696     if (rxlev >= SIGNAL_RSSI_MAXIMUM) {
697         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelGsm Value is Invalid.");
698         return level;
699     }
700     for (int32_t i = signalBar_; i >= 0; --i) {
701         if (rxlev >= GSM_SIGNAL_THRESHOLD[i]) {
702             level = i;
703             break;
704         }
705     }
706     return level;
707 }
708 
GetCurrentSignalLevelLte(int32_t rsrp)709 int32_t CellInfo::GetCurrentSignalLevelLte(int32_t rsrp)
710 {
711     int32_t level = SIGNAL_LEVEL_INVALID;
712     if (rsrp >= SIGNAL_RSSI_MAXIMUM) {
713         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelLte Value is Invalid.");
714         return level;
715     }
716     for (int32_t i = signalBar_; i >= 0; --i) {
717         if (rsrp >= LTE_SIGNAL_THRESHOLD[i]) {
718             level = i;
719             break;
720         }
721     }
722     return level;
723 }
724 
GetCurrentSignalLevelWcdma(int32_t rscp)725 int32_t CellInfo::GetCurrentSignalLevelWcdma(int32_t rscp)
726 {
727     int32_t level = SIGNAL_LEVEL_INVALID;
728     if (rscp >= SIGNAL_RSSI_MAXIMUM) {
729         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelWcdma Value is Invalid.");
730         return level;
731     }
732     for (int32_t i = signalBar_; i >= 0; --i) {
733         if (rscp >= WCDMA_SIGNAL_THRESHOLD[i]) {
734             level = i;
735             break;
736         }
737     }
738     return level;
739 }
740 
GetCurrentSignalLevelCdma(int32_t pilotStrength)741 int32_t CellInfo::GetCurrentSignalLevelCdma(int32_t pilotStrength)
742 {
743     int32_t level = SIGNAL_LEVEL_INVALID;
744     if (pilotStrength >= SIGNAL_RSSI_MAXIMUM) {
745         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelCdma Value is Invalid.");
746         return level;
747     }
748     for (int32_t i = signalBar_; i >= 0; --i) {
749         if (pilotStrength >= CDMA_SIGNAL_THRESHOLD[i]) {
750             level = i;
751             break;
752         }
753     }
754     return level;
755 }
756 
GetCurrentSignalLevelTdscdma(int32_t rscp)757 int32_t CellInfo::GetCurrentSignalLevelTdscdma(int32_t rscp)
758 {
759     int32_t level = SIGNAL_LEVEL_INVALID;
760     if (rscp >= SIGNAL_RSSI_MAXIMUM) {
761         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelTdscdma Value is Invalid.");
762         return level;
763     }
764     for (int32_t i = signalBar_; i >= 0; --i) {
765         if (rscp >= TD_SCDMA_SIGNAL_THRESHOLD[i]) {
766             level = i;
767             break;
768         }
769     }
770     return level;
771 }
772 
GetCurrentSignalLevelNr(int32_t rsrp)773 int32_t CellInfo::GetCurrentSignalLevelNr(int32_t rsrp)
774 {
775     int32_t level = SIGNAL_LEVEL_INVALID;
776     if (rsrp >= SIGNAL_RSSI_MAXIMUM) {
777         TELEPHONY_LOGE("CellInfo::GetCurrentSignalLevelNr Value is Invalid.");
778         return level;
779     }
780     for (int32_t i = signalBar_; i >= 0; --i) {
781         if (rsrp >= NR_SIGNAL_THRESHOLD[i]) {
782             level = i;
783             break;
784         }
785     }
786     return level;
787 }
788 
GetCellInfoList(std::vector<sptr<CellInformation>> & cellInfo)789 void CellInfo::GetCellInfoList(std::vector<sptr<CellInformation>> &cellInfo)
790 {
791     cellInfo.clear();
792     {
793         std::lock_guard<std::mutex> lock(mutex_);
794         for (auto &cell : cellInfos_) {
795             AddCellInformation(cell, cellInfo);
796         }
797     }
798     TELEPHONY_LOGD("CellInfo::GetCellInfoList size:%{public}zu slotId:%{public}d", cellInfo.size(), slotId_);
799 }
800 
ClearCellInfoList()801 void CellInfo::ClearCellInfoList()
802 {
803     std::lock_guard<std::mutex> lock(mutex_);
804     currentCellInfo_ = nullptr;
805     cellInfos_.clear();
806 }
807 
AddCellInformation(sptr<CellInformation> & cellInfo,std::vector<sptr<CellInformation>> & cellInfos)808 void CellInfo::AddCellInformation(sptr<CellInformation> &cellInfo, std::vector<sptr<CellInformation>> &cellInfos)
809 {
810     CellInformation::CellType type = cellInfo->GetNetworkType();
811     switch (type) {
812         case CellInformation::CellType::CELL_TYPE_GSM: {
813             sptr<GsmCellInformation> cell = new GsmCellInformation;
814             GsmCellInformation &gsmCell = *cell;
815             gsmCell = *(static_cast<GsmCellInformation *>(cellInfo.GetRefPtr()));
816             cellInfos.emplace_back(cell);
817             break;
818         }
819         case CellInformation::CellType::CELL_TYPE_LTE: {
820             sptr<LteCellInformation> cell = new LteCellInformation;
821             LteCellInformation &lteCell = *cell;
822             lteCell = *(static_cast<LteCellInformation *>(cellInfo.GetRefPtr()));
823             cellInfos.emplace_back(cell);
824             break;
825         }
826         case CellInformation::CellType::CELL_TYPE_WCDMA: {
827             sptr<WcdmaCellInformation> cell = new WcdmaCellInformation;
828             WcdmaCellInformation &wcdmaCell = *cell;
829             wcdmaCell = *(static_cast<WcdmaCellInformation *>(cellInfo.GetRefPtr()));
830             cellInfos.emplace_back(cell);
831             break;
832         }
833         case CellInformation::CellType::CELL_TYPE_CDMA: {
834             sptr<CdmaCellInformation> cell = new CdmaCellInformation;
835             CdmaCellInformation &cdmaCell = *cell;
836             cdmaCell = *(static_cast<CdmaCellInformation *>(cellInfo.GetRefPtr()));
837             cellInfos.emplace_back(cell);
838             break;
839         }
840         case CellInformation::CellType::CELL_TYPE_TDSCDMA: {
841             sptr<TdscdmaCellInformation> cell = new TdscdmaCellInformation;
842             TdscdmaCellInformation &tdscdmaCell = *cell;
843             tdscdmaCell = *(static_cast<TdscdmaCellInformation *>(cellInfo.GetRefPtr()));
844             cellInfos.emplace_back(cell);
845             break;
846         }
847         case CellInformation::CellType::CELL_TYPE_NR: {
848             sptr<NrCellInformation> cell = new NrCellInformation;
849             NrCellInformation &nrCell = *cell;
850             nrCell = *(static_cast<NrCellInformation *>(cellInfo.GetRefPtr()));
851             cellInfos.emplace_back(cell);
852             break;
853         }
854         default:
855             break;
856     }
857 }
858 
GetCellLocation()859 sptr<CellLocation> CellInfo::GetCellLocation()
860 {
861     if (currentCellInfo_ == nullptr) {
862         TELEPHONY_LOGE("CellInfo::GetCellLocation is null slotId:%{public}d", slotId_);
863         return nullptr;
864     }
865     CellInformation::CellType type = currentCellInfo_->GetNetworkType();
866     switch (type) {
867         case CellInformation::CellType::CELL_TYPE_GSM: {
868             sptr<GsmCellInformation> cellinfo =
869                 static_cast<GsmCellInformation *>(currentCellInfo_.GetRefPtr());
870             sptr<GsmCellLocation> cellLocation = new GsmCellLocation;
871             cellLocation->SetGsmParam(cellinfo->GetCellId(), cellinfo->GetLac());
872             return cellLocation;
873         }
874         case CellInformation::CellType::CELL_TYPE_TDSCDMA: {
875             sptr<GsmCellInformation> cellinfo = static_cast<GsmCellInformation *>(currentCellInfo_.GetRefPtr());
876             sptr<GsmCellLocation> cellLocation = new GsmCellLocation;
877             cellLocation->SetGsmParam(cellinfo->GetCellId(), cellinfo->GetLac());
878             return cellLocation;
879         }
880         case CellInformation::CellType::CELL_TYPE_WCDMA: {
881             sptr<WcdmaCellInformation> cellinfo = static_cast<WcdmaCellInformation *>(currentCellInfo_.GetRefPtr());
882             sptr<GsmCellLocation> cellLocation = new GsmCellLocation;
883             cellLocation->SetGsmParam(cellinfo->GetCellId(), cellinfo->GetLac(), cellinfo->GetPsc());
884             return cellLocation;
885         }
886         case CellInformation::CellType::CELL_TYPE_CDMA: {
887             sptr<CdmaCellInformation> cellinfo = static_cast<CdmaCellInformation *>(currentCellInfo_.GetRefPtr());
888             sptr<CdmaCellLocation> cellLocation = new CdmaCellLocation;
889             cellLocation->SetCdmaParam(cellinfo->GetBaseId(), cellinfo->GetLatitude(), cellinfo->GetLongitude(),
890                 cellinfo->GetNid(), cellinfo->GetSid());
891             return cellLocation;
892         }
893         case CellInformation::CellType::CELL_TYPE_LTE:
894         case CellInformation::CellType::CELL_TYPE_NR:
895             return GetCellLocationExt(type);
896         default:
897             TELEPHONY_LOGE("CellInfo::GetCellLocation cell type error slotId:%{public}d", slotId_);
898             break;
899     }
900     return nullptr;
901 }
902 
GetCellLocationExt(CellInformation::CellType type)903 sptr<CellLocation> CellInfo::GetCellLocationExt(CellInformation::CellType type)
904 {
905     if (currentCellInfo_ == nullptr) {
906         TELEPHONY_LOGE("CellInfo::GetCellLocationExt is null slotId:%{public}d", slotId_);
907         return nullptr;
908     }
909     if (type == CellInformation::CellType::CELL_TYPE_LTE) {
910         sptr<LteCellInformation> cellinfo = static_cast<LteCellInformation *>(currentCellInfo_.GetRefPtr());
911         sptr<GsmCellLocation> cellLocation = new GsmCellLocation;
912         cellLocation->SetGsmParam(cellinfo->GetCellId(), cellinfo->GetTac());
913         return cellLocation;
914     } else if (type == CellInformation::CellType::CELL_TYPE_NR) {
915         sptr<NrCellInformation> cellinfo = static_cast<NrCellInformation *>(currentCellInfo_.GetRefPtr());
916         sptr<GsmCellLocation> cellLocation = new GsmCellLocation;
917         cellLocation->SetGsmParam(cellinfo->GetCellId(), cellinfo->GetTac());
918         return cellLocation;
919     }
920     return nullptr;
921 }
922 } // namespace Telephony
923 } // namespace OHOS