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_send_manager.h"
17
18#include <functional>
19#include <memory.h>
20
21#include "cdma_sms_message.h"
22#include "gsm_sms_message.h"
23#include "gsm_sms_tpdu_codec.h"
24#include "i_sms_service_interface.h"
25#include "sms_hisysevent.h"
26#include "sms_receive_manager.h"
27#include "telephony_errors.h"
28#include "telephony_log_wrapper.h"
29
30namespace OHOS {
31namespace Telephony {
32static constexpr const char *NET_TYPE_GSM_STRING = "3gpp";
33static constexpr const char *NET_TYPE_CDMA_STRING = "3gpp2";
34static constexpr const char *NET_TYPE_UNKNOWN_STRING = "unknown";
35
36using namespace std;
37SmsSendManager::SmsSendManager(int32_t slotId) : slotId_(slotId) {}
38
39SmsSendManager::~SmsSendManager()
40{
41    if (gsmSmsSender_ != nullptr && networkManager_ != nullptr) {
42        if (auto id = gsmSmsSender_->GetNetworkId(); id.has_value()) {
43            networkManager_->NetworkUnregister(id.value());
44        }
45    }
46    if (cdmaSmsSender_ != nullptr && networkManager_ != nullptr) {
47        if (auto id = cdmaSmsSender_->GetNetworkId(); id.has_value()) {
48            networkManager_->NetworkUnregister(id.value());
49        }
50    }
51    if (networkManager_ != nullptr) {
52        networkManager_->UnRegisterHandler();
53    }
54}
55
56void SmsSendManager::Init()
57{
58    gsmSmsSender_ =
59        std::make_shared<GsmSmsSender>(slotId_, bind(&SmsSendManager::RetriedSmsDelivery, this, placeholders::_1));
60    if (gsmSmsSender_ == nullptr) {
61        TELEPHONY_LOGE("failed to create GsmSmsSender");
62        return;
63    }
64    gsmSmsSender_->Init();
65
66    cdmaSmsSender_ =
67        std::make_shared<CdmaSmsSender>(slotId_, bind(&SmsSendManager::RetriedSmsDelivery, this, placeholders::_1));
68    if (cdmaSmsSender_ == nullptr) {
69        TELEPHONY_LOGE("failed to create CdmaSmsSender");
70        return;
71    }
72    cdmaSmsSender_->Init();
73    InitNetworkHandle();
74}
75
76void SmsSendManager::InitNetworkHandle()
77{
78    networkManager_ = std::make_shared<SmsNetworkPolicyManager>(slotId_);
79    if (networkManager_ == nullptr) {
80        TELEPHONY_LOGE("failed to create networkManager");
81        return;
82    }
83    networkManager_->Init();
84    if (auto ret = networkManager_->NetworkRegister([this](bool isImsNetDomain, int32_t voiceServiceState) {
85        this->gsmSmsSender_->SetNetworkState(isImsNetDomain, voiceServiceState);
86    });
87        ret.has_value()) {
88        gsmSmsSender_->SetNetworkId(ret);
89    } else {
90        TELEPHONY_LOGE("gsm failed to register networkManager");
91    }
92    if (auto ret = networkManager_->NetworkRegister([this](bool isImsNetDomain, int32_t voiceServiceState) {
93        this->cdmaSmsSender_->SetNetworkState(isImsNetDomain, voiceServiceState);
94    });
95        ret.has_value()) {
96        cdmaSmsSender_->SetNetworkId(ret);
97    } else {
98        TELEPHONY_LOGE("cdma failed to register networkManager");
99    }
100}
101
102void SmsSendManager::TextBasedSmsDelivery(const string &desAddr, const string &scAddr, const string &text,
103    const sptr<ISendShortMessageCallback> &sendCallback,
104    const sptr<IDeliveryShortMessageCallback> &deliveryCallback, uint16_t dataBaseId, bool isMmsApp)
105{
106    if (desAddr.empty() || text.empty()) {
107        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
108        TELEPHONY_LOGE("TextBasedSmsDelivery::param Set Error.");
109        return;
110    }
111    if (networkManager_ == nullptr) {
112        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
113        TELEPHONY_LOGE("TextBasedSmsDelivery::networkManager nullptr error.");
114        return;
115    }
116    if (gsmSmsSender_ == nullptr || cdmaSmsSender_ == nullptr) {
117        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
118        TELEPHONY_LOGE("gsmSmsSender or cdmaSmsSender nullptr error.");
119        return;
120    }
121
122    NetWorkType netWorkType = networkManager_->GetNetWorkType();
123    TELEPHONY_LOGI("netWorkType = %{public}d.", netWorkType);
124    if (netWorkType == NetWorkType::NET_TYPE_GSM) {
125        gsmSmsSender_->RegisterImsHandler();
126        gsmSmsSender_->TextBasedSmsDelivery(desAddr, scAddr, text, sendCallback, deliveryCallback,
127            dataBaseId, isMmsApp);
128    } else if (netWorkType == NetWorkType::NET_TYPE_CDMA) {
129        cdmaSmsSender_->RegisterImsHandler();
130        cdmaSmsSender_->TextBasedSmsDelivery(desAddr, scAddr, text, sendCallback, deliveryCallback,
131            dataBaseId, isMmsApp);
132    } else {
133        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
134        SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
135            SmsMmsErrorCode::SMS_ERROR_UNKNOWN_NETWORK_TYPE, "text sms network unknown send error");
136        TELEPHONY_LOGI("network unknown send error.");
137    }
138}
139
140void SmsSendManager::DataBasedSmsDelivery(const string &desAddr, const string &scAddr, uint16_t port,
141    const uint8_t *data, uint16_t dataLen, const sptr<ISendShortMessageCallback> &sendCallback,
142    const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
143{
144    if (desAddr.empty() || data == nullptr) {
145        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
146        TELEPHONY_LOGE("DataBasedSmsDelivery::param Set Error.");
147        return;
148    }
149    if (networkManager_ == nullptr) {
150        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
151        TELEPHONY_LOGE("DataBasedSmsDelivery::networkManager nullptr error.");
152        return;
153    }
154    if (gsmSmsSender_ == nullptr || cdmaSmsSender_ == nullptr) {
155        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
156        TELEPHONY_LOGE("gsmSmsSender or cdmaSmsSender nullptr error.");
157        return;
158    }
159
160    NetWorkType netWorkType = networkManager_->GetNetWorkType();
161    if (netWorkType == NetWorkType::NET_TYPE_GSM) {
162        gsmSmsSender_->RegisterImsHandler();
163        gsmSmsSender_->DataBasedSmsDelivery(desAddr, scAddr, port, data, dataLen, sendCallback, deliveryCallback);
164    } else if (netWorkType == NetWorkType::NET_TYPE_CDMA) {
165        cdmaSmsSender_->RegisterImsHandler();
166        cdmaSmsSender_->DataBasedSmsDelivery(desAddr, scAddr, port, data, dataLen, sendCallback, deliveryCallback);
167    } else {
168        SmsSender::SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
169        SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
170            SmsMmsErrorCode::SMS_ERROR_UNKNOWN_NETWORK_TYPE, "data sms network unknown send error");
171        TELEPHONY_LOGI("network unknown send error.");
172    }
173}
174
175void SmsSendManager::RetriedSmsDelivery(const shared_ptr<SmsSendIndexer> smsIndexer)
176{
177    if (smsIndexer == nullptr) {
178        TELEPHONY_LOGI("RetriedSmsDelivery::smsIndexer is nullptr error.");
179        return;
180    }
181    if (gsmSmsSender_ == nullptr || cdmaSmsSender_ == nullptr || networkManager_ == nullptr) {
182        TELEPHONY_LOGE("Sender or network nullptr error.");
183        return;
184    }
185
186    NetWorkType oldNetWorkType = smsIndexer->GetNetWorkType();
187    NetWorkType newNetWorkType = networkManager_->GetNetWorkType();
188    if (oldNetWorkType != newNetWorkType) {
189        smsIndexer->SetNetWorkType(newNetWorkType);
190        shared_ptr<SmsSendIndexer> indexer = smsIndexer;
191        switch (newNetWorkType) {
192            case NetWorkType::NET_TYPE_CDMA:
193                if (smsIndexer->GetIsText()) {
194                    cdmaSmsSender_->ResendTextDelivery(indexer);
195                } else {
196                    cdmaSmsSender_->ResendDataDelivery(indexer);
197                }
198                break;
199            case NetWorkType::NET_TYPE_GSM:
200                if (smsIndexer->GetIsText()) {
201                    gsmSmsSender_->ResendTextDelivery(indexer);
202                } else {
203                    gsmSmsSender_->ResendDataDelivery(indexer);
204                }
205                break;
206            default:
207                SmsSender::SendResultCallBack(
208                    smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
209                TELEPHONY_LOGI("network unknown send error.");
210                break;
211        }
212        return;
213    }
214
215    if (newNetWorkType == NetWorkType::NET_TYPE_GSM) {
216        gsmSmsSender_->SendSmsToRil(smsIndexer);
217    } else if (newNetWorkType == NetWorkType::NET_TYPE_CDMA) {
218        cdmaSmsSender_->SendSmsToRil(smsIndexer);
219    } else {
220        SmsSender::SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
221        TELEPHONY_LOGI("Network Unknown.");
222    }
223}
224
225int32_t SmsSendManager::SplitMessage(const std::string &message, std::vector<std::u16string> &splitMessage)
226{
227    if (networkManager_ == nullptr) {
228        TELEPHONY_LOGE("SmsSendManager::SplitMessage networkManager nullptr Error.");
229        return TELEPHONY_ERR_LOCAL_PTR_NULL;
230    }
231
232    DataCodingScheme codingType;
233    std::vector<struct SplitInfo> cellsInfos;
234    NetWorkType netWorkType = networkManager_->GetNetWorkType();
235    std::string addr;
236    switch (netWorkType) {
237        case NetWorkType::NET_TYPE_CDMA: {
238            GsmSmsMessage gsmSmsMessage;
239            gsmSmsMessage.SetSmsCodingNationalType(SmsSender::GetSmsCodingNationalType(slotId_));
240            gsmSmsMessage.SplitMessage(cellsInfos, message, false, codingType, false, addr);
241            break;
242        }
243        case NetWorkType::NET_TYPE_GSM: {
244            CdmaSmsMessage cdmaSmsMessage;
245            cdmaSmsMessage.SplitMessage(cellsInfos, message, false, codingType, false, addr);
246            break;
247        }
248        default:
249            TELEPHONY_LOGE("netWorkType is NET_TYPE_UNKNOWN");
250            break;
251    }
252
253    for (auto &item : cellsInfos) {
254        splitMessage.emplace_back(StringUtils::ToUtf16(item.text));
255    }
256    return TELEPHONY_ERR_SUCCESS;
257}
258
259int32_t SmsSendManager::GetSmsSegmentsInfo(const std::string &message, bool force7BitCode, LengthInfo &lenInfo)
260{
261    if (networkManager_ == nullptr) {
262        TELEPHONY_LOGE("GetSmsSegmentsInfo networkManager_ Nullptr Error.");
263        return TELEPHONY_ERR_LOCAL_PTR_NULL;
264    }
265    NetWorkType netWorkType = networkManager_->GetNetWorkType();
266    switch (netWorkType) {
267        case NetWorkType::NET_TYPE_CDMA: {
268            CdmaSmsMessage cdmaSmsMessage;
269            return cdmaSmsMessage.GetSmsSegmentsInfo(message, force7BitCode, lenInfo);
270        }
271        case NetWorkType::NET_TYPE_GSM: {
272            GsmSmsMessage gsmSmsMessage;
273            return gsmSmsMessage.GetSmsSegmentsInfo(message, force7BitCode, lenInfo);
274        }
275        default:
276            TELEPHONY_LOGE("netWorkType is NET_TYPE_UNKNOWN");
277            break;
278    }
279    return TELEPHONY_ERR_UNKNOWN_NETWORK_TYPE;
280}
281
282std::shared_ptr<SmsSender> SmsSendManager::GetCdmaSmsSender() const
283{
284    return cdmaSmsSender_;
285}
286
287int32_t SmsSendManager::IsImsSmsSupported(int32_t slotId, bool &isSupported)
288{
289    if (networkManager_ == nullptr) {
290        TELEPHONY_LOGE("networkManager is nullptr error.");
291        return TELEPHONY_ERR_LOCAL_PTR_NULL;
292    }
293
294    if (gsmSmsSender_ == nullptr || cdmaSmsSender_ == nullptr || networkManager_ == nullptr) {
295        TELEPHONY_LOGE("Sender or network nullptr error.");
296        return TELEPHONY_ERR_LOCAL_PTR_NULL;
297    }
298
299    NetWorkType newNetWorkType = networkManager_->GetNetWorkType();
300    switch (newNetWorkType) {
301        case NetWorkType::NET_TYPE_GSM:
302            return gsmSmsSender_->IsImsSmsSupported(slotId, isSupported);
303        case NetWorkType::NET_TYPE_CDMA:
304            return cdmaSmsSender_->IsImsSmsSupported(slotId, isSupported);
305        default:
306            TELEPHONY_LOGE("network unknown send error.");
307            return TELEPHONY_ERR_UNKNOWN_NETWORK_TYPE;
308    }
309}
310
311bool SmsSendManager::SetImsSmsConfig(int32_t slotId, int32_t enable)
312{
313    bool result = false;
314    if (gsmSmsSender_ == nullptr || cdmaSmsSender_ == nullptr || networkManager_ == nullptr) {
315        TELEPHONY_LOGE("Sender or network nullptr error.");
316        return result;
317    }
318    NetWorkType newNetWorkType = networkManager_->GetNetWorkType();
319
320    switch (newNetWorkType) {
321        case NetWorkType::NET_TYPE_GSM:
322            result = gsmSmsSender_->SetImsSmsConfig(slotId, enable);
323            break;
324        case NetWorkType::NET_TYPE_CDMA:
325            result = cdmaSmsSender_->SetImsSmsConfig(slotId, enable);
326            break;
327        default:
328            TELEPHONY_LOGE("network unknown send error.");
329            break;
330    }
331    return result;
332}
333
334int32_t SmsSendManager::GetImsShortMessageFormat(std::u16string &format)
335{
336    format = StringUtils::ToUtf16(NET_TYPE_UNKNOWN_STRING);
337    if (networkManager_ == nullptr) {
338        TELEPHONY_LOGE("networkManager is nullptr error.");
339        return TELEPHONY_ERR_LOCAL_PTR_NULL;
340    }
341    switch (networkManager_->GetNetWorkType()) {
342        case NetWorkType::NET_TYPE_GSM:
343            format = StringUtils::ToUtf16(NET_TYPE_GSM_STRING);
344            break;
345        case NetWorkType::NET_TYPE_CDMA:
346            format = StringUtils::ToUtf16(NET_TYPE_CDMA_STRING);
347            break;
348        default:
349            break;
350    }
351    return TELEPHONY_ERR_SUCCESS;
352}
353
354void SmsSendManager::OnRilAdapterHostDied()
355{
356    if (gsmSmsSender_ != nullptr) {
357        gsmSmsSender_->OnRilAdapterHostDied();
358    }
359    if (cdmaSmsSender_ != nullptr) {
360        cdmaSmsSender_->OnRilAdapterHostDied();
361    }
362}
363} // namespace Telephony
364} // namespace OHOS
365