diff options
author | Szczepan Zalega <szczepan@nitrokey.com> | 2018-03-02 11:41:13 +0100 |
---|---|---|
committer | Szczepan Zalega <szczepan@nitrokey.com> | 2018-03-02 11:41:13 +0100 |
commit | 379daf936caa7fc8d7311a5dda101edb40d35ca5 (patch) | |
tree | 2d186dec6976b12a9f7b37e589c02703275a30ef /NitrokeyManager.cc | |
parent | d5486ba77235a874245fbee07a75cea89fa59ea2 (diff) | |
parent | c3d615b659b608f3a1d624f6fc78c303efbe1f8e (diff) | |
download | libnitrokey-379daf936caa7fc8d7311a5dda101edb40d35ca5.tar.gz libnitrokey-379daf936caa7fc8d7311a5dda101edb40d35ca5.tar.bz2 |
Merge branch 'wip-multiple_devices'
Allow to use multiple devices, iteratively.
Storage only.
Diffstat (limited to 'NitrokeyManager.cc')
-rw-r--r-- | NitrokeyManager.cc | 139 |
1 files changed, 138 insertions, 1 deletions
diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index d563b26..e5f10df 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -81,6 +81,13 @@ using nitrokey::misc::strcpyT; set_debug(true); } NitrokeyManager::~NitrokeyManager() { + std::lock_guard<std::mutex> lock(mex_dev_com_manager); + + for (auto d : connected_devices){ + if (d.second == nullptr) continue; + d.second->disconnect(); + connected_devices[d.first] = nullptr; + } } bool NitrokeyManager::set_current_device_speed(int retry_delay, int send_receive_delay){ @@ -98,6 +105,132 @@ using nitrokey::misc::strcpyT; return true; } + std::vector<std::string> NitrokeyManager::list_devices(){ + std::lock_guard<std::mutex> lock(mex_dev_com_manager); + + auto p = make_shared<Stick20>(); + return p->enumerate(); // make static + } + + std::vector<std::string> NitrokeyManager::list_devices_by_cpuID(){ + using misc::toHex; + //disconnect default device + disconnect(); + + std::lock_guard<std::mutex> lock(mex_dev_com_manager); + LOGD1("Disconnecting registered devices"); + for (auto & kv : connected_devices_byID){ + if (kv.second != nullptr) + kv.second->disconnect(); + } + connected_devices_byID.clear(); + + LOGD1("Enumerating devices"); + std::vector<std::string> res; + auto d = make_shared<Stick20>(); + const auto v = d->enumerate(); + LOGD1("Discovering IDs"); + for (auto & p: v){ + d = make_shared<Stick20>(); + LOGD1( std::string("Found: ") + p ); + d->set_path(p); + try{ + if (d->connect()){ + device = d; + std::string id; + try { + const auto status = get_status_storage(); + const auto sc_id = toHex(status.ActiveSmartCardID_u32); + const auto sd_id = toHex(status.ActiveSD_CardID_u32); + id += sc_id + ":" + sd_id; + id += "_p_" + p; + } + catch (const LongOperationInProgressException &e) { + LOGD1(std::string("Long operation in progress, setting ID to: ") + p); + id = p; + } + + connected_devices_byID[id] = d; + res.push_back(id); + LOGD1( std::string("Found: ") + p + " => " + id); + } else{ + LOGD1( std::string("Could not connect to: ") + p); + } + } + catch (const DeviceCommunicationException &e){ + LOGD1( std::string("Exception encountered: ") + p); + } + } + return res; + } + + bool NitrokeyManager::connect_with_ID(const std::string id) { + std::lock_guard<std::mutex> lock(mex_dev_com_manager); + + auto position = connected_devices_byID.find(id); + if (position == connected_devices_byID.end()) { + LOGD1(std::string("Could not find device ")+id + ". Refresh devices list with list_devices_by_cpuID()."); + return false; + } + + auto d = connected_devices_byID[id]; + device = d; + current_device_id = id; + + //validate connection + try{ + get_status(); + } + catch (const LongOperationInProgressException &){ + //ignore + } + catch (const DeviceCommunicationException &){ + d->disconnect(); + current_device_id = ""; + connected_devices_byID[id] = nullptr; + connected_devices_byID.erase(position); + return false; + } + nitrokey::log::Log::setPrefix(id); + LOGD1("Device successfully changed"); + return true; + } + + /** + * Connects device to path. + * Assumes devices are not being disconnected and caches connections (param cache_connections). + * @param path os-dependent device path + * @return false, when could not connect, true otherwise + */ + bool NitrokeyManager::connect_with_path(std::string path) { + const bool cache_connections = false; + + std::lock_guard<std::mutex> lock(mex_dev_com_manager); + + if (cache_connections){ + if(connected_devices.find(path) != connected_devices.end() + && connected_devices[path] != nullptr) { + device = connected_devices[path]; + return true; + } + } + + auto p = make_shared<Stick20>(); + p->set_path(path); + + if(!p->connect()) return false; + + if(cache_connections){ + connected_devices [path] = p; + } + + device = p; //previous device will be disconnected automatically + current_device_id = path; + nitrokey::log::Log::setPrefix(path); + LOGD1("Device successfully changed"); + return true; + } + bool NitrokeyManager::connect() { std::lock_guard<std::mutex> lock(mex_dev_com_manager); vector< shared_ptr<Device> > devices = { make_shared<Stick10>(), make_shared<Stick20>() }; @@ -233,7 +366,7 @@ using nitrokey::misc::strcpyT; return response.data(); } catch (DeviceSendingFailure &e){ - disconnect(); +// disconnect(); throw; } } @@ -979,5 +1112,9 @@ using nitrokey::misc::strcpyT; return data.data().SD_Card_Size_u8; } + const string NitrokeyManager::get_current_device_id() const { + return current_device_id; + } + } |