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