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