xref: /openbmc/libbej/include/libbej/bej_common.h (revision 6f3082ea656eba3c5e6675d4f847440c2eb24881)
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