1
0
mirror of https://github.com/stargieg/bacnet-stack synced 2025-10-26 23:35:52 +08:00

load uci value if uci config has mod time change

This commit is contained in:
Patrick Grimm 2013-09-21 04:19:45 +02:00
parent 44c3f6fa64
commit 3dfa360ef5
8 changed files with 350 additions and 44 deletions

View File

@ -94,6 +94,7 @@ static const int Analog_Value_Properties_Optional[] = {
PROP_NOTIFY_TYPE, PROP_NOTIFY_TYPE,
PROP_EVENT_TIME_STAMPS, PROP_EVENT_TIME_STAMPS,
#endif #endif
PROP_RELIABILITY,
-1 -1
}; };
@ -149,32 +150,33 @@ void Analog_Value_Init(
const char *ucilow_limit; const char *ucilow_limit;
const char *ucidead_limit_default; const char *ucidead_limit_default;
const char *ucidead_limit; const char *ucidead_limit;
const char *sec = "bacnet_av";
fprintf(stderr, "Analog_Value_Init\n"); fprintf(stderr, "Analog_Value_Init\n");
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
ctx = ucix_init("bacnet_av"); ctx = ucix_init(sec);
if(!ctx) if(!ctx)
fprintf(stderr, "Failed to load config file"); fprintf(stderr, "Failed to load config file\n");
ucidescription_default = ucix_get_option(ctx, "bacnet_av", "default", ucidescription_default = ucix_get_option(ctx, sec, "default",
"description"); "description");
uciunit_default = ucix_get_option_int(ctx, "bacnet_av", "default", uciunit_default = ucix_get_option_int(ctx, sec, "default",
"si_unit", 0); "si_unit", 0);
ucivalue_default = ucix_get_option(ctx, "bacnet_av", "default", ucivalue_default = ucix_get_option(ctx, sec, "default",
"value"); "value");
ucinc_default = ucix_get_option_int(ctx, "bacnet_av", "default", ucinc_default = ucix_get_option_int(ctx, sec, "default",
"nc", -1); "nc", -1);
ucievent_default = ucix_get_option_int(ctx, "bacnet_av", "default", ucievent_default = ucix_get_option_int(ctx, sec, "default",
"event", -1); "event", -1);
ucitime_delay_default = ucix_get_option_int(ctx, "bacnet_av", "default", ucitime_delay_default = ucix_get_option_int(ctx, sec, "default",
"time_delay", -1); "time_delay", -1);
ucilimit_default = ucix_get_option_int(ctx, "bacnet_av", "default", ucilimit_default = ucix_get_option_int(ctx, sec, "default",
"limit", -1); "limit", -1);
ucihigh_limit_default = ucix_get_option(ctx, "bacnet_av", "default", ucihigh_limit_default = ucix_get_option(ctx, sec, "default",
"high_limit"); "high_limit");
ucilow_limit_default = ucix_get_option(ctx, "bacnet_av", "default", ucilow_limit_default = ucix_get_option(ctx, sec, "default",
"low_limit"); "low_limit");
ucidead_limit_default = ucix_get_option(ctx, "bacnet_av", "default", ucidead_limit_default = ucix_get_option(ctx, sec, "default",
"dead_limit"); "dead_limit");
for (i = 0; i < MAX_ANALOG_VALUES; i++) { for (i = 0; i < MAX_ANALOG_VALUES; i++) {
@ -224,6 +226,8 @@ void Analog_Value_Init(
ucivalue = 0; ucivalue = 0;
} else { } else {
ucivalue = ucivalue_default; ucivalue = ucivalue_default;
AV_Descr[i].Reliability =
RELIABILITY_COMMUNICATION_FAILURE;
} }
} }
AV_Descr[i].Priority_Array[15] = strtof(ucivalue, AV_Descr[i].Priority_Array[15] = strtof(ucivalue,
@ -369,6 +373,81 @@ bool Analog_Value_Valid_Instance(
return false; return false;
} }
bool Analog_Value_Change_Of_Value(
uint32_t object_instance)
{
ANALOG_VALUE_DESCR *CurrentAV;
bool status = false;
unsigned index;
index = Analog_Value_Instance_To_Index(object_instance);
if (index < max_analog_values_int) {
CurrentAV = &AV_Descr[index];
status = CurrentAV->Change_Of_Value;
}
return status;
}
void Analog_Value_Change_Of_Value_Clear(
uint32_t object_instance)
{
ANALOG_VALUE_DESCR *CurrentAV;
unsigned index;
index = Analog_Value_Instance_To_Index(object_instance);
if (index < max_analog_values_int) {
CurrentAV = &AV_Descr[index];
CurrentAV->Change_Of_Value = false;
}
return;
}
/* returns true if value has changed */
bool Analog_Value_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list)
{
bool status = false;
if (value_list) {
value_list->propertyIdentifier = PROP_PRESENT_VALUE;
value_list->propertyArrayIndex = BACNET_ARRAY_ALL;
value_list->value.context_specific = false;
value_list->value.tag = BACNET_APPLICATION_TAG_ENUMERATED;
value_list->value.type.Enumerated =
Analog_Value_Present_Value(object_instance);
value_list->priority = BACNET_NO_PRIORITY;
value_list = value_list->next;
}
if (value_list) {
value_list->propertyIdentifier = PROP_STATUS_FLAGS;
value_list->propertyArrayIndex = BACNET_ARRAY_ALL;
value_list->value.context_specific = false;
value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING;
bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_FAULT, false);
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false);
if (Analog_Value_Out_Of_Service(object_instance)) {
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OUT_OF_SERVICE, true);
} else {
bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OUT_OF_SERVICE, false);
}
value_list->priority = BACNET_NO_PRIORITY;
}
status = Analog_Value_Change_Of_Value(object_instance);
return status;
}
float Analog_Value_Present_Value( float Analog_Value_Present_Value(
uint32_t object_instance) uint32_t object_instance)
{ {
@ -407,10 +486,9 @@ bool Analog_Value_Present_Value_Set(
if (index < max_analog_values_int) { if (index < max_analog_values_int) {
CurrentAV = &AV_Descr[index]; CurrentAV = &AV_Descr[index];
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */ ) ) {
(value >= 0.0) && (value <= 100.0)) { //CurrentAV->Present_Value = value;
CurrentAV->Present_Value = (uint8_t) value; CurrentAV->Priority_Array[priority - 1] = value;
CurrentAV->Priority_Array[priority - 1] = (uint8_t) value;
/* Note: you could set the physical output here to the next /* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no highest priority, or to the relinquish default if no
priorities are set. priorities are set.
@ -439,6 +517,38 @@ bool Analog_Value_Out_Of_Service(
return value; return value;
} }
void Analog_Value_Reliability_Set(
uint32_t object_instance,
uint8_t value)
{
ANALOG_VALUE_DESCR *CurrentAV;
unsigned index = 0;
index = Analog_Value_Instance_To_Index(object_instance);
if (index < max_analog_values_int) {
CurrentAV = &AV_Descr[index];
CurrentAV->Reliability = value;
}
return;
}
uint8_t Analog_Value_Reliability(
uint32_t object_instance)
{
ANALOG_VALUE_DESCR *CurrentAV;
unsigned index = 0; /* offset from instance lookup */
uint8_t value = 0;
index = Analog_Value_Instance_To_Index(object_instance);
if (index < max_analog_values_int) {
CurrentAV = &AV_Descr[index];
value = CurrentAV->Reliability;
}
return value;
}
void Analog_Value_Out_Of_Service_Set( void Analog_Value_Out_Of_Service_Set(
uint32_t object_instance, uint32_t object_instance,
bool value) bool value)
@ -456,7 +566,6 @@ void Analog_Value_Out_Of_Service_Set(
} }
static char *Analog_Value_Description( static char *Analog_Value_Description(
uint32_t object_instance) uint32_t object_instance)
{ {
@ -716,6 +825,12 @@ int Analog_Value_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
case PROP_RELIABILITY:
case PROP_STATE_RELIABILITY:
apdu_len = encode_application_boolean(&apdu[0],
CurrentAV->Reliability);
break;
case PROP_UNITS: case PROP_UNITS:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], CurrentAV->Units); encode_application_enumerated(&apdu[0], CurrentAV->Units);
@ -1050,6 +1165,15 @@ bool Analog_Value_Write_Property(
} }
break; break;
case PROP_RELIABILITY:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
CurrentAV->Reliability = value.type.Enumerated;
}
break;
case PROP_UNITS: case PROP_UNITS:
status = status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,

