xref: /openbmc/libbej/include/libbej/bej_common.h (revision 7c1be8ddd11a0ae7936cd5afc2c58c11735f88f3)
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     bejErrorNotSupported,
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     uint32_t schemaDictionarySize;
175     const uint8_t* annotationDictionary;
176     uint32_t annotationDictionarySize;
177     const uint8_t* errorDictionary;
178     uint32_t errorDictionarySize;
179 };
180 
181 /**
182  * @brief Callbacks to a stack that can store pointers.
183  */
184 struct BejPointerStackCallback
185 {
186     /**
187      * @brief A context for the stack.
188      */
189     void* stackContext;
190 
191     /**
192      * @brief Return true if the stack is empty.
193      */
194     bool (*stackEmpty)(void* stackContext);
195 
196     /**
197      * @brief View the pointer at the top of the stack. If the stack is
198      * empty, this will return NULL.
199      */
200     void* (*stackPeek)(void* stackContext);
201 
202     /**
203      * @brief Returns and removes the top most pointer from the stack. The
204      * Client of the libbej is responsible for destroying the memory used
205      * for storing the removed pointer (not the memory pointed by the
206      * pointer).
207      */
208     void* (*stackPop)(void* stackContext);
209 
210     /**
211      * @brief Push a pointer into the stack. Returns 0 if the operation is
212      * successful. Client of this API is responsible for allocating memory
213      * for storing the new pointer.
214      */
215     int (*stackPush)(void* p, void* stackContext);
216 
217     /**
218      * @brief Delete the stack.
219      */
220     void (*deleteStack)(void* stackContext);
221 };
222 
223 /**
224  * @brief Get the unsigned integer value from provided bytes.
225  *
226  * @param[in] bytes - valid pointer to a byte stream in little-endian
227  * format.
228  * @param[in] numOfBytes - number of bytes belongs to the value. Maximum
229  * number of bytes supported is 8. If numOfBytes > 8, the result is
230  * undefined.
231  * @return unsigend 64bit representation of the value.
232  */
233 uint64_t bejGetUnsignedInteger(const uint8_t* bytes, uint8_t numOfBytes);
234 
235 /**
236  * @brief Get the value from nnint type.
237  *
238  * @param[in] nnint - nnint should be pointing to a valid nnint.
239  * @return unsigend 64bit representation of the value.
240  */
241 uint64_t bejGetNnint(const uint8_t* nnint);
242 
243 /**
244  * @brief Get the size of the complete nnint.
245  *
246  * @param[in] nnint - pointer to a valid nnint.
247  * @return size of the complete nnint.
248  */
249 uint8_t bejGetNnintSize(const uint8_t* nnint);
250 
251 /**
252  * @brief Get the bytes needed represent the value as a bejInteger.
253  *
254  * This will return the number of bytes needed to encode the signed value
255  * into a bejInteger type.
256  *
257  * @param val - signed value needed to encode.
258  * @return size of the bejInteger.
259  */
260 uint8_t bejIntLengthOfValue(int64_t val);
261 
262 /**
263  * @brief Get the total bytes needed to encode an unsigned value using nnint
264  * format.
265  *
266  * @param[in] val - unsigned value needed to encode.
267  * @return size of the nnint value.
268  */
269 uint8_t bejNnintEncodingSizeOfUInt(uint64_t val);
270 
271 /**
272  * @brief Get the length field value of the unsigned value nnint encoding.
273  *
274  * @param val - unsigned value needed to encode.
275  * @return value of the length field in the encoded nnint.
276  */
277 uint8_t bejNnintLengthFieldOfUInt(uint64_t val);
278 
279 #ifdef __cplusplus
280 }
281 #endif
282