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 9 /** 10 * @file 11 * 12 * @brief DFM API 13 */ 14 15 #ifndef DFM_H 16 #define DFM_H 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdint.h> 26 #include <stdarg.h> 27 28 #include <dfmDefines.h> 29 #include <dfmTypes.h> 30 #include <dfmConfig.h> 31 32 /** 33 * @brief A callback type that is used by DFM to retrieve user supplied identifiers 34 * 35 * Example: 36 * DfmResult_t xGetUniqueSessionID(char cUniqueSessionIdBuffer[], uint32_t ulSize, uint32_t* pulBytesWritten) 37 * { 38 * // This function will write a device-unique SessionId to cUniqueSessionIdBuffer. 39 * 40 * // *** Some writing that must not exceed ulSize bytes... *** 41 * 42 * *pulBytesWritten = <string_length>; 43 * return DFM_SUCCESS; 44 * } 45 */ 46 typedef DfmResult_t (*DfmUserCallback_t)(char cBuffer[], uint32_t ulSize, uint32_t* pulBytesWritten); 47 48 /** 49 * @brief This user-supplied function callback is set in xDfmInitialize(). 50 * It is supposed to provide a device unique "Session ID". 51 * This is basically a "restart counter" that is combined with the "Device ID" 52 * to generate unique "alert keys" for each alert. 53 * 54 * THIS MUST NOT BE A CONSTANT DUMMY STRING, EVEN FOR BASIC TESTING. 55 * DUPLICATE ALERT KEYS ARE IGNORED BY DEVALERT. 56 * 57 * The alert key follows the pattern "DevAlert/DeviceID/SessionID/AlertCounter" 58 * and must be unique across all alerts from all devices, over all time. 59 * The Alert Counter is reset when the device is restarted. 60 * 61 * For production use, it is NOT ADVICED to use a RANDOM number, like below, 62 * since this may repeat. 63 * 64 * The recommended practice is to use one of these methods: 65 * - The current time ("wall-clock" time), e.g. in seconds since a certain date 66 * - A restart counter, stored in non-volatile storage. 67 * 68 * If using the current time as Session ID, seconds is sufficient resolution 69 * unless a restart and re-initialization may occur faster than that. 70 * 71 * @retval DFM_FAIL Failure 72 * @retval DFM_SUCCESS Success 73 */ 74 extern DfmUserCallback_t xDfmUserGetUniqueSessionID; 75 76 /** 77 * @brief This user-supplied function callback is set in xDfmInitialize(). 78 * It is suppoed to provide the "Device ID" for each alert. 79 * This is combined with the "Session ID" to generate unique "alert keys" for each alert. 80 * 81 * THIS MUST NOT BE A CONSTANT DUMMY STRING. DUPLICATE ALERT KEYS ARE IGNORED BY DEVALERT. 82 * 83 * If using AWS IoT Core, note that Device ID does not need to match the Thing Name 84 * (i.e. clientcredentialIOT_THING_NAME in /demos/include/aws_clientcredentials.h). 85 * It is good practice and recommended to have matching Thing Name and Device ID. 86 * 87 * @retval DFM_FAIL Failure 88 * @retval DFM_SUCCESS Success 89 */ 90 extern DfmUserCallback_t xDfmUserGetDeviceName; 91 92 /* 64-bit aligned */ 93 #define DFM_DEVICE_NAME_MAX_LEN ((((DFM_CFG_DEVICE_NAME_MAX_LEN) + 7) / 8) * 8) 94 95 /* 64-bit aligned with room for zero termination */ 96 #define DFM_FIRMWARE_VERSION_MAX_LEN ((((DFM_CFG_FIRMWARE_VERSION_MAX_LEN) + 1 + 7) / 8) * 8) 97 98 /* 64-bit aligned with room for zero termination */ 99 #define DFM_DESCRIPTION_MAX_LEN ((((DFM_CFG_DESCRIPTION_MAX_LEN) + 1 + 7) / 8) * 8) 100 101 #include <dfmKernelPort.h> 102 #include <dfmEntry.h> 103 #include <dfmAlert.h> 104 #include <dfmSession.h> 105 #include <dfmStorage.h> 106 #include <dfmCloud.h> 107 108 #include <dfmCodes.h> 109 110 #ifndef DFM_CFG_ENABLED 111 #error DFM_CFG_ENABLED not set in dfmConfig.h! 112 #endif 113 114 #ifndef DFM_CFG_FIRMWARE_VERSION_MAX_LEN 115 #error DFM_CFG_FIRMWARE_VERSION_MAX_LEN not set in dfmConfig.h! 116 #endif 117 118 #if DFM_CFG_PRODUCTID == 0 119 #error DFM_CFG_PRODUCTID not set in dfmConfig.h! 120 #endif 121 122 #ifndef DFM_ERROR_PRINT 123 #define DFM_ERROR_PRINT(msg) 124 #endif 125 126 #if (DFM_CFG_ENABLE_DEBUG_PRINT == 1) 127 #define DFM_DEBUG_PRINT(msg) DFM_ERROR_PRINT(msg) 128 #else 129 #define DFM_DEBUG_PRINT(msg) ((void)(msg)) 130 #endif 131 132 #if ((DFM_CFG_ENABLED) == 1) 133 134 /** 135 * @defgroup dfm_alert_apis DFM Alert API 136 * @ingroup dfm_apis 137 * @{ 138 */ 139 140 /******************************************************************************* 141 * Versions 142 * 143 * 1) Initial version 144 * 2) Added ulProduct to DFM header 145 * 3) Refactored DFM 146 ******************************************************************************/ 147 #define DFM_VERSION_INITIAL 1 148 #define DFM_VERSION_WITH_PRODUCT 2 149 #define DFM_VERSION_2_0 3 150 151 #define DFM_VERSION DFM_VERSION_2_0 152 153 #if (DFM_FIRMWARE_VERSION_MAX_LEN > 255) 154 #error "Firmware Max Length cannot be larger than 255" 155 #endif 156 157 /** 158 * @brief DFM data 159 */ 160 typedef struct DfmData 161 { 162 uint32_t ulDfmInitialized; 163 164 DfmSessionData_t xSessionData; 165 DfmKernelPortData_t xKernelPortData; 166 DfmStorageData_t xStorageData; 167 DfmCloudData_t xCloudData; 168 DfmAlertData_t xAlertData; 169 DfmEntryData_t xEntryData; 170 } DfmData_t; 171 172 /** 173 * @internal Initializes the entire DFM system 174 * 175 * @param[in] xGetUniqueSessionID This user-defined function provides the "Session ID". 176 * This is basically a "restart counter" that is combined with the "Device ID" 177 * to generate unique "alert keys" for each alert. 178 * 179 * THIS MUST NOT BE A CONSTANT DUMMY STRING, EVEN FOR BASIC TESTING. 180 * DUPLICATE ALERT KEYS ARE IGNORED BY DEVALERT. 181 * 182 * The alert key follows the pattern "DevAlert/DeviceID/SessionID/AlertCounter" 183 * and must be unique across all alerts from all devices, over all time. 184 * The Alert Counter is reset when the device is restarted. 185 * 186 * For production use, it is NOT ADVICED to use a RANDOM number, like below, 187 * since this may repeat. 188 * 189 * The recommended practice is to use one of these methods: 190 * - The current time ("wall-clock" time), e.g. in seconds since a certain date 191 * - A restart counter, stored in non-volatile storage. 192 * 193 * If using the current time as Session ID, seconds is sufficient resolution 194 * unless a restart and re-initialization may occur faster than that. 195 * 196 * @param[in] xGetDeviceName This user-defined function provides the "Device ID" for each alert. 197 * This is combined with the "Session ID" to generate unique "alert keys" for each alert. 198 * 199 * THIS MUST NOT BE A CONSTANT DUMMY STRING. DUPLICATE ALERT KEYS ARE IGNORED BY DEVALERT. 200 * 201 * If using AWS IoT Core, note that Device ID does not need to match the Thing Name 202 * (i.e. clientcredentialIOT_THING_NAME in /demos/include/aws_clientcredentials.h). 203 * It is good practice and recommended to have matching Thing Name and Device ID. 204 * 205 * @retval DFM_FAIL Failure 206 * @retval DFM_SUCCESS Success 207 */ 208 DfmResult_t xDfmInitialize(DfmUserCallback_t xGetUniqueSessionID, DfmUserCallback_t xGetDeviceName); 209 210 /** 211 * @brief Is DFM initialized? 212 * 213 * @retval DFM_FAIL Failure 214 * @retval DFM_SUCCESS Success 215 */ 216 uint32_t ulDfmIsInitialized(void); 217 218 /** 219 * @brief Enable DFM 220 * 221 * @param[in] ulOverride Flag indicating if it should override any previous disable calls. Setting this to 1 means that if for some reason it was decided to disable DFM on this device and it was stored to Flash, this Enable attempt will not do anything. 222 * 223 * @retval DFM_FAIL Failure 224 * @retval DFM_SUCCESS Success 225 */ 226 #define xDfmEnable(ulOverride) xDfmSessionEnable(ulOverride) 227 228 /** 229 * @brief Disable DFM 230 * 231 * @param[in] ulRemember Flag indicating if the Disable should be stored in permanent storage. Setting this to 1 means that any reboots of the device will remember the "Disabled" flag and xDfmEnable(1) must be called to override and re-enable DFM. 232 * 233 * @retval DFM_FAIL Failure 234 * @retval DFM_SUCCESS Success 235 */ 236 #define xDfmDisable(ulRemember) xDfmSessionDisable(ulRemember) 237 238 /** 239 * @brief Is DFM enabled? 240 * 241 * @retval DFM_FAIL Failure 242 * @retval DFM_SUCCESS Success 243 */ 244 #define ulDfmIsEnabled() ulDfmSessionIsEnabled() 245 246 /** @} */ 247 248 #else 249 250 /* Dummy defines */ 251 #define xDfmInitialize(p,fv) (DFM_FAIL) 252 #define ulDfmIsInitialized() (0) 253 #define xDfmEnable(ulOverride) (DFM_FAIL) 254 #define xDfmDisable() (DFM_FAIL) 255 #define ulDfmIsEnabled() (0) 256 257 #endif 258 259 #ifdef __cplusplus 260 } 261 #endif 262 263 #endif /* DFM_H */ 264