]> pilppa.org Git - libplp.git/blob - src/DeviceConfig.cc
add read_interval DeviceConfig methods
[libplp.git] / src / DeviceConfig.cc
1 /*
2  * DeviceConfig.cc
3  *
4  *  Created on: Dec 9, 2010
5  *      Author: lamikr
6  */
7
8 #include "DeviceConfig.hh"
9
10 #include <string.h>
11 #include <malloc.h>
12
13 #include "log.h"
14
15 #include "DataReader.hh"
16 #include "FileUtil.hh"
17
18 using namespace std;
19 using namespace plp;
20
21 string DeviceConfig::store_base_dir             = DEFAULT_STORAGE_BASE_DIR;
22 long DeviceConfig::read_interval_seconds        = 600;
23
24 ConfigHandle::ConfigHandle(uci_context *ctx_param,
25                         uci_package *pkg_param,
26                         const char *short_fname_param,
27                         const char *full_fname_param) {
28         _ctx            = ctx_param;
29         _pkg            = pkg_param;
30         short_fname     = strdup(short_fname_param);
31         full_fname      = strdup(full_fname_param);
32 }
33
34 ConfigHandle::~ConfigHandle() {
35         uci_unload(_ctx, _pkg);
36         uci_free_context(_ctx);
37         free(short_fname);
38         free(full_fname);
39 }
40
41 static int uci_create_named_section(ConfigHandle *cfg_handle,
42                                 const char *section_type,
43                                 const char *section_name,
44                                 bool save_immediately)
45 {
46         struct uci_ptr  ptr;
47         int             ret_val;
48         char            *cmd_dta;
49         int             len;
50
51         ret_val = -1;
52         if ((cfg_handle != NULL) &&
53             (cfg_handle->_ctx != NULL) &&
54             (cfg_handle->short_fname != NULL) &&
55             (cfg_handle->full_fname != NULL) &&
56             (section_type != NULL) &&
57             (section_name != NULL)) {
58                 len     = strlen(cfg_handle->short_fname);
59                 len     = len + 1;
60                 len     = len + strlen(section_type);
61                 len     = len + 1;
62                 len     = len + strlen(section_name);
63                 len     = len + 1;
64                 cmd_dta = (char *)malloc(len);
65                 if (cmd_dta != NULL) {
66                         snprintf(cmd_dta,
67                                 len,
68                                 "%s.%s=%s",
69                                 cfg_handle->short_fname,
70                                 section_name,
71                                 section_type);
72                         if (uci_lookup_ptr(cfg_handle->_ctx, &ptr, cmd_dta, true) == UCI_OK) {
73                                 ret_val = uci_set(cfg_handle->_ctx, &ptr);
74                                 if (ret_val == UCI_OK) {
75                                         if (save_immediately) {
76                                                 ret_val = uci_save(cfg_handle->_ctx, ptr.p);
77                                         }
78                                 }
79                         }
80                         free(cmd_dta);
81                 }
82         }
83         return ret_val;
84 }
85
86 static bool set_config_value_to_section(ConfigHandle *cfg_handle,
87                         const char *section_type,
88                         const char *section_name,
89                         const char *key,
90                         const char *value) {
91         struct uci_section      *sct;
92         struct uci_section      *tmp_sct;
93         int                     err_flg;
94         struct uci_element      *elem;
95         struct uci_ptr          ptr;
96         bool                    ret_val;
97
98         ret_val = false;
99         err_flg = UCI_OK;
100         if ((cfg_handle != NULL) &&
101             (cfg_handle->_ctx != NULL) &&
102             (cfg_handle->_pkg != NULL) &&
103             (section_type != NULL) &&
104             (section_name != NULL) &&
105             (key != NULL) &&
106             (value != NULL)) {
107                 sct     = NULL;
108                 uci_foreach_element(&cfg_handle->_pkg->sections, elem) {
109                         tmp_sct = uci_to_section(elem);
110                         if (strcmp(tmp_sct->type, section_type) == 0) {
111                                 sct     = tmp_sct;
112                                 break;
113                         }
114                 }
115                 if (sct == NULL) {
116                         log_debug("Creating new section %s to configuration file: %s\n", section_name, cfg_handle->full_fname);
117                         //err_flg       = uci_add_named_section(ctx, pkg, section_type, section_name, &sct);
118                         //err_flg       = uci_add_section(ctx, pkg, section_name, &sct);
119                         err_flg = uci_create_named_section(cfg_handle,
120                                                 section_type,
121                                                 section_name,
122                                                 false);
123                         if (err_flg == UCI_OK) {
124                                 uci_foreach_element(&cfg_handle->_pkg->sections, elem) {
125                                         tmp_sct = uci_to_section(elem);
126                                         if (strcmp(tmp_sct->type, section_type) == 0) {
127                                                 sct     = tmp_sct;
128                                                 break;
129                                         }
130                                 }
131                         }
132                 }
133                 if (err_flg == UCI_OK) {
134                         memset(&ptr, 0, sizeof(ptr));
135                         ptr.package     = cfg_handle->_pkg->e.name;
136                         ptr.section     = sct->e.name;
137                         ptr.option      = key;
138                         err_flg         = uci_lookup_ptr(cfg_handle->_ctx, &ptr, NULL, false);
139                         if (err_flg == UCI_OK) {
140                                 ptr.value       = value;
141                                 err_flg         = uci_set(cfg_handle->_ctx, &ptr);
142                                 if (err_flg == UCI_OK) {
143                                         err_flg = uci_save(cfg_handle->_ctx, cfg_handle->_pkg);
144                                         if (err_flg == UCI_OK) {
145                                                 ret_val = true;
146                                                 log_debug("Set value to section %s in configuration file: %s\n", section_name, cfg_handle->full_fname);
147                                         }
148                                         else {
149                                                 log_error("Failed to set value to configuration file: %s\n. Could not save the file\n", cfg_handle->full_fname);
150                                         }
151                                 }
152                                 else {
153                                         log_error("Failed to set value to configuration file: %s\n. Could not set new value\n", cfg_handle->full_fname);
154                                 }
155                         }
156                         else {
157                                 log_error("Failed to set value to configuration file: %s\n. Could not look-up pointer for package %s section %s.\n",
158                                         cfg_handle->full_fname,
159                                         cfg_handle->_pkg->e.name,
160                                         sct->e.name);
161                         }
162                         uci_free_context(cfg_handle->_ctx);
163                 }
164                 else {
165                         log_error("Failed to set value to configuration file: %s. Could not create section %s.\n", cfg_handle->full_fname, section_name);
166                 }
167         }
168         else {
169                 log_error("Failed to set value to configuration file, invalid parameters\n");
170         }
171         return ret_val;
172 }
173
174 DeviceConfig::DeviceConfig(string device_id_param) {
175         device_id       = device_id_param;
176         uci_handle      = load_device_config(device_id_param);
177         if (uci_handle != NULL) {
178                 device_type     = get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
179         }
180         else {
181                 log_error("Could not read device configuration.\n");
182         }
183 }
184
185 DeviceConfig::~DeviceConfig() {
186         if (uci_handle != NULL) {
187                 delete(uci_handle);
188                 uci_handle      = NULL;
189         }
190 }
191
192 void DeviceConfig::set_base_dir_name(string store_param) {
193         int     pos;
194         int     b_count;
195
196         pos     = store_param.find_last_of("/");
197         b_count = store_param.length();
198         if (pos == (b_count - 1)) {
199                 store_base_dir  = store_param;
200         }
201         else {
202                 store_base_dir  = store_param + "/";
203         }
204 }
205
206 long DeviceConfig::get_read_interval_seconds() {
207         return read_interval_seconds;
208 }
209
210 void DeviceConfig::set_read_interval_seconds(long seconds_param) {
211         read_interval_seconds   = seconds_param;
212 }
213
214 string DeviceConfig::get_base_dir_name() {
215         return store_base_dir;
216 }
217
218 string DeviceConfig::get_dir_name(string device_id_param) {
219         string  ret_val;
220         string  d_name;
221
222         d_name  = DeviceConfig::get_base_dir_name();
223         ret_val = FileUtil::concat_paths(d_name, device_id_param);
224         return ret_val;
225 }
226
227 string DeviceConfig::get_file_name(string device_id_param) {
228         string  ret_val;
229         string  fname;
230
231         fname   = DEVICE_CONFIG__FILE_NAME;
232         ret_val = get_dir_name(device_id_param);
233         ret_val = FileUtil::concat_paths(ret_val, fname);
234         return ret_val;
235 }
236
237 string DeviceConfig::get_config_value(string key) {
238         struct uci_section      *section;
239         struct uci_option       *option;
240         string                  ret_val;
241
242         if (uci_handle != NULL) {
243                 section = uci_lookup_section(uci_handle->_ctx,
244                                         uci_handle->_pkg,
245                                         DEVICE_CONFIG__SECTION_NAME);
246                 if (section != NULL) {
247                         option  = uci_lookup_option(uci_handle->_ctx, section, key.c_str());
248                         if (option != NULL) {
249                                 switch (option->type) {
250                                         case UCI_TYPE_STRING:
251                                                 //log_info("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string);
252                                                 ret_val = option->v.string;
253                                                 break;
254                                         default:
255                                                 log_error("key: %s Failed to read parameter value\n", key.c_str());
256                                                 break;
257                                 }
258                         }
259                         else {
260                                 log_error("key: %s Failed to read parameter value\n", key.c_str());
261                         }
262                 }
263         }
264         return ret_val;
265 }
266
267 void DeviceConfig::set_config_value(string key,
268                                 string value) {
269         string  cfg_dir;
270         string  cfg_fl;
271
272         cfg_dir = get_dir_name(device_id);
273         cfg_fl  = DEVICE_CONFIG__FILE_NAME;
274         set_config_value_to_section(uci_handle,
275                         DEVICE_CONFIG__SECTION_TYPE,
276                         DEVICE_CONFIG__SECTION_NAME,
277                         key.c_str(),
278                         value.c_str());
279 }
280
281 EnumSummaryCalculationType DeviceConfig::get_summary_calculation_type() {
282         EnumSummaryCalculationType      ret_val;
283
284         ret_val = MEAN;
285         if (device_type.empty() == false) {
286                 if (device_type.compare("Counter Device") == 0) {
287                         ret_val = DELTA;
288                 }
289         }
290         return ret_val;;
291 }
292
293 ConfigHandle *DeviceConfig::load_device_config(string device_id_param) {
294         int                     err_flg;
295         struct uci_context      *ctx;
296         struct uci_package      *pkg;
297         string                  cfg_fl;
298         string                  cfg_dir;
299         int                     b_count;
300         char                    *fname;
301         ConfigHandle            *ret_val;
302
303         ret_val = NULL;
304         cfg_dir = get_dir_name(device_id_param);
305         if (cfg_dir.empty() == false) {
306                 if (access(cfg_dir.c_str(), W_OK) != 0) {
307                         FileUtil::mkdirs(cfg_dir.c_str());
308                 }
309                 cfg_fl  = get_file_name(device_id_param);
310                 if (access(cfg_fl.c_str(), R_OK) == 0) {
311                         ctx     = uci_alloc_context();
312                         if (ctx != NULL) {
313                                 log_debug("confdir: %s, file: %s\n", cfg_dir.c_str(), cfg_fl.c_str());
314                                 uci_set_confdir(ctx, cfg_dir.c_str());
315                                 err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg);
316                                 if (err_flg == UCI_OK) {
317                                         //log_debug("Loaded device configuration: %s.\n", cfg_fl.c_str());
318                                         b_count = strlen(cfg_dir.c_str()) + strlen(cfg_fl.c_str()) + 10;
319                                         fname   = (char *)calloc(1, b_count);
320                                         if (fname != NULL) {
321                                                 strncpy(fname, cfg_dir.c_str(), b_count);
322                                                 strncat(fname, "/", 1);
323                                                 strncat(fname, cfg_fl.c_str(), strlen(cfg_fl.c_str()) + 1);
324
325                                                 ret_val = new ConfigHandle(ctx, pkg, cfg_fl.c_str(), fname);
326                                                 free(fname);
327                                         }
328                                 }
329                                 else {
330                                         log_debug("Failed to load device configuration: %s, err code: %d.\n", cfg_fl.c_str(), UCI_OK);
331                                         set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
332                                         uci_free_context(ctx);
333                                 }
334                         }
335                         else {
336                                 log_error("Failed to load device configuration, memory allocation error.\n");
337                                 set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
338                         }
339                 }
340                 else {
341                         log_error("Failed to load device configuration, file does not exist: %s.\n", cfg_fl.c_str());
342                 }
343         }
344         return ret_val;
345 }
346
347 DeviceConfig *DeviceConfig::get_device_config(string device_id_param) {
348         DeviceConfig    *ret_val;
349
350         ret_val = new DeviceConfig(device_id_param);
351         return ret_val;
352 }