View File

@ -29,7 +29,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacerror.h" #include "bacerror.h" //TODO rm ?
#include "cov.h"
#include "wp.h" #include "wp.h"
#include "rp.h" #include "rp.h"
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@ -46,11 +47,14 @@ extern "C" {
int max_analog_values; int max_analog_values;
typedef struct analog_value_descr { typedef struct analog_value_descr {
unsigned Object_ID;
char Object_Name[64]; char Object_Name[64];
char Object_Description[64]; char Object_Description[64];
uint8_t Present_Value; //uint8_t Present_Value;
unsigned Event_State:3; unsigned Event_State:3;
bool Out_Of_Service; bool Out_Of_Service;
uint8_t Reliability;
bool Change_Of_Value;
bool Disable; bool Disable;
uint8_t Units; uint8_t Units;
/* Here is our Priority Array. They are supposed to be Real, but */ /* Here is our Priority Array. They are supposed to be Real, but */
@ -127,6 +131,23 @@ int max_analog_values;
uint32_t object_instance, uint32_t object_instance,
bool value); bool value);
uint8_t Analog_Value_Reliability(
uint32_t object_instance);
void Analog_Value_Reliability_Set(
uint32_t object_instance,
uint8_t value);
bool Analog_Value_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list);
bool Analog_Value_Change_Of_Value(
uint32_t instance);
void Analog_Value_Change_Of_Value_Clear(
uint32_t instance);
bool Analog_Value_Description_Set( bool Analog_Value_Description_Set(
uint32_t object_instance, uint32_t object_instance,
char *text_string); char *text_string);

