• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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 "sms_misc_manager.h"
17 
18 #include "core_manager_inner.h"
19 #include "short_message.h"
20 #include "sms_mms_errors.h"
21 #include "string_utils.h"
22 #include "telephony_common_utils.h"
23 #include "telephony_log_wrapper.h"
24 
25 namespace OHOS {
26 namespace Telephony {
27 static constexpr int32_t WAIT_TIME_SECOND = 1;
28 static constexpr int32_t TIME_OUT_SECOND = 3;
29 static constexpr uint8_t GSM_TYPE = 1;
30 static constexpr uint8_t MIN_SMSC_LEN = 2;
31 static constexpr uint32_t RANG_MAX = 65535;
32 bool SmsMiscManager::hasGotCbRange_ = false;
33 
SmsMiscManager(int32_t slotId)34 SmsMiscManager::SmsMiscManager(int32_t slotId) : TelEventHandler("SmsMiscManager"), slotId_(slotId) {}
35 
SetCBConfig(bool enable,uint32_t fromMsgId,uint32_t toMsgId,uint8_t netType)36 int32_t SmsMiscManager::SetCBConfig(bool enable, uint32_t fromMsgId, uint32_t toMsgId, uint8_t netType)
37 {
38     bool ret = false;
39     if ((toMsgId > RANG_MAX) || (fromMsgId > toMsgId) || (netType != GSM_TYPE)) {
40         TELEPHONY_LOGI("cb channel invalid");
41         return TELEPHONY_ERR_ARGUMENT_INVALID;
42     }
43     std::unique_lock<std::mutex> lock(cbMutex_);
44     if (!hasGotCbRange_) {
45         GetModemCBRange();
46         if (mdRangeList_.size() != 0) {
47             if (!SendDataToRil(false, mdRangeList_)) {
48                 return TELEPHONY_ERR_RIL_CMD_FAIL;
49             }
50             mdRangeList_.clear();
51         }
52     }
53     std::list<gsmCBRangeInfo> oldRangeList = rangeList_;
54     if (enable) {
55         ret = OpenCBRange(fromMsgId, toMsgId);
56     } else {
57         ret = CloseCBRange(fromMsgId, toMsgId);
58     }
59     if (ret) {
60         if (!SendDataToRil(false, oldRangeList)) {
61             rangeList_ = oldRangeList;
62             return TELEPHONY_ERR_RIL_CMD_FAIL;
63         }
64         if (!SendDataToRil(true, rangeList_)) {
65             rangeList_ = oldRangeList;
66             return TELEPHONY_ERR_RIL_CMD_FAIL;
67         }
68     } else {
69         rangeList_ = oldRangeList;
70     }
71     return TELEPHONY_ERR_SUCCESS;
72 }
73 
GetRangeInfo() const74 std::list<SmsMiscManager::gsmCBRangeInfo> SmsMiscManager::GetRangeInfo() const
75 {
76     return rangeList_;
77 }
78 
79 // from 3GPP TS 27.005 3.3.4 Select Cell Broadcast Message Types
OpenCBRange(uint32_t fromMsgId,uint32_t toMsgId)80 bool SmsMiscManager::OpenCBRange(uint32_t fromMsgId, uint32_t toMsgId)
81 {
82     infoData data(fromMsgId, toMsgId);
83     rangeList_.emplace_back(fromMsgId, toMsgId);
84     CombineCBRange();
85     return true;
86 }
87 
SplitMsgId(uint32_t fromMsgId,uint32_t toMsgId,const std::list<gsmCBRangeInfo>::iterator & oldIter)88 void SmsMiscManager::SplitMsgId(
89     uint32_t fromMsgId, uint32_t toMsgId, const std::list<gsmCBRangeInfo>::iterator &oldIter)
90 {
91     auto &info = *oldIter;
92     rangeList_.emplace_back(info.fromMsgId, fromMsgId - 1);
93     rangeList_.emplace_back(toMsgId + 1, info.toMsgId);
94     rangeList_.erase(oldIter);
95 }
96 
97 // from 3GPP TS 27.005 3.3.4 Select Cell Broadcast Message Types
CloseCBRange(uint32_t fromMsgId,uint32_t toMsgId)98 bool SmsMiscManager::CloseCBRange(uint32_t fromMsgId, uint32_t toMsgId)
99 {
100     auto iter = rangeList_.begin();
101     while (iter != rangeList_.end()) {
102         auto oldIter = iter++;
103         auto &info = *oldIter;
104         if (fromMsgId == info.fromMsgId && toMsgId == info.toMsgId) {
105             rangeList_.erase(oldIter);
106             continue;
107         } else if (fromMsgId == info.fromMsgId && toMsgId > info.toMsgId) {
108             rangeList_.erase(oldIter);
109             continue;
110         } else if (fromMsgId == info.fromMsgId && toMsgId < info.toMsgId) {
111             rangeList_.emplace_back(toMsgId + 1, info.toMsgId);
112             rangeList_.erase(oldIter);
113             continue;
114         } else if (fromMsgId < info.fromMsgId && toMsgId == info.toMsgId) {
115             rangeList_.erase(oldIter);
116             continue;
117         } else if (fromMsgId > info.fromMsgId && toMsgId == info.toMsgId) {
118             rangeList_.emplace_back(info.fromMsgId, fromMsgId - 1);
119             rangeList_.erase(oldIter);
120             continue;
121         } else if (fromMsgId > info.fromMsgId && toMsgId < info.toMsgId) {
122             SplitMsgId(fromMsgId, toMsgId, oldIter);
123             continue;
124         } else if (fromMsgId > info.fromMsgId && fromMsgId <= info.toMsgId) {
125             rangeList_.emplace_back(info.fromMsgId, fromMsgId - 1);
126             rangeList_.erase(oldIter);
127             continue;
128         } else if (fromMsgId < info.fromMsgId && toMsgId > info.toMsgId) {
129             rangeList_.erase(oldIter);
130             continue;
131         } else if (toMsgId < info.toMsgId && toMsgId >= info.fromMsgId) {
132             rangeList_.emplace_back(toMsgId + 1, info.toMsgId);
133             rangeList_.erase(oldIter);
134             continue;
135         }
136     }
137     CombineCBRange();
138     return true;
139 }
140 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)141 void SmsMiscManager::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
142 {
143     if (event == nullptr) {
144         TELEPHONY_LOGE("SmsMiscManager ProcessEvent event == nullptr");
145         return;
146     }
147 
148     uint32_t eventId = 0;
149     TELEPHONY_LOGI("SmsMiscManager::ProcessEvent");
150     eventId = event->GetInnerEventId();
151     switch (eventId) {
152         case SET_CB_CONFIG_FINISH: {
153             isSuccess_ = true;
154             std::shared_ptr<HRilRadioResponseInfo> res = event->GetSharedObject<HRilRadioResponseInfo>();
155             if (res != nullptr) {
156                 isSuccess_ = (res->error == HRilErrType::NONE);
157             }
158             NotifyHasResponse();
159             break;
160         }
161         case GET_CB_CONFIG_FINISH: {
162             GetCBConfigFinish(event);
163             break;
164         }
165         case SET_SMSC_ADDR_FINISH: {
166             isSuccess_ = true;
167             std::shared_ptr<HRilRadioResponseInfo> res = event->GetSharedObject<HRilRadioResponseInfo>();
168             if (res != nullptr) {
169                 isSuccess_ = (res->error == HRilErrType::NONE);
170             }
171             NotifyHasResponse();
172             break;
173         }
174         case GET_SMSC_ADDR_FINISH: {
175             isSuccess_ = true;
176             std::shared_ptr<ServiceCenterAddress> addr = event->GetSharedObject<ServiceCenterAddress>();
177             if (addr != nullptr) {
178                 smscAddr_ = addr->address;
179             }
180             NotifyHasResponse();
181             break;
182         }
183         default:
184             TELEPHONY_LOGI("SmsMiscManager::ProcessEvent default!");
185             break;
186     }
187 }
188 
GetCBConfigFinish(const AppExecFwk::InnerEvent::Pointer & event)189 void SmsMiscManager::GetCBConfigFinish(const AppExecFwk::InnerEvent::Pointer &event)
190 {
191     isSuccess_ = true;
192     std::shared_ptr<CBConfigInfo> res = event->GetSharedObject<CBConfigInfo>();
193     if (res == nullptr) {
194         isSuccess_ = false;
195     } else {
196         UpdateCbRangList(res);
197     }
198     NotifyHasResponse();
199 }
200 
IsEmpty() const201 bool SmsMiscManager::IsEmpty() const
202 {
203     return rangeList_.empty();
204 }
205 
NotifyHasResponse()206 void SmsMiscManager::NotifyHasResponse()
207 {
208     if (fairList_.size() > 0) {
209         fairVar_ = fairList_.front();
210         fairList_.pop_front();
211     } else {
212         return;
213     }
214     condVar_.notify_all();
215 }
216 
UpdateCbRangList(std::shared_ptr<CBConfigInfo> res)217 void SmsMiscManager::UpdateCbRangList(std::shared_ptr<CBConfigInfo> res)
218 {
219     mdRangeList_.clear();
220     if (res->mids.empty()) {
221         return;
222     }
223     std::vector<std::string> dest;
224     SplitMids(res->mids, dest, ",");
225     for (auto v : dest) {
226         std::string start;
227         std::string end;
228         if (!SplitMidValue(v, start, end, "-")) {
229             continue;
230         }
231         if (!IsValidDecValue(start) || !IsValidDecValue(end)) {
232             TELEPHONY_LOGE("start or end not decimal");
233             return;
234         }
235         if (std::stoi(start) <= std::stoi(end)) {
236             infoData data(std::stoi(start), std::stoi(end));
237             mdRangeList_.emplace_back(data.startPos, data.endPos);
238         }
239     }
240     rangeList_ = mdRangeList_;
241     CombineCBRange();
242 }
243 
CombineCBRange()244 void SmsMiscManager::CombineCBRange()
245 {
246     rangeList_.sort();
247     rangeList_.unique();
248     auto iter = rangeList_.begin();
249     while (iter != rangeList_.end()) {
250         auto OtherIter = iter;
251         OtherIter++;
252         bool eraseFlag = false;
253         while (OtherIter != rangeList_.end()) {
254             if (OtherIter->fromMsgId == iter->fromMsgId) {
255                 eraseFlag = true;
256                 break;
257             } else if (OtherIter->toMsgId <= iter->toMsgId) {
258                 OtherIter = rangeList_.erase(OtherIter);
259                 continue;
260             } else if (OtherIter->fromMsgId <= static_cast<uint32_t>(iter->toMsgId + 1)) {
261                 iter->toMsgId = OtherIter->toMsgId;
262                 OtherIter = rangeList_.erase(OtherIter);
263                 continue;
264             }
265             OtherIter++;
266         }
267         if (eraseFlag) {
268             iter = rangeList_.erase(iter);
269         } else {
270             iter++;
271         }
272     }
273 }
274 
SplitMids(std::string src,std::vector<std::string> & dest,const std::string delimiter)275 void SmsMiscManager::SplitMids(std::string src, std::vector<std::string> &dest, const std::string delimiter)
276 {
277     size_t pos = src.find(delimiter);
278     while (pos != std::string::npos) {
279         dest.push_back(src.substr(0, pos));
280         src.erase(0, pos + delimiter.length());
281         pos = src.find(delimiter);
282     }
283     dest.push_back(src);
284 }
285 
SplitMidValue(std::string value,std::string & start,std::string & end,const std::string delimiter)286 bool SmsMiscManager::SplitMidValue(std::string value, std::string &start, std::string &end, const std::string delimiter)
287 {
288     if (value.empty()) {
289         return false;
290     }
291     size_t pos = value.find(delimiter);
292     if (pos == 0 || pos == value.size() - 1) {
293         return false;
294     } else if (pos == std::string::npos) {
295         start = value;
296         end = value;
297         return true;
298     }
299     start = value.substr(0, pos);
300     end = value.substr(pos + 1);
301     return true;
302 }
303 
RangeListToString(const std::list<gsmCBRangeInfo> rangeList)304 std::string SmsMiscManager::RangeListToString(const std::list<gsmCBRangeInfo> rangeList)
305 {
306     std::string ret;
307     bool isFirst = true;
308     for (const auto &item : rangeList) {
309         if (isFirst) {
310             isFirst = false;
311         } else {
312             ret += ",";
313         }
314         if (item.fromMsgId == item.toMsgId) {
315             ret += std::to_string(item.fromMsgId);
316         } else {
317             ret += std::to_string(item.fromMsgId) + "-" + std::to_string(item.toMsgId);
318         }
319     }
320     return ret;
321 }
322 
SendDataToRil(bool enable,std::list<gsmCBRangeInfo> list)323 bool SmsMiscManager::SendDataToRil(bool enable, std::list<gsmCBRangeInfo> list)
324 {
325     TELEPHONY_LOGI("enable CB channel:%{public}d", enable);
326     for (auto item : list) {
327         TELEPHONY_LOGI("[%{public}d-%{public}d]", item.fromMsgId, item.toMsgId);
328     }
329     std::unique_lock<std::mutex> lock(mutex_);
330     if (!list.empty()) {
331         isSuccess_ = false;
332         int32_t condition = conditonVar_++;
333         fairList_.push_back(condition);
334         CBConfigParam cbData;
335         cbData.mode = enable ? 1 : 0;
336         cbData.idList = RangeListToString(list);
337         cbData.dcsList = codeScheme_;
338         CoreManagerInner::GetInstance().SetCBConfig(
339             slotId_, SmsMiscManager::SET_CB_CONFIG_FINISH, cbData, shared_from_this());
340         while (!isSuccess_) {
341             TELEPHONY_LOGI("SendDataToRil::wait(), isSuccess_ = false");
342             if (condVar_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
343                 break;
344             }
345         }
346         return isSuccess_;
347     } else {
348         return true;
349     }
350 }
351 
GetModemCBRange()352 void SmsMiscManager::GetModemCBRange()
353 {
354     std::unique_lock<std::mutex> lock(mutex_);
355     if (!hasGotCbRange_) {
356         isSuccess_ = false;
357         int32_t condition = conditonVar_++;
358         fairList_.push_back(condition);
359         CoreManagerInner::GetInstance().GetCBConfig(slotId_, SmsMiscManager::GET_CB_CONFIG_FINISH, shared_from_this());
360         while (!isSuccess_) {
361             TELEPHONY_LOGI("GetCBConfig::wait(), isSuccess_ = false");
362             if (condVar_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
363                 break;
364             }
365         }
366         hasGotCbRange_ = true;
367     }
368 }
369 
AddSimMessage(const std::string & smsc,const std::string & pdu,ISmsServiceInterface::SimMessageStatus status)370 int32_t SmsMiscManager::AddSimMessage(
371     const std::string &smsc, const std::string &pdu, ISmsServiceInterface::SimMessageStatus status)
372 {
373     std::vector<ShortMessage> message;
374     int32_t result = GetAllSimMessages(message);
375     if (result != TELEPHONY_ERR_SUCCESS) {
376         TELEPHONY_LOGE("SmsMiscManager::AddSimMessage get result fail");
377         return result;
378     }
379     int32_t smsCountCurrent = static_cast<int32_t>(message.size());
380     TELEPHONY_LOGI("smsCountCurrent = %{public}d smsCapacityOfSim_ = %{public}d", smsCountCurrent, smsCapacityOfSim_);
381     if (smsCountCurrent >= smsCapacityOfSim_) {
382         TELEPHONY_LOGE("AddSimMessage sim card is full");
383         return TELEPHONY_ERR_FAIL;
384     }
385 
386     TELEPHONY_LOGI("smscLen = %{public}zu pudLen = %{public}zu status = %{public}d", smsc.size(), pdu.size(), status);
387     std::string smscAddr(smsc);
388     if (smsc.length() <= MIN_SMSC_LEN) {
389         smscAddr.clear();
390         smscAddr.insert(0, "00");
391     }
392     TELEPHONY_LOGD("smscAddr = %{private}s", smscAddr.c_str());
393     return CoreManagerInner::GetInstance().AddSmsToIcc(
394         slotId_, static_cast<int>(status), const_cast<std::string &>(pdu), smscAddr);
395 }
396 
DelSimMessage(uint32_t msgIndex)397 int32_t SmsMiscManager::DelSimMessage(uint32_t msgIndex)
398 {
399     TELEPHONY_LOGI("messageIndex = %{public}d", msgIndex);
400     bool hasSimCard = false;
401     CoreManagerInner::GetInstance().HasSimCard(slotId_, hasSimCard);
402     if (!hasSimCard) {
403         TELEPHONY_LOGE("no sim card");
404         return TELEPHONY_ERR_SLOTID_INVALID;
405     }
406     return CoreManagerInner::GetInstance().DelSmsIcc(slotId_, msgIndex);
407 }
408 
UpdateSimMessage(uint32_t msgIndex,ISmsServiceInterface::SimMessageStatus newStatus,const std::string & pdu,const std::string & smsc)409 int32_t SmsMiscManager::UpdateSimMessage(uint32_t msgIndex, ISmsServiceInterface::SimMessageStatus newStatus,
410     const std::string &pdu, const std::string &smsc)
411 {
412     std::string smscAddr(smsc);
413     if (smsc.length() <= MIN_SMSC_LEN) {
414         smscAddr.clear();
415         smscAddr.insert(0, "00");
416     }
417     return CoreManagerInner::GetInstance().UpdateSmsIcc(
418         slotId_, msgIndex, static_cast<int>(newStatus), const_cast<std::string &>(pdu), smscAddr);
419 }
420 
GetAllSimMessages(std::vector<ShortMessage> & message)421 int32_t SmsMiscManager::GetAllSimMessages(std::vector<ShortMessage> &message)
422 {
423     bool hasSimCard = false;
424     CoreManagerInner::GetInstance().HasSimCard(slotId_, hasSimCard);
425     if (!hasSimCard) {
426         TELEPHONY_LOGE("no sim card");
427         return TELEPHONY_ERR_SLOTID_INVALID;
428     }
429     std::vector<std::string> pdus = CoreManagerInner::GetInstance().ObtainAllSmsOfIcc(slotId_);
430     smsCapacityOfSim_ = static_cast<int32_t>(pdus.size());
431     TELEPHONY_LOGI("smsCapacityOfSim_[%{public}d]", smsCapacityOfSim_);
432     int index = 1;
433     PhoneType type = CoreManagerInner::GetInstance().GetPhoneType(slotId_);
434     std::string specification;
435     if (PhoneType::PHONE_TYPE_IS_GSM == type) {
436         specification = "3gpp";
437     } else if (PhoneType::PHONE_TYPE_IS_CDMA == type) {
438         specification = "3gpp2";
439     } else {
440         return TELEPHONY_ERR_UNKNOWN_NETWORK_TYPE;
441     }
442     for (auto &v : pdus) {
443         v = v.substr(0, v.find("FFFFF"));
444         if (v.compare("00") == 0) {
445             index++;
446             continue;
447         }
448         std::vector<unsigned char> pdu = StringUtils::HexToByteVector(v);
449         ShortMessage item = ShortMessage::CreateIccMessage(pdu, specification, index);
450         if (item.GetIccMessageStatus() != ShortMessage::SMS_SIM_MESSAGE_STATUS_FREE) {
451             message.emplace_back(item);
452         }
453         index++;
454     }
455     return TELEPHONY_ERR_SUCCESS;
456 }
457 
SetSmscAddr(const std::string & scAddr)458 int32_t SmsMiscManager::SetSmscAddr(const std::string &scAddr)
459 {
460     TELEPHONY_LOGI("SmsMiscManager::SetSmscAddr [%{private}s]", scAddr.c_str());
461     std::unique_lock<std::mutex> lock(mutex_);
462     isSuccess_ = false;
463     int32_t condition = conditonVar_++;
464     fairList_.push_back(condition);
465     CoreManagerInner::GetInstance().SetSmscAddr(
466         slotId_, SmsMiscManager::SET_SMSC_ADDR_FINISH, 0, scAddr, shared_from_this());
467     while (!isSuccess_) {
468         TELEPHONY_LOGI("SetSmscAddr::wait(), isSuccess_ = false");
469         if (condVar_.wait_for(lock, std::chrono::seconds(TIME_OUT_SECOND)) == std::cv_status::timeout) {
470             break;
471         }
472     }
473 
474     if (isSuccess_ == false) {
475         return TELEPHONY_ERR_RIL_CMD_FAIL;
476     }
477     return TELEPHONY_ERR_SUCCESS;
478 }
479 
GetSmscAddr(std::u16string & smscAddress)480 int32_t SmsMiscManager::GetSmscAddr(std::u16string &smscAddress)
481 {
482     TELEPHONY_LOGI("SmsMiscManager::GetSmscAddr");
483     std::unique_lock<std::mutex> lock(mutex_);
484     smscAddr_.clear();
485     isSuccess_ = false;
486     int32_t condition = conditonVar_++;
487     fairList_.push_back(condition);
488     CoreManagerInner::GetInstance().GetSmscAddr(slotId_, SmsMiscManager::GET_SMSC_ADDR_FINISH, shared_from_this());
489     while (!isSuccess_) {
490         TELEPHONY_LOGI("GetSmscAddr::wait(), isSuccess_ = false");
491         if (condVar_.wait_for(lock, std::chrono::seconds(TIME_OUT_SECOND)) == std::cv_status::timeout) {
492             break;
493         }
494     }
495     smscAddress = StringUtils::ToUtf16(smscAddr_);
496     return TELEPHONY_ERR_SUCCESS;
497 }
498 
SetDefaultSmsSlotId(int32_t slotId)499 int32_t SmsMiscManager::SetDefaultSmsSlotId(int32_t slotId)
500 {
501     TELEPHONY_LOGI("SetDefaultSmsSlotId slotId = %{public}d", slotId);
502     return CoreManagerInner::GetInstance().SetDefaultSmsSlotId(slotId);
503 }
504 
GetDefaultSmsSlotId()505 int32_t SmsMiscManager::GetDefaultSmsSlotId()
506 {
507     TELEPHONY_LOGI("GetDefaultSmsSlotId");
508     return CoreManagerInner::GetInstance().GetDefaultSmsSlotId();
509 }
510 
GetDefaultSmsSimId(int32_t & simId)511 int32_t SmsMiscManager::GetDefaultSmsSimId(int32_t &simId)
512 {
513     TELEPHONY_LOGI("GetDefaultSmsSimId");
514     return CoreManagerInner::GetInstance().GetDefaultSmsSimId(simId);
515 }
516 } // namespace Telephony
517 } // namespace OHOS
518