]> pilppa.org Git - lib1wire.git/blob - src/Factory.cc
fixed api change breaks
[lib1wire.git] / src / Factory.cc
1 /*
2  * Factory.cc
3  *
4  *  Created on: Dec 11, 2010
5  *      Author: lamikr
6  */
7
8 #include <string>
9 #include <sstream>
10 #include <iostream>
11
12 #include <string.h>
13
14 #include <plp/log.h>
15 #include <plp/DeviceConfig.hh>
16 #include <plp/DeviceTypes.hh>
17 #include <plp/FileUtil.hh>
18
19 #include "Factory.hh"
20 #include "W1TemperatureSensor.hh"
21 #include "W1CounterDevice.hh"
22
23 using namespace w1;
24 using namespace plp;
25 using namespace std;
26
27 template <class NumberDataType>
28 bool string_to_number(NumberDataType& result,
29                  const std::string& string_param,
30                  std::ios_base& (*format)(std::ios_base&))
31 {
32         std::istringstream iss(string_param);
33         return !(iss >> format >> result).fail();
34 }
35
36 Factory::Factory() {
37         // TODO Auto-generated constructor stub
38 }
39
40 Factory::~Factory() {
41         // TODO Auto-generated destructor stub
42 }
43
44 int Factory::get_family_code_by_device_type(string device_type_param) {
45         int     ret_val = -1;
46
47         if (device_type_param.compare(DEVICE_TYPE_TEMPERATURESENSOR) == 0) {
48                 ret_val = 0x10;
49         }
50         else if (device_type_param.compare(DEVICE_TYPE_COUNTER_DEVICE) == 0) {
51                 ret_val = 0x1d;
52         }
53         return ret_val;
54 }
55
56 string Factory::get_device_type_by_family_code(int family_code_param) {
57         string  ret_val;
58
59         switch(family_code_param) {
60                 case    0x10:
61                 case    0x28:
62                         ret_val = DEVICE_TYPE_TEMPERATURESENSOR;
63                         break;
64                 case    0x1d:
65                         ret_val = DEVICE_TYPE_COUNTER_DEVICE;
66                         break;
67                 default:
68                         ret_val = DEVICE_TYPE_UNKNOWN;
69                         log_error("Unknown w1 device type: %d\n", family_code_param);
70                         break;
71         }
72         return ret_val;
73 }
74
75 Device *Factory::create_w1_device(int family_code_param,
76                         string device_id_param,
77                         dirent *direntry_param) {
78         Device          *ret_val;
79         DeviceConfig    *config;
80         string          type;
81
82         ret_val = NULL;
83         type    = get_device_type_by_family_code(family_code_param);
84         switch(family_code_param) {
85                 case    0x10:
86                 case    0x28:
87                         ret_val = new W1TemperatureSensor(device_id_param, type, direntry_param);
88                         break;
89                 case    0x1d:
90                         ret_val = new W1CounterDevice(device_id_param, type, direntry_param);
91                         break;
92                 case    0x81:
93                         // 0x81 is the 1-wire USB dongle... No need to create device for it.
94                         break;
95                 default:
96                         log_debug("Unsupported 1-wire-family code: %#x, device not created: %s\n", family_code_param, device_id_param.c_str());
97                         break;
98         }
99         if (ret_val != NULL) {
100                 // check that device config exist
101                 config  = DeviceConfig::get_device_config(device_id_param);
102                 if (config != NULL) {
103                         // if not, create default device config
104                         type    = config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
105                         if (type.empty() == true) {
106                                 type    = ret_val->get_type();
107                                 config->set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type);
108                                 config->set_config_value(DEVICE_CONFIG_VALUE_KEY__ID, ret_val->get_id());
109                         }
110                         delete(config);
111                 }
112         }
113         return ret_val;
114 }
115
116 Device *Factory::create_w1_device(string device_type_param,
117                         string device_id_param) {
118         int     family_code;
119         Device  *ret_val;
120
121         family_code     = get_family_code_by_device_type(device_type_param);
122         ret_val         = create_w1_device(family_code, device_id_param, NULL);
123         return ret_val;
124 }
125
126 Device *Factory::create_w1_device(dirent *direntry_param, int *err_code_param) {
127         string  folder_name;
128         string  tmp_str;
129         string  device_name;
130         int     pos;
131         int     family_code;
132         bool    suc_flg;
133         Device  *ret_val;
134
135         ret_val         = NULL;
136         *err_code_param = 0;
137         folder_name     = direntry_param->d_name;
138         pos             = folder_name.find("-");
139         if (pos > 0) {
140                 tmp_str = folder_name.substr(0, pos);
141                 // number in string is in hex format, convert to int
142                 suc_flg = string_to_number<int>(family_code, tmp_str, hex);
143                 // if family code = 0x81 (1-wire usb dongle), do not try to create the device
144                 if (family_code != 0x81) {
145                         if (suc_flg == true) {
146                                 log_debug("1-wire device family code: %#x\n", family_code);
147                                 device_name     = folder_name.substr(pos + 1, folder_name.length() - pos);
148                                 ret_val         = Factory::create_w1_device(family_code,
149                                                                 device_name,
150                                                                 direntry_param);
151                                 if ((ret_val == NULL) &&
152                                     (family_code != 0x81)) {
153                                         *err_code_param = 1;
154                                 }
155                         }
156                 }
157         }
158         return ret_val;
159 }
160
161 list<Device *> Factory::get_device_list() {
162         list<Device *>                  ret_val;
163         DIR                             *dir;
164         int                             err_flg;
165         struct dirent                   *direntry;
166         Device                          *device;
167         bool                            is_subdir;
168         list<DataReader *>              rdr_list;
169         list<Device *>::iterator        dev_iter;
170         list<DataReader *>::iterator    rdr_iter;
171         DataReader                      *reader;
172         string                          id1;
173         string                          id2;
174         string                          type;
175         string                          dev_type;
176         bool                            found;
177
178         // scan through the list of devices detected from the 1-wire network
179         dir     = opendir(W1_SCAN_ROOTDIR);
180         if (dir != NULL) {
181                 direntry        = readdir(dir);
182                 while(direntry != NULL) {
183                         is_subdir       = FileUtil::is_subdirectory(W1_SCAN_ROOTDIR, direntry);
184                         if (is_subdir == true) {
185                                 err_flg = 0;
186                                 device  = create_w1_device(direntry, &err_flg);
187                                 if (device != NULL) {
188                                         ret_val.push_back(device);
189                                 }
190                                 else {
191                                         if (err_flg != 0) {
192                                                 log_info("Unsupported 1-wire device detected: %s\n", direntry->d_name);
193                                         }
194                                 }
195                         }
196                         direntry        = readdir(dir);
197                 }
198                 err_flg = closedir(dir);
199                 if (err_flg < 0) {
200                         log_error("Failed to close 1-wire device directory: %s\n", W1_SCAN_ROOTDIR);
201                 }
202         }
203         // scan through the list of devices which have saved data
204         rdr_list        = get_data_reader_list();
205         for (rdr_iter = rdr_list.begin(); rdr_iter != rdr_list.end(); rdr_iter++) {
206                 reader  = (DataReader *)*rdr_iter;
207                 id1     = reader->get_device_id();
208                 found   = false;
209                 for (dev_iter = ret_val.begin(); dev_iter != ret_val.end(); dev_iter++) {
210                         device  = (Device *)*dev_iter;
211                         id2     = device->get_id();
212                         if (id1.compare(id2) == 0) {
213                                 found   = true;
214                                 break;
215                         }
216                 }
217                 if (found == false) {
218                         // reader device is not in the list of active devices. create and add it to list as in-active one...
219                         type    = reader->get_device_type();
220                         device  = create_w1_device(type, id1);
221                         ret_val.push_back(device);
222                 }
223         }
224         while(rdr_list.empty() == false) {
225                 reader  = rdr_list.back();
226                 rdr_list.pop_back();
227                 delete(reader);
228         }
229         return ret_val;
230 }
231
232 list<DataReader *> Factory::get_data_reader_list() {
233         DIR                     *dir;
234         string                  dr_name;
235         int                     err_flg;
236         struct dirent           *direntry;
237         DataReader              *reader;
238         bool                    is_subdir;
239         list<DataReader *>      ret_val;
240
241         dr_name = DeviceConfig::get_base_dir_name();
242         dir     = opendir(dr_name.c_str());
243         if (dir != NULL) {
244                 direntry        = readdir(dir);
245                 while(direntry != NULL) {
246                         if (strcmp(direntry->d_name, "cache") != 0) {
247                                 is_subdir       = FileUtil::is_subdirectory(dr_name.c_str(), direntry);
248                                 if (is_subdir == true) {
249                                         reader  = new DataReader(direntry->d_name);
250                                         ret_val.push_back(reader);
251                                 }
252                         }
253                         direntry        = readdir(dir);
254                 }
255                 err_flg = closedir(dir);
256                 if (err_flg < 0) {
257                         log_error("Failed to close 1-wire device data directory: %s\n", dr_name.c_str());
258                 }
259         }
260         return ret_val;
261 }