1/* 2 * Copyright (C) 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 "mms_persist_helper.h" 17 18#include "gsm_pdu_hex_value.h" 19#include "telephony_log_wrapper.h" 20 21namespace OHOS { 22namespace Telephony { 23const std::string SMS_PROFILE_URI = "datashare:///com.ohos.smsmmsability"; 24const std::string SMS_PROFILE_MMS_PDU_URI = "datashare:///com.ohos.smsmmsability/sms_mms/mms_pdu"; 25static constexpr const char *PDU_CONTENT = "pdu_content"; 26static constexpr const char *ID = "id"; 27static constexpr uint8_t SLIDE_STEP = 2; 28static constexpr uint32_t SPLIT_PDU_LENGTH = 195 * 1024; 29 30std::shared_ptr<DataShare::DataShareHelper> MmsPersistHelper::CreateSmsHelper() 31{ 32 if (mmsPduDataShareHelper_ == nullptr) { 33 mmsPduDataShareHelper_ = CreateDataAHelper(TELEPHONY_SMS_MMS_SYS_ABILITY_ID, SMS_PROFILE_URI); 34 } 35 return mmsPduDataShareHelper_; 36} 37 38std::shared_ptr<DataShare::DataShareHelper> MmsPersistHelper::CreateDataAHelper( 39 int32_t systemAbilityId, const std::string &dataAbilityUri) const 40{ 41 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 42 if (saManager == nullptr) { 43 TELEPHONY_LOGE("Get system ability mgr failed"); 44 return nullptr; 45 } 46 auto remoteObj = saManager->GetSystemAbility(systemAbilityId); 47 if (remoteObj == nullptr) { 48 TELEPHONY_LOGE("GetSystemAbility Service Failed"); 49 return nullptr; 50 } 51 return DataShare::DataShareHelper::Creator(remoteObj, dataAbilityUri); 52} 53 54void MmsPersistHelper::DeleteMmsPdu(const std::string &dbUrl) 55{ 56 std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper(); 57 if (helper == nullptr) { 58 TELEPHONY_LOGE("helper is nullptr"); 59 return; 60 } 61 62 Uri uri(SMS_PROFILE_MMS_PDU_URI); 63 DataShare::DataSharePredicates predicates; 64 std::vector<std::string> dbUrls = SplitUrl(dbUrl); 65 int32_t result = -1; 66 for (std::string url : dbUrls) { 67 predicates.EqualTo("id", url); 68 result = helper->Delete(uri, predicates); 69 if (result < 0) { 70 TELEPHONY_LOGE("delete mms pdu fail"); 71 helper->Release(); 72 return; 73 } 74 } 75 helper->Release(); 76 mmsPdu_ = ""; 77 TELEPHONY_LOGI("result:%{public}d", result); 78} 79 80bool MmsPersistHelper::InsertMmsPdu(const std::string &mmsPdu, std::string &dbUrl) 81{ 82 std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper(); 83 if (helper == nullptr) { 84 TELEPHONY_LOGE("helper is nullptr"); 85 return false; 86 } 87 Uri uri(SMS_PROFILE_MMS_PDU_URI); 88 89 std::vector<std::string> mmsPdus = SplitPdu(mmsPdu); 90 for (std::string mmsPdu : mmsPdus) { 91 DataShare::DataShareValuesBucket bucket; 92 bucket.Put(PDU_CONTENT, mmsPdu); 93 int32_t result = helper->Insert(uri, bucket); 94 if (result < 0) { 95 TELEPHONY_LOGE("mms pdu insert fail"); 96 return false; 97 } 98 dbUrl += std::to_string(result) + ','; 99 } 100 helper->Release(); 101 TELEPHONY_LOGI("download mms insert db, dbUrl:%{public}s", dbUrl.c_str()); 102 return dbUrl.empty() ? false : true; 103} 104 105std::vector<std::string> MmsPersistHelper::SplitPdu(const std::string &mmsPdu) 106{ 107 std::string targetMmsPdu; 108 for (size_t i = 0; i < mmsPdu.size(); i++) { 109 targetMmsPdu += static_cast<char>((mmsPdu[i] & HEX_VALUE_0F) | HEX_VALUE_F0); 110 targetMmsPdu += static_cast<char>((mmsPdu[i] & HEX_VALUE_F0) | HEX_VALUE_0F); 111 } 112 113 std::vector<std::string> mmsPdus; 114 for (uint32_t locate = 0; locate * SPLIT_PDU_LENGTH < targetMmsPdu.size(); locate++) { 115 std::string mmsPduData; 116 if ((locate + 1) * SPLIT_PDU_LENGTH < targetMmsPdu.size()) { 117 mmsPduData = targetMmsPdu.substr(locate * SPLIT_PDU_LENGTH, SPLIT_PDU_LENGTH); 118 mmsPdus.push_back(mmsPduData); 119 } else { 120 mmsPduData = targetMmsPdu.substr(locate * SPLIT_PDU_LENGTH); 121 mmsPdus.push_back(mmsPduData); 122 break; 123 } 124 } 125 TELEPHONY_LOGI("pduLen:%{public}zu,target:%{public}zu,pageLen:%{public}zu", mmsPdu.size(), targetMmsPdu.size(), 126 mmsPdus.size()); 127 return mmsPdus; 128} 129 130std::string MmsPersistHelper::GetMmsPdu(const std::string &dbUrl) 131{ 132 if (!QueryMmsPdu(dbUrl)) { 133 return ""; 134 } 135 return mmsPdu_; 136} 137 138void MmsPersistHelper::SetMmsPdu(const std::string &mmsPdu) 139{ 140 mmsPdu_ = mmsPdu; 141} 142 143std::vector<std::string> MmsPersistHelper::SplitUrl(std::string url) 144{ 145 std::vector<std::string> dbUrls; 146 while (url.size() > 0) { 147 size_t locate = url.find_first_of(','); 148 if (locate == 0 || locate == std::string::npos) { 149 break; 150 } 151 dbUrls.push_back(url.substr(0, locate)); 152 url = url.substr(locate + 1); 153 } 154 return dbUrls; 155} 156 157bool MmsPersistHelper::QueryMmsPdu(const std::string &dbUrl) 158{ 159 std::shared_ptr<DataShare::DataShareHelper> helper = CreateSmsHelper(); 160 if (helper == nullptr) { 161 TELEPHONY_LOGE("helper is nullptr"); 162 return false; 163 } 164 165 std::vector<std::string> dbUrls = SplitUrl(dbUrl); 166 std::string mmsPdu; 167 for (std::string url : dbUrls) { 168 Uri uri(SMS_PROFILE_MMS_PDU_URI); 169 std::vector<std::string> colume; 170 DataShare::DataSharePredicates predicates; 171 predicates.EqualTo(ID, url); 172 auto resultSet = helper->Query(uri, predicates, colume); 173 if (resultSet == nullptr) { 174 TELEPHONY_LOGE("Query Result Set nullptr Failed."); 175 helper->Release(); 176 return false; 177 } 178 int count = 0; 179 resultSet->GetRowCount(count); 180 if (count <= 0) { 181 TELEPHONY_LOGE("MmsPdu count: %{public}d error", count); 182 resultSet->Close(); 183 helper->Release(); 184 return false; 185 } 186 int columnIndex; 187 std::vector<uint8_t> blobValue; 188 resultSet->GoToFirstRow(); 189 resultSet->GetColumnIndex(PDU_CONTENT, columnIndex); 190 resultSet->GetBlob(columnIndex, blobValue); 191 blobValue.pop_back(); 192 for (size_t i = 0; i + 1 < blobValue.size(); i = i + SLIDE_STEP) { 193 char pduChar = (blobValue[i] & HEX_VALUE_0F) | (blobValue[i + 1] & HEX_VALUE_F0); 194 mmsPdu += static_cast<char>(pduChar); 195 } 196 TELEPHONY_LOGI("blob len:%{public}zu, ", blobValue.size()); 197 resultSet->Close(); 198 } 199 helper->Release(); 200 TELEPHONY_LOGI("mmsPdu len:%{public}zu", mmsPdu.size()); 201 SetMmsPdu(mmsPdu); 202 return true; 203} 204} // namespace Telephony 205} // namespace OHOS