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