X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=src%2FFactory.cc;h=9d704b59e32b620489bd1174df32458a68e1c375;hb=f280d6c6383f3642069fac8a490f827195619278;hp=e9637a4bd7101487cf4f2cf83d27dd4e04ddd415;hpb=83dba70b46600014932da34e8744ba70584077aa;p=lib1wire.git diff --git a/src/Factory.cc b/src/Factory.cc index e9637a4..9d704b5 100644 --- a/src/Factory.cc +++ b/src/Factory.cc @@ -5,14 +5,34 @@ * Author: lamikr */ +#include +#include +#include + +#include + #include +#include +#include +#include + #include "Factory.hh" #include "W1TemperatureSensor.hh" #include "W1CounterDevice.hh" using namespace w1; +using namespace plp; using namespace std; +template +bool string_to_number(NumberDataType& result, + const std::string& string_param, + std::ios_base& (*format)(std::ios_base&)) +{ + std::istringstream iss(string_param); + return !(iss >> format >> result).fail(); +} + Factory::Factory() { // TODO Auto-generated constructor stub } @@ -21,47 +41,255 @@ Factory::~Factory() { // TODO Auto-generated destructor stub } -W1Device *Factory::get_device(int family_code, - string device_id, - dirent *direntry_param) { - W1Device *ret_val; - DeviceConfig *config; +/** + * Returns family code for the device. + * + * @return w1 family code for the device type. If family code is not found, -1 is returned. + */ +int Factory::get_family_code_by_device_type(string device_type_param) { + int ret_val; - ret_val = NULL; - log_debug("family_code: %d\n", family_code); - switch(family_code) { + ret_val = -1; + if (device_type_param.compare(DEVICE_TYPE_TEMPERATURESENSOR) == 0) { + ret_val = 0x10; + } + else if (device_type_param.compare(DEVICE_TYPE_COUNTER_DEVICE) == 0) { + ret_val = 0x1d; + } + return ret_val; +} + +string Factory::get_device_type_by_family_code(int family_code_param) { + string ret_val; + + switch(family_code_param) { case 0x10: case 0x28: - ret_val = new W1TemperatureSensor(family_code, device_id, direntry_param); - log_debug("temperature sensor: %d\n", ret_val->get_family_code()); + ret_val = DEVICE_TYPE_TEMPERATURESENSOR; break; case 0x1d: - ret_val = new W1CounterDevice(family_code, device_id, direntry_param); - log_debug("counter device: %d\n", family_code); + ret_val = DEVICE_TYPE_COUNTER_DEVICE; break; default: - log_debug("device not created, unsupported device type: %d\n", family_code); + ret_val = DEVICE_TYPE_UNKNOWN; + log_error("Unknown w1 device type: %d\n", family_code_param); break; } - if (ret_val != NULL) { - // check that device config exist - // if not, create default... - config = get_device_config(device_id); - if (config != NULL) { - string type; - type = config->get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE); - if (type.empty() == true) { - type = ret_val->get_device_type(); - config->set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type); + return ret_val; +} + +Device *Factory::create_w1_device(int family_code_param, + string device_id_param, + dirent *direntry_param) { + Device *ret_val; + string type; + + ret_val = NULL; + type = get_device_type_by_family_code(family_code_param); + if (type.empty() == false) { + ret_val = create_w1_device(family_code_param, + type, + device_id_param, + direntry_param); + } + return ret_val; +} + +Device *Factory::create_w1_device(int device_w1_family_code_param, + string device_type_param, + string device_id_param, + dirent *direntry_param) { + Device *ret_val; + DeviceConfig *config; + + ret_val = NULL; + if (device_type_param.empty() == false) { + switch(device_w1_family_code_param) { + case 0x10: + case 0x28: + ret_val = new W1TemperatureSensor(device_id_param, device_type_param, direntry_param); + break; + case 0x1d: + ret_val = new W1CounterDevice(device_id_param, device_type_param, direntry_param); + break; + case 0x81: + // 0x81 is the 1-wire USB dongle... No need to create device for it. + break; + default: + log_debug("Unsupported 1-wire-family code: %#x, device not created: %s\n", device_w1_family_code_param, device_id_param.c_str()); + break; + } + if (ret_val != NULL) { + // check that device config exist + config = DeviceConfig::get_device_config(device_id_param); + if (config != NULL) { + // if not, create default device config + device_type_param = config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE); + if (device_type_param.empty() == true) { + device_type_param = ret_val->get_type(); + config->set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, device_type_param); + config->set_config_value(DEVICE_CONFIG_VALUE_KEY__ID, ret_val->get_id()); + } + delete(config); } } } return ret_val; } -DeviceConfig *Factory::get_device_config(string device_id) { - DeviceConfig *ret_val; +Device *Factory::create_w1_device(string device_type_param, + string device_id_param) { + int family_code; + Device *ret_val; - ret_val = new DeviceConfig(device_id); + ret_val = NULL; + if (device_type_param.empty() == false) { + family_code = get_family_code_by_device_type(device_type_param); + if (family_code != -1) { + ret_val = create_w1_device(family_code, device_type_param, device_id_param, NULL); + } + } + return ret_val; +} + +Device *Factory::create_w1_device(dirent *direntry_param, + int *err_code_param) { + string folder_name; + string tmp_str; + string device_id; + int pos; + int family_code; + bool suc_flg; + Device *ret_val; + + ret_val = NULL; + *err_code_param = 0; + folder_name = direntry_param->d_name; + pos = folder_name.find("-"); + if (pos > 0) { + tmp_str = folder_name.substr(0, pos); + // number in string is in hex format, convert to int + suc_flg = string_to_number(family_code, tmp_str, hex); + // if family code = 0x81 (1-wire usb dongle), do not try to create the device + if (family_code != 0x81) { + if (suc_flg == true) { + log_debug("1-wire device family code: %#x\n", family_code); + device_id = folder_name.substr(pos + 1, folder_name.length() - pos); + ret_val = Factory::create_w1_device(family_code, + device_id, + direntry_param); + if ((ret_val == NULL) && + (family_code != 0x81)) { + *err_code_param = 1; + } + } + } + } + return ret_val; +} + +list Factory::get_device_list() { + list ret_val; + DIR *dir; + int err_flg; + struct dirent *direntry; + Device *device; + bool is_subdir; + list rdr_list; + list::iterator dev_iter; + list::iterator rdr_iter; + DataReader *reader; + string id1; + string id2; + string type; + string dev_type; + bool found; + + // scan through the list of devices detected from the 1-wire network + dir = opendir(W1_SCAN_ROOTDIR); + if (dir != NULL) { + direntry = readdir(dir); + while(direntry != NULL) { + is_subdir = FileUtil::is_subdirectory(W1_SCAN_ROOTDIR, direntry); + if (is_subdir == true) { + err_flg = 0; + device = create_w1_device(direntry, &err_flg); + if (device != NULL) { + ret_val.push_back(device); + } + else { + if (err_flg != 0) { + log_info("Unsupported 1-wire device detected: %s\n", direntry->d_name); + } + } + } + direntry = readdir(dir); + } + err_flg = closedir(dir); + if (err_flg < 0) { + log_error("Failed to close 1-wire device directory: %s\n", W1_SCAN_ROOTDIR); + } + } + // scan through the list of devices which have saved data + rdr_list = get_data_reader_list(); + for (rdr_iter = rdr_list.begin(); rdr_iter != rdr_list.end(); rdr_iter++) { + reader = (DataReader *)*rdr_iter; + id1 = reader->get_device_id(); + found = false; + for (dev_iter = ret_val.begin(); dev_iter != ret_val.end(); dev_iter++) { + device = (Device *)*dev_iter; + id2 = device->get_id(); + if (id1.compare(id2) == 0) { + found = true; + break; + } + } + if (found == false) { + // reader device is not in the list of active devices. create and add it to list as in-active one... + type = reader->get_device_type(); + if (type.empty() == false) { + device = create_w1_device(type, id1); + if (device != NULL) { + ret_val.push_back(device); + } + } + } + } + while(rdr_list.empty() == false) { + reader = rdr_list.back(); + rdr_list.pop_back(); + delete(reader); + } + return ret_val; +} + +list Factory::get_data_reader_list() { + DIR *dir; + string dr_name; + int err_flg; + struct dirent *direntry; + DataReader *reader; + bool is_subdir; + list ret_val; + + dr_name = DeviceConfig::get_base_dir_name(); + dir = opendir(dr_name.c_str()); + if (dir != NULL) { + direntry = readdir(dir); + while(direntry != NULL) { + if (strcmp(direntry->d_name, "cache") != 0) { + is_subdir = FileUtil::is_subdirectory(dr_name.c_str(), direntry); + if (is_subdir == true) { + reader = new DataReader(direntry->d_name); + ret_val.push_back(reader); + } + } + direntry = readdir(dir); + } + err_flg = closedir(dir); + if (err_flg < 0) { + log_error("Failed to close 1-wire device data directory: %s\n", dr_name.c_str()); + } + } return ret_val; }