]> pilppa.org Git - libplp.git/blob - src/DeviceConfig.cc
38941f3cb508dc52d5abaee2c4c46e7d91c5f133
[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         err_flg = UCI_OK;
99         if ((cfg_handle != NULL) &&
100             (cfg_handle->_ctx != NULL) &&
101             (cfg_handle->_pkg != NULL) &&
102             (section_type != NULL) &&
103             (section_name != NULL) &&
104             (key != NULL) &&
105             (value != NULL)) {
106                 sct     = NULL;
107                 uci_foreach_element(&cfg_handle->_pkg->sections, elem) {
108                         tmp_sct = uci_to_section(elem);
109                         if (strcmp(tmp_sct->type, section_type) == 0) {
110                                 sct     = tmp_sct;
111                                 break;
112                         }
113                 }
114                 if (sct == NULL) {
115                         log_debug("Creating new section %s to configuration file: %s\n", section_name, cfg_handle->full_fname);
116                         //err_flg       = uci_add_named_section(ctx, pkg, section_type, section_name, &sct);
117                         //err_flg       = uci_add_section(ctx, pkg, section_name, &sct);
118                         err_flg = uci_create_named_section(cfg_handle,
119                                                 section_type,
120                                                 section_name,
121                                                 false);
122                         if (err_flg == UCI_OK) {
123                                 uci_foreach_element(&cfg_handle->_pkg->sections, elem) {
124                                         tmp_sct = uci_to_section(elem);
125                                         if (strcmp(tmp_sct->type, section_type) == 0) {
126                                                 sct     = tmp_sct;
127                                                 break;
128                                         }
129                                 }
130                         }
131                 }
132                 if (err_flg == UCI_OK) {
133                         memset(&ptr, 0, sizeof(ptr));
134                         ptr.package     = cfg_handle->_pkg->e.name;
135                         ptr.section     = sct->e.name;
136                         ptr.option      = key;
137                         err_flg         = uci_lookup_ptr(cfg_handle->_ctx, &ptr, NULL, false);
138                         if (err_flg == UCI_OK) {
139                                 ptr.value       = value;
140                                 err_flg         = uci_set(cfg_handle->_ctx, &ptr);
141                                 if (err_flg == UCI_OK) {
142                                         err_flg = uci_save(cfg_handle->_ctx, cfg_handle->_pkg);
143                                         if (err_flg == UCI_OK) {
144                                                 ret_val = true;
145                                                 log_debug("Set value to section %s in configuration file: %s\n", section_name, cfg_handle->full_fname);
146                                         }
147                                         else {
148                                                 log_error("Failed to set value to configuration file: %s\n. Could not save the file\n", cfg_handle->full_fname);
149                                         }
150                                 }
151                                 else {
152                                         log_error("Failed to set value to configuration file: %s\n. Could not set new value\n", cfg_handle->full_fname);
153                                 }
154                         }
155                         else {
156                                 log_error("Failed to set value to configuration file: %s\n. Could not look-up pointer for package %s section %s.\n",
157                                         cfg_handle->full_fname,
158                                         cfg_handle->_pkg->e.name,
159                                         sct->e.name);
160                         }
161                         uci_free_context(cfg_handle->_ctx);
162                 }
163                 else {
164                         log_error("Failed to set value to configuration file: %s. Could not create section %s.\n", cfg_handle->full_fname, section_name);
165                 }
166         }
167         else {
168                 log_error("Failed to set value to configuration file, invalid parameters\n");
169         }
170         return ret_val;
171 }
172
173 DeviceConfig::DeviceConfig(string device_id_param) {
174         device_id       = device_id_param;
175         uci_handle      = load_device_config(device_id_param);
176         if (uci_handle != NULL) {
177                 device_type     = get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
178         }
179         else {
180                 log_error("Could not read device configuration.\n");
181         }
182 }
183
184 DeviceConfig::~DeviceConfig() {
185         if (uci_handle != NULL) {
186                 delete(uci_handle);
187                 uci_handle      = NULL;
188         }
189 }
190
191 void DeviceConfig::set_base_dir_name(string store_param) {
192         int     pos;
193         int     b_count;
194
195         pos     = store_param.find_last_of("/");
196         b_count = store_param.length();
197         if (pos == (b_count - 1)) {
198                 store_base_dir  = store_param;
199         }
200         else {
201                 store_base_dir  = store_param + "/";
202         }
203 }
204
205 string DeviceConfig::get_base_dir_name() {
206         return store_base_dir;
207 }
208
209 string DeviceConfig::get_dir_name(string device_id_param) {
210         string  ret_val;
211         string  d_name;
212
213         d_name  = DeviceConfig::get_base_dir_name();
214         ret_val = FileUtil::concat_paths(d_name, device_id_param);
215         return ret_val;
216 }
217
218 string DeviceConfig::get_file_name(string device_id_param) {
219         string  ret_val;
220         string  fname;
221
222         fname   = DEVICE_CONFIG__FILE_NAME;
223         ret_val = get_dir_name(device_id_param);
224         ret_val = FileUtil::concat_paths(ret_val, fname);
225         return ret_val;
226 }
227
228 string DeviceConfig::get_config_value(string key) {
229         struct uci_section      *section;
230         struct uci_option       *option;
231         string                  ret_val;
232
233         if (uci_handle != NULL) {
234                 section = uci_lookup_section(uci_handle->_ctx,
235                                         uci_handle->_pkg,
236                                         DEVICE_CONFIG__SECTION_NAME);
237                 if (section != NULL) {
238                         option  = uci_lookup_option(uci_handle->_ctx, section, key.c_str());
239                         if (option != NULL) {
240                                 switch (option->type) {
241                                         case UCI_TYPE_STRING:
242                                                 //log_info("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string);
243                                                 ret_val = option->v.string;
244                                                 break;
245                                         default:
246                                                 log_error("key: %s Failed to read parameter value\n", key.c_str());
247                                                 break;
248                                 }
249                         }
250                         else {
251                                 log_error("key: %s Failed to read parameter value\n", key.c_str());
252                         }
253                 }
254         }
255         return ret_val;
256 }
257
258 void DeviceConfig::set_config_value(string key,
259                                 string value) {
260         string  cfg_dir;
261         string  cfg_fl;
262
263         cfg_dir = get_dir_name(device_id);
264         cfg_fl  = DEVICE_CONFIG__FILE_NAME;
265         set_config_value_to_section(uci_handle,
266                         DEVICE_CONFIG__SECTION_TYPE,
267                         DEVICE_CONFIG__SECTION_NAME,
268                         key.c_str(),
269                         value.c_str());
270 }
271
272 EnumSummaryCalculationType DeviceConfig::get_summary_calculation_type() {
273         EnumSummaryCalculationType      ret_val;
274
275         ret_val = MEAN;
276         if (device_type.empty() == false) {
277                 if (device_type.compare("Counter Device") == 0) {
278                         ret_val = DELTA;
279                 }
280         }
281         return ret_val;;
282 }
283
284 ConfigHandle *DeviceConfig::load_device_config(string device_id_param) {
285         int                     err_flg;
286         struct uci_context      *ctx;
287         struct uci_package      *pkg;
288         string                  cfg_fl;
289         string                  cfg_dir;
290         int                     b_count;
291         char                    *fname;
292         ConfigHandle            *ret_val;
293
294         ret_val = NULL;
295         cfg_dir = get_dir_name(device_id_param);
296         if (cfg_dir.empty() == false) {
297                 if (access(cfg_dir.c_str(), W_OK) != 0) {
298                         FileUtil::mkdirs(cfg_dir.c_str());
299                 }
300                 cfg_fl  = get_file_name(device_id_param);
301                 if (access(cfg_fl.c_str(), R_OK) == 0) {
302                         ctx     = uci_alloc_context();
303                         if (ctx != NULL) {
304                                 log_debug("confdir: %s, file: %s\n", cfg_dir.c_str(), cfg_fl.c_str());
305                                 uci_set_confdir(ctx, cfg_dir.c_str());
306                                 err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg);
307                                 if (err_flg == UCI_OK) {
308                                         //log_debug("Loaded device configuration: %s.\n", cfg_fl.c_str());
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 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 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_param) {
339         DeviceConfig    *ret_val;
340
341         ret_val = new DeviceConfig(device_id_param);
342         return ret_val;
343 }