12ee81decSopenharmony_ci/* 22ee81decSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 32ee81decSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42ee81decSopenharmony_ci * you may not use this file except in compliance with the License. 52ee81decSopenharmony_ci * You may obtain a copy of the License at 62ee81decSopenharmony_ci * 72ee81decSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82ee81decSopenharmony_ci * 92ee81decSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102ee81decSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112ee81decSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122ee81decSopenharmony_ci * See the License for the specific language governing permissions and 132ee81decSopenharmony_ci * limitations under the License. 142ee81decSopenharmony_ci */ 152ee81decSopenharmony_ci 162ee81decSopenharmony_ci#include "utils_tlv.h" 172ee81decSopenharmony_ci 182ee81decSopenharmony_ci#include <stddef.h> 192ee81decSopenharmony_ci 202ee81decSopenharmony_ci#include "securec.h" 212ee81decSopenharmony_ci 222ee81decSopenharmony_ci#define TLV_TAG_LEN sizeof(uint16_t) 232ee81decSopenharmony_ci#define TLV_LENGTH_LEN sizeof(uint16_t) 242ee81decSopenharmony_ci#define TLV_TLV_HEAD_LEN (TLV_TAG_LEN + TLV_LENGTH_LEN) 252ee81decSopenharmony_ci 262ee81decSopenharmony_cistatic uint8_t *GetNextTlv(const uint8_t *buffer) 272ee81decSopenharmony_ci{ 282ee81decSopenharmony_ci return (uint8_t *)buffer + ((TlvCommon *)buffer)->len + TLV_TLV_HEAD_LEN; 292ee81decSopenharmony_ci} 302ee81decSopenharmony_ci 312ee81decSopenharmony_cistatic uint8_t *ParseTlv(const uint8_t *buffer, TlvCommon *tlv, const uint8_t *boundary, uint32_t *retCode) 322ee81decSopenharmony_ci{ 332ee81decSopenharmony_ci if (buffer + TLV_TLV_HEAD_LEN > boundary) { 342ee81decSopenharmony_ci *retCode = TLV_ERR_PARSE_PAYLOAD_ERR; 352ee81decSopenharmony_ci return NULL; 362ee81decSopenharmony_ci } 372ee81decSopenharmony_ci if (GetNextTlv(buffer) > boundary) { 382ee81decSopenharmony_ci *retCode = TLV_ERR_PARSE_PAYLOAD_ERR; 392ee81decSopenharmony_ci return NULL; 402ee81decSopenharmony_ci } 412ee81decSopenharmony_ci tlv->tag = ((TlvCommon *)buffer)->tag; 422ee81decSopenharmony_ci tlv->len = ((TlvCommon *)buffer)->len; 432ee81decSopenharmony_ci tlv->value = (uint8_t *)buffer + TLV_TLV_HEAD_LEN; 442ee81decSopenharmony_ci *retCode = TLV_OK; 452ee81decSopenharmony_ci return GetNextTlv(buffer); 462ee81decSopenharmony_ci} 472ee81decSopenharmony_ci 482ee81decSopenharmony_cistatic uint8_t *AppendTlv(uint8_t *buffer, const TlvCommon *tlv, const uint8_t *boundary, uint32_t *retCode) 492ee81decSopenharmony_ci{ 502ee81decSopenharmony_ci if (buffer > boundary) { 512ee81decSopenharmony_ci *retCode = TLV_ERR_BUFF_NO_ENOUGH; 522ee81decSopenharmony_ci return NULL; 532ee81decSopenharmony_ci } 542ee81decSopenharmony_ci if (buffer + ((TlvCommon *)tlv)->len + TLV_TLV_HEAD_LEN > boundary) { 552ee81decSopenharmony_ci *retCode = TLV_ERR_BUFF_NO_ENOUGH; 562ee81decSopenharmony_ci return NULL; 572ee81decSopenharmony_ci } 582ee81decSopenharmony_ci ((TlvCommon *)buffer)->tag = tlv->tag; 592ee81decSopenharmony_ci ((TlvCommon *)buffer)->len = tlv->len; 602ee81decSopenharmony_ci if (tlv->len != 0 && tlv->value != NULL) { 612ee81decSopenharmony_ci if (memcpy_s(buffer + TLV_TLV_HEAD_LEN, boundary - buffer - TLV_TLV_HEAD_LEN, tlv->value, tlv->len) != EOK) { 622ee81decSopenharmony_ci *retCode = TLV_ERR_BUFF_NO_ENOUGH; 632ee81decSopenharmony_ci return NULL; 642ee81decSopenharmony_ci } 652ee81decSopenharmony_ci } 662ee81decSopenharmony_ci *retCode = TLV_OK; 672ee81decSopenharmony_ci return GetNextTlv(buffer); 682ee81decSopenharmony_ci} 692ee81decSopenharmony_ci 702ee81decSopenharmony_ciuint32_t Serialize(const TlvCommon *tlv, uint32_t tlvCount, uint8_t *buff, uint32_t maxBuffSize, uint32_t *buffSize) 712ee81decSopenharmony_ci{ 722ee81decSopenharmony_ci if (tlv == NULL || buff == NULL || buffSize == NULL) { 732ee81decSopenharmony_ci return TLV_ERR_INVALID_PARA; 742ee81decSopenharmony_ci } 752ee81decSopenharmony_ci 762ee81decSopenharmony_ci uint8_t *curr = buff; 772ee81decSopenharmony_ci uint8_t *boundary = buff + maxBuffSize; 782ee81decSopenharmony_ci 792ee81decSopenharmony_ci uint32_t retCode = TLV_OK; 802ee81decSopenharmony_ci for (uint32_t index = 0; index < tlvCount; index++) { 812ee81decSopenharmony_ci curr = AppendTlv(curr, &tlv[index], boundary, &retCode); 822ee81decSopenharmony_ci if (curr == NULL || retCode != TLV_OK) { 832ee81decSopenharmony_ci return retCode; 842ee81decSopenharmony_ci } 852ee81decSopenharmony_ci } 862ee81decSopenharmony_ci *buffSize = curr - buff; 872ee81decSopenharmony_ci return TLV_OK; 882ee81decSopenharmony_ci} 892ee81decSopenharmony_ci 902ee81decSopenharmony_ciuint32_t Deserialize(const uint8_t *buff, uint32_t buffSize, TlvCommon *tlv, uint32_t maxTlvCount, uint32_t *tlvCount) 912ee81decSopenharmony_ci{ 922ee81decSopenharmony_ci if (buff == NULL || tlv == NULL || tlvCount == NULL) { 932ee81decSopenharmony_ci return TLV_ERR_INVALID_PARA; 942ee81decSopenharmony_ci } 952ee81decSopenharmony_ci 962ee81decSopenharmony_ci uint8_t *msg = (uint8_t *)buff; 972ee81decSopenharmony_ci const uint8_t *boundary = buff + buffSize; 982ee81decSopenharmony_ci uint32_t index = 0; 992ee81decSopenharmony_ci 1002ee81decSopenharmony_ci while (msg != NULL) { 1012ee81decSopenharmony_ci if (index >= maxTlvCount) { 1022ee81decSopenharmony_ci return TLV_ERR_BUFF_NO_ENOUGH; 1032ee81decSopenharmony_ci } 1042ee81decSopenharmony_ci uint32_t retCode = TLV_OK; 1052ee81decSopenharmony_ci msg = ParseTlv(msg, &tlv[index], boundary, &retCode); 1062ee81decSopenharmony_ci if (msg == NULL || retCode != TLV_OK) { 1072ee81decSopenharmony_ci break; 1082ee81decSopenharmony_ci } 1092ee81decSopenharmony_ci index++; 1102ee81decSopenharmony_ci } 1112ee81decSopenharmony_ci 1122ee81decSopenharmony_ci *tlvCount = index; 1132ee81decSopenharmony_ci return TLV_OK; 1142ee81decSopenharmony_ci} 115