1 /*
2  * Percepio DFM v2.0.0
3  * Copyright 2023 Percepio AB
4  * www.percepio.com
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * DFM Entry
9  */
10 
11 #include <dfm.h>
12 #include <string.h>
13 
14 #if ((DFM_CFG_ENABLED) >= 1)
15 
16 #define DFM_ENTRY_VERSION 1
17 
18 typedef struct DfmEntryHeader
19 {
20 	uint8_t cStartMarkers[4];
21 	uint16_t usEndianess;
22 	uint16_t usVersion;
23 	uint16_t usType;
24 	uint16_t usEntryId;
25 	uint16_t usChunkIndex;
26 	uint16_t usChunkCount;
27 	uint32_t ulAlertId;
28 	uint16_t usSessionIdSize;
29 	uint16_t usDeviceNameSize;
30 	uint16_t usDescriptionSize;
31 	uint16_t usReserved;
32 	uint32_t ulDataSize;
33 } DfmEntryHeader_t;
34 
35 typedef struct DfmEntryPayloadHeader
36 {
37 	uint8_t ucStartMarkers[4];		/* The DFM Payload start markers, must be 0x50, 0x44, 0x61, 0x50 ("PDaP") */
38 	uint16_t usEndianness;			/* The endianness checker, assign to 0x0FF0 */
39 	uint8_t ucVersion;				/* The version of the DFM subsystem, current version is 3 */
40 	uint8_t ucFilenameSize;			/* The maximum length of cFilenameBuffer */
41 	uint32_t ulFileSize;			/* The size of the file (buffer) */
42 	char cFilenameBuffer[DFM_PAYLOAD_DESCRIPTION_MAX_LEN]; /* Size will always be 4-byte aligned */
43 	uint8_t ucEndMarkers[4];		/* The DFM Payload end markers, must be 0x50, 0x61, 0x44, 0x50 ("PaDP") */
44 	uint32_t ulChecksum;			/* Checksum on the whole thing, 0 for not enabled */
45 } DfmEntryPayloadHeader_t;
46 
47 typedef struct DfmEntryFooter
48 {
49 	uint8_t cEndMarkers[4];
50 } DfmEntryFooter_t;
51 
52 static DfmEntryData_t* pxDfmEntryData = (void*)0;
53 
54 static DfmResult_t prvDfmEntryVerify(DfmEntryHandle_t xEntryHandle);
55 static uint32_t prvDfmEntryGetHeaderSize(void);
56 static DfmResult_t prvDfmEntrySetup(uint16_t usType, uint16_t usEntryId, uint16_t usChunkIndex, uint16_t usChunkCount, uint32_t ulDescriptionSize, const char* szDescription, void* pvData, uint32_t ulDataSize, DfmEntryHandle_t* pxEntryHandle);
57 
58 /* This function is only used to get around constant "if" condition */
prvDfmEntryGetHeaderSize(void)59 static uint32_t prvDfmEntryGetHeaderSize(void)
60 {
61 	return sizeof(DfmEntryHeader_t);
62 }
63 
prvDfmEntryVerify(DfmEntryHandle_t xEntryHandle)64 static DfmResult_t prvDfmEntryVerify(DfmEntryHandle_t xEntryHandle)
65 {
66 	uint32_t ulEntrySize;
67 	DfmEntryHeader_t* pxEntryHeader;
68 	uint8_t* cEndMarkers;
69 
70 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
71 
72 	if (xDfmEntryGetSize(xEntryHandle, &ulEntrySize) == DFM_FAIL)
73 	{
74 		return DFM_FAIL;
75 	}
76 
77 	if (ulEntrySize > sizeof(pxDfmEntryData->buffer))
78 	{
79 		return DFM_FAIL;
80 	}
81 
82 	if ((pxEntryHeader->cStartMarkers[0] != (uint8_t)0xD1) ||
83 		(pxEntryHeader->cStartMarkers[1] != (uint8_t)0xD2) ||
84 		(pxEntryHeader->cStartMarkers[2] != (uint8_t)0xD3) ||
85 		(pxEntryHeader->cStartMarkers[3] != (uint8_t)0xD4))
86 	{
87 		return DFM_FAIL;
88 	}
89 
90 	if (xDfmEntryGetEndMarkers(xEntryHandle, &cEndMarkers) == DFM_FAIL)
91 	{
92 		return DFM_FAIL;
93 	}
94 
95 	if ((cEndMarkers[0] != (uint8_t)0xD4) ||
96 		(cEndMarkers[1] != (uint8_t)0xD3) ||
97 		(cEndMarkers[2] != (uint8_t)0xD2) ||
98 		(cEndMarkers[3] != (uint8_t)0xD1))
99 	{
100 		return DFM_FAIL;
101 	}
102 
103 	if ((pxEntryHeader->usType != (uint16_t)DFM_ENTRY_TYPE_ALERT) &&
104 		(pxEntryHeader->usType != (uint16_t)DFM_ENTRY_TYPE_PAYLOAD) &&
105 		(pxEntryHeader->usType != (uint16_t)DFM_ENTRY_TYPE_PAYLOAD_HEADER))
106 	{
107 		return DFM_FAIL;
108 	}
109 
110 	if (pxEntryHeader->usVersion > (uint16_t)DFM_ENTRY_VERSION)
111 	{
112 		return DFM_FAIL;
113 	}
114 
115 	if (pxEntryHeader->usChunkIndex == (uint16_t)0)
116 	{
117 		return DFM_FAIL;
118 	}
119 
120 	if (pxEntryHeader->usChunkIndex > pxEntryHeader->usChunkCount)
121 	{
122 		return DFM_FAIL;
123 	}
124 
125 	return DFM_SUCCESS;
126 }
127 
prvDfmEntrySetup(uint16_t usType,uint16_t usEntryId,uint16_t usChunkIndex,uint16_t usChunkCount,uint32_t ulDescriptionSize,const char * szDescription,void * pvData,uint32_t ulDataSize,DfmEntryHandle_t * pxEntryHandle)128 static DfmResult_t prvDfmEntrySetup(uint16_t usType, uint16_t usEntryId, uint16_t usChunkIndex, uint16_t usChunkCount, uint32_t ulDescriptionSize, const char* szDescription, void* pvData, uint32_t ulDataSize, DfmEntryHandle_t* pxEntryHandle)
129 {
130 	DfmEntryHeader_t* pxEntryHeader = (DfmEntryHeader_t*)pxDfmEntryData->buffer; /*cstat !MISRAC2012-Rule-11.3 We convert the untyped buffer to something we can work with. We can't use an exact type since the buffer may need to contain bigger Entries that haven been previously stored*/
131 	char* szSessionId = (void*)0;
132 	uint32_t ulOffset = 0UL;
133 	uint32_t ulAlertId = 0UL;
134 	const char* szDeviceName = (void*)0;
135 
136 	if (szDescription == (void*)0)
137 	{
138 		return DFM_FAIL;
139 	}
140 
141 	if (szDescription[0] == (char)0)
142 	{
143 		return DFM_FAIL;
144 	}
145 
146 	if (pvData == (void*)0)
147 	{
148 		return DFM_FAIL;
149 	}
150 
151 	if (ulDataSize == 0UL)
152 	{
153 		return DFM_FAIL;
154 	}
155 
156 	if (pxEntryHandle == (void*)0)
157 	{
158 		return DFM_FAIL;
159 	}
160 
161 	if (usChunkIndex == (uint16_t)0)
162 	{
163 		return DFM_FAIL;
164 	}
165 
166 	if (usChunkIndex > usChunkCount)
167 	{
168 		return DFM_FAIL;
169 	}
170 
171 	if (xDfmSessionGetUniqueSessionId(&szSessionId) == DFM_FAIL)
172 	{
173 		return DFM_FAIL;
174 	}
175 
176 	if (xDfmSessionGetAlertId(&ulAlertId) == DFM_FAIL)
177 	{
178 		return DFM_FAIL;
179 	}
180 
181 	if (xDfmSessionGetDeviceName(&szDeviceName) == DFM_FAIL)
182 	{
183 		return DFM_FAIL;
184 	}
185 
186 	pxEntryHeader->cStartMarkers[0] = 0xD1;
187 	pxEntryHeader->cStartMarkers[1] = 0xD2;
188 	pxEntryHeader->cStartMarkers[2] = 0xD3;
189 	pxEntryHeader->cStartMarkers[3] = 0xD4;
190 
191 	pxEntryHeader->usEndianess = 0x0FF0;
192 	pxEntryHeader->usVersion = DFM_ENTRY_VERSION;
193 	pxEntryHeader->usType = usType;
194 	pxEntryHeader->usEntryId = usEntryId;
195 	pxEntryHeader->usChunkIndex = usChunkIndex;
196 	pxEntryHeader->usChunkCount = usChunkCount;
197 	pxEntryHeader->ulAlertId = ulAlertId;
198 	pxEntryHeader->usSessionIdSize = DFM_SESSION_ID_MAX_LEN;
199 	pxEntryHeader->usDeviceNameSize = DFM_DEVICE_NAME_MAX_LEN;
200 	pxEntryHeader->usDescriptionSize = (uint16_t)ulDescriptionSize;
201 	pxEntryHeader->ulDataSize = ulDataSize;
202 
203 	ulOffset += sizeof(DfmEntryHeader_t);
204 
205 	/* TODO: 64-bit support */
206 	/* Write SessionId after Header */
207 	(void)memcpy((char*)((uint32_t)pxDfmEntryData->buffer + ulOffset), szSessionId, DFM_SESSION_ID_MAX_LEN); /*cstat !MISRAC2012-Rule-11.6 We need to write the Session Id to the buffer with an offset*/
208 
209 	ulOffset += (uint32_t)(DFM_SESSION_ID_MAX_LEN);
210 
211 	/* TODO: 64-bit support */
212 	/* Write DeviceName after SessionId */
213 	(void)memcpy((char*)((uint32_t)pxDfmEntryData->buffer + ulOffset), szDeviceName, DFM_DEVICE_NAME_MAX_LEN); /*cstat !MISRAC2012-Rule-11.6 We need to write the Device Name to the buffer with an offset*/
214 
215 	ulOffset += (uint32_t)(DFM_DEVICE_NAME_MAX_LEN);
216 
217 	/* TODO: 64-bit support */
218 	/* Write Description after DeviceName */
219 	(void)memcpy((char*)((uint32_t)pxDfmEntryData->buffer + ulOffset), szDescription, ulDescriptionSize); /*cstat !MISRAC2012-Rule-11.6 We need to write the Description to the buffer with an offset*/
220 
221 	ulOffset += ulDescriptionSize;
222 
223 	/* TODO: 64-bit support */
224 	/* Write Data after Description */
225 	(void)memcpy((void*)((uint32_t)pxDfmEntryData->buffer + ulOffset), pvData, ulDataSize); /*cstat !MISRAC2012-Rule-11.6 We need to write the Entry data to the buffer with an offset*/
226 
227 	ulOffset += ulDataSize;
228 
229 	/* TODO: 64-bit support */
230 	/* Write Footer after Data */
231 	DfmEntryFooter_t* pxEntryFooter = (DfmEntryFooter_t*)((uint32_t)pxDfmEntryData->buffer + ulOffset);
232 	pxEntryFooter->cEndMarkers[0] = pxEntryHeader->cStartMarkers[3];
233 	pxEntryFooter->cEndMarkers[1] = pxEntryHeader->cStartMarkers[2];
234 	pxEntryFooter->cEndMarkers[2] = pxEntryHeader->cStartMarkers[1];
235 	pxEntryFooter->cEndMarkers[3] = pxEntryHeader->cStartMarkers[0];
236 
237 	*pxEntryHandle = (DfmEntryHandle_t)pxEntryHeader;
238 
239 	return DFM_SUCCESS;
240 }
241 
242 /*
243  * Since the sizes are dynamic, an Entry will be stored and read by interpreting consecutive parts as:
244  * Alert: DfmEntryHeader_t -> session[ulSessionIdSize] -> description[ulDescriptionSize] -> alert[ulDataSize] -> DfmEntryFooter_t
245  * Payload: DfmEntryHeader_t -> session[ulSessionIdSize] -> description[ulDescriptionSize] -> payload[ulDataSize] -> DfmEntryFooter_t
246  */
xDfmEntryInitialize(DfmEntryData_t * pxBuffer)247 DfmResult_t xDfmEntryInitialize(DfmEntryData_t* pxBuffer)
248 {
249 	if (pxBuffer == (void*)0)
250 	{
251 		return DFM_FAIL;
252 	}
253 
254 	pxDfmEntryData = pxBuffer;
255 
256 	/* Verify that entry buffer can hold alert size. Calls prvDfmEntryGetHeaderSize() to avoid constant "if" condition. */
257 	if ((prvDfmEntryGetHeaderSize() + (uint32_t)(DFM_SESSION_ID_MAX_LEN) + (uint32_t)(DFM_DESCRIPTION_MAX_LEN) + (uint32_t)(DFM_DEVICE_NAME_MAX_LEN) + sizeof(DfmAlert_t) + sizeof(DfmEntryFooter_t)) > sizeof(pxDfmEntryData->buffer))
258 	{
259 		return DFM_FAIL;
260 	}
261 
262 	/* Verify that entry buffer can hold payload size. Calls prvDfmEntryGetHeaderSize() to avoid constant "if" condition. */
263 	if ((prvDfmEntryGetHeaderSize() + (uint32_t)(DFM_SESSION_ID_MAX_LEN) + (uint32_t)(DFM_PAYLOAD_DESCRIPTION_MAX_LEN) + (uint32_t)(DFM_DEVICE_NAME_MAX_LEN) + (uint32_t)(DFM_CFG_MAX_PAYLOAD_CHUNK_SIZE) + sizeof(DfmEntryFooter_t)) > sizeof(pxDfmEntryData->buffer))
264 	{
265 		return DFM_FAIL;
266 	}
267 
268 	pxDfmEntryData->ulInitialized = 1;
269 
270 	return DFM_SUCCESS;
271 }
272 
xDfmEntryGetBuffer(void ** ppvBuffer,uint32_t * pulBufferSize)273 DfmResult_t xDfmEntryGetBuffer(void** ppvBuffer, uint32_t* pulBufferSize)
274 {
275 	if (pxDfmEntryData == (void*)0)
276 	{
277 		return DFM_FAIL;
278 	}
279 
280 	if (pxDfmEntryData->ulInitialized == 0UL)
281 	{
282 		return DFM_FAIL;
283 	}
284 
285 	if (ppvBuffer == (void*)0)
286 	{
287 		return DFM_FAIL;
288 	}
289 
290 	if (pulBufferSize == (void*)0)
291 	{
292 		return DFM_FAIL;
293 	}
294 
295 	*ppvBuffer = pxDfmEntryData->buffer;
296 	*pulBufferSize = sizeof(pxDfmEntryData->buffer);
297 
298 	return DFM_SUCCESS;
299 }
300 
xDfmEntryCreateAlert(DfmAlertHandle_t xAlertHandle,DfmEntryHandle_t * pxEntryHandle)301 DfmResult_t xDfmEntryCreateAlert(DfmAlertHandle_t xAlertHandle, DfmEntryHandle_t *pxEntryHandle)
302 {
303 	const char* szDescription = (void*)0;
304 
305 	if (pxDfmEntryData == (void*)0)
306 	{
307 		return DFM_FAIL;
308 	}
309 
310 	if (pxDfmEntryData->ulInitialized == 0UL)
311 	{
312 		return DFM_FAIL;
313 	}
314 
315 	if (xAlertHandle == 0)
316 	{
317 		return DFM_FAIL;
318 	}
319 
320 	if (xDfmAlertGetDescription(xAlertHandle, &szDescription) == DFM_FAIL)
321 	{
322 		return DFM_FAIL;
323 	}
324 
325 	if (prvDfmEntrySetup((uint16_t)(DFM_ENTRY_TYPE_ALERT), (uint16_t)0, (uint16_t)1, (uint16_t)1, (uint32_t)(DFM_DESCRIPTION_MAX_LEN), szDescription, (void*)xAlertHandle, sizeof(DfmAlert_t), pxEntryHandle) == DFM_FAIL)
326 	{
327 		return DFM_FAIL;
328 	}
329 
330 	return DFM_SUCCESS;
331 }
332 
xDfmEntryCreatePayloadHeader(DfmAlertHandle_t xAlertHandle,uint16_t usEntryId,uint32_t ulPayloadSize,char * szDescription,DfmEntryHandle_t * pxEntryHandle)333 DfmResult_t xDfmEntryCreatePayloadHeader(DfmAlertHandle_t xAlertHandle, uint16_t usEntryId, uint32_t ulPayloadSize, char* szDescription, DfmEntryHandle_t* pxEntryHandle)
334 {
335 	DfmEntryPayloadHeader_t xPayloadHeader = { 0 };
336 	uint32_t i;
337 
338 	if (pxDfmEntryData == (void*)0)
339 	{
340 		return DFM_FAIL;
341 	}
342 
343 	if (pxDfmEntryData->ulInitialized == 0UL)
344 	{
345 		return DFM_FAIL;
346 	}
347 
348 	if (xAlertHandle == 0)
349 	{
350 		return DFM_FAIL;
351 	}
352 
353 	if (ulPayloadSize == 0UL)
354 	{
355 		return DFM_FAIL;
356 	}
357 
358 	if (szDescription == (void*)0)
359 	{
360 		return DFM_FAIL;
361 	}
362 
363 	if (szDescription[0] == (char)0)
364 	{
365 		return DFM_FAIL;
366 	}
367 
368 	if (pxEntryHandle == (void*)0)
369 	{
370 		return DFM_FAIL;
371 	}
372 
373 	xPayloadHeader.ucStartMarkers[0] = 0x50;
374 	xPayloadHeader.ucStartMarkers[1] = 0x44;
375 	xPayloadHeader.ucStartMarkers[2] = 0x61;
376 	xPayloadHeader.ucStartMarkers[3] = 0x50;
377 	xPayloadHeader.usEndianness = 0x0FF0;
378 	xPayloadHeader.ucVersion = DFM_VERSION;
379 	xPayloadHeader.ucFilenameSize = (uint8_t)sizeof(xPayloadHeader.cFilenameBuffer);
380 	xPayloadHeader.ulFileSize = ulPayloadSize;
381 
382 	for (i = 0; i < sizeof(xPayloadHeader.cFilenameBuffer); i++)
383 	{
384 		xPayloadHeader.cFilenameBuffer[i] = szDescription[i];
385 
386 		if (xPayloadHeader.cFilenameBuffer[i] == (char)0)
387 		{
388 			break;
389 		}
390 	}
391 
392 	xPayloadHeader.ucEndMarkers[0] = 0x50;
393 	xPayloadHeader.ucEndMarkers[1] = 0x61;
394 	xPayloadHeader.ucEndMarkers[2] = 0x44;
395 	xPayloadHeader.ucEndMarkers[3] = 0x50;
396 	xPayloadHeader.ulChecksum = 0;
397 
398 	if (prvDfmEntrySetup((uint16_t)(DFM_ENTRY_TYPE_PAYLOAD_HEADER), usEntryId, (uint16_t)1, (uint16_t)1, (uint32_t)(DFM_PAYLOAD_DESCRIPTION_MAX_LEN), szDescription, &xPayloadHeader, sizeof(xPayloadHeader), pxEntryHandle) == DFM_FAIL)
399 	{
400 		return DFM_FAIL;
401 	}
402 
403 	return DFM_SUCCESS;
404 }
405 
xDfmEntryCreatePayloadChunk(DfmAlertHandle_t xAlertHandle,uint16_t usEntryId,uint16_t usChunkIndex,uint16_t usChunkCount,void * pvPayload,uint32_t ulSize,char * szDescription,DfmEntryHandle_t * pxEntryHandle)406 DfmResult_t xDfmEntryCreatePayloadChunk(DfmAlertHandle_t xAlertHandle, uint16_t usEntryId, uint16_t usChunkIndex, uint16_t usChunkCount, void* pvPayload, uint32_t ulSize, char* szDescription, DfmEntryHandle_t* pxEntryHandle)
407 {
408 	if (pxDfmEntryData == (void*)0)
409 	{
410 		return DFM_FAIL;
411 	}
412 
413 	if (pxDfmEntryData->ulInitialized == 0UL)
414 	{
415 		return DFM_FAIL;
416 	}
417 
418 	if (xAlertHandle == 0)
419 	{
420 		return DFM_FAIL;
421 	}
422 
423 	if (prvDfmEntrySetup((uint16_t)(DFM_ENTRY_TYPE_PAYLOAD), usEntryId, usChunkIndex, usChunkCount, (uint32_t)(DFM_PAYLOAD_DESCRIPTION_MAX_LEN), szDescription, pvPayload, ulSize, pxEntryHandle) == DFM_FAIL)
424 	{
425 		return DFM_FAIL;
426 	}
427 
428 	return DFM_SUCCESS;
429 }
430 
xDfmEntryCreateAlertFromBuffer(DfmEntryHandle_t * pxEntryHandle)431 DfmResult_t xDfmEntryCreateAlertFromBuffer(DfmEntryHandle_t* pxEntryHandle)
432 {
433 	DfmEntryHeader_t* pxEntryHeader;
434 
435 	if (pxDfmEntryData == (void*)0)
436 	{
437 		return DFM_FAIL;
438 	}
439 
440 	if (pxDfmEntryData->ulInitialized == 0UL)
441 	{
442 		return DFM_FAIL;
443 	}
444 
445 	if (pxEntryHandle == (void*)0)
446 	{
447 		return DFM_FAIL;
448 	}
449 
450 	/* We assume the data is in the buffer */
451 
452 	pxEntryHeader = (DfmEntryHeader_t*)pxDfmEntryData->buffer; /*cstat !MISRAC2012-Rule-11.3 We convert the untyped buffer to something we can work with. We can't use an exact type since the buffer may need to contain bigger Entries that haven been previously stored*/
453 
454 	if (prvDfmEntryVerify((DfmEntryHandle_t)pxEntryHeader) == DFM_FAIL)
455 	{
456 		return DFM_FAIL;
457 	}
458 
459 	if (pxEntryHeader->usType != (uint16_t)(DFM_ENTRY_TYPE_ALERT))
460 	{
461 		return DFM_FAIL;
462 	}
463 
464 	*pxEntryHandle = (DfmEntryHandle_t)pxEntryHeader;
465 
466 	return DFM_SUCCESS;
467 }
468 
xDfmEntryCreatePayloadChunkFromBuffer(const char * szSessionId,uint32_t ulAlertId,DfmEntryHandle_t * pxEntryHandle)469 DfmResult_t xDfmEntryCreatePayloadChunkFromBuffer(const char* szSessionId, uint32_t ulAlertId, DfmEntryHandle_t* pxEntryHandle)
470 {
471 	DfmEntryHeader_t* pxEntryHeader;
472 	const char* szPayloadSession = (void*)0;
473 	uint32_t i;
474 
475 	if (pxDfmEntryData == (void*)0)
476 	{
477 		return DFM_FAIL;
478 	}
479 
480 	if (pxDfmEntryData->ulInitialized == 0UL)
481 	{
482 		return DFM_FAIL;
483 	}
484 
485 	if (pxEntryHandle == (void*)0)
486 	{
487 		return DFM_FAIL;
488 	}
489 
490 	/* TODO: 64-bit compatible */
491 	/* Make sure szSessiondId is not pointing to a string inside the buffer since that means this function is incorrectly used! */
492 	if (((uint32_t)szSessionId >= (uint32_t)pxDfmEntryData->buffer) && ((uint32_t)szSessionId < (uint32_t)pxDfmEntryData->buffer + sizeof(pxDfmEntryData->buffer)))
493 	{
494 		return DFM_FAIL;
495 	}
496 
497 	/* We assume the data is in the buffer */
498 
499 	pxEntryHeader = (DfmEntryHeader_t*)pxDfmEntryData->buffer; /*cstat !MISRAC2012-Rule-11.3 We convert the untyped buffer to something we can work with. We can't use an exact type since the buffer may need to contain bigger Entries that haven been previously stored*/
500 
501 	if (prvDfmEntryVerify((DfmEntryHandle_t)pxEntryHeader) == DFM_FAIL)
502 	{
503 		return DFM_FAIL;
504 	}
505 
506 	if (pxEntryHeader->usType != (uint16_t)(DFM_ENTRY_TYPE_PAYLOAD) && pxEntryHeader->usType != (uint16_t)(DFM_ENTRY_TYPE_PAYLOAD_HEADER))
507 	{
508 		return DFM_FAIL;
509 	}
510 
511 	/* Make sure stored alert id matches what we asked for */
512 	if (pxEntryHeader->ulAlertId != ulAlertId)
513 	{
514 		return DFM_FAIL;
515 	}
516 
517 	if (xDfmEntryGetSessionId((DfmEntryHandle_t)pxEntryHeader, &szPayloadSession) == DFM_FAIL)
518 	{
519 		return DFM_FAIL;
520 	}
521 
522 	/* Make sure stored session matches what we asked for */
523 	for (i = 0; i < (uint32_t)(DFM_SESSION_ID_MAX_LEN); i++)
524 	{
525 		if (szSessionId[i] != szPayloadSession[i])
526 		{
527 			return DFM_FAIL;
528 		}
529 
530 		if (szSessionId[i] == (char)0)
531 		{
532 			break;
533 		}
534 	}
535 
536 	*pxEntryHandle = (DfmEntryHandle_t)pxEntryHeader;
537 
538 	return DFM_SUCCESS;
539 }
540 
xDfmEntryGetSize(DfmEntryHandle_t xEntryHandle,uint32_t * pulSize)541 DfmResult_t xDfmEntryGetSize(DfmEntryHandle_t xEntryHandle, uint32_t *pulSize)
542 {
543 	DfmEntryHeader_t* pxEntryHeader;
544 
545 	if (pxDfmEntryData == (void*)0)
546 	{
547 		return DFM_FAIL;
548 	}
549 
550 	if (pxDfmEntryData->ulInitialized == 0UL)
551 	{
552 		return DFM_FAIL;
553 	}
554 
555 	if (xEntryHandle == 0)
556 	{
557 		return DFM_FAIL;
558 	}
559 
560 	if (pulSize == (void*)0)
561 	{
562 		return DFM_FAIL;
563 	}
564 
565 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
566 
567 	*pulSize = sizeof(DfmEntryHeader_t) + pxEntryHeader->usSessionIdSize + pxEntryHeader->usDeviceNameSize + pxEntryHeader->usDescriptionSize + pxEntryHeader->ulDataSize + sizeof(DfmEntryFooter_t);
568 
569 	return DFM_SUCCESS;
570 }
571 
xDfmEntryGetStartMarkers(DfmEntryHandle_t xEntryHandle,uint8_t ** pucMarkersBuffer)572 DfmResult_t xDfmEntryGetStartMarkers(DfmEntryHandle_t xEntryHandle, uint8_t** pucMarkersBuffer)
573 {
574 	DfmEntryHeader_t* pxEntryHeader;
575 
576 	if (pxDfmEntryData == (void*)0)
577 	{
578 		return DFM_FAIL;
579 	}
580 
581 	if (pxDfmEntryData->ulInitialized == 0UL)
582 	{
583 		return DFM_FAIL;
584 	}
585 
586 	if (xEntryHandle == 0)
587 	{
588 		return DFM_FAIL;
589 	}
590 
591 	if (pucMarkersBuffer == (void*)0)
592 	{
593 		return DFM_FAIL;
594 	}
595 
596 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
597 
598 	*pucMarkersBuffer = pxEntryHeader->cStartMarkers;
599 
600 	return DFM_SUCCESS;
601 }
602 
xDfmEntryGetEndianess(DfmEntryHandle_t xEntryHandle,uint16_t * pusEndianess)603 DfmResult_t xDfmEntryGetEndianess(DfmEntryHandle_t xEntryHandle, uint16_t* pusEndianess)
604 {
605 	DfmEntryHeader_t* pxEntryHeader;
606 
607 	if (pxDfmEntryData == (void*)0)
608 	{
609 		return DFM_FAIL;
610 	}
611 
612 	if (pxDfmEntryData->ulInitialized == 0UL)
613 	{
614 		return DFM_FAIL;
615 	}
616 
617 	if (xEntryHandle == 0)
618 	{
619 		return DFM_FAIL;
620 	}
621 
622 	if (pusEndianess == (void*)0)
623 	{
624 		return DFM_FAIL;
625 	}
626 
627 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
628 
629 	*pusEndianess = pxEntryHeader->usEndianess;
630 
631 	return DFM_SUCCESS;
632 }
633 
xDfmEntryGetVersion(DfmEntryHandle_t xEntryHandle,uint16_t * pusVersion)634 DfmResult_t xDfmEntryGetVersion(DfmEntryHandle_t xEntryHandle, uint16_t* pusVersion)
635 {
636 	DfmEntryHeader_t* pxEntryHeader;
637 
638 	if (pxDfmEntryData == (void*)0)
639 	{
640 		return DFM_FAIL;
641 	}
642 
643 	if (pxDfmEntryData->ulInitialized == 0UL)
644 	{
645 		return DFM_FAIL;
646 	}
647 
648 	if (xEntryHandle == 0)
649 	{
650 		return DFM_FAIL;
651 	}
652 
653 	if (pusVersion == (void*)0)
654 	{
655 		return DFM_FAIL;
656 	}
657 
658 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
659 
660 	*pusVersion = pxEntryHeader->usVersion;
661 
662 	return DFM_SUCCESS;
663 }
664 
xDfmEntryGetType(DfmEntryHandle_t xEntryHandle,uint16_t * pusType)665 DfmResult_t xDfmEntryGetType(DfmEntryHandle_t xEntryHandle, uint16_t* pusType)
666 {
667 	DfmEntryHeader_t* pxEntryHeader;
668 
669 	if (pxDfmEntryData == (void*)0)
670 	{
671 		return DFM_FAIL;
672 	}
673 
674 	if (pxDfmEntryData->ulInitialized == 0UL)
675 	{
676 		return DFM_FAIL;
677 	}
678 
679 	if (xEntryHandle == 0)
680 	{
681 		return DFM_FAIL;
682 	}
683 
684 	if (pusType == (void*)0)
685 	{
686 		return DFM_FAIL;
687 	}
688 
689 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
690 
691 	*pusType = pxEntryHeader->usType;
692 
693 	return DFM_SUCCESS;
694 }
695 
xDfmEntryGetEntryId(DfmEntryHandle_t xEntryHandle,uint16_t * pusEntryId)696 DfmResult_t xDfmEntryGetEntryId(DfmEntryHandle_t xEntryHandle, uint16_t* pusEntryId)
697 {
698 	DfmEntryHeader_t* pxEntryHeader;
699 
700 	if (pxDfmEntryData == (void*)0)
701 	{
702 		return DFM_FAIL;
703 	}
704 
705 	if (pxDfmEntryData->ulInitialized == 0UL)
706 	{
707 		return DFM_FAIL;
708 	}
709 
710 	if (xEntryHandle == 0)
711 	{
712 		return DFM_FAIL;
713 	}
714 
715 	if (pusEntryId == (void*)0)
716 	{
717 		return DFM_FAIL;
718 	}
719 
720 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
721 
722 	*pusEntryId = pxEntryHeader->usEntryId;
723 
724 	return DFM_SUCCESS;
725 }
726 
xDfmEntryGetChunkIndex(DfmEntryHandle_t xEntryHandle,uint16_t * pusChunkIndex)727 DfmResult_t xDfmEntryGetChunkIndex(DfmEntryHandle_t xEntryHandle, uint16_t* pusChunkIndex)
728 {
729 	DfmEntryHeader_t* pxEntryHeader;
730 
731 	if (pxDfmEntryData == (void*)0)
732 	{
733 		return DFM_FAIL;
734 	}
735 
736 	if (pxDfmEntryData->ulInitialized == 0UL)
737 	{
738 		return DFM_FAIL;
739 	}
740 
741 	if (xEntryHandle == 0)
742 	{
743 		return DFM_FAIL;
744 	}
745 
746 	if (pusChunkIndex == (void*)0)
747 	{
748 		return DFM_FAIL;
749 	}
750 
751 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
752 
753 	*pusChunkIndex = pxEntryHeader->usChunkIndex;
754 
755 	return DFM_SUCCESS;
756 }
757 
xDfmEntryGetChunkCount(DfmEntryHandle_t xEntryHandle,uint16_t * pusChunkCount)758 DfmResult_t xDfmEntryGetChunkCount(DfmEntryHandle_t xEntryHandle, uint16_t* pusChunkCount)
759 {
760 	DfmEntryHeader_t* pxEntryHeader;
761 
762 	if (pxDfmEntryData == (void*)0)
763 	{
764 		return DFM_FAIL;
765 	}
766 
767 	if (pxDfmEntryData->ulInitialized == 0UL)
768 	{
769 		return DFM_FAIL;
770 	}
771 
772 	if (xEntryHandle == 0)
773 	{
774 		return DFM_FAIL;
775 	}
776 
777 	if (pusChunkCount == (void*)0)
778 	{
779 		return DFM_FAIL;
780 	}
781 
782 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
783 
784 	*pusChunkCount = pxEntryHeader->usChunkCount;
785 
786 	return DFM_SUCCESS;
787 }
788 
xDfmEntryGetSessionIdSize(DfmEntryHandle_t xEntryHandle,uint16_t * pusSize)789 DfmResult_t xDfmEntryGetSessionIdSize(DfmEntryHandle_t xEntryHandle, uint16_t* pusSize)
790 {
791 	DfmEntryHeader_t* pxEntryHeader;
792 
793 	if (pxDfmEntryData == (void*)0)
794 	{
795 		return DFM_FAIL;
796 	}
797 
798 	if (pxDfmEntryData->ulInitialized == 0UL)
799 	{
800 		return DFM_FAIL;
801 	}
802 
803 	if (xEntryHandle == 0)
804 	{
805 		return DFM_FAIL;
806 	}
807 
808 	if (pusSize == (void*)0)
809 	{
810 		return DFM_FAIL;
811 	}
812 
813 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
814 
815 	*pusSize = pxEntryHeader->usSessionIdSize;
816 
817 	return DFM_SUCCESS;
818 }
819 
xDfmEntryGetDeviceNameSize(DfmEntryHandle_t xEntryHandle,uint16_t * pusSize)820 DfmResult_t xDfmEntryGetDeviceNameSize(DfmEntryHandle_t xEntryHandle, uint16_t* pusSize)
821 {
822 	DfmEntryHeader_t* pxEntryHeader;
823 
824 	if (pxDfmEntryData == (void*)0)
825 	{
826 		return DFM_FAIL;
827 	}
828 
829 	if (pxDfmEntryData->ulInitialized == 0UL)
830 	{
831 		return DFM_FAIL;
832 	}
833 
834 	if (xEntryHandle == 0)
835 	{
836 		return DFM_FAIL;
837 	}
838 
839 	if (pusSize == (void*)0)
840 	{
841 		return DFM_FAIL;
842 	}
843 
844 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
845 
846 	*pusSize = pxEntryHeader->usDeviceNameSize;
847 
848 	return DFM_SUCCESS;
849 }
850 
xDfmEntryGetDescriptionSize(DfmEntryHandle_t xEntryHandle,uint16_t * pusSize)851 DfmResult_t xDfmEntryGetDescriptionSize(DfmEntryHandle_t xEntryHandle, uint16_t* pusSize)
852 {
853 	DfmEntryHeader_t* pxEntryHeader;
854 
855 	if (pxDfmEntryData == (void*)0)
856 	{
857 		return DFM_FAIL;
858 	}
859 
860 	if (pxDfmEntryData->ulInitialized == 0UL)
861 	{
862 		return DFM_FAIL;
863 	}
864 
865 	if (xEntryHandle == 0)
866 	{
867 		return DFM_FAIL;
868 	}
869 
870 	if (pusSize == (void*)0)
871 	{
872 		return DFM_FAIL;
873 	}
874 
875 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
876 
877 	*pusSize = pxEntryHeader->usDescriptionSize;
878 
879 	return DFM_SUCCESS;
880 }
881 
xDfmEntryGetDataSize(DfmEntryHandle_t xEntryHandle,uint32_t * pulSize)882 DfmResult_t xDfmEntryGetDataSize(DfmEntryHandle_t xEntryHandle, uint32_t* pulSize)
883 {
884 	DfmEntryHeader_t* pxEntryHeader;
885 
886 	if (pxDfmEntryData == (void*)0)
887 	{
888 		return DFM_FAIL;
889 	}
890 
891 	if (pxDfmEntryData->ulInitialized == 0UL)
892 	{
893 		return DFM_FAIL;
894 	}
895 
896 	if (xEntryHandle == 0)
897 	{
898 		return DFM_FAIL;
899 	}
900 
901 	if (pulSize == (void*)0)
902 	{
903 		return DFM_FAIL;
904 	}
905 
906 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
907 
908 	*pulSize = pxEntryHeader->ulDataSize;
909 
910 	return DFM_SUCCESS;
911 }
912 
xDfmEntryGetAlertId(DfmEntryHandle_t xEntryHandle,uint32_t * pulAlertId)913 DfmResult_t xDfmEntryGetAlertId(DfmEntryHandle_t xEntryHandle, uint32_t* pulAlertId)
914 {
915 	DfmEntryHeader_t* pxEntryHeader;
916 
917 	if (pxDfmEntryData == (void*)0)
918 	{
919 		return DFM_FAIL;
920 	}
921 
922 	if (pxDfmEntryData->ulInitialized == 0UL)
923 	{
924 		return DFM_FAIL;
925 	}
926 
927 	if (xEntryHandle == 0)
928 	{
929 		return DFM_FAIL;
930 	}
931 
932 	if (pulAlertId == (void*)0)
933 	{
934 		return DFM_FAIL;
935 	}
936 
937 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
938 
939 	*pulAlertId = pxEntryHeader->ulAlertId;
940 
941 	return DFM_SUCCESS;
942 }
943 
xDfmEntryGetSessionId(DfmEntryHandle_t xEntryHandle,const char ** pszSessionId)944 DfmResult_t xDfmEntryGetSessionId(DfmEntryHandle_t xEntryHandle, const char** pszSessionId)
945 {
946 	DfmEntryHeader_t* pxEntryHeader;
947 
948 	if (pxDfmEntryData == (void*)0)
949 	{
950 		return DFM_FAIL;
951 	}
952 
953 	if (pxDfmEntryData->ulInitialized == 0UL)
954 	{
955 		return DFM_FAIL;
956 	}
957 
958 	if (xEntryHandle == 0)
959 	{
960 		return DFM_FAIL;
961 	}
962 
963 	if (pszSessionId == (void*)0)
964 	{
965 		return DFM_FAIL;
966 	}
967 
968 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
969 
970 	/* TODO: 64-bit support */
971 	/* SessionId is located right after Header */
972 	*pszSessionId = (char*)((uint32_t)pxEntryHeader + sizeof(DfmEntryHeader_t)); /*cstat !MISRAC2012-Rule-18.4 The Session Id is stored after the Entry Header*/
973 
974 	return DFM_SUCCESS;
975 }
976 
xDfmEntryGetDeviceName(DfmEntryHandle_t xEntryHandle,const char ** pszDeviceName)977 DfmResult_t xDfmEntryGetDeviceName(DfmEntryHandle_t xEntryHandle, const char** pszDeviceName)
978 {
979 	DfmEntryHeader_t* pxEntryHeader;
980 
981 	if (pxDfmEntryData == (void*)0)
982 	{
983 		return DFM_FAIL;
984 	}
985 
986 	if (pxDfmEntryData->ulInitialized == 0UL)
987 	{
988 		return DFM_FAIL;
989 	}
990 
991 	if (xEntryHandle == 0)
992 	{
993 		return DFM_FAIL;
994 	}
995 
996 	if (pszDeviceName == (void*)0)
997 	{
998 		return DFM_FAIL;
999 	}
1000 
1001 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
1002 
1003 	/* TODO: 64-bit support. Also check alignment of all sizes. */
1004 	/* Description is located right after SessionId */
1005 	*pszDeviceName = (char*)((uint32_t)pxEntryHeader + sizeof(DfmEntryHeader_t) + (uint32_t)pxEntryHeader->usSessionIdSize); /*cstat !MISRAC2012-Rule-18.4 The Device Name is stored after the Entry Header and Session Id*/
1006 
1007 	return DFM_SUCCESS;
1008 }
1009 
xDfmEntryGetDescription(DfmEntryHandle_t xEntryHandle,const char ** pszDescription)1010 DfmResult_t xDfmEntryGetDescription(DfmEntryHandle_t xEntryHandle, const char** pszDescription)
1011 {
1012 	DfmEntryHeader_t* pxEntryHeader;
1013 
1014 	if (pxDfmEntryData == (void*)0)
1015 	{
1016 		return DFM_FAIL;
1017 	}
1018 
1019 	if (pxDfmEntryData->ulInitialized == 0UL)
1020 	{
1021 		return DFM_FAIL;
1022 	}
1023 
1024 	if (xEntryHandle == 0)
1025 	{
1026 		return DFM_FAIL;
1027 	}
1028 
1029 	if (pszDescription == (void*)0)
1030 	{
1031 		return DFM_FAIL;
1032 	}
1033 
1034 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
1035 
1036 	/* TODO: 64-bit support. Also check alignment of all sizes. */
1037 	/* Description is located right after SessionId */
1038 	*pszDescription = (char*)((uint32_t)pxEntryHeader + sizeof(DfmEntryHeader_t) + (uint32_t)pxEntryHeader->usSessionIdSize + (uint32_t)pxEntryHeader->usDeviceNameSize); /*cstat !MISRAC2012-Rule-18.4 The Description is stored after the Entry Header, Session Id and Device Name*/
1039 
1040 	return DFM_SUCCESS;
1041 }
1042 
xDfmEntryGetData(DfmEntryHandle_t xEntryHandle,void ** ppvData)1043 DfmResult_t xDfmEntryGetData(DfmEntryHandle_t xEntryHandle, void** ppvData)
1044 {
1045 	DfmEntryHeader_t* pxEntryHeader;
1046 
1047 	if (pxDfmEntryData == (void*)0)
1048 	{
1049 		return DFM_FAIL;
1050 	}
1051 
1052 	if (pxDfmEntryData->ulInitialized == 0UL)
1053 	{
1054 		return DFM_FAIL;
1055 	}
1056 
1057 	if (xEntryHandle == 0)
1058 	{
1059 		return DFM_FAIL;
1060 	}
1061 
1062 	if (ppvData == (void*)0)
1063 	{
1064 		return DFM_FAIL;
1065 	}
1066 
1067 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
1068 
1069 	/* TODO: 64-bit support. Also check alignment of all sizes. */
1070 	/* Data is located right after Description */
1071 	*ppvData = (void*)((uint32_t)pxEntryHeader + sizeof(DfmEntryHeader_t) + (uint32_t)pxEntryHeader->usSessionIdSize + (uint32_t)pxEntryHeader->usDeviceNameSize + (uint32_t)pxEntryHeader->usDescriptionSize); /*cstat !MISRAC2012-Rule-11.6 !MISRAC2012-Rule-18.4 The Entry Data is stored after the Entry Header, Session Id, Device Name and Description*/
1072 
1073 	return DFM_SUCCESS;
1074 }
1075 
xDfmEntryGetEndMarkers(DfmEntryHandle_t xEntryHandle,uint8_t ** pucMarkersBuffer)1076 DfmResult_t xDfmEntryGetEndMarkers(DfmEntryHandle_t xEntryHandle, uint8_t** pucMarkersBuffer)
1077 {
1078 	DfmEntryHeader_t* pxEntryHeader;
1079 
1080 	if (pxDfmEntryData == (void*)0)
1081 	{
1082 		return DFM_FAIL;
1083 	}
1084 
1085 	if (pxDfmEntryData->ulInitialized == 0UL)
1086 	{
1087 		return DFM_FAIL;
1088 	}
1089 
1090 	if (xEntryHandle == 0)
1091 	{
1092 		return DFM_FAIL;
1093 	}
1094 
1095 	if (pucMarkersBuffer == (void*)0)
1096 	{
1097 		return DFM_FAIL;
1098 	}
1099 
1100 	pxEntryHeader = (DfmEntryHeader_t*)xEntryHandle;
1101 
1102 	if ((pxEntryHeader->cStartMarkers[0] != (uint16_t)0xD1) ||
1103 		(pxEntryHeader->cStartMarkers[1] != (uint16_t)0xD2) ||
1104 		(pxEntryHeader->cStartMarkers[2] != (uint16_t)0xD3) ||
1105 		(pxEntryHeader->cStartMarkers[3] != (uint16_t)0xD4))
1106 	{
1107 		return DFM_FAIL;
1108 	}
1109 
1110 	/* TODO: 64-bit support. Also check alignment of all sizes. */
1111 	/* Footer is located right after Data */
1112 	*pucMarkersBuffer = (uint8_t*)((uint32_t)pxEntryHeader + sizeof(DfmEntryHeader_t) + (uint32_t)pxEntryHeader->usSessionIdSize + (uint32_t)pxEntryHeader->usDeviceNameSize + (uint32_t)pxEntryHeader->usDescriptionSize + pxEntryHeader->ulDataSize); /*cstat !MISRAC2012-Rule-18.4 The End Markers are stored after the Entry Header, Session Id, Device Name, Description and Entry Data*/
1113 
1114 	return DFM_SUCCESS;
1115 }
1116 
1117 #endif
1118