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