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