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