View File

@ -862,6 +862,7 @@ int Binary_Input_Read_Property(
if (CurrentBI->Disable) if (CurrentBI->Disable)
return BACNET_STATUS_ERROR; return BACNET_STATUS_ERROR;
fprintf(stderr,"object_property: %i\n", rpdata->object_property);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =

View File

@ -107,7 +107,6 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#if 0
{OBJECT_ANALOG_INPUT, {OBJECT_ANALOG_INPUT,
Analog_Input_Init, Analog_Input_Init,
Analog_Input_Count, Analog_Input_Count,
@ -138,7 +137,6 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#endif
{OBJECT_ANALOG_VALUE, {OBJECT_ANALOG_VALUE,
Analog_Value_Init, Analog_Value_Init,
Analog_Value_Count, Analog_Value_Count,
@ -150,9 +148,9 @@ static object_functions_t My_Object_Table[] = {
Analog_Value_Property_Lists, Analog_Value_Property_Lists,
NULL /* ReadRangeInfo */ , NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ , NULL /* Iterator */ ,
NULL /* Value_Lists */ , Analog_Value_Encode_Value_List ,
NULL /* COV */ , Analog_Value_Change_Of_Value,
NULL /* COV Clear */ , Analog_Value_Change_Of_Value_Clear,
Analog_Value_Intrinsic_Reporting}, Analog_Value_Intrinsic_Reporting},
{OBJECT_BINARY_INPUT, {OBJECT_BINARY_INPUT,
Binary_Input_Init, Binary_Input_Init,
@ -169,7 +167,6 @@ static object_functions_t My_Object_Table[] = {
Binary_Input_Change_Of_Value, Binary_Input_Change_Of_Value,
Binary_Input_Change_Of_Value_Clear, Binary_Input_Change_Of_Value_Clear,
Binary_Input_Intrinsic_Reporting}, Binary_Input_Intrinsic_Reporting},
#if 0
{OBJECT_BINARY_OUTPUT, {OBJECT_BINARY_OUTPUT,
Binary_Output_Init, Binary_Output_Init,
Binary_Output_Count, Binary_Output_Count,
@ -215,8 +212,8 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#endif //#endif
#if defined(INTRINSIC_REPORTING) //#if defined(INTRINSIC_REPORTING)
{OBJECT_NOTIFICATION_CLASS, {OBJECT_NOTIFICATION_CLASS,
Notification_Class_Init, Notification_Class_Init,
Notification_Class_Count, Notification_Class_Count,
@ -232,8 +229,8 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#endif //#endif
#if 0 //#if 0
{OBJECT_LIFE_SAFETY_POINT, {OBJECT_LIFE_SAFETY_POINT,
Life_Safety_Point_Init, Life_Safety_Point_Init,
Life_Safety_Point_Count, Life_Safety_Point_Count,
@ -294,7 +291,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#endif //#endif
{OBJECT_MULTI_STATE_VALUE, {OBJECT_MULTI_STATE_VALUE,
Multistate_Value_Init, Multistate_Value_Init,
Multistate_Value_Count, Multistate_Value_Count,
@ -325,7 +322,7 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#if defined(BACFILE) //#if defined(BACFILE)
{OBJECT_FILE, {OBJECT_FILE,
bacfile_init, bacfile_init,
bacfile_count, bacfile_count,
@ -341,7 +338,6 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#endif
{MAX_BACNET_OBJECT_TYPE, {MAX_BACNET_OBJECT_TYPE,
NULL /* Init */ , NULL /* Init */ ,
NULL /* Count */ , NULL /* Count */ ,

View File

@ -227,7 +227,7 @@ void Trend_Log_Init(
if ((uciname != 0) && (ucidisable == 0)) { if ((uciname != 0) && (ucidisable == 0)) {
TL_Descr[i].Disable=false; TL_Descr[i].Disable=false;
max_trend_logs_int = i+1; max_trend_logs_int = i+1;
sprintf(name, "%s", uciname); sprintf(name, "TL_%s", uciname);
ucix_string_copy(TL_Descr[i].Object_Name, ucix_string_copy(TL_Descr[i].Object_Name,
sizeof(TL_Descr[i].Object_Name), name); sizeof(TL_Descr[i].Object_Name), name);
ucidescription = ucix_get_option(ctxd, uciobject_s, ucidescription = ucix_get_option(ctxd, uciobject_s,

View File

@ -60,7 +60,8 @@
#include "bacfile.h" #include "bacfile.h"
#endif /* defined(BACFILE) */ #endif /* defined(BACFILE) */
#include "ucix.h" #include "ucix.h"
#include "av.h"
#include "bi.h"
/** @file server/main.c Example server application using the BACnet Stack. */ /** @file server/main.c Example server application using the BACnet Stack. */
@ -160,7 +161,15 @@ int main(
uint32_t address_binding_tmr = 0; uint32_t address_binding_tmr = 0;
uint32_t recipient_scan_tmr = 0; uint32_t recipient_scan_tmr = 0;
int uci_id = 0; int uci_id = 0;
float val_f, pval_f;
int val_i, pval_i;
struct uci_context *ctx; struct uci_context *ctx;
time_t chk_mtime = 0;
time_t ucimodtime_bacnet_bi = 0;
time_t ucimodtime_bacnet_av = 0;
int uci_idx = 0;
char *section;
char *type;
ctx = ucix_init("bacnet_dev"); ctx = ucix_init("bacnet_dev");
if(!ctx) if(!ctx)
@ -235,6 +244,83 @@ int main(
#endif #endif
/* output */ /* output */
/* update Analog Value from uci */
section = "bacnet_av";
type = "av";
chk_mtime = 0;
chk_mtime = check_uci_update(section, ucimodtime_bacnet_av);
if(chk_mtime != 0) {
ucimodtime_bacnet_av = chk_mtime;
printf("Config changed, reloading %s\n",section);
ctx = ucix_init(section);
struct uci_itr_ctx itr;
value_tuple_t *cur;
itr.list = NULL;
itr.section = section;
itr.ctx = ctx;
ucix_for_each_section_type(ctx, section, type,
(void *)load_value, &itr);
for( cur = itr.list; cur; cur = cur->next ) {
printf("section %s idx %s \n", section, cur->idx);
val_f = strtof(cur->value,NULL);
uci_idx = atoi(cur->idx);
if (val_f || !strcmp(cur->value, "0")) {
printf("idx %s ",cur->idx);
printf("value %s\n",cur->value);
pval_f = Analog_Value_Present_Value(uci_idx);
if ( val_f != pval_f ) {
Analog_Value_Present_Value_Set(uci_idx,val_f,16);
}
if (Analog_Value_Out_Of_Service(uci_idx))
Analog_Value_Out_Of_Service_Set(uci_idx,0);
if (Analog_Value_Reliability(uci_idx))
Analog_Value_Reliability_Set(uci_idx,
RELIABILITY_NO_FAULT_DETECTED);
} else {
printf("idx %s ",cur->idx);
printf("Out_Of_Service\n");
Analog_Value_Out_Of_Service_Set(uci_idx,1);
Analog_Value_Reliability_Set(uci_idx,
RELIABILITY_COMMUNICATION_FAILURE);
}
}
ucix_cleanup(ctx);
}
/* update end */
/* update Binary Input from uci */
section = "bacnet_bi";
type = "bi";
chk_mtime = 0;
chk_mtime = check_uci_update(section, ucimodtime_bacnet_bi);
if(chk_mtime != 0) {
ucimodtime_bacnet_bi = chk_mtime;
printf("Config changed, reloading %s\n",section);
ctx = ucix_init(section);
struct uci_itr_ctx itr;
value_tuple_t *cur;
itr.list = NULL;
itr.section = section;
itr.ctx = ctx;
ucix_for_each_section_type(ctx, section, type,
(void *)load_value, &itr);
for( cur = itr.list; cur; cur = cur->next ) {
printf("section %s idx %s \n", section, cur->idx);
if (cur->value) {
printf("idx %s ",cur->idx);
printf("value %s\n",cur->value);
val_i = atoi(cur->value);
uci_idx = atoi(cur->idx);
pval_i = Binary_Input_Present_Value(uci_idx);
if ( val_i != pval_i ) {
Binary_Input_Present_Value_Set(uci_idx,val_i,16);
}
}
}
ucix_cleanup(ctx);
}
/* update end */
/* blink LEDs, Turn on or off outputs, etc */ /* blink LEDs, Turn on or off outputs, etc */
} }

View File

@ -16,10 +16,29 @@
* Copyright (C) 2008 John Crispin <blogic@openwrt.org> * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
*/ */
#include <stdbool.h>
#include <time.h>
#ifndef _UCI_H__ #ifndef _UCI_H__
#define _UCI_H__ #define _UCI_H__
struct uci_context* ucix_init(const char *config_file); struct uci_context* ucix_init(const char *config_file);
struct uci_context* ucix_init_path(const char *path, const char *config_file); struct uci_context* ucix_init_path(const char *path, const char *config_file);
/* value/name tuples */
struct value_tuple {
char value[16];
char idx[18];
struct value_tuple *next;
};
/* structure to hold tuple-list and uci context during iteration */
struct uci_itr_ctx {
struct value_tuple *list;
struct uci_context *ctx;
char *section;
};
typedef struct value_tuple value_tuple_t;
void ucix_cleanup(struct uci_context *ctx); void ucix_cleanup(struct uci_context *ctx);
void ucix_save(struct uci_context *ctx); void ucix_save(struct uci_context *ctx);
void ucix_save_state(struct uci_context *ctx); void ucix_save_state(struct uci_context *ctx);
@ -46,4 +65,8 @@ bool ucix_string_copy(char *dest, size_t i, char *src);
void ucix_for_each_section_type(struct uci_context *ctx, void ucix_for_each_section_type(struct uci_context *ctx,
const char *p, const char *t, const char *p, const char *t,
void (*cb)(const char*, void*), void *priv); void (*cb)(const char*, void*), void *priv);
/* Check if given uci file was updated */
time_t check_uci_update(const char *config, time_t mtime);
/* Add tuple */
void load_value(const char *sec_idx, struct uci_itr_ctx *itr);
#endif #endif

View File

@ -19,6 +19,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <uci_config.h> #include <uci_config.h>
#include <uci.h> #include <uci.h>
@ -241,3 +243,56 @@ bool ucix_string_copy(char *dest, size_t j, char *src)
return false; return false;
} }
/* Check if given uci file was updated */
time_t check_uci_update(const char *config, time_t mtime)
{
struct stat s;
char path[128];
time_t f_mtime = 0;
snprintf(path, sizeof(path), "/var/state/%s", config);
if( stat(path, &s) > -1 )
f_mtime = s.st_mtime;
snprintf(path, sizeof(path), "/etc/config/%s", config);
if( stat(path, &s) > -1 ) {
if( (f_mtime == 0) || (s.st_mtime > f_mtime) ) {
f_mtime = s.st_mtime;
}
}
snprintf(path, sizeof(path), "/tmp/.uci/%s", config);
if( stat(path, &s) > -1 ) {
if( (f_mtime == 0) || (s.st_mtime > f_mtime) ) {
f_mtime = s.st_mtime;
}
}
if( (mtime == 0) || (f_mtime > mtime) ) {
return f_mtime;
} else {
f_mtime = 0;
}
return f_mtime;
}
/* Add tuple */
void load_value(const char *sec_idx, struct uci_itr_ctx *itr)
{
value_tuple_t *t;
if (!strcmp(sec_idx, "default"))
return;
const char *value;
value = ucix_get_option(itr->ctx, itr->section, sec_idx, "value");
if( (t = (value_tuple_t *)malloc(sizeof(value_tuple_t))) != NULL ) {
strncpy(t->idx, sec_idx, sizeof(t->idx));
if ( value != NULL ) {
strncpy(t->value, value, sizeof(t->value));
}
t->next = itr->list;
itr->list = t;
}
}