diff --git a/src/include/switch_xml_config.h b/src/include/switch_xml_config.h index fc669e4fc1..6a81e4b16f 100644 --- a/src/include/switch_xml_config.h +++ b/src/include/switch_xml_config.h @@ -39,6 +39,7 @@ SWITCH_BEGIN_EXTERN_C /*! \brief Type of value to parse */ typedef enum { SWITCH_CONFIG_INT, /*< (ptr=int* default=int data=NULL) Integer */ + SWITCH_CONFIG_ATOMIC, /*< (ptr=switch_atomic_t* default=uint32_t data=NULL) Integer */ SWITCH_CONFIG_STRING, /*< (ptr=[char* or char ** (for alloc)] default=char* data=switch_xml_config_string_options_t*) Zero-terminated C-string */ SWITCH_CONFIG_BOOL, /*< (ptr=switch_bool_t* default=switch_bool_t data=NULL) Yes and no */ SWITCH_CONFIG_CUSTOM, /*< (ptr= default= data=switch_xml_config_callback_t) Custom, get value through function pointer */ @@ -70,6 +71,13 @@ typedef struct { int max; } switch_xml_config_int_options_t; +typedef struct { + switch_bool_t enforce_min; + uint32_t min; + switch_bool_t enforce_max; + uint32_t max; +} switch_xml_config_atomic_options_t; + struct switch_xml_config_item; typedef struct switch_xml_config_item switch_xml_config_item_t; diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c index c33dba4e8a..a6fdc55496 100644 --- a/src/switch_xml_config.c +++ b/src/switch_xml_config.c @@ -36,6 +36,7 @@ SWITCH_DECLARE_DATA switch_xml_config_string_options_t switch_config_string_strd static switch_xml_config_enum_item_t switch_config_types_enum[] = { {"int", SWITCH_CONFIG_INT}, + {"switch_atomic_t", SWITCH_CONFIG_INT}, {"string", SWITCH_CONFIG_STRING}, {"bool", SWITCH_CONFIG_BOOL}, {"custom", SWITCH_CONFIG_CUSTOM}, @@ -203,6 +204,48 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev } } break; + case SWITCH_CONFIG_ATOMIC: + { + switch_xml_config_atomic_options_t *atomic_options = (switch_xml_config_atomic_options_t *) item->data; + switch_atomic_t *dest = (switch_atomic_t *) ptr; + uint32_t uintval; + if (value) { + if (switch_is_number(value)) { + uintval = (uint32_t) strtoll(value, 10); + } else { + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid value [%s] for parameter [%s], setting default [%u]\n", + value, item->key, uintval); + } + + if (atomic_options) { + /* Enforce validation options */ + if ((atomic_options->enforce_min && !(uintval >= atomic_options->min)) || (atomic_options->enforce_max && !(uintval <= atomic_options->max))) { + /* Validation failed, set default */ + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + /* Then complain */ + if (atomic_options->enforce_min && atomic_options->enforce_max) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Invalid value [%s] for parameter [%s], should be between [%u] and [%u], setting default [%u]\n", value, + item->key, atomic_options->min, atomic_options->max, uintval); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Invalid value [%s] for parameter [%s], should be %s [%u], setting default [%u]\n", value, item->key, + atomic_options->enforce_min ? "at least" : "at max", + atomic_options->enforce_min ? atomic_options->min : atomic_options->max, uintval); + } + } + } + } else { + uintval = (uint32_t) (uintptr_t) item->defaultvalue; + } + + if (switch_atomic_read(dest) != uintval) { + switch_atomic_set(dest, uintval); + changed = SWITCH_TRUE; + } + } + break; case SWITCH_CONFIG_STRING: { switch_xml_config_string_options_t string_options_default = { 0 };