ad689e82创建于 2023年12月10日历史提交
/*

 * 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_encode_buffer.h"



#include "mms_decode_buffer.h"

#include "securec.h"

#include "sms_constants_utils.h"

#include "telephony_log_wrapper.h"



namespace OHOS {

namespace Telephony {

using namespace std;

/**

 * @brief DecodeInteger

 * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules

 * Uintvar-integer = 1*5 OCTET

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeUintvar(uint32_t value)

{

    const uint8_t setNotHighestBitZero = 0x80;

    const uint8_t setHighestBitZero = 0x7f;

    const uint8_t shiftUintBits = 7;

    char reversed[8] = {0};

    int len = 1;

    reversed[0] = (char)value & setHighestBitZero;

    value = value >> shiftUintBits;

    while (value > 0) {

        reversed[len] = setNotHighestBitZero | (value & setHighestBitZero);

        len++;

        value = value >> shiftUintBits;

    }



    int j = 0;

    for (j = 0; j < len; j++) {

        if (!WriteByte(reversed[len - j - 1])) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    return true;

}



bool MmsEncodeBuffer::WriteByte(uint8_t value)

{

    if (curPosition_ >= MMS_PDU_MAX_SIZE) {

        TELEPHONY_LOGE("Encode buffer current position invalid.");

        return false;

    }

    pduBuffer_[curPosition_++] = value;

    return true;

}



bool MmsEncodeBuffer::WriteBuffer(MmsEncodeBuffer &buff)

{

    uint32_t len = buff.GetCurPosition();

    if (curPosition_ + len >= MMS_PDU_MAX_SIZE) {

        TELEPHONY_LOGE("Encode buffer current position invalid.");

        return false;

    }

    if (memcpy_s(pduBuffer_.get() + curPosition_, len, buff.pduBuffer_.get(), len) != EOK) {

        TELEPHONY_LOGE("Encode buffer memcpy_s fail.");

        return false;

    }

    curPosition_ += buff.GetCurPosition();

    return true;

}



bool MmsEncodeBuffer::WriteBuffer(std::unique_ptr<char[]> input, uint32_t length)

{

    if (input == nullptr) {

        TELEPHONY_LOGE("Encode buffer input is null.");

        return false;

    }



    if (curPosition_ + length >= MMS_PDU_MAX_SIZE) {

        TELEPHONY_LOGE("Encode buffer current position invalid.");

        return false;

    }

    if (memcpy_s(pduBuffer_.get() + curPosition_, length, input.get(), length) != EOK) {

        TELEPHONY_LOGE("Encode buffer memcpy_s fail.");

        return false;

    }

    curPosition_ += length;

    return true;

}



/**

 * @brief EncodeShortLength

 * wap-230-wsp-20010705-a.pdf   section:8.4.2.2 Length

 * Short-length = <Any octet 0-30>

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeShortLength(uint8_t value)

{

    const uint8_t minShortLength = 30;

    if (value > minShortLength) {

        TELEPHONY_LOGE("Encode buffer value invalid.");

        return false;

    }

    if (!WriteByte(value)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}



/**

 * @brief EncodeShortInteger

 * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules

 * Short-integer = OCTET

 * Integers in range 0-127 shall be encoded as a one octet value with

 * the most significant bit set to one (1xxx xxxx) and with the value

 * in the remaining least significant bits

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeShortInteger(uint8_t value)

{

    const uint8_t setHighestBitOne = 0x80;

    if (!WriteByte(value | setHighestBitOne)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}



/**

 * @brief EncodeOctet

 * wap-230-wsp-20010705-a   section:8.1.2 Variable Length Unsigned Integers

 * octet 8 bits of opaque data

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeOctet(uint8_t value)

{

    if (!WriteByte(value)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}



/**

 * @brief EncodeValueLength

 * wap-230-wsp-20010705-a   section:8.4.2.2 Length

 * value-length = short-length | (Length-quote Length)

 * short-length = <Any octet 0-30>

 * Length-quote = <Octet 31>

 * (Length-quote Length) = Length-quote + Uintvar-length

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeValueLength(uint32_t value)

{

    const uint8_t lengthQuote = 0x1f;

    const uint32_t maxShortLength = 30;



    if (value <= maxShortLength) {

        return EncodeShortLength(value);

    }

    if (!WriteByte(lengthQuote)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    if (!EncodeUintvar(value)) {

        TELEPHONY_LOGE("Encode buffer EncodeUintvar fail.");

        return false;

    }

    return true;

}



bool MmsEncodeBuffer::EncodeInteger(uint32_t value)

{

    const uint32_t maxShortInteger = 127;

    if (value <= maxShortInteger) {

        return EncodeShortInteger(value);

    } else {

        return EncodeLongInteger(value);

    }

    return true;

}



/**

 * @brief EncodeLongInteger

 * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules

 * Long-integer = [Short-length] [Multi-octet-integer]

 * Short-length = 1 byte

 * Multi-octet-integer = <Short-length> bytes

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeLongInteger(uint64_t value)

{

    const uint64_t getLast8Bit = 0x000000FF;

    const uint8_t rightMoveBits = 8;



    uint64_t temp = value;

    uint8_t count = 0;

    uint8_t result[8] = {0};

    while (temp > 0) {

        result[count] = temp & getLast8Bit;

        temp = temp >> rightMoveBits;

        count++;

    }



    if (value == 0) {

        count = 1;

    }

    if (!WriteByte(count)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }



    for (int16_t i = static_cast<int16_t>(count) - 1; i >= 0; i--) {

        if (!WriteByte(result[i])) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    return true;

}



/**

 * @brief EncodeText

 * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules

 * Text-string = [Quote] *TEXT End-of-string

 * Quote = <Octet 127>

 * End-of-string = <Octet 0>

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeText(std::string value)

{

    const uint8_t quoteText = 0x7f;

    if (value.empty()) {

        TELEPHONY_LOGI("Encode buffer value is empty string.");

        return true;

    }



    if (value.at(0) > quoteText) {

        if (!WriteByte(quoteText)) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    for (std::size_t i = 0; i < value.length(); i++) {

        if (!WriteByte(value.at(i))) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    if (!WriteByte(0)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}



/**

 * @brief EncodeQuotedText

 * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules

 * Quoted-string = <Octet 34> *TEXT End-of-string

 * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeQuotedText(std::string value)

{

    if (value.empty()) {

        return true;

    }

    if (!WriteByte('\"')) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    for (std::size_t i = 0; i < value.length(); i++) {

        if (!WriteByte(value.at(i))) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    if (!WriteByte(0)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}



/**

 * @brief EncodeTokenText

 * wap-230-wsp-20010705-a   section:8.4.2.2 Length

 * Token-text = Token End-of-string

 * End-of-string = <Octet 0>

 * @param value

 * @return true

 * @return false

 */

bool MmsEncodeBuffer::EncodeTokenText(std::string value)

{

    if (value.empty()) {

        return true;

    }

    for (std::size_t i = 0; i < value.length(); i++) {

        if (!MmsDecodeBuffer::CharIsToken(value.at(i))) {

            TELEPHONY_LOGE("Encode buffer EncodeTokenText fail.");

            return false;

        }

    }

    for (std::size_t i = 0; i < value.length(); i++) {

        if (!WriteByte(value.at(i))) {

            TELEPHONY_LOGE("Encode buffer WriteByte fail.");

            return false;

        }

    }

    if (!WriteByte(0)) {

        TELEPHONY_LOGE("Encode buffer WriteByte fail.");

        return false;

    }

    return true;

}

} // namespace Telephony

} // namespace OHOS