xref: /openbmc/libbej/include/libbej/bej_common.h (revision 6f3082ea)
1 #pragma once
2 
3 #include <stdbool.h>
4 #include <stdint.h>
5 
6 #ifdef __cplusplus
7 extern "C"
8 {
9 #endif
10 
11 /**
12  * @brief Use this value to indicate that the dictonary needs to be traversed
13  * starting at the first property of the dictionary.
14  */
15 #define BEJ_DICTIONARY_START_AT_HEAD 0
16 
17 /**
18  * @brief If expr is non zero, return with that value.
19  */
20 #ifndef RETURN_IF_IERROR
21 #define RETURN_IF_IERROR(expr)                                                 \
22     do                                                                         \
23     {                                                                          \
24         int __status = (expr);                                                 \
25         if (__status != 0)                                                     \
26         {                                                                      \
27             return __status;                                                   \
28         }                                                                      \
29     } while (0)
30 #endif
31 
32 /**
33  * @brief Check a given varable is NULL. If it is NULL, this will return with
34  * bejErrorNullParameter. If the variable is not NULL, this will not return.
35  */
36 #define NULL_CHECK(param, structStr)                                           \
37     do                                                                         \
38     {                                                                          \
39         if ((param) == NULL)                                                   \
40         {                                                                      \
41             fprintf(stderr, "nullCheck: %s cannot be null\n", structStr);      \
42             return bejErrorNullParameter;                                      \
43         }                                                                      \
44     } while (0)
45 
46 /**
47  * @brief RDE BEJ decoding errors.
48  */
49 enum BejError
50 {
51     bejErrorNoError = 0,
52     bejErrorUnknown,
53     bejErrorInvalidSize,
54     bejErrorNotSuppoted,
55     bejErrorUnknownProperty,
56     bejErrorInvalidSchemaType,
57     bejErrorInvalidPropertyOffset,
58     bejErrorNullParameter,
59 };
60 
61 /**
62  * @brief BEJ schema classes.
63  */
64 enum BejSchemaClass
65 {
66     bejMajorSchemaClass = 0,
67     bejEventSchemaClass = 1,
68     bejAnnotationSchemaClass = 2,
69     bejCollectionMemberTypeSchemaClass = 3,
70     bejErrorSchemaClass = 4,
71 };
72 
73 /**
74  * @brief BEJ data types supported in BEJ version 0xF1F0F000.
75  */
76 enum BejPrincipalDataType
77 {
78     bejSet = 0,
79     bejArray = 1,
80     bejNull = 2,
81     bejInteger = 3,
82     bejEnum = 4,
83     bejString = 5,
84     bejReal = 6,
85     bejBoolean = 7,
86     bejBytestring = 8,
87     bejChoice = 9,
88     bejPropertyAnnotation = 10,
89     bejPrincipalDataReserved1 = 11,
90     bejPrincipalDataReserved2 = 12,
91     bejPrincipalDataReserved3 = 13,
92     bejResourceLink = 14,
93     bejResourceLinkExpansion = 15,
94 };
95 
96 /**
97  * @brief Format BEJ tuple.
98  */
99 struct BejTupleF
100 {
101     uint8_t deferredBinding:1;
102     uint8_t readOnlyProperty:1;
103     uint8_t nullableProperty:1;
104     uint8_t reserved:1;
105     enum BejPrincipalDataType principalDataType:4;
106 } __attribute__((__packed__));
107 
108 /**
109  * @brief Sequence Number BEJ tuple.
110  */
111 struct BejTupleS
112 {
113     uint8_t schema;
114     // Dictionaries contain 16bit sequence numbers. So allocating 16bits for
115     // the sequence number here.
116     uint16_t sequenceNumber;
117 };
118 
119 /**
120  * @brief Represent offsets of Format, Value Length and Value of a SFLV
121  * tuple.
122  */
123 struct BejSFLVOffset
124 {
125     uint32_t formatOffset;
126     uint32_t valueLenNnintOffset;
127     uint32_t valueOffset;
128 };
129 
130 /**
131  * @brief Fields in Bej Real data type.
132  */
133 struct BejReal
134 {
135     // Number bytes in exp.
136     uint8_t expLen;
137     int64_t whole;
138     uint64_t zeroCount;
139     uint64_t fract;
140     int64_t exp;
141 };
142 
143 /**
144  * @brief SFLV BEJ tuple infomation.
145  */
146 struct BejSFLV
147 {
148     struct BejTupleS tupleS;
149     struct BejTupleF format;
150     // Value portion size in bytes.
151     uint32_t valueLength;
152     // Value end-offset with respect to the begining of the encoded stream.
153     uint32_t valueEndOffset;
154     // Pointer to the value.
155     const uint8_t* value;
156 };
157 
158 /**
159  * @brief bejEncoding PLDM data type header.
160  */
161 struct BejPldmBlockHeader
162 {
163     uint32_t bejVersion;
164     uint16_t reserved;
165     uint8_t schemaClass;
166 } __attribute__((__packed__));
167 
168 /**
169  * @brief Points to dictionaries used for encoding and decoding.
170  */
171 struct BejDictionaries
172 {
173     const uint8_t* schemaDictionary;
174     const uint8_t* annotationDictionary;
175     const uint8_t* errorDictionary;
176 };
177 
178 /**
179  * @brief Callbacks to a stack that can store pointers.
180  */
181 struct BejPointerStackCallback
182 {
183     /**
184      * @brief A context for the stack.
185      */
186     void* stackContext;
187 
188     /**
189      * @brief Return true if the stack is empty.
190      */
191     bool (*stackEmpty)(void* stackContext);
192 
193     /**
194      * @brief View the pointer at the top of the stack. If the stack is
195      * empty, this will return NULL.
196      */
197     void* (*stackPeek)(void* stackContext);
198 
199     /**
200      * @brief Returns and removes the top most pointer from the stack. The
201      * Client of the libbej is responsible for destroying the memory used
202      * for storing the removed pointer (not the memory pointed by the
203      * pointer).
204      */
205     void* (*stackPop)(void* stackContext);
206 
207     /**
208      * @brief Push a pointer into the stack. Returns 0 if the operation is
209      * successful. Client of this API is responsible for allocating memory
210      * for storing the new pointer.
211      */
212     int (*stackPush)(void* p, void* stackContext);
213 
214     /**
215      * @brief Delete the stack.
216      */
217     void (*deleteStack)(void* stackContext);
218 };
219 
220 /**
221  * @brief Get the unsigned integer value from provided bytes.
222  *
223  * @param[in] bytes - valid pointer to a byte stream in little-endian
224  * format.
225  * @param[in] numOfBytes - number of bytes belongs to the value. Maximum
226  * number of bytes supported is 8. If numOfBytes > 8, the result is
227  * undefined.
228  * @return unsigend 64bit representation of the value.
229  */
230 uint64_t bejGetUnsignedInteger(const uint8_t* bytes, uint8_t numOfBytes);
231 
232 /**
233  * @brief Get the value from nnint type.
234  *
235  * @param[in] nnint - nnint should be pointing to a valid nnint.
236  * @return unsigend 64bit representation of the value.
237  */
238 uint64_t bejGetNnint(const uint8_t* nnint);
239 
240 /**
241  * @brief Get the size of the complete nnint.
242  *
243  * @param[in] nnint - pointer to a valid nnint.
244  * @return size of the complete nnint.
245  */
246 uint8_t bejGetNnintSize(const uint8_t* nnint);
247 
248 /**
249  * @brief Get the bytes needed represent the value as a bejInteger.
250  *
251  * This will return the number of bytes needed to encode the signed value
252  * into a bejInteger type.
253  *
254  * @param val - signed value needed to encode.
255  * @return size of the bejInteger.
256  */
257 uint8_t bejIntLengthOfValue(int64_t val);
258 
259 /**
260  * @brief Get the total bytes needed to encode an unsigned value using nnint
261  * format.
262  *
263  * @param[in] val - unsigned value needed to encode.
264  * @return size of the nnint value.
265  */
266 uint8_t bejNnintEncodingSizeOfUInt(uint64_t val);
267 
268 /**
269  * @brief Get the length field value of the unsigned value nnint encoding.
270  *
271  * @param val - unsigned value needed to encode.
272  * @return value of the length field in the encoded nnint.
273  */
274 uint8_t bejNnintLengthFieldOfUInt(uint64_t val);
275 
276 #ifdef __cplusplus
277 }
278 #endif
279