• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #ifndef HC_TLV_PARSER_H
17 #define HC_TLV_PARSER_H
18 
19 #include <hc_parcel.h>
20 #include <hc_vector.h>
21 #include <hc_string.h>
22 
23 #define USE_DEFAULT_TAG 0xFFFF
24 #define TLV_FAIL (-1)
25 #define NO_REVERT 0
26 #define NEED_REVERT 1
27 #define MAX_TOTOL_LEN (100 * 1024 * 1024)
28 
29 typedef struct TlvBaseT {
30     unsigned short tag;
31     unsigned short length;
32     unsigned short checkTag;
33     unsigned short hasValue;
34     int32_t (*parse)(struct TlvBaseT *, HcParcel *, HcBool);
35     int32_t (*getlen)(struct TlvBaseT *);
36     int32_t (*encode)(struct TlvBaseT *, HcParcel *);
37     void (*deinit)(struct TlvBaseT *);
38 } TlvBase;
39 
40 #define DECLARE_TLV_STRUCT(x) \
41     TlvBase base; \
42     unsigned int offsetCount; \
43     unsigned int offset[x];
44 
45 unsigned short GetTag(unsigned short checkTag, unsigned short defaultTag);
46 
47 #define BEGIN_TLV_STRUCT_DEFINE(TlvS, CheckTag) \
48 void Init##TlvS(TlvS *tlv, unsigned short checkTag) \
49 { \
50     typedef TlvS TlvStructType; \
51     unsigned int index = 0; \
52     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
53     tlv->base.checkTag = GetTag(checkTag, CheckTag);
54 
55 #define TLV_MEMBER_OPTION(TlvMember, TlvMemberName, CheckTag) \
56     Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
57     tlv->TlvMemberName.base.option = 1; \
58     tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
59 
60 #define TLV_MEMBER(TlvMember, TlvMemberName, CheckTag) \
61     Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
62     tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
63 
64 #define END_TLV_STRUCT_DEFINE(void) \
65     tlv->offsetCount = index; \
66     tlv->base.parse = ParseTlvStruct; \
67     tlv->base.getlen = GetLenTlvStruct; \
68     tlv->base.encode = EncodeTlvStruct; \
69     tlv->base.deinit = DeinitTlvStruct; \
70 }
71 
72 #define DECLARE_TLV_FIX_LENGTH_TYPE(TlvName, TypeName) \
73 typedef struct \
74 { \
75     TlvBase base; \
76     TypeName data; \
77 } TlvName;
78 
79 DECLARE_TLV_FIX_LENGTH_TYPE(TlvInt32, int)
80 DECLARE_TLV_FIX_LENGTH_TYPE(TlvInt16, short)
81 DECLARE_TLV_FIX_LENGTH_TYPE(TlvInt8, char)
82 DECLARE_TLV_FIX_LENGTH_TYPE(TlvUint32, uint32_t)
83 DECLARE_TLV_FIX_LENGTH_TYPE(TlvUint16, uint16_t)
84 DECLARE_TLV_FIX_LENGTH_TYPE(TlvUint8, uint8_t)
85 DECLARE_TLV_FIX_LENGTH_TYPE(TlvUint64, uint64_t)
86 DECLARE_TLV_FIX_LENGTH_TYPE(TlvInt64, uint64_t)
87 
88 #define DEFINE_TLV_FIX_LENGTH_TYPE(TlvName, Revert) \
89 int32_t ParseTlv##TlvName(TlvBase *tlv, HcParcel *parcel, HcBool strict) \
90 { \
91     (void)strict; \
92     TlvName *realTlv = (TlvName *)(tlv); \
93     HcBool readRet = HC_FALSE; \
94     if (tlv->length != sizeof(realTlv->data)) \
95     { \
96         return TLV_FAIL; \
97     } \
98 \
99     if (Revert) \
100     { \
101         readRet = ParcelReadRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
102     } else { \
103         readRet = ParcelRead(parcel, &realTlv->data, sizeof(realTlv->data)); \
104     } \
105     if (readRet) \
106     { \
107         return tlv->length; \
108     } else { \
109         return TLV_FAIL; \
110     } \
111 } \
112 \
113 int32_t GetLenTlv##TlvName(TlvBase *tlv) \
114 { \
115     TlvName *realTlv = (TlvName *)(tlv); \
116     return (int32_t)sizeof(realTlv->data); \
117 } \
118 \
119 int32_t EncodeTlv##TlvName(TlvBase *tlv, HcParcel *parcel) \
120 { \
121     HcBool writeRet = HC_FALSE; \
122     TlvName *realTlv = (TlvName *)(tlv); \
123     if (Revert) \
124     { \
125         writeRet = ParcelWriteRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
126     } else { \
127         writeRet = ParcelWrite(parcel, &realTlv->data, sizeof(realTlv->data)); \
128     } \
129     if (writeRet) \
130     { \
131         return sizeof(realTlv->data); \
132     } else { \
133         return TLV_FAIL; \
134     } \
135 } \
136 \
137 DECLARE_TLV_PARSE_FUNC(TlvName, ParseTlv##TlvName, GetLenTlv##TlvName, EncodeTlv##TlvName);
138 
139 void DeinitTlvFixMember(TlvBase *tlv);
140 
141 #define DECLARE_TLV_PARSE_FUNC(TlvName, TlvParseFunc, TlvGetLenFunc, TlvEncodeFunc) \
142 void Init##TlvName(TlvName *tlv, unsigned short checkTag) \
143 { \
144     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
145     tlv->base.parse = TlvParseFunc; \
146     tlv->base.getlen = TlvGetLenFunc; \
147     tlv->base.encode = TlvEncodeFunc; \
148     tlv->base.deinit = DeinitTlvFixMember; \
149     tlv->base.checkTag = checkTag; \
150 }
151 
152 #define TLV_INIT(TlvName, TlvData) Init##TlvName(TlvData, USE_DEFAULT_TAG);
153 
154 #define TLV_DEINIT(TlvData) TlvData.base.deinit((TlvBase *)(&TlvData));
155 typedef struct {
156     TlvBase base;
157     unsigned int offsetCount;
158     unsigned int offset[0];
159 } TlvOffsetExample;
160 
161 HcBool ParseTlvHead(TlvBase *tlv, HcParcel *parcel);
162 int32_t ParseTlvNode(TlvBase *tlv, HcParcel *parcel, HcBool strict);
163 int32_t GetlenTlvNode(TlvBase *tlv);
164 void DeinitTlvNode(TlvBase *tlv);
165 
166 int32_t ParseTlvStruct(TlvBase *tlv, HcParcel *parcel, HcBool strict);
167 int32_t EncodeTlvStruct(TlvBase *tlv, HcParcel *parcel);
168 int32_t GetLenTlvStruct(TlvBase *tlv);
169 void DeinitTlvStruct(TlvBase *tlv);
170 int32_t EncodeTlvNode(TlvBase *tlv, HcParcel *parcel, HcBool isRoot);
171 HcBool DecodeTlvMessage(TlvBase *msg, HcParcel *parcel, HcBool strict);
172 HcBool EncodeTlvMessage(TlvBase *msg, HcParcel *parcel);
173 
174 typedef struct {
175     TlvBase base;
176     HcParcel data;
177 } TlvBuffer;
178 
179 void InitTlvBuffer(TlvBuffer *tlv, unsigned short checkTag);
180 int32_t ParseTlvBuffer(TlvBase *tlv, HcParcel *parcel, HcBool strict);
181 int32_t GetlenTlvBuffer(TlvBase *tlv);
182 int32_t EncodeTlvBuffer(TlvBase *tlv, HcParcel *parcel);
183 void DeinitTlvBuffer(TlvBase *tlv);
184 
185 typedef struct {
186     TlvBase base;
187     HcString data;
188 } TlvString;
189 
190 void InitTlvString(TlvString *tlv, unsigned short checkTag);
191 int32_t ParseTlvString(TlvBase *tlv, HcParcel *parcel, HcBool strict);
192 int32_t GetlenTlvString(TlvBase *tlv);
193 int32_t EncodeTlvString(TlvBase *tlv, HcParcel *parcel);
194 void DeinitTlvString(TlvBase *tlv);
195 
196 #define DECLEAR_INIT_FUNC(TlvStruct) \
197 void Init##TlvStruct(TlvStruct *tlv, unsigned short checkTag);
198 
199 DECLEAR_INIT_FUNC(TlvUint64)
200 DECLEAR_INIT_FUNC(TlvUint32)
201 DECLEAR_INIT_FUNC(TlvUint16)
202 DECLEAR_INIT_FUNC(TlvUint8)
203 DECLEAR_INIT_FUNC(TlvInt64)
204 DECLEAR_INIT_FUNC(TlvInt32)
205 DECLEAR_INIT_FUNC(TlvInt16)
206 DECLEAR_INIT_FUNC(TlvInt8)
207 
208 #define DECLARE_TLV_VECTOR(TlvVecName, TlvVecElement) \
209 DECLARE_HC_VECTOR(Vec##TlvVecName, TlvVecElement) \
210 typedef struct { \
211     TlvBase base; \
212     Vec##TlvVecName data; \
213 } TlvVecName; \
214 void DeinitTlv##TlvVecName(TlvBase *tlv); \
215 void Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag);
216 
217 #define IMPLEMENT_TLV_VECTOR(TlvVecName, TlvElementName, VecAllocCount) \
218 IMPLEMENT_HC_VECTOR(Vec##TlvVecName, TlvElementName, VecAllocCount) \
219 int32_t ParseTlv##TlvVecName(TlvBase *tlv, HcParcel *parcel, HcBool strict) \
220 { \
221     TlvVecName *realTlv = (TlvVecName *)(tlv); \
222     uint32_t count = 0; \
223     if (!ParcelReadUint32(parcel, &count)) { \
224         return TLV_FAIL; \
225     } \
226     int32_t totalLen = sizeof(count); \
227     uint32_t index = 0; \
228     for (index = 0; index < count; ++index) { \
229         TlvElementName tlvElement; \
230         TlvElementName *curElement = realTlv->data.pushBack(&realTlv->data, &tlvElement); \
231         if (curElement == NULL) { \
232             return TLV_FAIL; \
233         } \
234         TLV_INIT(TlvElementName, curElement); \
235 \
236         int32_t elementLen = ParseTlvNode((TlvBase *)curElement, parcel, strict); \
237         if (elementLen < 0) { \
238             return TLV_FAIL; \
239         } \
240         totalLen += elementLen; \
241         if (totalLen >= MAX_TOTOL_LEN) { \
242             return TLV_FAIL; \
243         } \
244     } \
245 \
246     return totalLen; \
247 } \
248 \
249 int32_t EncodeTlv##TlvVecName(TlvBase *tlv, HcParcel *parcel) \
250 { \
251     TlvVecName *realTlv = (TlvVecName *)(tlv); \
252     uint32_t index = 0; \
253     TlvElementName *element = NULL; \
254     uint32_t totalLen = 4; \
255     uint32_t count = realTlv->data.size(&realTlv->data); \
256     if (!ParcelWriteUint32(parcel, count)) { \
257         return TLV_FAIL; \
258     } \
259 \
260     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
261         if (element != NULL) { \
262             uint32_t len = EncodeTlvNode((TlvBase *)element, parcel, HC_FALSE); \
263             totalLen += len; \
264             if (totalLen >= MAX_TOTOL_LEN) { \
265                 return TLV_FAIL; \
266             } \
267         } \
268     } \
269     return totalLen; \
270 } \
271 int32_t GetLenTlv##TlvVecName(TlvBase *tlv) \
272 { \
273     TlvVecName *realTlv = (TlvVecName *)(tlv); \
274     uint32_t index = 0; \
275     TlvElementName *element = NULL; \
276     uint32_t totalLen = sizeof(uint32_t); \
277     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
278         if (element != NULL) { \
279             totalLen += GetlenTlvNode((TlvBase *)element); \
280             if (totalLen >= MAX_TOTOL_LEN) { \
281                 return TLV_FAIL; \
282             } \
283         } else { \
284             return TLV_FAIL; \
285         } \
286     } \
287     return totalLen; \
288 } \
289 \
290 void DeinitTlv##TlvVecName(TlvBase *tlv) \
291 { \
292     TlvVecName *realTlv = (TlvVecName *)(tlv); \
293     uint32_t index = 0; \
294     TlvElementName *element = NULL; \
295     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
296         if (element != NULL) { \
297             TLV_DEINIT((*element)); \
298         } \
299     } \
300     DESTROY_HC_VECTOR(Vec##TlvVecName, &((TlvVecName *)tlv)->data); \
301 } \
302 \
303 void Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag) \
304 { \
305     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
306     tlv->base.parse = ParseTlv##TlvVecName; \
307     tlv->base.encode = EncodeTlv##TlvVecName; \
308     tlv->base.getlen = GetLenTlv##TlvVecName; \
309     tlv->base.deinit = DeinitTlv##TlvVecName; \
310     tlv->base.checkTag = checkTag; \
311     tlv->data = CREATE_HC_VECTOR(Vec##TlvVecName); \
312 }
313 #endif
314