/* * Factory.cc * * Created on: Dec 11, 2010 * 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 } Factory::~Factory() { // TODO Auto-generated destructor stub } /** * 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 = -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 = DEVICE_TYPE_TEMPERATURESENSOR; break; case 0x1d: ret_val = DEVICE_TYPE_COUNTER_DEVICE; break; default: ret_val = DEVICE_TYPE_UNKNOWN; log_error("Unknown w1 device type: %d\n", family_code_param); break; } return ret_val; } Device *Factory::create_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_device(family_code_param, type, device_id_param, direntry_param); } return ret_val; } Device *Factory::create_device(int device_w1_family_code_param, string device_type_param, string device_id_param, dirent *direntry_param) { Device *ret_val; DeviceConfig *config; bool succ; 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 succ = config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, device_type_param); if (succ == false) { device_type_param = ret_val->get_type(); config->set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, device_type_param, false); config->set_config_value(DEVICE_CONFIG_VALUE_KEY__ID, ret_val->get_id(), true); } delete(config); } } } return ret_val; } Device *Factory::create_device(string device_type_param, string device_id_param) { int family_code; Device *ret_val; 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_device(family_code, device_type_param, device_id_param, NULL); } } return ret_val; } Device *Factory::create_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_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_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... found = reader->get_device_type(type); if (found == true) { device = create_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; }