1 /*
2 * Copyright (c) 2020 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 "dmslite_tlv_common.h"
17
18 #include "dmslite_inner_common.h"
19 #include "dmslite_utils.h"
20
21 #include <stdbool.h>
22 #include <string.h>
23
24 #include "securec.h"
25
26 #include "dmslite_log.h"
27
GetNodeByType(uint8_t nodeType,const TlvNode * tlvHead)28 TlvNode* GetNodeByType(uint8_t nodeType, const TlvNode *tlvHead)
29 {
30 TlvNode* tlvNode = (TlvNode *)tlvHead;
31 while (tlvNode != NULL) {
32 if (tlvNode->type == nodeType) {
33 return tlvNode;
34 }
35 tlvNode = tlvNode->next;
36 }
37 return NULL;
38 }
39
ConvertIntDataBig2Little(const uint8_t * dataIn,uint8_t typeSize)40 static uint64_t ConvertIntDataBig2Little(const uint8_t *dataIn, uint8_t typeSize)
41 {
42 uint64_t dataOut = 0;
43 switch (typeSize) {
44 case INT_16:
45 Convert16DataBig2Little(dataIn, (uint16_t*)&dataOut);
46 break;
47 case INT_32:
48 Convert32DataBig2Little(dataIn, (uint32_t*)&dataOut);
49 break;
50 case INT_64:
51 Convert64DataBig2Little(dataIn, (uint64_t*)&dataOut);
52 break;
53 default:
54 break;
55 }
56 return dataOut;
57 }
58
ConvertIntByDefault(const uint8_t * dataIn,uint8_t typeSize)59 static uint64_t ConvertIntByDefault(const uint8_t *dataIn, uint8_t typeSize)
60 {
61 switch (typeSize) {
62 case INT_8:
63 return *((int8_t*)dataIn);
64 case INT_16:
65 return *((int16_t*)dataIn);
66 case INT_32:
67 return *((int32_t*)dataIn);
68 case INT_64:
69 return *((int64_t*)dataIn);
70 default:
71 return 0;
72 }
73 }
74
UnMarshallInt(const TlvNode * tlvHead,uint8_t nodeType,uint8_t fieldSize)75 static uint64_t UnMarshallInt(const TlvNode *tlvHead, uint8_t nodeType, uint8_t fieldSize)
76 {
77 if (tlvHead == NULL) {
78 return 0;
79 }
80 TlvNode* tlvNode = GetNodeByType(nodeType, tlvHead);
81 if (tlvNode == NULL || tlvNode->value == NULL) {
82 HILOGE("[Bad node type %hhu]", nodeType);
83 return 0;
84 }
85 if (fieldSize != tlvNode->length) {
86 HILOGE("[Mismatched fieldSize=%hhu while nodeLength=%hu]", fieldSize, tlvNode->length);
87 return 0;
88 }
89 return IsBigEndian() ? ConvertIntByDefault(tlvNode->value, fieldSize)
90 : ConvertIntDataBig2Little(tlvNode->value, fieldSize);
91 }
92
UnMarshallUint8(const TlvNode * tlvHead,uint8_t nodeType)93 uint8_t UnMarshallUint8(const TlvNode *tlvHead, uint8_t nodeType)
94 {
95 return UnMarshallInt(tlvHead, nodeType, sizeof(uint8_t));
96 }
97
UnMarshallUint16(const TlvNode * tlvHead,uint8_t nodeType)98 uint16_t UnMarshallUint16(const TlvNode *tlvHead, uint8_t nodeType)
99 {
100 return UnMarshallInt(tlvHead, nodeType, sizeof(uint16_t));
101 }
102
UnMarshallUint32(const TlvNode * tlvHead,uint8_t nodeType)103 uint32_t UnMarshallUint32(const TlvNode *tlvHead, uint8_t nodeType)
104 {
105 return UnMarshallInt(tlvHead, nodeType, sizeof(uint32_t));
106 }
107
UnMarshallUint64(const TlvNode * tlvHead,uint8_t nodeType)108 uint64_t UnMarshallUint64(const TlvNode *tlvHead, uint8_t nodeType)
109 {
110 return UnMarshallInt(tlvHead, nodeType, sizeof(uint64_t));
111 }
112
UnMarshallInt8(const TlvNode * tlvHead,uint8_t nodeType)113 int8_t UnMarshallInt8(const TlvNode *tlvHead, uint8_t nodeType)
114 {
115 return UnMarshallInt(tlvHead, nodeType, sizeof(int8_t));
116 }
117
UnMarshallInt16(const TlvNode * tlvHead,uint8_t nodeType)118 int16_t UnMarshallInt16(const TlvNode *tlvHead, uint8_t nodeType)
119 {
120 return UnMarshallInt(tlvHead, nodeType, sizeof(int16_t));
121 }
122
UnMarshallInt32(const TlvNode * tlvHead,uint8_t nodeType)123 int32_t UnMarshallInt32(const TlvNode *tlvHead, uint8_t nodeType)
124 {
125 return UnMarshallInt(tlvHead, nodeType, sizeof(int32_t));
126 }
127
UnMarshallInt64(const TlvNode * tlvHead,uint8_t nodeType)128 int64_t UnMarshallInt64(const TlvNode *tlvHead, uint8_t nodeType)
129 {
130 return UnMarshallInt(tlvHead, nodeType, sizeof(int64_t));
131 }
132
UnMarshallString(const TlvNode * tlvHead,uint8_t nodeType)133 const char* UnMarshallString(const TlvNode *tlvHead, uint8_t nodeType)
134 {
135 HILOGI("[Get string value for node %hhu]", nodeType);
136 if (tlvHead == NULL) {
137 return "";
138 }
139 TlvNode* tlvNode = GetNodeByType(nodeType, tlvHead);
140 if (tlvNode == NULL || tlvNode->value == NULL) {
141 HILOGE("[Bad node type %hhu]", nodeType);
142 return "";
143 }
144 const char* value = (const char*)tlvNode->value;
145 if (value[tlvNode->length - 1] != '\0') {
146 HILOGE("[Non-zero ending string, length:%hu, ending:%d]", tlvNode->length, value[tlvNode->length - 1]);
147 return "";
148 } else {
149 return value;
150 }
151 }