* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mms_buffer.h"
#include "securec.h"
#include "sms_constants_utils.h"
#include "telephony_log_wrapper.h"
namespace OHOS {
namespace Telephony {
static constexpr const char *APP_SAND_ABSOLUTE_DIR = "/data/app/";
static constexpr const char *APP_SAND_RELATIVE_DIR = "/data/storage/";
MmsBuffer::MmsBuffer()
{
pduBuffer_ = std::make_unique<char[]>(MMS_PDU_MAX_SIZE);
if (pduBuffer_ == nullptr) {
TELEPHONY_LOGE("MmsBuffer make_unique create pduBuffer error");
totolLength_ = 0;
return;
}
totolLength_ = MMS_PDU_MAX_SIZE;
}
MmsBuffer::~MmsBuffer()
{
if (pduBuffer_ != nullptr) {
pduBuffer_.reset();
}
}
std::unique_ptr<char[]> MmsBuffer::ReadDataBuffer(uint32_t desLen)
{
return ReadDataBuffer(curPosition_, desLen);
}
std::unique_ptr<char[]> MmsBuffer::ReadDataBuffer(uint32_t offset, uint32_t desLen)
{
if (desLen > MMS_PDU_MAX_SIZE) {
TELEPHONY_LOGE("desLen over size error");
return nullptr;
}
std::unique_ptr<char[]> result = std::make_unique<char[]>(desLen);
if (result == nullptr) {
TELEPHONY_LOGE("make unique result nullptr Error .");
return nullptr;
}
if (offset + desLen > totolLength_) {
TELEPHONY_LOGE("read over buffer error .");
return nullptr;
}
if (memcpy_s(result.get(), desLen, &pduBuffer_[offset], desLen) != EOK) {
TELEPHONY_LOGE("read memcpy_s error .");
return nullptr;
}
return result;
}
bool MmsBuffer::WriteDataBuffer(std::unique_ptr<char[]> inBuff, uint32_t len)
{
if (inBuff == nullptr) {
TELEPHONY_LOGE("InBuffer nullptr Error .");
return false;
}
if (len <= 0 || len > MMS_PDU_MAX_SIZE) {
TELEPHONY_LOGE("Data Len Over Error .");
return false;
}
if (pduBuffer_) {
pduBuffer_.reset();
}
pduBuffer_ = std::make_unique<char[]>(len);
if (!pduBuffer_) {
TELEPHONY_LOGE("make unique pduBuffer nullptr Error .");
return false;
}
if (memcpy_s(pduBuffer_.get(), len, inBuff.get(), len) != EOK) {
TELEPHONY_LOGE("MemCpy_s Error .");
return false;
}
totolLength_ = len;
return true;
}
bool MmsBuffer::WriteBufferFromFile(std::string &strPathName)
{
FILE *pFile = nullptr;
char realPath[PATH_MAX] = {0};
uint32_t fileLen = 0;
if (strPathName.empty() || realpath(strPathName.c_str(), realPath) == NULL) {
TELEPHONY_LOGE("path or realPath is NULL");
return false;
}
std::string filePath = realPath;
std::string absDir = APP_SAND_ABSOLUTE_DIR;
std::string relDir = APP_SAND_RELATIVE_DIR;
if ((absDir.compare(filePath.substr(0, absDir.size())) != 0) &&
(relDir.compare(filePath.substr(0, relDir.size())) != 0)) {
TELEPHONY_LOGE("filePath no app sand box.");
return false;
}
pFile = fopen(realPath, "rb");
if (pFile == nullptr) {
TELEPHONY_LOGE("Open File Error");
return false;
}
if (fseek(pFile, 0, SEEK_END) != 0) {
(void)fclose(pFile);
return false;
}
fileLen = (uint32_t)ftell(pFile);
if (fileLen == 0) {
(void)fclose(pFile);
totolLength_ = 0;
TELEPHONY_LOGE("Mmms File Is Empty.");
return true;
}
if (fileLen < 0 || fileLen > MMS_PDU_MAX_SIZE) {
(void)fclose(pFile);
TELEPHONY_LOGE("Mms Over Long Error .");
return false;
}
if (!WriteBufferFromFile(pFile, fileLen)) {
(void)fclose(pFile);
return false;
}
(void)fclose(pFile);
return true;
}
bool MmsBuffer::WriteBufferFromFile(FILE *pFile, uint32_t fileLen)
{
if (pduBuffer_) {
pduBuffer_.reset();
}
pduBuffer_ = std::make_unique<char[]>(fileLen);
if (!pduBuffer_) {
TELEPHONY_LOGE("make unique pduBuffer nullptr Error .");
return false;
}
if (fseek(pFile, 0, SEEK_SET) != 0) {
return false;
}
totolLength_ = fread(pduBuffer_.get(), 1, fileLen, pFile);
return true;
}
uint32_t MmsBuffer::GetCurPosition() const
{
return curPosition_;
}
uint32_t MmsBuffer::GetSize() const
{
return totolLength_;
}
}
}