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 Storage
9  */
10 
11 #include <dfm.h>
12 #include <string.h>
13 
14 #if ((DFM_CFG_ENABLED) >= 1)
15 
16 static DfmStorageData_t* pxStorageData = (void*)0;
17 
18 #define DFM_STORAGE_VERSION 1
19 #define DFM_STORAGE_ALERT_TYPE 0x1512
20 #define DFM_STORAGE_PAYLOAD_TYPE 0x8371
21 
xDfmStorageInitialize(DfmStorageData_t * pxBuffer)22 DfmResult_t xDfmStorageInitialize(DfmStorageData_t* pxBuffer)
23 {
24 	if (pxBuffer == (void*)0)
25 	{
26 		return DFM_FAIL;
27 	}
28 
29 	pxStorageData = pxBuffer;
30 
31 	if (xDfmStoragePortInitialize(&pxStorageData->xStoragePortData) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The mocked storage port used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
32 	{
33 		return DFM_FAIL;
34 	}
35 
36 	pxStorageData->ulInitialized = 1;
37 
38 	return DFM_SUCCESS;
39 }
40 
xDfmStorageStoreSession(void * pvSession,uint32_t ulSessionSize)41 DfmResult_t xDfmStorageStoreSession(void* pvSession, uint32_t ulSessionSize)
42 {
43 	if (pxStorageData == (void*)0)
44 	{
45 		return DFM_FAIL;
46 	}
47 
48 	if (pxStorageData->ulInitialized == 0UL)
49 	{
50 		return DFM_FAIL;
51 	}
52 
53 	if (ulDfmSessionIsEnabled() == 0UL)
54 	{
55 		return DFM_FAIL;
56 	}
57 
58 	if (pvSession == (void*)0)
59 	{
60 		return DFM_FAIL;
61 	}
62 
63 	if (ulSessionSize == 0UL)
64 	{
65 		return DFM_FAIL;
66 	}
67 
68 	return xDfmStoragePortStoreSession(pvSession, ulSessionSize);
69 }
70 
xDfmStorageGetSession(void * pvBuffer,uint32_t ulBufferSize)71 DfmResult_t xDfmStorageGetSession(void* pvBuffer, uint32_t ulBufferSize)
72 {
73 	if (pxStorageData == (void*)0)
74 	{
75 		return DFM_FAIL;
76 	}
77 
78 	if (pxStorageData->ulInitialized == 0UL)
79 	{
80 		return DFM_FAIL;
81 	}
82 
83 	if (ulDfmSessionIsEnabled() == 0UL)
84 	{
85 		return DFM_FAIL;
86 	}
87 
88 	if (pvBuffer == (void*)0)
89 	{
90 		return DFM_FAIL;
91 	}
92 
93 	if (ulBufferSize == 0UL)
94 	{
95 		return DFM_FAIL;
96 	}
97 
98 	return xDfmStoragePortGetSession(pvBuffer, ulBufferSize);
99 }
100 
xDfmStorageStoreAlert(DfmEntryHandle_t xEntryHandle)101 DfmResult_t xDfmStorageStoreAlert(DfmEntryHandle_t xEntryHandle)
102 {
103 	DfmStorageStrategy_t xStorageStrategy = DFM_STORAGE_STRATEGY_SKIP;
104 
105 	if (pxStorageData == (void*)0)
106 	{
107 		return DFM_FAIL;
108 	}
109 
110 	if (pxStorageData->ulInitialized == 0UL)
111 	{
112 		return DFM_FAIL;
113 	}
114 
115 	if (ulDfmSessionIsEnabled() == 0UL)
116 	{
117 		return DFM_FAIL;
118 	}
119 
120 	if (xEntryHandle == 0)
121 	{
122 		return DFM_FAIL;
123 	}
124 
125 	if (xDfmSessionGetStorageStrategy(&xStorageStrategy) == DFM_FAIL)
126 	{
127 		return DFM_FAIL;
128 	}
129 
130 	if (xStorageStrategy == DFM_STORAGE_STRATEGY_IGNORE)
131 	{
132 		return DFM_FAIL;
133 	}
134 
135 	if (xDfmStoragePortStoreAlert(xEntryHandle, (uint32_t)(xStorageStrategy == DFM_STORAGE_STRATEGY_OVERWRITE)) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The mocked storage port used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
136 	{
137 		return DFM_FAIL;
138 	}
139 
140 	return DFM_SUCCESS;
141 }
142 
xDfmStorageGetAlert(void * pvBuffer,uint32_t ulBufferSize)143 DfmResult_t xDfmStorageGetAlert(void* pvBuffer, uint32_t ulBufferSize)
144 {
145 	if (pxStorageData == (void*)0)
146 	{
147 		return DFM_FAIL;
148 	}
149 
150 	if (pxStorageData->ulInitialized == 0UL)
151 	{
152 		return DFM_FAIL;
153 	}
154 
155 	if (ulDfmSessionIsEnabled() == 0UL)
156 	{
157 		return DFM_FAIL;
158 	}
159 
160 	if (pvBuffer == (void*)0)
161 	{
162 		return DFM_FAIL;
163 	}
164 
165 	if (ulBufferSize == 0UL)
166 	{
167 		return DFM_FAIL;
168 	}
169 
170 	if (xDfmStoragePortGetAlert(pvBuffer, ulBufferSize) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The mocked storage port used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
171 	{
172 		return DFM_FAIL;
173 	}
174 
175 	return DFM_SUCCESS;
176 }
177 
xDfmStorageStorePayloadChunk(DfmEntryHandle_t xEntryHandle)178 DfmResult_t xDfmStorageStorePayloadChunk(DfmEntryHandle_t xEntryHandle)
179 {
180 	DfmStorageStrategy_t xStorageStrategy = DFM_STORAGE_STRATEGY_SKIP;
181 
182 	if (pxStorageData == (void*)0)
183 	{
184 		return DFM_FAIL;
185 	}
186 
187 	if (pxStorageData->ulInitialized == 0UL)
188 	{
189 		return DFM_FAIL;
190 	}
191 
192 	if (ulDfmSessionIsEnabled() == 0UL)
193 	{
194 		return DFM_FAIL;
195 	}
196 
197 	if (xEntryHandle == 0)
198 	{
199 		return DFM_FAIL;
200 	}
201 
202 	if (xDfmSessionGetStorageStrategy(&xStorageStrategy) == DFM_FAIL)
203 	{
204 		return DFM_FAIL;
205 	}
206 
207 	if (xStorageStrategy == DFM_STORAGE_STRATEGY_IGNORE)
208 	{
209 		return DFM_FAIL;
210 	}
211 
212 	if (xDfmStoragePortStorePayloadChunk(xEntryHandle, (uint32_t)(xStorageStrategy == DFM_STORAGE_STRATEGY_OVERWRITE)) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The mocked storage port used for MISRA always returns DFM_SUCCESS so this check will never be true. In a real system that will not be the case.*/
213 	{
214 		return DFM_FAIL;
215 	}
216 
217 	return DFM_SUCCESS;
218 }
219 
xDfmStorageGetPayloadChunk(char * szSessionId,uint32_t ulAlertId,void * pvBuffer,uint32_t ulBufferSize)220 DfmResult_t xDfmStorageGetPayloadChunk(char* szSessionId, uint32_t ulAlertId, void* pvBuffer, uint32_t ulBufferSize)
221 {
222 	if (pxStorageData == (void*)0)
223 	{
224 		return DFM_FAIL;
225 	}
226 
227 	if (pxStorageData->ulInitialized == 0UL)
228 	{
229 		return DFM_FAIL;
230 	}
231 
232 	if (ulDfmSessionIsEnabled() == 0UL)
233 	{
234 		return DFM_FAIL;
235 	}
236 
237 	if (szSessionId == (void*)0)
238 	{
239 		return DFM_FAIL;
240 	}
241 
242 	if (szSessionId[0] == (char)0)
243 	{
244 		return DFM_FAIL;
245 	}
246 
247 	if (pvBuffer == (void*)0)
248 	{
249 		return DFM_FAIL;
250 	}
251 
252 	if (ulBufferSize == 0UL)
253 	{
254 		return DFM_FAIL;
255 	}
256 
257 	/* TODO: 64-bit compatible */
258 	/* Make sure szSessiondId is not pointing to a string inside the buffer since that means this function is incorrectly used and it will be overwritten! */
259 	if (((uint32_t)szSessionId >= (uint32_t)pvBuffer) && ((uint32_t)szSessionId < (((uint32_t)pvBuffer) + ulBufferSize))) /*cstat !MISRAC2012-Rule-11.6 !MISRAC2012-Rule-18.3 !MISRAC2012-Rule-18.4 We need to verify that szSessionId is not pointing at an address inside pvBuffer. This means that we need to offset the buffer pointer by the buffer size before comparison.*/
260 	{
261 		return DFM_FAIL;
262 	}
263 
264 	if (xDfmStoragePortGetPayloadChunk(szSessionId, ulAlertId, pvBuffer, ulBufferSize) == DFM_FAIL) /*cstat !MISRAC2012-Rule-14.3_b The mocked storage port used for MISRA always returns DFM_SUCCESS here so this check will never be true. In a real system that will not be the case.*/
265 	{
266 		return DFM_FAIL;
267 	}
268 
269 	return DFM_SUCCESS;
270 }
271 
272 #endif
273