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