11#include "config.h"
2+ #include <stdbool.h>
23#include <stddef.h>
4+ #include <stdint.h>
35#include <stdio.h>
46#include <string.h>
57#include "core.h"
@@ -54,6 +56,11 @@ const char* config_err_to_str(config_err_t err) {
5456 return "CONFIG_ERR_FILE_SYSTEM" ;
5557 case CONFIG_ERR_TRUNCATED :
5658 return "CONFIG_ERR_TRUNCATED" ;
59+ case CONFIG_ERR_INVALID_VALUE :
60+ return "CONFIG_ERR_INVALID_VALUE" ;
61+ case CONFIG_ERR_N_ERRS :
62+ // Intentional fall through
63+ (void )0 ;
5764 }
5865 return "INVALID" ;
5966}
@@ -63,15 +70,16 @@ const char* config_err_to_str(config_err_t err) {
6370// =============================================================================
6471
6572static const char * config_key_strings [CFG_KEY_N_KEYS ] = {
66- [CFG_KEY_API_KEY ] = "API_KEY" ,
6773 [CFG_KEY_CONFIG_VERSION ] = "CONFIG_VERSION" ,
6874 [CFG_KEY_DEVICE_NAME ] = "DEVICE_NAME" ,
6975 [CFG_KEY_DEVICE_TYPE ] = "DEVICE_TYPE" ,
7076 [CFG_KEY_LED_COUNT ] = "LED_COUNT" ,
7177 [CFG_KEY_LED_TYPE ] = "LED_TYPE" ,
7278 [CFG_KEY_PORTAL_ADDRESS ] = "PORTAL_ADDRESS" ,
79+ [CFG_KEY_PORTAL_API_KEY ] = "PORTAL_API_KEY" ,
80+ [CFG_KEY_PORTAL_PORT ] = "PORTAL_PORT" ,
7381 [CFG_KEY_RFID_READER_TYPE ] = "RFID_READER_TYPE" ,
74- [CFG_KEY_SKELETON_CARD ] = "SKELETON_CARD " ,
82+ [CFG_KEY_RFID_SKELETON_CARD ] = "RFID_SKELETON_CARD " ,
7583 [CFG_KEY_WIFI_PSK ] = "WIFI_PSK" ,
7684 [CFG_KEY_WIFI_SSID ] = "WIFI_SSID" ,
7785};
@@ -90,11 +98,12 @@ static const char* config_key_strings[CFG_KEY_N_KEYS] = {
9098// valid if the function returns CONFIG_OK.
9199//
92100// On success, up to `size` bytes will be copied to `out_value`, which will
93- // be null terminated for any `size` greater than zero.
101+ // be null terminated for any `size` greater than zero. Size is recommended to
102+ // be at least CONFIG_MAX_VALUE_LENGTH + 1.
94103//
95104// On failure, a relevant error code will be returned. The value in `out_value`
96105// must be ignored.
97- config_err_t config_value_get (config_key_t key , char * out_value , size_t size ) {
106+ static config_err_t config_value_get (config_key_t key , char * out_value , size_t size ) {
98107 // Validate the key
99108 if (0 > key || key >= CFG_KEY_N_KEYS ) {
100109 return CONFIG_ERR_INVALID_ARG ;
@@ -175,3 +184,241 @@ config_err_t config_value_get(config_key_t key, char* out_value, size_t size) {
175184
176185 return ret_val ;
177186}
187+
188+ // =============================================================================
189+ // Config
190+ // =============================================================================
191+
192+ typedef struct interlock_config {
193+ // Device
194+ device_type_t device_type ;
195+ char device_name [CONFIG_MAX_VALUE_LENGTH + 1 ];
196+
197+ // Portal
198+ char portal_address [CONFIG_MAX_VALUE_LENGTH + 1 ];
199+ char portal_api_key [CONFIG_MAX_VALUE_LENGTH + 1 ];
200+ uint16_t portal_port ;
201+
202+ // WIFI
203+ char wifi_ssid [CONFIG_MAX_VALUE_LENGTH + 1 ];
204+ char wifi_psk [CONFIG_MAX_VALUE_LENGTH + 1 ];
205+
206+ // LED
207+ uint16_t led_count ;
208+ led_type_t led_type ;
209+
210+ // RFID
211+ rfid_reader_type_t rfid_reader_type ;
212+ bool rfid_use_skeleton_card ;
213+ rfid_number_t skeleton_card ;
214+ } interlock_config_t ;
215+
216+ static bool config_str_to_device_type (const char * str , device_type_t * type ) {
217+ if (0 == strcmp_icase (str , "DOOR" )) {
218+ * type = DEVICE_TYPE_DOOR ;
219+ return true;
220+ }
221+
222+ if (0 == strcmp_icase (str , "INTERLOCK" )) {
223+ * type = DEVICE_TYPE_INTERLOCK ;
224+ return true;
225+ }
226+
227+ return false;
228+ }
229+
230+ static bool config_str_to_led_type (const char * str , led_type_t * type ) {
231+ if (0 == strcmp_icase (str , "RGBW" )) {
232+ * type = LED_TYPE_RGBW ;
233+ return true;
234+ }
235+
236+ if (0 == strcmp_icase (str , "BGRW" )) {
237+ * type = LED_TYPE_BGRW ;
238+ return true;
239+ }
240+
241+ return false;
242+ }
243+
244+ static bool config_str_to_rfid_reader_type (const char * str , rfid_reader_type_t * type ) {
245+ if (0 == strcmp_icase (str , "RF125PS" )) {
246+ * type = RFID_READER_TYPE_RF125PS ;
247+ return true;
248+ }
249+
250+ if (0 == strcmp_icase (str , "LEGACY" )) {
251+ * type = RFID_READER_TYPE_LEGACY ;
252+ return true;
253+ }
254+
255+ return false;
256+ }
257+
258+ static bool config_str_to_u16 (const char * str , uint16_t * val ) {
259+ long l ;
260+ if (!strtol_easy (str , & l )) {
261+ return false;
262+ }
263+
264+ if (l < 0 || l > UINT16_MAX ) {
265+ return false;
266+ }
267+
268+ * val = (uint16_t )l ;
269+ return true;
270+ }
271+
272+ static void config_read_From_file_log_error (config_key_t key , config_err_t err ) {
273+ ESP_LOGE (TAG , "Error reading config value for %s: %s" , config_key_strings [key ], config_err_to_str (err ));
274+ }
275+
276+ static void config_read_from_file_helper (config_key_t key , char * buffer , size_t buffer_size , uint32_t * status ) {
277+ config_err_t err = config_value_get (key , buffer , buffer_size );
278+ if (CONFIG_OK != err ) {
279+ config_read_From_file_log_error (key , err );
280+ * status |= (1 << err );
281+ }
282+ }
283+
284+ // Returns true if the config was successfully read.
285+ static bool config_read_from_file (interlock_config_t * config ) {
286+ uint32_t status = 0 ; // Bit field of errors
287+ char buffer [CONFIG_MAX_VALUE_LENGTH + 1 ] = {0 }; // Working buffer non string config items
288+
289+ memset (config , 0 , sizeof (interlock_config_t ));
290+
291+ // Device type
292+ config_read_from_file_helper (CFG_KEY_DEVICE_TYPE , buffer , sizeof (buffer ), & status );
293+ if (!config_str_to_device_type (buffer , & config -> device_type )) {
294+ status |= CONFIG_ERR_INVALID_ARG ;
295+ }
296+
297+ // Device name
298+ config_read_from_file_helper (CFG_KEY_DEVICE_NAME , config -> device_name , sizeof (config -> device_name ), & status );
299+
300+ // Portal address
301+ config_read_from_file_helper (CFG_KEY_PORTAL_ADDRESS , config -> portal_address , sizeof (config -> portal_address ),
302+ & status );
303+
304+ // Portal API key
305+ config_read_from_file_helper (CFG_KEY_PORTAL_API_KEY , config -> portal_api_key , sizeof (config -> portal_api_key ),
306+ & status );
307+
308+ // Portal port
309+ config_read_from_file_helper (CFG_KEY_PORTAL_PORT , buffer , sizeof (buffer ), & status );
310+ if (!config_str_to_u16 (buffer , & config -> portal_port )) {
311+ status |= CONFIG_ERR_INVALID_ARG ;
312+ }
313+
314+ // Wifi SSID
315+ config_read_from_file_helper (CFG_KEY_WIFI_SSID , config -> wifi_ssid , sizeof (config -> wifi_ssid ), & status );
316+
317+ // Wifi PSK
318+ config_read_from_file_helper (CFG_KEY_WIFI_PSK , config -> wifi_psk , sizeof (config -> wifi_psk ), & status );
319+
320+ // LED count
321+ config_read_from_file_helper (CFG_KEY_LED_COUNT , buffer , sizeof (buffer ), & status );
322+ if (!config_str_to_u16 (buffer , & config -> led_count )) {
323+ config_read_From_file_log_error (CFG_KEY_LED_COUNT , CONFIG_ERR_INVALID_ARG );
324+ status |= CONFIG_ERR_INVALID_ARG ;
325+ }
326+
327+ // LED Type
328+ config_read_from_file_helper (CFG_KEY_LED_TYPE , buffer , sizeof (buffer ), & status );
329+ if (!config_str_to_led_type (buffer , & config -> led_type )) {
330+ config_read_From_file_log_error (CFG_KEY_LED_TYPE , CONFIG_ERR_INVALID_ARG );
331+ status |= CONFIG_ERR_INVALID_ARG ;
332+ }
333+
334+ // RFID reader type
335+ config_read_from_file_helper (CFG_KEY_RFID_READER_TYPE , buffer , sizeof (buffer ), & status );
336+ if (!config_str_to_rfid_reader_type (buffer , & config -> rfid_reader_type )) {
337+ config_read_From_file_log_error (CFG_KEY_RFID_READER_TYPE , CONFIG_ERR_INVALID_ARG );
338+ status |= CONFIG_ERR_INVALID_ARG ;
339+ }
340+
341+ // RFID skeleton card
342+ long skeleton_card ;
343+ config_read_from_file_helper (CFG_KEY_RFID_SKELETON_CARD , buffer , sizeof (buffer ), & status );
344+ if (0 == strcmp_icase (buffer , "NONE" )) {
345+ config -> rfid_use_skeleton_card = false;
346+ config -> skeleton_card = UINT64_MAX ;
347+ } else if (strtol_easy (buffer , & skeleton_card ) && skeleton_card > 0 ) {
348+ config -> rfid_use_skeleton_card = true;
349+ config -> skeleton_card = skeleton_card ;
350+ } else {
351+ config_read_From_file_log_error (CFG_KEY_RFID_SKELETON_CARD , CONFIG_ERR_INVALID_ARG );
352+ status |= CONFIG_ERR_INVALID_ARG ;
353+ }
354+
355+ // Print out any config errors:
356+ if (0 != status ) {
357+ ESP_LOGE (TAG , "The following errors were encountered when reading the config file:" );
358+ for (int i = 0 ; i < CONFIG_ERR_N_ERRS ; i ++ ) {
359+ if ((status & (1 << i )) && i != CONFIG_OK ) {
360+ ESP_LOGE (TAG , " - %s" , config_err_to_str (i ));
361+ }
362+ }
363+ }
364+
365+ return 0 == status ;
366+ }
367+
368+ static interlock_config_t config = {0 };
369+
370+ bool config_init () {
371+ return config_read_from_file (& config );
372+ }
373+
374+ // =============================================================================
375+ // Getters
376+ // =============================================================================
377+
378+ device_type_t config_get_device_type (void ) {
379+ return config .device_type ;
380+ }
381+
382+ const char * config_get_device_name (void ) {
383+ return config .device_name ;
384+ }
385+
386+ const char * config_get_portal_address (void ) {
387+ return config .portal_address ;
388+ }
389+
390+ const char * config_get_portal_api_key (void ) {
391+ return config .portal_api_key ;
392+ }
393+
394+ uint16_t config_get_portal_port (void ) {
395+ return config .portal_port ;
396+ }
397+
398+ const char * config_get_wifi_ssid (void ) {
399+ return config .wifi_ssid ;
400+ }
401+
402+ const char * config_get_wifi_psk (void ) {
403+ return config .wifi_psk ;
404+ }
405+
406+ uint16_t config_get_led_count (void ) {
407+ return config .led_count ;
408+ }
409+
410+ led_type_t config_get_led_type (void ) {
411+ return config .led_type ;
412+ }
413+
414+ rfid_reader_type_t config_get_rfid_reader_type (void ) {
415+ return config .rfid_reader_type ;
416+ }
417+
418+ bool config_get_rfid_use_skeleton_card (void ) {
419+ return config .rfid_use_skeleton_card ;
420+ }
421+
422+ rfid_number_t config_get_skeleton_card (void ) {
423+ return config .skeleton_card ;
424+ }
0 commit comments