add: config loading
This commit is contained in:
		
							parent
							
								
									3cd6668f9c
								
							
						
					
					
						commit
						25ba0ff723
					
				
					 22 changed files with 5799 additions and 75 deletions
				
			
		| 
						 | 
				
			
			@ -21,6 +21,8 @@ aux_source_directory(helpers HELPERS_SRC)
 | 
			
		|||
aux_source_directory(handlers HANDLERS_SRC)
 | 
			
		||||
aux_source_directory(drivers DRIVERS_SRC)
 | 
			
		||||
 | 
			
		||||
configure_file("controller.ini" "controller.ini" COPYONLY)
 | 
			
		||||
 | 
			
		||||
target_sources(controller PRIVATE ${SRC_DIR} ${MODELS_SRC} ${HELPERS_SRC} ${HANDLERS_SRC} ${DRIVERS_SRC})
 | 
			
		||||
target_include_directories(controller PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								controller.ini
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								controller.ini
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
[controller]
 | 
			
		||||
name = new emgauwa device
 | 
			
		||||
discovery-port = 4421
 | 
			
		||||
relay-count = 10
 | 
			
		||||
 | 
			
		||||
[relay-0]
 | 
			
		||||
driver = piface
 | 
			
		||||
pin = 0
 | 
			
		||||
 | 
			
		||||
[relay-1]
 | 
			
		||||
driver = piface
 | 
			
		||||
pin = 1
 | 
			
		||||
 | 
			
		||||
[relay-2]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 11
 | 
			
		||||
 | 
			
		||||
[relay-3]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 13
 | 
			
		||||
 | 
			
		||||
[relay-4]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 15
 | 
			
		||||
 | 
			
		||||
[relay-5]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 8
 | 
			
		||||
 | 
			
		||||
[relay-6]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 10
 | 
			
		||||
 | 
			
		||||
[relay-7]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 12
 | 
			
		||||
 | 
			
		||||
[relay-8]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 16
 | 
			
		||||
 | 
			
		||||
[relay-9]
 | 
			
		||||
driver = gpio
 | 
			
		||||
pin = 18
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <lmdb.h>
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
database_setup(MDB_env **mdb_env)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,10 +5,10 @@
 | 
			
		|||
#include <drivers.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
driver_gpio_set(relay_t *relay, int value)
 | 
			
		||||
driver_gpio_set(int pin, int value)
 | 
			
		||||
{
 | 
			
		||||
    // disable "unused parameter" warning (happens when using wiring_debug)
 | 
			
		||||
    (void)relay;
 | 
			
		||||
    (void)pin;
 | 
			
		||||
    (void)value;
 | 
			
		||||
    digitalWrite(relay->number, value);
 | 
			
		||||
    digitalWrite(pin, value);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,10 +5,10 @@
 | 
			
		|||
#include <drivers.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
driver_piface_set(relay_t *relay, int value)
 | 
			
		||||
driver_piface_set(int pin, int value)
 | 
			
		||||
{
 | 
			
		||||
    // disable "unused parameter" warning (happens when using wiring_debug)
 | 
			
		||||
    (void)relay;
 | 
			
		||||
    (void)pin;
 | 
			
		||||
    (void)value;
 | 
			
		||||
    digitalWrite(DRIVER_PIFACE_GPIO_BASE + relay->number, value);
 | 
			
		||||
    digitalWrite(DRIVER_PIFACE_GPIO_BASE + pin, value);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,28 +19,22 @@ handler_loop(controller_t *controller)
 | 
			
		|||
    for(uint_fast8_t i = 0; i < controller->relay_count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        relay_t *relay = controller->relays[i];
 | 
			
		||||
        int is_active = 0;
 | 
			
		||||
        if(relay_is_active(relay, time(NULL)))
 | 
			
		||||
        {
 | 
			
		||||
            LOG_DEBUG("relay %d is active", i);
 | 
			
		||||
            if(relay->number >= 2)
 | 
			
		||||
            {
 | 
			
		||||
                driver_gpio_set(relay, HIGH);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                driver_piface_set(relay, HIGH);
 | 
			
		||||
            }
 | 
			
		||||
            is_active = 1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        switch(global_config.relay_configs[i].driver)
 | 
			
		||||
        {
 | 
			
		||||
            if(relay->number >= 2)
 | 
			
		||||
            {
 | 
			
		||||
                driver_gpio_set(relay, LOW);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                driver_piface_set(relay, LOW);
 | 
			
		||||
            }
 | 
			
		||||
            case RELAY_DRIVER_GPIO:
 | 
			
		||||
                driver_gpio_set(global_config.relay_configs[i].pin, is_active);
 | 
			
		||||
                break;
 | 
			
		||||
            case RELAY_DRIVER_PIFACE:
 | 
			
		||||
                driver_piface_set(global_config.relay_configs[i].pin, is_active);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                LOG_WARN("relay %d is not using a driver", i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										69
									
								
								helpers/load_config.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								helpers/load_config.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <helpers.h>
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <logger.h>
 | 
			
		||||
#include <confini.h>
 | 
			
		||||
 | 
			
		||||
#define CONFINI_IS_KEY(SECTION, KEY) \
 | 
			
		||||
    (ini_array_match(SECTION, disp->append_to, '.', disp->format) && \
 | 
			
		||||
     ini_string_match_ii(KEY, disp->data, disp->format))
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
helper_load_config(IniDispatch *disp, void *config_void)
 | 
			
		||||
{
 | 
			
		||||
    config_t *config = (config_t*)config_void;
 | 
			
		||||
    char relay_section_name[10]; // "relay-255\0" is longest name 
 | 
			
		||||
 | 
			
		||||
    if(disp->type == INI_KEY)
 | 
			
		||||
    {
 | 
			
		||||
        if(CONFINI_IS_KEY("controller", "name"))
 | 
			
		||||
        {
 | 
			
		||||
            strncpy(config->name, disp->value, MAX_NAME_LENGTH);
 | 
			
		||||
            config->name[MAX_NAME_LENGTH] = '\0';
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if(CONFINI_IS_KEY("controller", "discovery-port"))
 | 
			
		||||
        {
 | 
			
		||||
            config->discovery_port = atoi(disp->value);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        if(CONFINI_IS_KEY("controller", "relay-count"))
 | 
			
		||||
        {
 | 
			
		||||
            config->relay_count = atoi(disp->value);
 | 
			
		||||
            config->relay_configs = malloc(sizeof(config_relay_t) * config->relay_count);
 | 
			
		||||
            for(uint8_t i = 0; i < config->relay_count; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                config->relay_configs[i].driver= RELAY_DRIVER_NONE;
 | 
			
		||||
            }
 | 
			
		||||
            LOG_TRACE("config relay-count set to %u", config->relay_count);
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        for(uint8_t i = 0; i < config->relay_count; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            sprintf(relay_section_name, "relay-%u", i);
 | 
			
		||||
            if(CONFINI_IS_KEY(relay_section_name, "pin"))
 | 
			
		||||
            {
 | 
			
		||||
                config->relay_configs[i].pin = atoi(disp->value);
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            if(CONFINI_IS_KEY(relay_section_name, "driver"))
 | 
			
		||||
            {
 | 
			
		||||
                if(strcasecmp(disp->value, "gpio") == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    config->relay_configs[i].driver = RELAY_DRIVER_GPIO;
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
                if(strcasecmp(disp->value, "piface") == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    config->relay_configs[i].driver = RELAY_DRIVER_PIFACE;
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
                LOG_WARN("invalid driver '%s' in section '%s'", disp->value, relay_section_name);
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +1,25 @@
 | 
			
		|||
#ifndef CONTROLLER_CONFIG_H
 | 
			
		||||
#define CONTROLLER_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include <log_levels.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Limit the maximum length of a controller/relay/etc name
 | 
			
		||||
 *
 | 
			
		||||
 * The NULL terminator is not included. Arrays of length #MAX_NAME_LENGTH + 1 are required.
 | 
			
		||||
 */
 | 
			
		||||
#define MAX_NAME_LENGTH 128
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
#include <enums.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Maximum number of dbs for the databases for the MDB_env
 | 
			
		||||
 *
 | 
			
		||||
 * Used when calling mdb_env_set_maxdbs() in database_setup()
 | 
			
		||||
 */
 | 
			
		||||
#define MDB_MAXDBS 8
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint8_t pin;
 | 
			
		||||
    relay_driver_t driver;
 | 
			
		||||
} config_relay_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Indicates to which level to log
 | 
			
		||||
 *
 | 
			
		||||
 * @see include/log_levels.h
 | 
			
		||||
 */
 | 
			
		||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    char name[MAX_NAME_LENGTH + 1];
 | 
			
		||||
    uint16_t discovery_port;
 | 
			
		||||
    uint8_t relay_count;
 | 
			
		||||
    config_relay_t *relay_configs;
 | 
			
		||||
} config_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief How many milli seconds to wait until poll timeout in main loop
 | 
			
		||||
 */
 | 
			
		||||
#define ACCEPT_TIMEOUT_MSECONDS 1000
 | 
			
		||||
extern config_t global_config;
 | 
			
		||||
 | 
			
		||||
#endif //CONTROLLER_CONFIG_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										547
									
								
								include/confini.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										547
									
								
								include/confini.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,547 @@
 | 
			
		|||
/*  -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*-  */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
    @file       confini.h
 | 
			
		||||
    @brief      libconfini header
 | 
			
		||||
    @author     Stefano Gioffré
 | 
			
		||||
    @copyright  GNU General Public License, version 3 or any later version
 | 
			
		||||
    @version    1.14.0
 | 
			
		||||
    @date       2016-2020
 | 
			
		||||
    @see        https://madmurphy.github.io/libconfini
 | 
			
		||||
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef _LIBCONFINI_HEADER_
 | 
			
		||||
#define _LIBCONFINI_HEADER_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PRIVATE (HEADER-SCOPED) MACROS  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define __INIFORMAT_TABLE_CB_FIELDS__(NAME, OFFSET, SIZE, DEFVAL) \
 | 
			
		||||
    unsigned char NAME:SIZE;
 | 
			
		||||
#define __INIFORMAT_TABLE_CB_DEFAULT__(NAME, OFFSET, SIZE, DEFVAL) DEFVAL,
 | 
			
		||||
#define __INIFORMAT_TABLE_CB_ZERO__(NAME, OFFSET, SIZE, DEFVAL) 0,
 | 
			
		||||
#define _LIBCONFINI_INIFORMAT_TYPE_ \
 | 
			
		||||
    struct IniFormat { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_FIELDS__) }
 | 
			
		||||
#define _LIBCONFINI_DEFAULT_FORMAT_ \
 | 
			
		||||
    { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_DEFAULT__) }
 | 
			
		||||
#define _LIBCONFINI_UNIXLIKE_FORMAT_ \
 | 
			
		||||
    { INIFORMAT_TABLE_AS(__INIFORMAT_TABLE_CB_ZERO__) }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PUBLIC MACROS  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Calls a user-given macro (that accepts four arguments) for each row
 | 
			
		||||
            of the table
 | 
			
		||||
**/
 | 
			
		||||
/*
 | 
			
		||||
    NOTE: The following table and the order of its rows **define** (and link
 | 
			
		||||
    together) both the #IniFormat and #IniFormatNum data types declared in this
 | 
			
		||||
    header
 | 
			
		||||
*/
 | 
			
		||||
#define INIFORMAT_TABLE_AS(_____)                 /*  IniFormat table  *\
 | 
			
		||||
 | 
			
		||||
        NAME                      BIT  SIZE DEFAULT
 | 
			
		||||
                                                                      */\
 | 
			
		||||
 _____( delimiter_symbol,         0,   7,   INI_EQUALS                ) \
 | 
			
		||||
 _____( case_sensitive,           7,   1,   false                     )/*
 | 
			
		||||
                                                                      */\
 | 
			
		||||
 _____( semicolon_marker,         8,   2,   INI_DISABLED_OR_COMMENT   ) \
 | 
			
		||||
 _____( hash_marker,              10,  2,   INI_DISABLED_OR_COMMENT   ) \
 | 
			
		||||
 _____( section_paths,            12,  2,   INI_ABSOLUTE_AND_RELATIVE ) \
 | 
			
		||||
 _____( multiline_nodes,          14,  2,   INI_MULTILINE_EVERYWHERE  )/*
 | 
			
		||||
                                                                      */\
 | 
			
		||||
 _____( no_single_quotes,         16,  1,   false                     ) \
 | 
			
		||||
 _____( no_double_quotes,         17,  1,   false                     ) \
 | 
			
		||||
 _____( no_spaces_in_names,       18,  1,   false                     ) \
 | 
			
		||||
 _____( implicit_is_not_empty,    19,  1,   false                     ) \
 | 
			
		||||
 _____( do_not_collapse_values,   20,  1,   false                     ) \
 | 
			
		||||
 _____( preserve_empty_quotes,    21,  1,   false                     ) \
 | 
			
		||||
 _____( disabled_after_space,     22,  1,   false                     ) \
 | 
			
		||||
 _____( disabled_can_be_implicit, 23,  1,   false                     )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Checks whether a format does **not** support escape sequences
 | 
			
		||||
**/
 | 
			
		||||
#define INIFORMAT_HAS_NO_ESC(FORMAT) \
 | 
			
		||||
    (FORMAT.multiline_nodes == INI_NO_MULTILINE && \
 | 
			
		||||
    FORMAT.no_double_quotes && FORMAT.no_single_quotes)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PUBLIC TYPEDEFS  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  24-bit bitfield representing the format of an INI file (INI
 | 
			
		||||
            dialect)
 | 
			
		||||
**/
 | 
			
		||||
typedef _LIBCONFINI_INIFORMAT_TYPE_ IniFormat;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Global statistics about an INI file
 | 
			
		||||
**/
 | 
			
		||||
typedef struct IniStatistics {
 | 
			
		||||
    const IniFormat format;
 | 
			
		||||
    const size_t bytes;
 | 
			
		||||
    const size_t members;
 | 
			
		||||
} IniStatistics;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Dispatch of a single INI node
 | 
			
		||||
**/
 | 
			
		||||
typedef struct IniDispatch {
 | 
			
		||||
    const IniFormat format;
 | 
			
		||||
    uint8_t type;
 | 
			
		||||
    char * data;
 | 
			
		||||
    char * value;
 | 
			
		||||
    const char * append_to;
 | 
			
		||||
    size_t d_len;
 | 
			
		||||
    size_t v_len;
 | 
			
		||||
    size_t at_len;
 | 
			
		||||
    size_t dispatch_id;
 | 
			
		||||
} IniDispatch;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  The unique ID of an INI format (24-bit maximum)
 | 
			
		||||
**/
 | 
			
		||||
typedef uint32_t IniFormatNum;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Callback function for handling an #IniStatistics structure
 | 
			
		||||
**/
 | 
			
		||||
typedef int (* IniStatsHandler) (
 | 
			
		||||
    IniStatistics * statistics,
 | 
			
		||||
    void * user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Callback function for handling an #IniDispatch structure
 | 
			
		||||
**/
 | 
			
		||||
typedef int (* IniDispHandler) (
 | 
			
		||||
    IniDispatch * dispatch,
 | 
			
		||||
    void * user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Callback function for handling an INI string belonging to a
 | 
			
		||||
            sequence of INI strings
 | 
			
		||||
**/
 | 
			
		||||
typedef int (* IniStrHandler) (
 | 
			
		||||
    char * ini_string,
 | 
			
		||||
    size_t string_length,
 | 
			
		||||
    size_t string_num,
 | 
			
		||||
    IniFormat format,
 | 
			
		||||
    void * user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Callback function for handling a selected fragment of an INI string
 | 
			
		||||
**/
 | 
			
		||||
typedef int (* IniSubstrHandler) (
 | 
			
		||||
    const char * ini_string,
 | 
			
		||||
    size_t fragm_offset,
 | 
			
		||||
    size_t fragm_length,
 | 
			
		||||
    size_t fragm_num,
 | 
			
		||||
    IniFormat format,
 | 
			
		||||
    void * user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PUBLIC FUNCTIONS  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int strip_ini_cache (
 | 
			
		||||
    register char * const ini_source,
 | 
			
		||||
    const size_t ini_length,
 | 
			
		||||
    const IniFormat format,
 | 
			
		||||
    const IniStatsHandler f_init,
 | 
			
		||||
    const IniDispHandler f_foreach,
 | 
			
		||||
    void * const user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int load_ini_file (
 | 
			
		||||
    FILE * const ini_file,
 | 
			
		||||
    const IniFormat format,
 | 
			
		||||
    const IniStatsHandler f_init,
 | 
			
		||||
    const IniDispHandler f_foreach,
 | 
			
		||||
    void * const user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int load_ini_path (
 | 
			
		||||
    const char * const path,
 | 
			
		||||
    const IniFormat format,
 | 
			
		||||
    const IniStatsHandler f_init,
 | 
			
		||||
    const IniDispHandler f_foreach,
 | 
			
		||||
    void * const user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern bool ini_string_match_ss (
 | 
			
		||||
    const char * const simple_string_a,
 | 
			
		||||
    const char * const simple_string_b,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern bool ini_string_match_si (
 | 
			
		||||
    const char * const simple_string,
 | 
			
		||||
    const char * const ini_string,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern bool ini_string_match_ii (
 | 
			
		||||
    const char * const ini_string_a,
 | 
			
		||||
    const char * const ini_string_b,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern bool ini_array_match (
 | 
			
		||||
    const char * const ini_string_a,
 | 
			
		||||
    const char * const ini_string_b,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t ini_unquote (
 | 
			
		||||
    char * const ini_string,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t ini_string_parse (
 | 
			
		||||
    char * const ini_string,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t ini_array_get_length (
 | 
			
		||||
    const char * const ini_string,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int ini_array_foreach (
 | 
			
		||||
    const char * const ini_string,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format,
 | 
			
		||||
    const IniSubstrHandler f_foreach,
 | 
			
		||||
    void * const user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t ini_array_shift (
 | 
			
		||||
    const char ** const ini_strptr,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern size_t ini_array_collapse (
 | 
			
		||||
    char * const ini_string,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern char * ini_array_break (
 | 
			
		||||
    char * const ini_string,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern char * ini_array_release (
 | 
			
		||||
    char ** const ini_strptr,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int ini_array_split (
 | 
			
		||||
    char * const ini_string,
 | 
			
		||||
    const char delimiter,
 | 
			
		||||
    const IniFormat format,
 | 
			
		||||
    const IniStrHandler f_foreach,
 | 
			
		||||
    void * const user_data
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void ini_global_set_lowercase_mode (
 | 
			
		||||
    const bool lowercase
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void ini_global_set_implicit_value (
 | 
			
		||||
    char * const implicit_value,
 | 
			
		||||
    const size_t implicit_v_len
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern IniFormatNum ini_fton (
 | 
			
		||||
    const IniFormat format
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern IniFormat ini_ntof (
 | 
			
		||||
    const IniFormatNum format_id
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int ini_get_bool (
 | 
			
		||||
    const char * const ini_string,
 | 
			
		||||
    const int when_fail
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PUBLIC LINKS  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern int (* const ini_get_int) (
 | 
			
		||||
    const char * ini_string
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern long int (* const ini_get_lint) (
 | 
			
		||||
    const char * ini_string
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern long long int (* const ini_get_llint) (
 | 
			
		||||
    const char * ini_string
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern double (* const ini_get_double) (
 | 
			
		||||
    const char * ini_string
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Legacy support, soon to be replaced with a `float` data type --
 | 
			
		||||
            please **do not use `ini_get_float()`!**
 | 
			
		||||
**/
 | 
			
		||||
#define ini_get_float \
 | 
			
		||||
    _Pragma("GCC warning \"function `ini_get_float()` is deprecated for parsing a `double` data type; use `ini_get_double()` instead\"") \
 | 
			
		||||
    ini_get_double
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  PUBLIC CONSTANTS AND VARIABLES  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Error mask (flags not present in user-generated interruptions)
 | 
			
		||||
**/
 | 
			
		||||
#define CONFINI_ERROR 252
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Error codes
 | 
			
		||||
**/
 | 
			
		||||
enum ConfiniInterruptNo {
 | 
			
		||||
    CONFINI_SUCCESS = 0,    /**< There have been no interruptions, everything
 | 
			
		||||
                                 went well [value=0] **/
 | 
			
		||||
    CONFINI_IINTR = 1,      /**< Interrupted by the user during `f_init()`
 | 
			
		||||
                                 [value=1] **/
 | 
			
		||||
    CONFINI_FEINTR = 2,     /**< Interrupted by the user during `f_foreach()`
 | 
			
		||||
                                 [value=2] **/
 | 
			
		||||
    CONFINI_ENOENT = 4,     /**< File inaccessible [value=4] **/
 | 
			
		||||
    CONFINI_ENOMEM = 5,     /**< Error allocating virtual memory [value=5] **/
 | 
			
		||||
    CONFINI_EIO = 6,        /**< Error reading the file [value=6] **/
 | 
			
		||||
    CONFINI_EOOR = 7,       /**< Out-of-range error: callbacks are more than
 | 
			
		||||
                                 expected [value=7] **/
 | 
			
		||||
    CONFINI_EBADF = 8,      /**< The stream specified is not a seekable stream
 | 
			
		||||
                                 [value=8] **/
 | 
			
		||||
    CONFINI_EFBIG = 9,      /**< File too large [value=9] **/
 | 
			
		||||
    CONFINI_EROADDR = 10    /**< Address is read-only [value=10] **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  INI node types
 | 
			
		||||
**/
 | 
			
		||||
enum IniNodeType {
 | 
			
		||||
    INI_UNKNOWN = 0,            /**< This is a node impossible to categorize
 | 
			
		||||
                                     [value=0] **/
 | 
			
		||||
    INI_VALUE = 1,              /**< Not used by **libconfini** (values are
 | 
			
		||||
                                     dispatched together with keys) -- but
 | 
			
		||||
                                     available for user's implementations
 | 
			
		||||
                                     [value=1] **/
 | 
			
		||||
    INI_KEY = 2,                /**< This is a key [value=2] **/
 | 
			
		||||
    INI_SECTION = 3,            /**< This is a section or a section path
 | 
			
		||||
                                     [value=3] **/
 | 
			
		||||
    INI_COMMENT = 4,            /**< This is a comment [value=4] **/
 | 
			
		||||
    INI_INLINE_COMMENT = 5,     /**< This is an inline comment [value=5] **/
 | 
			
		||||
    INI_DISABLED_KEY = 6,       /**< This is a disabled key [value=6] **/
 | 
			
		||||
    INI_DISABLED_SECTION = 7    /**< This is a disabled section path
 | 
			
		||||
                                     [value=7] **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Common array and key-value delimiters (but a delimiter may also be
 | 
			
		||||
            any other ASCII character not present in this list)
 | 
			
		||||
**/
 | 
			
		||||
enum IniDelimiters {
 | 
			
		||||
    INI_ANY_SPACE = 0,  /**< In multi-line INIs:
 | 
			
		||||
                             `/(?:\\(?:\n\r?|\r\n?)|[\t \v\f])+/`, in
 | 
			
		||||
                             non-multi-line INIs: `/[\t \v\f])+/` **/
 | 
			
		||||
    INI_EQUALS = '=',   /**< Equals character (`=`) **/
 | 
			
		||||
    INI_COLON = ':',    /**< Colon character (`:`) **/
 | 
			
		||||
    INI_DOT = '.',      /**< Dot character (`.`) **/
 | 
			
		||||
    INI_COMMA = ','     /**< Comma character (`,`) **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Possible values of #IniFormat::semicolon_marker and
 | 
			
		||||
            #IniFormat::hash_marker (i.e., meaning of `/\s+;/` and `/\s+#/` in
 | 
			
		||||
            respect to a format)
 | 
			
		||||
**/
 | 
			
		||||
enum IniCommentMarker {
 | 
			
		||||
    INI_DISABLED_OR_COMMENT = 0,    /**< This marker opens a comment or a
 | 
			
		||||
                                         disabled entry **/
 | 
			
		||||
    INI_ONLY_COMMENT = 1,           /**< This marker opens a comment **/
 | 
			
		||||
    INI_IGNORE = 2,                 /**< This marker opens a comment that has
 | 
			
		||||
                                         been marked for deletion and must not
 | 
			
		||||
                                         be dispatched or counted **/
 | 
			
		||||
    INI_IS_NOT_A_MARKER = 3         /**< This is not a marker at all, but a
 | 
			
		||||
                                         normal character instead **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Possible values of #IniFormat::section_paths
 | 
			
		||||
**/
 | 
			
		||||
enum IniSectionPaths {
 | 
			
		||||
    INI_ABSOLUTE_AND_RELATIVE = 0,  /**< Section paths starting with a dot
 | 
			
		||||
                                         express nesting to the current parent,
 | 
			
		||||
                                         to root otherwise **/
 | 
			
		||||
    INI_ABSOLUTE_ONLY = 1,          /**< Section paths starting with a dot will
 | 
			
		||||
                                         be cleaned of their leading dot and
 | 
			
		||||
                                         appended to root **/
 | 
			
		||||
    INI_ONE_LEVEL_ONLY = 2,         /**< Format supports sections, but the dot
 | 
			
		||||
                                         does not express nesting and is not a
 | 
			
		||||
                                         meta-character **/
 | 
			
		||||
    INI_NO_SECTIONS = 3             /**< Format does *not* support sections --
 | 
			
		||||
                                         `/\[[^\]]*\]/g`, if any, will be
 | 
			
		||||
                                         treated as keys! **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Possible values of #IniFormat::multiline_nodes
 | 
			
		||||
**/
 | 
			
		||||
enum IniMultiline {
 | 
			
		||||
    INI_MULTILINE_EVERYWHERE = 0,       /**< Comments, section paths and keys
 | 
			
		||||
                                             -- disabled or not -- are allowed
 | 
			
		||||
                                             to be multi-line **/
 | 
			
		||||
    INI_BUT_COMMENTS = 1,               /**< Only section paths and keys --
 | 
			
		||||
                                             disabled or not -- are allowed to
 | 
			
		||||
                                             be multi-line **/
 | 
			
		||||
    INI_BUT_DISABLED_AND_COMMENTS = 2,  /**< Only active section paths and
 | 
			
		||||
                                             active keys are allowed to be
 | 
			
		||||
                                             multi-line **/
 | 
			
		||||
    INI_NO_MULTILINE = 3                /**< Multi-line escape sequences are
 | 
			
		||||
                                             disabled **/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  A model format for standard INI files
 | 
			
		||||
**/
 | 
			
		||||
static const IniFormat INI_DEFAULT_FORMAT = _LIBCONFINI_DEFAULT_FORMAT_;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  A model format for Unix-like .conf files (where space characters
 | 
			
		||||
            are delimiters between keys and values)
 | 
			
		||||
**/
 | 
			
		||||
/*  All fields are set to `0` here.  */
 | 
			
		||||
static const IniFormat INI_UNIXLIKE_FORMAT = _LIBCONFINI_UNIXLIKE_FORMAT_;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  If set to `true`, key and section names in case-insensitive INI
 | 
			
		||||
            formats will be dispatched lowercase, verbatim otherwise (default
 | 
			
		||||
            value: `false`)
 | 
			
		||||
**/
 | 
			
		||||
extern bool INI_GLOBAL_LOWERCASE_MODE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Value to be assigned to implicit keys (default value: `NULL`)
 | 
			
		||||
**/
 | 
			
		||||
extern char * INI_GLOBAL_IMPLICIT_VALUE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
    @brief  Length of the value assigned to implicit keys (default value: `0`)
 | 
			
		||||
**/
 | 
			
		||||
extern size_t INI_GLOBAL_IMPLICIT_V_LEN;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  CLEAN THE PRIVATE ENVIRONMENT  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#undef _LIBCONFINI_UNIXLIKE_FORMAT_
 | 
			
		||||
#undef _LIBCONFINI_DEFAULT_FORMAT_
 | 
			
		||||
#undef _LIBCONFINI_INIFORMAT_TYPE_
 | 
			
		||||
#undef __INIFORMAT_TABLE_CB_ZERO__
 | 
			
		||||
#undef __INIFORMAT_TABLE_CB_DEFAULT__
 | 
			
		||||
#undef __INIFORMAT_TABLE_CB_FIELDS__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  END OF `_LIBCONFINI_HEADER_`  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  EOF  */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,38 @@
 | 
			
		|||
#ifndef CONTROLLER_CONTANTS_H
 | 
			
		||||
#define CONTROLLER_CONTANTS_H
 | 
			
		||||
 | 
			
		||||
#include <log_levels.h>
 | 
			
		||||
 | 
			
		||||
#define SECONDS_PER_DAY 86400 // 60 * 60 * 24
 | 
			
		||||
 | 
			
		||||
#define SECONDS_PER_MINUTE 60
 | 
			
		||||
 | 
			
		||||
#define POLL_FDS_COUNT 2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Limit the maximum length of a controller/relay/etc name
 | 
			
		||||
 *
 | 
			
		||||
 * The NULL terminator is not included. Arrays of length #MAX_NAME_LENGTH + 1 are required.
 | 
			
		||||
 */
 | 
			
		||||
#define MAX_NAME_LENGTH 128
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Maximum number of dbs for the databases for the MDB_env
 | 
			
		||||
 *
 | 
			
		||||
 * Used when calling mdb_env_set_maxdbs() in database_setup()
 | 
			
		||||
 */
 | 
			
		||||
#define MDB_MAXDBS 8
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Indicates to which level to log
 | 
			
		||||
 *
 | 
			
		||||
 * @see include/log_levels.h
 | 
			
		||||
 */
 | 
			
		||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief How many milli seconds to wait until poll timeout in main loop
 | 
			
		||||
 */
 | 
			
		||||
#define ACCEPT_TIMEOUT_MSECONDS 1000
 | 
			
		||||
 | 
			
		||||
#endif /* CONTROLLER_CONTANTS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,13 +2,14 @@
 | 
			
		|||
#define CONTROLLER_DRIVERS_H
 | 
			
		||||
 | 
			
		||||
#include <models/relay.h>
 | 
			
		||||
#include <enums.h>
 | 
			
		||||
 | 
			
		||||
#define DRIVER_PIFACE_GPIO_BASE 200
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
driver_piface_set(relay_t *relay, int value);
 | 
			
		||||
driver_piface_set(int pin, int value);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
driver_gpio_set(relay_t *relay, int value);
 | 
			
		||||
driver_gpio_set(int pin, int value);
 | 
			
		||||
 | 
			
		||||
#endif /* CONTROLLER_DRIVERS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +1,21 @@
 | 
			
		|||
#ifndef CONTROLLER_ENUMS_H
 | 
			
		||||
#define CONTROLLER_ENUMS_H
 | 
			
		||||
 | 
			
		||||
enum poll_fgs
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    POLL_FDS_DISCOVERY,
 | 
			
		||||
    POLL_FDS_COMMAND
 | 
			
		||||
};
 | 
			
		||||
} poll_fds_t;
 | 
			
		||||
 | 
			
		||||
enum discovery_mapping
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    DISCOVERY_MAPPING_ID = 0,
 | 
			
		||||
    DISCOVERY_MAPPING_NAME = 1,
 | 
			
		||||
    DISCOVERY_MAPPING_COMMAND_PORT = 2,
 | 
			
		||||
    DISCOVERY_MAPPING_RELAY_COUNT = 3,
 | 
			
		||||
};
 | 
			
		||||
} discovery_mapping_t;
 | 
			
		||||
 | 
			
		||||
enum control_mapping
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    COMMAND_MAPPING_CODE = 0,
 | 
			
		||||
    COMMAND_MAPPING_NAME = 1,
 | 
			
		||||
| 
						 | 
				
			
			@ -23,9 +23,9 @@ enum control_mapping
 | 
			
		|||
    COMMAND_MAPPING_SCHEDULE_ID = 3,
 | 
			
		||||
    COMMAND_MAPPING_PERIODS_COUNT = 4,
 | 
			
		||||
    COMMAND_MAPPING_PERIODS_BLOB = 5,
 | 
			
		||||
};
 | 
			
		||||
} control_mapping_t;
 | 
			
		||||
 | 
			
		||||
enum command_code
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    COMMAND_CODE_GET_TIME = 1,
 | 
			
		||||
    COMMAND_CODE_GET_ID = 2,
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,13 @@ enum command_code
 | 
			
		|||
    COMMAND_CODE_GET_SCHEDULE = 103,
 | 
			
		||||
    COMMAND_CODE_SET_RELAY_NAME = 104,
 | 
			
		||||
    COMMAND_CODE_GET_RELAY_NAME = 105,
 | 
			
		||||
};
 | 
			
		||||
} command_code_t;
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    RELAY_DRIVER_NONE = 0,
 | 
			
		||||
    RELAY_DRIVER_GPIO = 1,
 | 
			
		||||
    RELAY_DRIVER_PIFACE = 2,
 | 
			
		||||
} relay_driver_t;
 | 
			
		||||
 | 
			
		||||
#endif /* CONTROLLER_ENUMS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
#ifndef CONTROLLER_HELPERS_H
 | 
			
		||||
#define CONTROLLER_HELPERS_H
 | 
			
		||||
 | 
			
		||||
#include <confini.h>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
helper_connect_tcp_server(char* host, uint16_t port);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -22,4 +24,7 @@ helper_get_port(int sock);
 | 
			
		|||
int
 | 
			
		||||
helper_open_discovery_socket(uint16_t discovery_port);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
helper_load_config(IniDispatch *disp, void *config_void);
 | 
			
		||||
 | 
			
		||||
#endif /* CONTROLLER_HELPERS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ char _LOGGER_TIMESTAMP[_LOGGER_TIMESTAMP_SIZE];
 | 
			
		|||
char*
 | 
			
		||||
logger_get_timestamp();
 | 
			
		||||
 | 
			
		||||
#define _LOGGER_MESSAGE(msg) COLOR_NONE " %s %s:%d:%s: " msg "\n", logger_get_timestamp(), __FILENAME__, __LINE__, __func__
 | 
			
		||||
#define _LOGGER_MESSAGE(msg) " %s %s:%d:%s: " COLOR_NONE msg "\n", logger_get_timestamp(), __FILENAME__, __LINE__, __func__
 | 
			
		||||
 | 
			
		||||
#if LOG_LEVEL >= LOG_LEVEL_TRACE
 | 
			
		||||
    #define LOG_TRACE(msg, ...) fprintf(stdout, COLOR_TRACE "[TRACE]" _LOGGER_MESSAGE(msg), ##__VA_ARGS__)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,8 +48,7 @@ typedef enum
 | 
			
		|||
    DB_KEY_CONTROLLER_NAME = 1,
 | 
			
		||||
    DB_KEY_CONTROLLER_COMMAND_PORT = 2,
 | 
			
		||||
    DB_KEY_CONTROLLER_DISCOVERY_PORT = 3,
 | 
			
		||||
    DB_KEY_CONTROLLER_RELAY_COUNT = 4,
 | 
			
		||||
    DB_KEY_CONTROLLER_RELAYS = 5,
 | 
			
		||||
    DB_KEY_CONTROLLER_RELAYS = 4,
 | 
			
		||||
} db_key_controller_e;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@
 | 
			
		|||
#include <time.h>
 | 
			
		||||
#include <lmdb.h>
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
#include <models/schedule.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								main.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -20,6 +20,9 @@
 | 
			
		|||
#include <wiringPi.h>
 | 
			
		||||
#include <piFace.h>
 | 
			
		||||
#include <wiring_debug.h>
 | 
			
		||||
#include <confini.h>
 | 
			
		||||
 | 
			
		||||
config_t global_config;
 | 
			
		||||
 | 
			
		||||
static MDB_env *mdb_env;
 | 
			
		||||
static controller_t *this_controller;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +42,8 @@ terminate(int signum)
 | 
			
		|||
 | 
			
		||||
    controller_free(this_controller);
 | 
			
		||||
 | 
			
		||||
    free(global_config.relay_configs);
 | 
			
		||||
 | 
			
		||||
    exit(signum);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +65,23 @@ main(int argc, char** argv)
 | 
			
		|||
    signal(SIGABRT, terminate);
 | 
			
		||||
    signal(SIGTERM, terminate);
 | 
			
		||||
 | 
			
		||||
    /******************** LOAD CONFIG ********************/
 | 
			
		||||
 | 
			
		||||
    char ini_file_name[] = "controller.ini";
 | 
			
		||||
    FILE * const ini_file = fopen(ini_file_name, "rb");
 | 
			
		||||
    if(ini_file == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        LOG_ERROR("%s file was not found", ini_file_name);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    if(load_ini_file( ini_file, INI_DEFAULT_FORMAT, NULL, helper_load_config, &global_config))
 | 
			
		||||
    {
 | 
			
		||||
        LOG_ERROR("unable to parse ini file");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    fclose(ini_file);
 | 
			
		||||
 | 
			
		||||
    if(sizeof(time_t) < 8)
 | 
			
		||||
    {
 | 
			
		||||
        LOG_WARN("this system is not using 8-bit time");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,8 @@
 | 
			
		|||
 | 
			
		||||
#include <models/controller.h>
 | 
			
		||||
#include <macros.h>
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
 | 
			
		||||
controller_t*
 | 
			
		||||
controller_create(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -13,10 +15,12 @@ controller_create(void)
 | 
			
		|||
    controller_t *new_controller = malloc(sizeof(*new_controller));
 | 
			
		||||
    uuid_generate(new_controller->id);
 | 
			
		||||
 | 
			
		||||
    strcpy(new_controller->name, "new emgauwa device");
 | 
			
		||||
    strncpy(new_controller->name, global_config.name, MAX_NAME_LENGTH);
 | 
			
		||||
    new_controller->name[MAX_NAME_LENGTH] = '\0';
 | 
			
		||||
 | 
			
		||||
    new_controller->command_port = 0;
 | 
			
		||||
    new_controller->discovery_port = 4421;
 | 
			
		||||
    new_controller->relay_count = 10;
 | 
			
		||||
    new_controller->discovery_port = global_config.discovery_port;
 | 
			
		||||
    new_controller->relay_count = global_config.relay_count;
 | 
			
		||||
 | 
			
		||||
    new_controller->relays = malloc(sizeof(relay_t) * new_controller->relay_count);
 | 
			
		||||
    uint8_t i;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,8 +70,7 @@ controller_load(MDB_env *mdb_env)
 | 
			
		|||
    controller_load_single(mdb_txn, mdb_dbi, DB_KEY_CONTROLLER_DISCOVERY_PORT, &value);
 | 
			
		||||
    new_controller->discovery_port = ((uint16_t*)value.mv_data)[0];
 | 
			
		||||
 | 
			
		||||
    controller_load_single(mdb_txn, mdb_dbi, DB_KEY_CONTROLLER_RELAY_COUNT, &value);
 | 
			
		||||
    new_controller->relay_count = ((uint8_t*)value.mv_data)[0];
 | 
			
		||||
    new_controller->relay_count = global_config.relay_count;
 | 
			
		||||
 | 
			
		||||
    mdb_txn_abort(mdb_txn); // transaction is read only
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,14 +78,6 @@ controller_save(controller_t *controller, MDB_env *mdb_env)
 | 
			
		|||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    value.mv_size = sizeof(controller->relay_count);
 | 
			
		||||
    value.mv_data = &controller->relay_count;
 | 
			
		||||
    if(controller_save_single(mdb_txn, mdb_dbi, DB_KEY_CONTROLLER_RELAY_COUNT, value))
 | 
			
		||||
    {
 | 
			
		||||
        LOG_ERROR("failed to save relay count");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mdb_txn_commit(mdb_txn);
 | 
			
		||||
 | 
			
		||||
    for(uint8_t i = 0; i < controller->relay_count; ++i)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,6 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <uuid/uuid.h>
 | 
			
		||||
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
#include <logger.h>
 | 
			
		||||
#include <models/relay.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue