1 #pragma once
2 
3 #include "rde_common.h"
4 
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 
9 #ifdef __cplusplus
10 extern "C"
11 {
12 #endif
13 
14     /**
15      * @brief Indicates whether a new BEJ section falls inside a BEJ array or a
16      * BEJ set or none of those.
17      */
18     enum BejSectionType
19     {
20         bejSectionNoType,
21         bejSectionSet,
22         bejSectionArray,
23     };
24 
25     /**
26      * @brief These stack entries are needed to implement the decoding
27      * non-recursively.
28      */
29     struct BejStackProperty
30     {
31         // Indicates whether we are inside an array or a set or an annotation.
32         enum BejSectionType sectionType;
33         // Indicate whether we have property names for properties.
34         bool addPropertyName;
35         // Offset to the parent property in schema dictionary.
36         uint16_t mainDictPropOffset;
37         // Offset to the parent property in annotation dictionary.
38         uint16_t annoDictPropOffset;
39         // Offset to the end of the array or set or annotation.
40         uint32_t streamEndOffset;
41     };
42 
43     struct BejDictionaries
44     {
45         const uint8_t* schemaDictionary;
46         const uint8_t* annotationDictionary;
47         const uint8_t* errorDictionary;
48     };
49 
50     /**
51      * @brief Holds the information related to the current bejTuple being
52      * decoded.
53      */
54     struct BejDecoderStates
55     {
56         bool addPropertyName;
57         uint16_t mainDictPropOffset;
58         uint16_t annoDictPropOffset;
59         uint32_t encodedStreamOffset;
60         const uint8_t* encodedSubStream;
61     };
62 
63     /**
64      * @brief Callbacks for decoded data.
65      *
66      * dataPtr in the callback functions can be used for extra arguments.
67      */
68     struct BejDecodedCallback
69     {
70         /**
71          * @brief Calls when a Set is detected.
72          */
73         int (*callbackSetStart)(const char* propertyName, void* dataPtr);
74 
75         /**
76          * @brief Calls when an end of a Set is found.
77          */
78         int (*callbackSetEnd)(void* dataPtr);
79 
80         /**
81          * @brief Calls when an array is detected.
82          */
83         int (*callbackArrayStart)(const char* propertyName, void* dataPtr);
84 
85         /**
86          * @brief Calls when an end of an array is found.
87          */
88         int (*callbackArrayEnd)(void* dataPtr);
89 
90         /**
91          * @brief Calls after a property is finished unless this is the last
92          * property in a Set or an array. In that case appropriate
93          * callbackSetEnd or callbackArrayEnd will be called.
94          */
95         int (*callbackPropertyEnd)(void* dataPtr);
96 
97         /**
98          * @brief Calls when a Null property is found or the property length is
99          * 0.
100          */
101         int (*callbackNull)(const char* propertyName, void* dataPtr);
102 
103         /**
104          * @brief Calls when an Integer property is found.
105          */
106         int (*callbackInteger)(const char* propertyName, int64_t value,
107                                void* dataPtr);
108 
109         /**
110          * @brief Calls when an Enum property is found.
111          */
112         int (*callbackEnum)(const char* propertyName, const char* value,
113                             void* dataPtr);
114 
115         /**
116          * @brief Calls when a String property is found.
117          */
118         int (*callbackString)(const char* propertyName, const char* value,
119                               void* dataPtr);
120 
121         /**
122          * @brief Calls when a Real value property is found.
123          */
124         int (*callbackReal)(const char* propertyName,
125                             const struct BejReal* value, void* dataPtr);
126 
127         /**
128          * @brief Calls when a Bool property is found.
129          */
130         int (*callbackBool)(const char* propertyName, bool value,
131                             void* dataPtr);
132 
133         /**
134          * @brief Calls when an Annotated property is found.
135          */
136         int (*callbackAnnotation)(const char* propertyName, void* dataPtr);
137 
138         /**
139          * @brief Calls when a read only property is found.
140          */
141         int (*callbackReadonlyProperty)(uint32_t sequenceNumber, void* dataPtr);
142     };
143 
144     /**
145      * @brief Stack for holding BejStackProperty types. Decoder core is not
146      * responsible for creating or deleting stack memory. User of the decoder
147      * core is responsible for creating and deleting stack memory.
148      *
149      * dataPtr in the callback functions can be used for extra arguments.
150      */
151     struct BejStackCallback
152     {
153         /**
154          * @brief Return true if the stack is empty.
155          */
156         bool (*stackEmpty)(void* dataPtr);
157 
158         /**
159          * @brief View the object at the top of the stack. If the stack is
160          * empty, this will return NULL.
161          */
162         const struct BejStackProperty* (*stackPeek)(void* dataPtr);
163 
164         /**
165          * @brief Removes the top most object from the stack. Client of the
166          * decoder core is responsible for destroying the memory for the removed
167          * object.
168          */
169         void (*stackPop)(void* dataPtr);
170 
171         /**
172          * @brief Push an object into the stack. Returns 0 if the operation is
173          * successfull. Client of the decoder core is responsible for allocating
174          * memory for the new object.
175          */
176         int (*stackPush)(const struct BejStackProperty* const property,
177                          void* dataPtr);
178     };
179 
180     /**
181      * @brief Used to pass parameters to BEJ decoding local functions.
182      */
183     struct BejHandleTypeFuncParam
184     {
185         struct BejDecoderStates state;
186         struct BejSFLV sflv;
187         const uint8_t* mainDictionary;
188         const uint8_t* annotDictionary;
189         const struct BejDecodedCallback* decodedCallback;
190         const struct BejStackCallback* stackCallback;
191         void* callbacksDataPtr;
192         void* stackDataPtr;
193     };
194 
195     /**
196      * @brief Decodes a PLDM block. Maximum encoded stream size the decoder
197      * supports is 32bits.
198      *
199      * @param[in] dictionaries - dictionaries needed for decoding.
200      * @param[in] encodedPldmBlock - encoded PLDM block.
201      * @param[in] blockLength - length of the PLDM block.
202      * @param[in] stackCallback - callbacks for stack handlers. callbacks in
203      * stackCallback struct should be set to valid functions.
204      * @param[in] decodedCallback - callbacks for extracting decoded
205      * properties. callbacks in decodedCallback struct should be set to
206      * NULL or valid functions.
207      * @param[in] callbacksDataPtr - data pointer to pass to decoded callbacks.
208      * This can be used pass additional data.
209      * @param[in] stackDataPtr - data pointer to pass to stack callbacks. This
210      * can be used pass additional data.
211      *
212      * @return 0 if successful.
213      */
214     int bejDecodePldmBlock(const struct BejDictionaries* dictionaries,
215                            const uint8_t* encodedPldmBlock,
216                            uint32_t blockLength,
217                            const struct BejStackCallback* stackCallback,
218                            const struct BejDecodedCallback* decodedCallback,
219                            void* callbacksDataPtr, void* stackDataPtr);
220 
221 #ifdef __cplusplus
222 }
223 #endif
224