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 Session
9  */
10 
11 #include <dfm.h>
12 
13 #if ((DFM_CFG_ENABLED) >= 1)
14 
15 typedef struct DfmSessionStorage
16 {
17 	uint32_t ulVersion;
18 	uint32_t ulEnabled;
19 } DfmSessionStorage_t;
20 
21 #define DFM_SESSION_STORAGE_VERSION 1
22 
23 #define DFM_SESSION_STORAGE_DUMMY_VALUE 0x93105271UL
24 
25 #if ((DFM_DEVICE_NAME_MAX_LEN) < 8)
26 #error Minimum DFM_CFG_DEVICE_NAME_MAX_LEN size is 8!
27 #endif
28 
29 static DfmSessionData_t* pxDfmSessionData = (void*)0;
30 
31 DfmResult_t prvGetSessionStorageVersion(DfmSessionStorage_t* pxSessionStorage, uint32_t* pulVersion);
32 DfmResult_t prvGetSessionStorageEnabled(DfmSessionStorage_t* pxSessionStorage, uint32_t* pulEnabled);
33 
xDfmSessionInitialize(DfmSessionData_t * pxBuffer)34 DfmResult_t xDfmSessionInitialize(DfmSessionData_t* pxBuffer)
35 {
36 	uint32_t i;
37 	uint32_t ulBytesWritten;
38 
39 	if (pxBuffer == (void*)0)
40 	{
41 		return DFM_FAIL;
42 	}
43 
44 	pxDfmSessionData = pxBuffer;
45 
46 	pxDfmSessionData->ulAlertCounter = 0;
47 
48 	pxDfmSessionData->ulProduct = DFM_CFG_PRODUCTID;
49 
50 	pxDfmSessionData->xStorageStrategy = DFM_CFG_STORAGE_STRATEGY;
51 	pxDfmSessionData->xCloudStrategy = DFM_CFG_CLOUD_STRATEGY;
52 	pxDfmSessionData->xSessionIdStrategy = DFM_CFG_SESSIONID_STRATEGY;
53 
54 	pxDfmSessionData->ulDfmStatus = DFM_STATUS_CODE_OK;
55 
56 	/* We disable it here */
57 	pxDfmSessionData->ulEnabled = DFM_DISABLED;
58 
59 	if (pxDfmSessionData->xSessionIdStrategy == DFM_SESSIONID_STRATEGY_ONSTARTUP)
60 	{
61 		/* Verify that the user supplied callback has been set */
62 		if (xDfmUserGetUniqueSessionID == 0)
63 		{
64 			return DFM_FAIL;
65 		}
66 
67 		if (xDfmUserGetUniqueSessionID(pxDfmSessionData->cUniqueSessionIdBuffer, DFM_SESSION_ID_MAX_LEN, &ulBytesWritten) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The User implementation used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
68 		{
69 			return DFM_FAIL;
70 		}
71 
72 		if (pxDfmSessionData->cUniqueSessionIdBuffer[0] == (char)0)
73 		{
74 			return DFM_FAIL;
75 		}
76 	}
77 	else
78 	{
79 		pxDfmSessionData->cUniqueSessionIdBuffer[0] = (char)0;
80 	}
81 
82 	pxDfmSessionData->cDeviceNameBuffer[0] = (char)0;
83 
84 	for (i = 0; i < (uint32_t)DFM_CFG_FIRMWARE_VERSION_MAX_LEN; i++)
85 	{
86 		pxDfmSessionData->cFirmwareVersionBuffer[i] = (char)(DFM_CFG_FIRMWARE_VERSION)[i];
87 
88 		if (pxDfmSessionData->cFirmwareVersionBuffer[i] == (char)0)
89 		{
90 			break;
91 		}
92 	}
93 
94 	pxDfmSessionData->ulInitialized = 1;
95 
96 	return DFM_SUCCESS;
97 }
98 
xDfmSessionEnable(uint32_t ulOverride)99 DfmResult_t xDfmSessionEnable(uint32_t ulOverride)
100 {
101 	uint8_t cSessionStorageBuffer[8] = {0}; /* This must be large enough to hold all previous versions of DfmSessionStorage_t */
102 	uint32_t ulStoredEnabledValue = DFM_SESSION_STORAGE_DUMMY_VALUE;
103 
104 	if (pxDfmSessionData == (void*)0)
105 	{
106 		return DFM_FAIL;
107 	}
108 
109 	if (pxDfmSessionData->ulInitialized == 0UL)
110 	{
111 		return DFM_FAIL;
112 	}
113 
114 	if (ulDfmIsInitialized() == 0UL)
115 	{
116 		return DFM_FAIL;
117 	}
118 
119 	/* Already enabled? */
120 	if (pxDfmSessionData->ulEnabled == DFM_ENABLED)
121 	{
122 		return DFM_SUCCESS;
123 	}
124 
125 	/* Is a previous session stored? */
126 	if (xDfmStorageGetSession(cSessionStorageBuffer, sizeof(cSessionStorageBuffer)) == DFM_SUCCESS)
127 	{
128 		if (prvGetSessionStorageEnabled((DfmSessionStorage_t*)cSessionStorageBuffer, &ulStoredEnabledValue) == DFM_FAIL) /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
129 		{
130 			/* Unexpected error */
131 			ulStoredEnabledValue = DFM_SESSION_STORAGE_DUMMY_VALUE;
132 		}
133 	}
134 
135 	if ((ulStoredEnabledValue == DFM_SESSION_STORAGE_DUMMY_VALUE) || ((ulOverride == 1UL) && (ulStoredEnabledValue == DFM_DISABLED)))
136 	{
137 		/* Couldn't read stored value or we override a disabled value */
138 		((DfmSessionStorage_t*)cSessionStorageBuffer)->ulVersion = DFM_SESSION_STORAGE_VERSION; /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
139 		((DfmSessionStorage_t*)cSessionStorageBuffer)->ulEnabled = DFM_ENABLED; /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
140 
141 		(void)xDfmStorageStoreSession(cSessionStorageBuffer, sizeof(DfmSessionStorage_t)); /* Attempt to store the session info. We can't really do anything if it fails. */
142 
143 		ulStoredEnabledValue = DFM_ENABLED;
144 	}
145 
146 	if (ulStoredEnabledValue == DFM_DISABLED)
147 	{
148 		/* We are expressly disabled and not overriding */
149 		return DFM_FAIL;
150 	}
151 
152 	pxDfmSessionData->ulEnabled = DFM_ENABLED;
153 
154 	return DFM_SUCCESS;
155 }
156 
xDfmSessionDisable(uint32_t ulRemember)157 DfmResult_t xDfmSessionDisable(uint32_t ulRemember)
158 {
159 	uint8_t cSessionStorageBuffer[8] = { 0 }; /* This must be large enough to hold all previous versions of DfmSessionStorage_t */
160 	uint32_t ulStoredEnabledValue = DFM_SESSION_STORAGE_DUMMY_VALUE;
161 
162 	if (pxDfmSessionData == (void*)0)
163 	{
164 		return DFM_FAIL;
165 	}
166 
167 	if (pxDfmSessionData->ulInitialized == 0UL)
168 	{
169 		return DFM_FAIL;
170 	}
171 
172 	/* Is a previous session stored? */
173 	if (xDfmStorageGetSession(cSessionStorageBuffer, sizeof(cSessionStorageBuffer)) == DFM_SUCCESS)
174 	{
175 		if (prvGetSessionStorageEnabled((DfmSessionStorage_t*)cSessionStorageBuffer, &ulStoredEnabledValue) == DFM_FAIL) /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
176 		{
177 			/* Unexpected error */
178 			ulStoredEnabledValue = DFM_SESSION_STORAGE_DUMMY_VALUE;
179 		}
180 	}
181 
182 	if (ulStoredEnabledValue != DFM_DISABLED)
183 	{
184 		/* We didn't find disabled */
185 		((DfmSessionStorage_t*)cSessionStorageBuffer)->ulVersion = DFM_SESSION_STORAGE_VERSION; /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
186 		((DfmSessionStorage_t*)cSessionStorageBuffer)->ulEnabled = DFM_DISABLED; /*cstat !MISRAC2012-Rule-11.3 We use an untyped buffer to retrieve the session data since we can't know what version and size it might have been stored in the past. The stored Session data might be larger than the current DfmSessionStorage_t*/
187 
188 		if (ulRemember != 0UL)
189 		{
190 			(void)xDfmStorageStoreSession(cSessionStorageBuffer, sizeof(DfmSessionStorage_t)); /* Attempt to store the session info. We can't really do anything if it fails. */
191 		}
192 	}
193 
194 	pxDfmSessionData->ulEnabled = DFM_DISABLED;
195 
196 	return DFM_SUCCESS;
197 }
198 
ulDfmSessionIsEnabled()199 uint32_t ulDfmSessionIsEnabled()
200 {
201 	if (pxDfmSessionData == (void*)0)
202 	{
203 		return 0;
204 	}
205 
206 	if (pxDfmSessionData->ulInitialized == 0UL)
207 	{
208 		return 0;
209 	}
210 
211 	if (ulDfmIsInitialized() == 0UL)
212 	{
213 		return 0;
214 	}
215 
216 	return (uint32_t)(pxDfmSessionData->ulEnabled == DFM_ENABLED);
217 }
218 
xDfmSessionGetUniqueSessionId(char ** pszUniqueSessionId)219 DfmResult_t xDfmSessionGetUniqueSessionId(char **pszUniqueSessionId)
220 {
221 	uint32_t ulBytesWritten = 0UL;
222 
223 	if (pxDfmSessionData == (void*)0)
224 	{
225 		return DFM_FAIL;
226 	}
227 
228 	if (pxDfmSessionData->ulInitialized == 0UL)
229 	{
230 		return DFM_FAIL;
231 	}
232 
233 	if (pszUniqueSessionId == (void*)0)
234 	{
235 		return DFM_FAIL;
236 	}
237 
238 	if (pxDfmSessionData->cUniqueSessionIdBuffer[0] == (char)0)
239 	{
240 		if (pxDfmSessionData->xSessionIdStrategy == DFM_SESSIONID_STRATEGY_ONALERT)
241 		{
242 			/* Verify that the user supplied callback has been set */
243 			if (xDfmUserGetUniqueSessionID == 0)
244 			{
245 				return DFM_FAIL;
246 			}
247 
248 			/* Attempt to get a valid session id. Reserve last buffer slot for null termination. */
249 			if (xDfmUserGetUniqueSessionID(pxDfmSessionData->cUniqueSessionIdBuffer, (uint32_t)(DFM_SESSION_ID_MAX_LEN) - 1UL, &ulBytesWritten) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The User implementation used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
250 			{
251 				return DFM_FAIL;
252 			}
253 
254 			if (pxDfmSessionData->cUniqueSessionIdBuffer[0] == (char)0)
255 			{
256 				return DFM_FAIL;
257 			}
258 
259 			if (ulBytesWritten > (uint32_t)(DFM_SESSION_ID_MAX_LEN) - 1UL)
260 			{
261 				/* Wrote outside buffer? */
262 				return DFM_FAIL;
263 			}
264 
265 			/* Make sure we have null termination */
266 			pxDfmSessionData->cUniqueSessionIdBuffer[ulBytesWritten] = (char)0;
267 		}
268 		else
269 		{
270 			/* This should have been set on startup! */
271 			return DFM_FAIL;
272 		}
273 	}
274 
275 	*pszUniqueSessionId = pxDfmSessionData->cUniqueSessionIdBuffer;
276 
277 	return DFM_SUCCESS;
278 }
279 
xDfmSessionSetDeviceName(const char * szDeviceName)280 DfmResult_t xDfmSessionSetDeviceName(const char* szDeviceName)
281 {
282 	if (pxDfmSessionData == (void*)0)
283 	{
284 		return DFM_FAIL;
285 	}
286 
287 	if (pxDfmSessionData->ulInitialized == 0UL)
288 	{
289 		return DFM_FAIL;
290 	}
291 
292 	if (szDeviceName == (void*)0)
293 	{
294 		return DFM_FAIL;
295 	}
296 
297 	/* Copy the device name string, but make sure we leave the last byte for zero termination */
298 	for (int i = 0; i < DFM_DEVICE_NAME_MAX_LEN - 1; i++)
299 	{
300 		pxDfmSessionData->cDeviceNameBuffer[i] = szDeviceName[i];
301 
302 		/* Break at zero termination */
303 		if (szDeviceName[i] == (char)0)
304 		{
305 			break;
306 		}
307 	}
308 
309 	pxDfmSessionData->cDeviceNameBuffer[DFM_DEVICE_NAME_MAX_LEN - 1] = (char)0;
310 
311 	return DFM_SUCCESS;
312 }
313 
xDfmSessionGetDeviceName(const char ** pszDeviceName)314 DfmResult_t xDfmSessionGetDeviceName(const char** pszDeviceName)
315 {
316 	uint32_t ulBytesWritten = 0UL;
317 
318 	if (pxDfmSessionData == (void*)0)
319 	{
320 		return DFM_FAIL;
321 	}
322 
323 	if (pxDfmSessionData->ulInitialized == 0UL)
324 	{
325 		return DFM_FAIL;
326 	}
327 
328 	if (pszDeviceName == (void*)0)
329 	{
330 		return DFM_FAIL;
331 	}
332 
333 	if (pxDfmSessionData->cDeviceNameBuffer[0] == (char)0)
334 	{
335 		/* Verify that the user supplied callback has been set */
336 		if (xDfmUserGetDeviceName == 0)
337 		{
338 			return DFM_FAIL;
339 		}
340 
341 		/* Attempt to get a valid device name. Reserve last buffer slot for null termination. */
342 		if (xDfmUserGetDeviceName(pxDfmSessionData->cDeviceNameBuffer, (uint32_t)(DFM_DEVICE_NAME_MAX_LEN) - 1UL, &ulBytesWritten) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The User implementation used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
343 		{
344 			return DFM_FAIL;
345 		}
346 
347 		if (pxDfmSessionData->cDeviceNameBuffer[0] == (char)0)
348 		{
349 			return DFM_FAIL;
350 		}
351 
352 		if (ulBytesWritten > (uint32_t)(DFM_DEVICE_NAME_MAX_LEN) - 1UL)
353 		{
354 			/* Wrote too much, no room for null termination! */
355 			return DFM_FAIL;
356 		}
357 
358 		/* Make sure we have null termination */
359 		pxDfmSessionData->cDeviceNameBuffer[ulBytesWritten] = (char)0;
360 	}
361 
362 	*pszDeviceName = pxDfmSessionData->cDeviceNameBuffer;
363 
364 	return DFM_SUCCESS;
365 }
366 
xDfmSessionGenerateNewAlertId(void)367 DfmResult_t xDfmSessionGenerateNewAlertId(void)
368 {
369 	if (pxDfmSessionData == (void*)0)
370 	{
371 		return DFM_FAIL;
372 	}
373 
374 	if (pxDfmSessionData->ulInitialized == 0UL)
375 	{
376 		return DFM_FAIL;
377 	}
378 
379 	/* alertIDs start at 1 */
380 	pxDfmSessionData->ulAlertCounter++;
381 
382 	return DFM_SUCCESS;
383 }
384 
xDfmSessionGetAlertId(uint32_t * pulAlertId)385 DfmResult_t xDfmSessionGetAlertId(uint32_t* pulAlertId)
386 {
387 	if (pxDfmSessionData == (void*)0)
388 	{
389 		return DFM_FAIL;
390 	}
391 
392 	if (pxDfmSessionData->ulInitialized == 0UL)
393 	{
394 		return DFM_FAIL;
395 	}
396 
397 	if (pulAlertId == (void*)0)
398 	{
399 		return DFM_FAIL;
400 	}
401 
402 	*pulAlertId = pxDfmSessionData->ulAlertCounter;
403 
404 	return DFM_SUCCESS;
405 }
406 
xDfmSessionGetProduct(uint32_t * pulProduct)407 DfmResult_t xDfmSessionGetProduct(uint32_t* pulProduct)
408 {
409 	if (pxDfmSessionData == (void*)0)
410 	{
411 		return DFM_FAIL;
412 	}
413 
414 	if (pxDfmSessionData->ulInitialized == 0UL)
415 	{
416 		return DFM_FAIL;
417 	}
418 
419 	if (pulProduct == (void*)0)
420 	{
421 		return DFM_FAIL;
422 	}
423 
424 	*pulProduct = pxDfmSessionData->ulProduct;
425 
426 	return DFM_SUCCESS;
427 }
428 
xDfmSessionGetFirmwareVersion(char ** pszFirmwareVersion)429 DfmResult_t xDfmSessionGetFirmwareVersion(char** pszFirmwareVersion)
430 {
431 	if (pxDfmSessionData == (void*)0)
432 	{
433 		return DFM_FAIL;
434 	}
435 
436 	if (pxDfmSessionData->ulInitialized == 0UL)
437 	{
438 		return DFM_FAIL;
439 	}
440 
441 	if (pszFirmwareVersion == (void*)0)
442 	{
443 		return DFM_FAIL;
444 	}
445 
446 	*pszFirmwareVersion = pxDfmSessionData->cFirmwareVersionBuffer;
447 	return DFM_SUCCESS;
448 }
449 
xDfmSessionSetStatus(uint32_t ulStatus)450 DfmResult_t xDfmSessionSetStatus(uint32_t ulStatus)
451 {
452 	if (pxDfmSessionData == (void*)0)
453 	{
454 		return DFM_FAIL;
455 	}
456 
457 	if (pxDfmSessionData->ulInitialized == 0UL)
458 	{
459 		return DFM_FAIL;
460 	}
461 
462 	if (pxDfmSessionData->ulDfmStatus != DFM_STATUS_CODE_OK)
463 	{
464 		return DFM_FAIL;
465 	}
466 
467 	pxDfmSessionData->ulDfmStatus = ulStatus;
468 
469 	return DFM_SUCCESS;
470 }
471 
xDfmSessionGetStatus(uint32_t * pulStatus)472 DfmResult_t xDfmSessionGetStatus(uint32_t* pulStatus)
473 {
474 	if (pxDfmSessionData == (void*)0)
475 	{
476 		return DFM_FAIL;
477 	}
478 
479 	if (pxDfmSessionData->ulInitialized == 0UL)
480 	{
481 		return DFM_FAIL;
482 	}
483 
484 	if (pulStatus == (void*)0)
485 	{
486 		return DFM_FAIL;
487 	}
488 
489 	*pulStatus = pxDfmSessionData->ulDfmStatus;
490 
491 	return DFM_SUCCESS;
492 }
493 
xDfmSessionSetCloudStrategy(DfmCloudStrategy_t xStrategy)494 DfmResult_t xDfmSessionSetCloudStrategy(DfmCloudStrategy_t xStrategy)
495 {
496 	if (pxDfmSessionData == (void*)0)
497 	{
498 		return DFM_FAIL;
499 	}
500 
501 	if (pxDfmSessionData->ulInitialized == 0UL)
502 	{
503 		return DFM_FAIL;
504 	}
505 
506 	pxDfmSessionData->xCloudStrategy = xStrategy;
507 
508 	return DFM_SUCCESS;
509 }
510 
xDfmSessionGetCloudStrategy(DfmCloudStrategy_t * pxStrategy)511 DfmResult_t xDfmSessionGetCloudStrategy(DfmCloudStrategy_t* pxStrategy)
512 {
513 	if (pxDfmSessionData == (void*)0)
514 	{
515 		return DFM_FAIL;
516 	}
517 
518 	if (pxDfmSessionData->ulInitialized == 0UL)
519 	{
520 		return DFM_FAIL;
521 	}
522 
523 	if (pxStrategy == (void*)0)
524 	{
525 		return DFM_FAIL;
526 	}
527 
528 	*pxStrategy = pxDfmSessionData->xCloudStrategy;
529 
530 	return DFM_SUCCESS;
531 }
532 
xDfmSessionSetStorageStrategy(DfmStorageStrategy_t xStrategy)533 DfmResult_t xDfmSessionSetStorageStrategy(DfmStorageStrategy_t xStrategy)
534 {
535 	if (pxDfmSessionData == (void*)0)
536 	{
537 		return DFM_FAIL;
538 	}
539 
540 	if (pxDfmSessionData->ulInitialized == 0UL)
541 	{
542 		return DFM_FAIL;
543 	}
544 
545 	pxDfmSessionData->xStorageStrategy = xStrategy;
546 
547 	return DFM_SUCCESS;
548 }
549 
xDfmSessionGetStorageStrategy(DfmStorageStrategy_t * pxStrategy)550 DfmResult_t xDfmSessionGetStorageStrategy(DfmStorageStrategy_t* pxStrategy)
551 {
552 	if (pxDfmSessionData == (void*)0)
553 	{
554 		return DFM_FAIL;
555 	}
556 
557 	if (pxDfmSessionData->ulInitialized == 0UL)
558 	{
559 		return DFM_FAIL;
560 	}
561 
562 	if (pxStrategy == (void*)0)
563 	{
564 		return DFM_FAIL;
565 	}
566 
567 	*pxStrategy = pxDfmSessionData->xStorageStrategy;
568 
569 	return DFM_SUCCESS;
570 }
571 
xDfmSessionSetSessionIdStrategy(DfmSessionIdStrategy_t xStrategy)572 DfmResult_t xDfmSessionSetSessionIdStrategy(DfmSessionIdStrategy_t xStrategy)
573 {
574 	if (pxDfmSessionData == (void*)0)
575 	{
576 		return DFM_FAIL;
577 	}
578 
579 	if (pxDfmSessionData->ulInitialized == 0UL)
580 	{
581 		return DFM_FAIL;
582 	}
583 
584 	pxDfmSessionData->xSessionIdStrategy = xStrategy;
585 
586 	return DFM_SUCCESS;
587 }
588 
xDfmSessionGetSessionIdStrategy(DfmSessionIdStrategy_t * pxStrategy)589 DfmResult_t xDfmSessionGetSessionIdStrategy(DfmSessionIdStrategy_t* pxStrategy)
590 {
591 	if (pxDfmSessionData == (void*)0)
592 	{
593 		return DFM_FAIL;
594 	}
595 
596 	if (pxDfmSessionData->ulInitialized == 0UL)
597 	{
598 		return DFM_FAIL;
599 	}
600 
601 	if (pxStrategy == (void*)0)
602 	{
603 		return DFM_FAIL;
604 	}
605 
606 	*pxStrategy = pxDfmSessionData->xSessionIdStrategy;
607 
608 	return DFM_SUCCESS;
609 }
610 
prvGetSessionStorageVersion(DfmSessionStorage_t * pxSessionStorage,uint32_t * pulVersion)611 DfmResult_t prvGetSessionStorageVersion(DfmSessionStorage_t* pxSessionStorage, uint32_t* pulVersion)
612 {
613 	if (pxSessionStorage->ulVersion != 1UL)
614 	{
615 		return DFM_FAIL;
616 	}
617 
618 	*pulVersion = pxSessionStorage->ulVersion;
619 
620 	return DFM_SUCCESS;
621 }
622 
prvGetSessionStorageEnabled(DfmSessionStorage_t * pxSessionStorage,uint32_t * pulEnabled)623 DfmResult_t prvGetSessionStorageEnabled(DfmSessionStorage_t* pxSessionStorage, uint32_t* pulEnabled)
624 {
625 	if (pxSessionStorage->ulVersion != 1UL)
626 	{
627 		return DFM_FAIL;
628 	}
629 
630 	*pulEnabled = pxSessionStorage->ulEnabled;
631 
632 	return DFM_SUCCESS;
633 }
634 
635 #endif
636