1 /*
2  * Percepio DFM v2.1.0
3  * Copyright 2023 Percepio AB
4  * www.percepio.com
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * DFM Alert
9  */
10 
11 #include <dfm.h>
12 
13 #if ((DFM_CFG_ENABLED) >= 1)
14 
15 static DfmResult_t prvDfmAlertInitialize(DfmAlertHandle_t xAlertHandle, uint8_t ucDfmVersion, uint32_t ulProduct, const char* szFirmwareVersion);
16 static uint32_t prvDfmAlertCalculateChecksum(uint8_t* pxData, uint32_t ulSize);
17 static void prvDfmAlertReset(DfmAlert_t* pxAlert);
18 static DfmResult_t prvDfmProcessAlert(DfmAlertEntryCallback_t xAlertCallback, DfmAlertEntryCallback_t xPayloadCallback);
19 static DfmResult_t prvDfmGetAll(DfmAlertEntryCallback_t xAlertCallback, DfmAlertEntryCallback_t xPayloadCallback);
20 
21 static DfmResult_t prvStoreAlert(DfmEntryHandle_t xEntryHandle);
22 static DfmResult_t prvStorePayloadChunk(DfmEntryHandle_t xEntryHandle);
23 static DfmResult_t prvSendAlert(DfmEntryHandle_t xEntryHandle);
24 static DfmResult_t prvSendPayloadChunk(DfmEntryHandle_t xEntryHandle);
25 
26 DfmAlertData_t* pxDfmAlertData = (void*)0;
27 
28 #if defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1)
prvStoreRetainedMemoryAlert(DfmEntryHandle_t xEntryHandle)29 static DfmResult_t prvStoreRetainedMemoryAlert(DfmEntryHandle_t xEntryHandle)
30 {
31 	return xDfmRetainedMemoryWriteAlert(xEntryHandle);
32 }
33 
prvStoreRetainedMemoryPayloadChunk(DfmEntryHandle_t xEntryHandle)34 static DfmResult_t prvStoreRetainedMemoryPayloadChunk(DfmEntryHandle_t xEntryHandle)
35 {
36 	/* We don't care if payload stuff fails */
37 	(void)xDfmRetainedMemoryWritePayloadChunk(xEntryHandle);
38 
39 	return DFM_SUCCESS;
40 }
41 #endif
42 
prvStoreAlert(DfmEntryHandle_t xEntryHandle)43 static DfmResult_t prvStoreAlert(DfmEntryHandle_t xEntryHandle)
44 {
45 	return xDfmStorageStoreAlert(xEntryHandle);
46 }
47 
prvStorePayloadChunk(DfmEntryHandle_t xEntryHandle)48 static DfmResult_t prvStorePayloadChunk(DfmEntryHandle_t xEntryHandle)
49 {
50 	/* We don't care if payload stuff fails */
51 	(void)xDfmStorageStorePayloadChunk(xEntryHandle);
52 
53 	return DFM_SUCCESS;
54 }
55 
prvSendAlert(DfmEntryHandle_t xEntryHandle)56 static DfmResult_t prvSendAlert(DfmEntryHandle_t xEntryHandle)
57 {
58 	return xDfmCloudSendAlert(xEntryHandle);
59 }
60 
prvSendPayloadChunk(DfmEntryHandle_t xEntryHandle)61 static DfmResult_t prvSendPayloadChunk(DfmEntryHandle_t xEntryHandle)
62 {
63 	/* We don't care if payload stuff fails */
64 	(void)xDfmCloudSendPayloadChunk(xEntryHandle);
65 
66 	return DFM_SUCCESS;
67 }
68 
xDfmAlertInitialize(DfmAlertData_t * pxBuffer)69 DfmResult_t xDfmAlertInitialize(DfmAlertData_t *pxBuffer)
70 {
71 	if (pxBuffer == (void*)0)
72 	{
73 		return DFM_FAIL;
74 	}
75 
76 	pxDfmAlertData = pxBuffer;
77 
78 	pxDfmAlertData->ulPayloadCount = 0;
79 	pxDfmAlertData->ulInitialized = 1;
80 
81 	return prvDfmAlertInitialize((DfmAlertHandle_t)&pxDfmAlertData->xAlert, DFM_VERSION, DFM_CFG_PRODUCTID, DFM_CFG_FIRMWARE_VERSION);
82 }
83 
xDfmAlertGetVersion(DfmAlertHandle_t xAlertHandle,uint8_t * pucVersion)84 DfmResult_t xDfmAlertGetVersion(DfmAlertHandle_t xAlertHandle, uint8_t* pucVersion)
85 {
86 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
87 
88 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
89 	{
90 		return DFM_FAIL;
91 	}
92 
93 	if (pxAlert == (void*)0)
94 	{
95 		return DFM_FAIL;
96 	}
97 
98 	if (pucVersion == (void*)0)
99 	{
100 		return DFM_FAIL;
101 	}
102 
103 	*pucVersion = pxAlert->ucVersion;
104 
105 	return DFM_SUCCESS;
106 }
107 
xDfmAlertGetProduct(DfmAlertHandle_t xAlertHandle,uint32_t * pulProduct)108 DfmResult_t xDfmAlertGetProduct(DfmAlertHandle_t xAlertHandle, uint32_t* pulProduct)
109 {
110 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
111 
112 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
113 	{
114 		return DFM_FAIL;
115 	}
116 
117 	if (pxAlert == (void*)0)
118 	{
119 		return DFM_FAIL;
120 	}
121 
122 	*pulProduct = pxAlert->ulProduct;
123 
124 	return DFM_SUCCESS;
125 }
126 
xDfmAlertGetFirmwareVersion(DfmAlertHandle_t xAlertHandle,const char ** pszFirmwareVersion)127 DfmResult_t xDfmAlertGetFirmwareVersion(DfmAlertHandle_t xAlertHandle, const char** pszFirmwareVersion)
128 {
129 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
130 
131 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
132 	{
133 		return DFM_FAIL;
134 	}
135 
136 	if (pxAlert == (void*)0)
137 	{
138 		return DFM_FAIL;
139 	}
140 
141 	*pszFirmwareVersion = pxAlert->cFirmwareVersionBuffer;
142 
143 	return DFM_SUCCESS;
144 }
145 
xDfmAlertReset(DfmAlertHandle_t xAlertHandle)146 DfmResult_t xDfmAlertReset(DfmAlertHandle_t xAlertHandle)
147 {
148 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
149 
150 	if (pxDfmAlertData == (void*)0)
151 	{
152 		return DFM_FAIL;
153 	}
154 
155 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
156 	{
157 		return DFM_FAIL;
158 	}
159 
160 	if (pxAlert == (void*)0)
161 	{
162 		return DFM_FAIL;
163 	}
164 
165 	prvDfmAlertReset(pxAlert);
166 
167 	return DFM_SUCCESS;
168 }
169 
xDfmAlertBegin(uint32_t ulAlertType,const char * szAlertDescription,DfmAlertHandle_t * pxAlertHandle)170 DfmResult_t xDfmAlertBegin(uint32_t ulAlertType, const char* szAlertDescription, DfmAlertHandle_t* pxAlertHandle)
171 {
172 	DfmAlert_t* pxAlert;
173 	uint32_t i;
174 
175 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
176 	{
177 		return DFM_FAIL;
178 	}
179 
180 	if (pxDfmAlertData == (void*)0)
181 	{
182 		return DFM_FAIL;
183 	}
184 
185 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
186 	{
187 		return DFM_FAIL;
188 	}
189 
190 	if (pxAlertHandle == (void*)0)
191 	{
192 		return DFM_FAIL;
193 	}
194 
195 	if (szAlertDescription == (void*)0)
196 	{
197 		return DFM_FAIL;
198 	}
199 
200 	if (szAlertDescription[0] == (char)0)
201 	{
202 		return DFM_FAIL;
203 	}
204 
205 	pxAlert = &pxDfmAlertData->xAlert;
206 
207 	prvDfmAlertReset(pxAlert);
208 
209 	pxAlert->ucVersion = DFM_VERSION;
210 
211 	pxAlert->ulAlertType = ulAlertType;
212 
213 	if (xDfmSessionGenerateNewAlertId() == DFM_FAIL)
214 	{
215 		return DFM_FAIL;
216 	}
217 
218 	for (i = (uint32_t)0; i < (uint32_t)(DFM_DESCRIPTION_MAX_LEN); i++)
219 	{
220 		pxAlert->cAlertDescription[i] = szAlertDescription[i];
221 
222 		if (szAlertDescription[i] == (char)0)
223 		{
224 			break;
225 		}
226 	}
227 
228 	*pxAlertHandle = (DfmAlertHandle_t)pxAlert;
229 
230 	return DFM_SUCCESS;
231 }
232 
xDfmAlertAddSymptom(DfmAlertHandle_t xAlertHandle,uint32_t ulSymptomId,uint32_t ulValue)233 DfmResult_t xDfmAlertAddSymptom(DfmAlertHandle_t xAlertHandle, uint32_t ulSymptomId, uint32_t ulValue)
234 {
235 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
236 
237 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
238 	{
239 		return DFM_FAIL;
240 	}
241 
242 	if (pxDfmAlertData == (void*)0)
243 	{
244 		return DFM_FAIL;
245 	}
246 
247 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
248 	{
249 		return DFM_FAIL;
250 	}
251 
252 	if (pxAlert == (void*)0)
253 	{
254 		return DFM_FAIL;
255 	}
256 
257 	if (pxDfmAlertData->xAlert.ucSymptomCount >= (uint8_t)(DFM_CFG_MAX_SYMPTOMS))
258 	{
259 		(void)xDfmSessionSetStatus(DFM_STATUS_CODE_MAX_SYMPTOMS_EXCEEDED);
260 		return DFM_FAIL;
261 	}
262 
263 	pxAlert->xSymptoms[pxDfmAlertData->xAlert.ucSymptomCount].ulId = ulSymptomId;
264 	pxAlert->xSymptoms[pxDfmAlertData->xAlert.ucSymptomCount].ulValue = ulValue;
265 
266 	pxDfmAlertData->xAlert.ucSymptomCount++;
267 
268 	return DFM_SUCCESS;
269 }
270 
xDfmAlertGetSymptom(DfmAlertHandle_t xAlertHandle,uint32_t ulIndex,uint32_t * pulSymptomId,uint32_t * pulValue)271 DfmResult_t xDfmAlertGetSymptom(DfmAlertHandle_t xAlertHandle, uint32_t ulIndex, uint32_t* pulSymptomId, uint32_t* pulValue)
272 {
273 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
274 
275 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
276 	{
277 		return DFM_FAIL;
278 	}
279 
280 	if (pxDfmAlertData == (void*)0)
281 	{
282 		return DFM_FAIL;
283 	}
284 
285 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
286 	{
287 		return DFM_FAIL;
288 	}
289 
290 	if (pxAlert == (void*)0)
291 	{
292 		return DFM_FAIL;
293 	}
294 
295 	if (ulIndex >= (uint32_t)(DFM_CFG_MAX_SYMPTOMS))
296 	{
297 		return DFM_FAIL;
298 	}
299 
300 	if (ulIndex >= (uint32_t)pxAlert->ucSymptomCount)
301 	{
302 		return DFM_FAIL;
303 	}
304 
305 	*pulSymptomId = pxAlert->xSymptoms[ulIndex].ulId;
306 	*pulValue = pxAlert->xSymptoms[ulIndex].ulValue;
307 
308 	return DFM_SUCCESS;
309 }
310 
xDfmAlertAddPayload(DfmAlertHandle_t xAlertHandle,void * pvData,uint32_t ulSize,const char * szDescription)311 DfmResult_t xDfmAlertAddPayload(DfmAlertHandle_t xAlertHandle, void* pvData, uint32_t ulSize, const char* szDescription)
312 {
313 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
314 	uint32_t i;
315 
316 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
317 	{
318 		return DFM_FAIL;
319 	}
320 
321 	if (pxDfmAlertData == (void*)0)
322 	{
323 		return DFM_FAIL;
324 	}
325 
326 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
327 	{
328 		return DFM_FAIL;
329 	}
330 
331 	if (pxAlert == (void*)0)
332 	{
333 		return DFM_FAIL;
334 	}
335 
336 	if (pvData == (void*)0)
337 	{
338 		return DFM_FAIL;
339 	}
340 
341 	if (ulSize == (uint32_t)0)
342 	{
343 		return DFM_FAIL;
344 	}
345 
346 	if (szDescription == (void*)0)
347 	{
348 		return DFM_FAIL;
349 	}
350 
351 	if (szDescription[0] == (char)0)
352 	{
353 		return DFM_FAIL;
354 	}
355 
356 	if (pxDfmAlertData->ulPayloadCount >= (uint32_t)(DFM_CFG_MAX_PAYLOADS))
357 	{
358 		return DFM_FAIL;
359 	}
360 
361 	pxDfmAlertData->xPayloads[pxDfmAlertData->ulPayloadCount].pvData = pvData;
362 
363 	pxDfmAlertData->xPayloads[pxDfmAlertData->ulPayloadCount].ulSize = ulSize;
364 
365 	for (i = (uint32_t)0; i < (uint32_t)(DFM_PAYLOAD_DESCRIPTION_MAX_LEN); i++)
366 	{
367 		pxDfmAlertData->xPayloads[pxDfmAlertData->ulPayloadCount].cDescriptionBuffer[i] = szDescription[i];
368 
369 		if (szDescription[i] == (char)0)
370 		{
371 			break;
372 		}
373 	}
374 
375 	pxDfmAlertData->ulPayloadCount++;
376 
377 	return DFM_SUCCESS;
378 }
379 
xDfmAlertGetPayload(DfmAlertHandle_t xAlertHandle,uint32_t ulIndex,void ** ppvData,uint32_t * pulSize,char ** pszDescription)380 DfmResult_t xDfmAlertGetPayload(DfmAlertHandle_t xAlertHandle, uint32_t ulIndex, void** ppvData, uint32_t* pulSize, char** pszDescription)
381 {
382 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
383 
384 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
385 	{
386 		return DFM_FAIL;
387 	}
388 
389 	if (pxDfmAlertData == (void*)0)
390 	{
391 		return DFM_FAIL;
392 	}
393 
394 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
395 	{
396 		return DFM_FAIL;
397 	}
398 
399 	if (pxAlert == (void*)0)
400 	{
401 		return DFM_FAIL;
402 	}
403 
404 	if (ppvData == (void*)0)
405 	{
406 		return DFM_FAIL;
407 	}
408 
409 	if (pulSize == (void*)0)
410 	{
411 		return DFM_FAIL;
412 	}
413 
414 	if (pszDescription == (void*)0)
415 	{
416 		return DFM_FAIL;
417 	}
418 
419 	if (ulIndex >= (uint32_t)(DFM_CFG_MAX_PAYLOADS))
420 	{
421 		return DFM_FAIL;
422 	}
423 
424 	if (ulIndex >= pxDfmAlertData->ulPayloadCount)
425 	{
426 		return DFM_FAIL;
427 	}
428 
429 	*ppvData = pxDfmAlertData->xPayloads[ulIndex].pvData;
430 
431 	*pulSize = pxDfmAlertData->xPayloads[ulIndex].ulSize;
432 
433 	*pszDescription = pxDfmAlertData->xPayloads[ulIndex].cDescriptionBuffer;
434 
435 	return DFM_SUCCESS;
436 }
437 
xDfmAlertGetType(DfmAlertHandle_t xAlertHandle,uint32_t * pulAlertType)438 DfmResult_t xDfmAlertGetType(DfmAlertHandle_t xAlertHandle, uint32_t* pulAlertType)
439 {
440 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
441 
442 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
443 	{
444 		return DFM_FAIL;
445 	}
446 
447 	if (pxDfmAlertData == (void*)0)
448 	{
449 		return DFM_FAIL;
450 	}
451 
452 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
453 	{
454 		return DFM_FAIL;
455 	}
456 
457 	if (pxAlert == (void*)0)
458 	{
459 		return DFM_FAIL;
460 	}
461 
462 	if (pulAlertType == (void*)0)
463 	{
464 		return DFM_FAIL;
465 	}
466 
467 	*pulAlertType = pxAlert->ulAlertType;
468 
469 	return DFM_SUCCESS;
470 }
471 
xDfmAlertGetDescription(DfmAlertHandle_t xAlertHandle,const char ** pszAlertDescription)472 DfmResult_t xDfmAlertGetDescription(DfmAlertHandle_t xAlertHandle, const char** pszAlertDescription)
473 {
474 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
475 
476 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
477 	{
478 		return DFM_FAIL;
479 	}
480 
481 	if (pxDfmAlertData == (void*)0)
482 	{
483 		return DFM_FAIL;
484 	}
485 
486 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
487 	{
488 		return DFM_FAIL;
489 	}
490 
491 	if (pxAlert == (void*)0)
492 	{
493 		return DFM_FAIL;
494 	}
495 
496 	if (pszAlertDescription == (void*)0)
497 	{
498 		return DFM_FAIL;
499 	}
500 
501 	*pszAlertDescription = pxAlert->cAlertDescription;
502 
503 	return DFM_SUCCESS;
504 }
505 
xDfmAlertEndCustom(DfmAlertHandle_t xAlertHandle,uint32_t ulEndType)506 DfmResult_t xDfmAlertEndCustom(DfmAlertHandle_t xAlertHandle, uint32_t ulEndType)
507 {
508 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
509 
510 	if (ulDfmSessionIsEnabled() == (uint32_t)0)
511 	{
512 		return DFM_FAIL;
513 	}
514 
515 	if (pxDfmAlertData == (void*)0)
516 	{
517 		return DFM_FAIL;
518 	}
519 
520 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
521 	{
522 		return DFM_FAIL;
523 	}
524 
525 	if (pxAlert == (void*)0)
526 	{
527 		return DFM_FAIL;
528 	}
529 
530 	pxAlert->ulChecksum = prvDfmAlertCalculateChecksum((uint8_t*)pxAlert, sizeof(DfmAlert_t) - sizeof(uint32_t));
531 
532 	if ((ulEndType & DFM_ALERT_END_TYPE_SEND) > 0)
533 	{
534 		/* Try to send */
535 		if (prvDfmProcessAlert(prvSendAlert, prvSendPayloadChunk) == DFM_SUCCESS)
536 		{
537 			prvDfmAlertReset(pxAlert);
538 
539 			return DFM_SUCCESS;
540 		}
541 	}
542 
543 	if ((ulEndType & DFM_ALERT_END_TYPE_STORE) > 0)
544 	{
545 		/* Try to store */
546 		if (prvDfmProcessAlert(prvStoreAlert, prvStorePayloadChunk) == DFM_SUCCESS)
547 		{
548 			prvDfmAlertReset(pxAlert);
549 
550 			return DFM_SUCCESS;
551 		}
552 	}
553 
554 
555 #if (defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1))
556 	if ((ulEndType & DFM_ALERT_END_TYPE_RETAIN) > 0)
557 	{
558 		/* Try to store in retained memory*/
559 		if (prvDfmProcessAlert(prvStoreRetainedMemoryAlert, prvStoreRetainedMemoryPayloadChunk) == DFM_SUCCESS)
560 		{
561 			prvDfmAlertReset(pxAlert);
562 
563 			return DFM_SUCCESS;
564 		}
565 	}
566 #endif
567 
568 	/* Could not send or store */
569 	prvDfmAlertReset(pxAlert);
570 
571 	return DFM_FAIL;
572 }
573 
prvDfmAlertInitialize(DfmAlertHandle_t xAlertHandle,uint8_t ucDfmVersion,uint32_t ulProduct,const char * szFirmwareVersion)574 static DfmResult_t prvDfmAlertInitialize(DfmAlertHandle_t xAlertHandle, uint8_t ucDfmVersion, uint32_t ulProduct, const char* szFirmwareVersion)
575 {
576 	uint32_t i;
577 	DfmAlert_t* pxAlert = (DfmAlert_t*)xAlertHandle;
578 
579 	if (pxDfmAlertData == (void*)0)
580 	{
581 		return DFM_FAIL;
582 	}
583 
584 	if (pxAlert == (void*)0)
585 	{
586 		return DFM_FAIL;
587 	}
588 
589 	if (szFirmwareVersion == (void*)0) /*cstat !MISRAC2012-Rule-14.3_b C-STAT complains because DFM_CFG_FIRMWARE_VERSION refers to a static string that is never null in this project. In user projects, this is not guaranteed and must therefor be checked.*/
590 	{
591 		return DFM_FAIL;
592 	}
593 
594 	pxDfmAlertData->xAlert.ucStartMarkers[0] = 0x50; /* 'P' */
595 	pxDfmAlertData->xAlert.ucStartMarkers[1] = 0x44; /* 'D' */
596 	pxDfmAlertData->xAlert.ucStartMarkers[2] = 0x66; /* 'f' */
597 	pxDfmAlertData->xAlert.ucStartMarkers[3] = 0x6D; /* 'm' */
598 
599 	pxDfmAlertData->xAlert.usEndianness = 0x0FF0;
600 	pxDfmAlertData->xAlert.ucVersion = ucDfmVersion;
601 	pxDfmAlertData->xAlert.ucMaxSymptoms = (DFM_CFG_MAX_SYMPTOMS);
602 	pxDfmAlertData->xAlert.ucFirmwareVersionSize = (DFM_FIRMWARE_VERSION_MAX_LEN);
603 	pxDfmAlertData->xAlert.ucDescriptionSize = (DFM_DESCRIPTION_MAX_LEN);
604 	pxDfmAlertData->xAlert.ulProduct = ulProduct;
605 
606 	for (i = (uint32_t)0; i < (uint32_t)(DFM_FIRMWARE_VERSION_MAX_LEN); i++)
607 	{
608 		pxAlert->cFirmwareVersionBuffer[i] = szFirmwareVersion[i];
609 		if (szFirmwareVersion[i] == (char)0)
610 		{
611 			break;
612 		}
613 	}
614 
615 	prvDfmAlertReset(pxAlert);
616 
617 	pxAlert->ucEndMarkers[0] = 0x6D; /* 'm' */
618 	pxAlert->ucEndMarkers[1] = 0x66; /* 'f' */
619 	pxAlert->ucEndMarkers[2] = 0x44; /* 'D' */
620 	pxAlert->ucEndMarkers[3] = 0x50; /* 'P' */
621 
622 	return DFM_SUCCESS;
623 }
624 
xDfmAlertSendAll(void)625 DfmResult_t xDfmAlertSendAll(void)
626 {
627 	return prvDfmGetAll(xDfmCloudSendAlert, xDfmCloudSendPayloadChunk);
628 }
629 
xDfmAlertGetAll(DfmAlertEntryCallback_t xCallback)630 DfmResult_t xDfmAlertGetAll(DfmAlertEntryCallback_t xCallback)
631 {
632 	return prvDfmGetAll(xCallback, xCallback);
633 }
634 
xDfmAlertStoreRetainedMemory(void)635 DfmResult_t xDfmAlertStoreRetainedMemory(void)
636 {
637 #if (defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1))
638 	DfmEntryHandle_t xEntryHandle = 0;
639 	uint32_t i;
640 	const char* szSessionId = (void*)0;
641 	char cSessionIdBuffer[DFM_SESSION_ID_MAX_LEN] = { 0 };
642 	uint32_t ulAlertId = 0;
643 	void* pvBuffer = (void*)0;
644 	uint32_t ulBufferSize = 0;
645 
646 	if (pxDfmAlertData == (void*)0)
647 	{
648 		return DFM_FAIL;
649 	}
650 
651 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
652 	{
653 		return DFM_FAIL;
654 	}
655 
656 	if (xDfmEntryGetBuffer(&pvBuffer, &ulBufferSize) == DFM_FAIL)
657 	{
658 		return DFM_FAIL;
659 	}
660 
661 	memset(pvBuffer, 0, ulBufferSize);
662 
663 	if (xDfmRetainedMemoryReadAlert(pvBuffer, ulBufferSize) == DFM_SUCCESS)
664 	{
665 		while(1)
666 		{
667 			if (xDfmEntryCreateAlertFromBuffer(&xEntryHandle) == DFM_FAIL)
668 			{
669 				break;
670 			}
671 
672 			if (xDfmEntryGetSessionId(xEntryHandle, &szSessionId) == DFM_FAIL)
673 			{
674 				break;
675 			}
676 
677 			if (xDfmEntryGetAlertId(xEntryHandle, &ulAlertId) == DFM_FAIL)
678 			{
679 				break;
680 			}
681 
682 			/* Create local copy of sessionId since the buffer containing it WILL be overwritten! */
683 			for (i = 0; i < sizeof(cSessionIdBuffer); i++)
684 			{
685 				cSessionIdBuffer[i] = szSessionId[i];
686 
687 				if (cSessionIdBuffer[i] == (char)0)
688 				{
689 					break;
690 				}
691 			}
692 
693 			if (prvStoreAlert(xEntryHandle) == DFM_FAIL)
694 			{
695 				break;
696 			}
697 
698 			memset(pvBuffer, 0, ulBufferSize);
699 
700 			while (xDfmRetainedMemoryReadPayloadChunk(cSessionIdBuffer, ulAlertId, pvBuffer, ulBufferSize) == DFM_SUCCESS)
701 			{
702 				if (xDfmEntryCreatePayloadChunkFromBuffer(cSessionIdBuffer , ulAlertId, &xEntryHandle) == DFM_FAIL)
703 				{
704 					break;
705 				}
706 
707 				if (prvStorePayloadChunk(xEntryHandle) == DFM_FAIL)
708 				{
709 					break;
710 				}
711 
712 				memset(pvBuffer, 0, ulBufferSize);
713 			}
714 
715 			break;
716 		}
717 	}
718 
719 	(void)xDfmRetainedMemoryClear();
720 
721 	return DFM_SUCCESS;
722 #else
723 	return DFM_FAIL;
724 #endif
725 }
726 
prvDfmGetAll(DfmAlertEntryCallback_t xAlertCallback,DfmAlertEntryCallback_t xPayloadCallback)727 static DfmResult_t prvDfmGetAll(DfmAlertEntryCallback_t xAlertCallback, DfmAlertEntryCallback_t xPayloadCallback)
728 {
729 	DfmEntryHandle_t xEntryHandle = 0;
730 	uint32_t i;
731 	const char* szSessionId = (void*)0;
732 	char cSessionIdBuffer[DFM_SESSION_ID_MAX_LEN] = { 0 };
733 	uint32_t ulAlertId = 0;
734 	void* pvBuffer = (void*)0;
735 	uint32_t ulBufferSize = 0;
736 
737 	if (pxDfmAlertData == (void*)0)
738 	{
739 		return DFM_FAIL;
740 	}
741 
742 	if (pxDfmAlertData->ulInitialized == (uint32_t)0)
743 	{
744 		return DFM_FAIL;
745 	}
746 
747 	if (xAlertCallback == 0)
748 	{
749 		return DFM_FAIL;
750 	}
751 
752 	if (xPayloadCallback == 0)
753 	{
754 		return DFM_FAIL;
755 	}
756 
757 	if (xDfmEntryGetBuffer(&pvBuffer, &ulBufferSize) == DFM_FAIL)
758 	{
759 		return DFM_FAIL;
760 	}
761 
762 #if (defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1))
763 	memset(pvBuffer, 0, ulBufferSize);
764 
765 	if (xDfmRetainedMemoryReadAlert(pvBuffer, ulBufferSize) == DFM_SUCCESS)
766 	{
767 		while (1)
768 		{
769 			if (xDfmEntryCreateAlertFromBuffer(&xEntryHandle) == DFM_FAIL)
770 			{
771 				break;
772 			}
773 
774 			if (xAlertCallback(xEntryHandle) == DFM_FAIL)
775 			{
776 				break;
777 			}
778 
779 			if (xDfmEntryGetSessionId(xEntryHandle, &szSessionId) == DFM_FAIL)
780 			{
781 				break;
782 			}
783 
784 			if (xDfmEntryGetAlertId(xEntryHandle, &ulAlertId) == DFM_FAIL)
785 			{
786 				break;
787 			}
788 
789 			/* Create local copy of sessionId since the buffer containing it WILL be overwritten! */
790 			for (i = 0; i < sizeof(cSessionIdBuffer); i++)
791 			{
792 				cSessionIdBuffer[i] = szSessionId[i];
793 
794 				if (cSessionIdBuffer[i] == (char)0)
795 				{
796 					break;
797 				}
798 			}
799 
800 			memset(pvBuffer, 0, ulBufferSize);
801 
802 			while (xDfmRetainedMemoryReadPayloadChunk(cSessionIdBuffer, ulAlertId, pvBuffer, ulBufferSize) == DFM_SUCCESS)
803 			{
804 				if (xDfmEntryCreatePayloadChunkFromBuffer(cSessionIdBuffer , ulAlertId, &xEntryHandle) == DFM_FAIL)
805 				{
806 					break;
807 				}
808 
809 				if (xPayloadCallback(xEntryHandle) == DFM_FAIL)
810 				{
811 					break;
812 				}
813 
814 				memset(pvBuffer, 0, ulBufferSize);
815 			}
816 
817 			break;
818 		}
819 	}
820 
821 	(void)xDfmRetainedMemoryClear();
822 #endif
823 
824 	memset(pvBuffer, 0, ulBufferSize);
825 
826 	while (xDfmStorageGetAlert(pvBuffer, ulBufferSize) == DFM_SUCCESS)
827 	{
828 		if (xDfmEntryCreateAlertFromBuffer(&xEntryHandle) == DFM_FAIL)
829 		{
830 			break;
831 		}
832 
833 		if (xAlertCallback(xEntryHandle) == DFM_FAIL)
834 		{
835 			break;
836 		}
837 
838 		if (xDfmEntryGetSessionId(xEntryHandle, &szSessionId) == DFM_FAIL)
839 		{
840 			break;
841 		}
842 
843 		if (xDfmEntryGetAlertId(xEntryHandle, &ulAlertId) == DFM_FAIL)
844 		{
845 			break;
846 		}
847 
848 		/* Create local copy of sessionId since the buffer containing it WILL be overwritten! */
849 		for (i = 0; i < sizeof(cSessionIdBuffer); i++)
850 		{
851 			cSessionIdBuffer[i] = szSessionId[i];
852 
853 			if (cSessionIdBuffer[i] == (char)0)
854 			{
855 				break;
856 			}
857 		}
858 
859 		memset(pvBuffer, 0, ulBufferSize);
860 
861 		while (xDfmStorageGetPayloadChunk(cSessionIdBuffer, ulAlertId, pvBuffer, ulBufferSize) == DFM_SUCCESS)
862 		{
863 			if (xDfmEntryCreatePayloadChunkFromBuffer(cSessionIdBuffer , ulAlertId, &xEntryHandle) == DFM_FAIL)
864 			{
865 				break;
866 			}
867 
868 			if (xPayloadCallback(xEntryHandle) == DFM_FAIL)
869 			{
870 				break;
871 			}
872 
873 			memset(pvBuffer, 0, ulBufferSize);
874 		}
875 	}
876 
877 	return DFM_SUCCESS;
878 }
879 
prvDfmAlertReset(DfmAlert_t * pxAlert)880 static void prvDfmAlertReset(DfmAlert_t* pxAlert)
881 {
882 	uint32_t i;
883 
884 	pxAlert->ucVersion = 0;
885 
886 	pxAlert->ulAlertType = 0;
887 
888 	for (i = (uint32_t)0; i < (uint32_t)(DFM_CFG_MAX_SYMPTOMS); i++)
889 	{
890 		pxAlert->xSymptoms[i].ulId = 0;
891 		pxAlert->xSymptoms[i].ulValue = 0;
892 	}
893 	pxAlert->ucSymptomCount = 0;
894 
895 	pxAlert->cAlertDescription[0] = (char)0;
896 
897 	for (i = (uint32_t)0; i < (uint32_t)(DFM_CFG_MAX_PAYLOADS); i++)
898 	{
899 		pxDfmAlertData->xPayloads[i].pvData = (void*)0;
900 		pxDfmAlertData->xPayloads[i].ulSize = 0;
901 		pxDfmAlertData->xPayloads[i].cDescriptionBuffer[0] = (char)0;
902 	}
903 	pxDfmAlertData->ulPayloadCount = 0;
904 
905 	pxAlert->ulChecksum = 0;
906 }
907 
prvDfmProcessAlert(DfmAlertEntryCallback_t xAlertCallback,DfmAlertEntryCallback_t xPayloadCallback)908 static DfmResult_t prvDfmProcessAlert(DfmAlertEntryCallback_t xAlertCallback, DfmAlertEntryCallback_t xPayloadCallback)
909 {
910 	uint16_t j, usChunkCount;
911 	uint32_t i, ulOffset, ulChunkSize;
912 	DfmEntryHandle_t xEntryHandle = 0;
913 	DfmAlert_t* pxAlert = &pxDfmAlertData->xAlert;
914 
915 	if (xAlertCallback == 0) /*cstat !MISRAC2012-Rule-14.3_b This is a sanity check. It should never fail, but it will crash hard if someoone has made a mistake and we remove this check.*/
916 	{
917 		return DFM_FAIL;
918 	}
919 
920 	if (xPayloadCallback == 0) /*cstat !MISRAC2012-Rule-14.3_b This is a sanity check. It should never fail, but it will crash hard if someoone has made a mistake and we remove this check.*/
921 	{
922 		return DFM_FAIL;
923 	}
924 
925 	if (xDfmEntryCreateAlert((DfmAlertHandle_t)pxAlert, &xEntryHandle) == DFM_FAIL)
926 	{
927 		return DFM_FAIL;
928 	}
929 
930 	if (xAlertCallback(xEntryHandle) == DFM_FAIL)
931 	{
932 		return DFM_FAIL;
933 	}
934 
935 	for (i = 0; i < pxDfmAlertData->ulPayloadCount; i++)
936 	{
937 		/* We attempt to store the payloads, but if they fail there's not much we can do about it */
938 		usChunkCount = (uint16_t)(((pxDfmAlertData->xPayloads[i].ulSize - 1UL) / (uint32_t)(DFM_CFG_MAX_PAYLOAD_CHUNK_SIZE)) + 1UL);
939 		ulOffset = 0;
940 
941 		/* First we create the payload header */
942 		if (xDfmEntryCreatePayloadHeader((DfmAlertHandle_t)pxAlert, (uint16_t)(i + 1UL), pxDfmAlertData->xPayloads[i].ulSize, pxDfmAlertData->xPayloads[i].cDescriptionBuffer, &xEntryHandle) == DFM_FAIL)
943 		{
944 			/* Couldn't create header for this payload, continue to next */
945 			continue;
946 		}
947 
948 		/* Send payload header */
949 		if (xPayloadCallback(xEntryHandle) == DFM_FAIL)
950 		{
951 			/* Payload header wasn't handled, skip the rest */
952 			return DFM_FAIL;
953 		}
954 
955 		for (j = 0; j < usChunkCount; j++)
956 		{
957 			ulChunkSize = DFM_CFG_MAX_PAYLOAD_CHUNK_SIZE;
958 			if (ulChunkSize > pxDfmAlertData->xPayloads[i].ulSize - ulOffset)
959 			{
960 				ulChunkSize = pxDfmAlertData->xPayloads[i].ulSize - ulOffset;
961 			}
962 
963 			if (xDfmEntryCreatePayloadChunk((DfmAlertHandle_t)pxAlert, (uint16_t)(i + 1UL), j + (uint16_t)1, usChunkCount, (void*)((uintptr_t)pxDfmAlertData->xPayloads[i].pvData + ulOffset), ulChunkSize, pxDfmAlertData->xPayloads[i].cDescriptionBuffer, &xEntryHandle) == DFM_FAIL) /*cstat !MISRAC2012-Rule-11.6 We need to modify the address by an offset in order to get next payload chunk*/
964 			{
965 				/* Couldn't create entry for this payload chunk, continue to next */
966 				continue;
967 			}
968 
969 			if (xPayloadCallback(xEntryHandle) == DFM_FAIL)
970 			{
971 				/* Payload chunk wasn't handled, skip the rest */
972 				return DFM_FAIL;
973 			}
974 
975 			ulOffset += ulChunkSize;
976 		}
977 	}
978 
979 	return DFM_SUCCESS;
980 }
981 
prvDfmAlertCalculateChecksum(uint8_t * pxData,uint32_t ulSize)982 static uint32_t prvDfmAlertCalculateChecksum(uint8_t* pxData, uint32_t ulSize)
983 {
984 	(void)pxData;
985 	(void)ulSize;
986 
987 	return 0;
988 }
989 
990 #endif
991