From 2faa8f6782a2e6294ed8849048a281d12d60da1c Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 4 Dec 2017 16:29:56 +0100 Subject: Initial support for multiple devices with C++ and test Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index d563b26..da5f61a 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -81,6 +81,11 @@ using nitrokey::misc::strcpyT; set_debug(true); } NitrokeyManager::~NitrokeyManager() { + 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 +103,31 @@ using nitrokey::misc::strcpyT; return true; } + std::vector NitrokeyManager::list_devices(){ + auto p = make_shared(); + return p->enumerate(); // make static + } + + bool NitrokeyManager::connect_with_path(std::string path) { + std::lock_guard lock(mex_dev_com_manager); + + if(connected_devices.find(path) != connected_devices.end() + && connected_devices[path] != nullptr) { + device = connected_devices[path]; + return true; + } + + + auto p = make_shared(); + p->set_path(path); + + if(!p->connect()) return false; + + connected_devices [path] = p; + device = p; + return true; + } + bool NitrokeyManager::connect() { std::lock_guard lock(mex_dev_com_manager); vector< shared_ptr > devices = { make_shared(), make_shared() }; -- cgit v1.2.1 From 388cf5fcb33f24bc04f79cd1fbea980214518d54 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 4 Dec 2017 19:21:09 +0100 Subject: List devices by unique SC:SD id Add C API and tests Add mutexes Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 7 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index da5f61a..4935076 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -81,6 +81,8 @@ using nitrokey::misc::strcpyT; set_debug(true); } NitrokeyManager::~NitrokeyManager() { + std::lock_guard lock(mex_dev_com_manager); + for (auto d : connected_devices){ if (d.second == nullptr) continue; d.second->disconnect(); @@ -104,27 +106,98 @@ using nitrokey::misc::strcpyT; } std::vector NitrokeyManager::list_devices(){ + std::lock_guard lock(mex_dev_com_manager); + auto p = make_shared(); return p->enumerate(); // make static } - bool NitrokeyManager::connect_with_path(std::string path) { + std::vector NitrokeyManager::list_devices_by_cpuID(){ std::lock_guard lock(mex_dev_com_manager); - if(connected_devices.find(path) != connected_devices.end() - && connected_devices[path] != nullptr) { - device = connected_devices[path]; - return true; + std::vector res; + auto d = make_shared(); + const auto v = d->enumerate(); + for (auto & p: v){ + d = make_shared(); + d->set_path(p); + try{ + if (d->connect()){ + device = d; + const auto status = get_status_storage(); + const auto sc_id = status.ActiveSmartCardID_u32; + const auto sd_id = status.ActiveSD_CardID_u32; + + auto id = std::to_string(sc_id) + ":" + std::to_string(sd_id); + connected_devices_byID[id] = d; + res.push_back(id); + } else{ + std::cout << "Could not connect to: " + p << std::endl; + } + } + catch (const DeviceCommunicationException &e){ + //ignore + std::cout << p << ": " << " Exception encountered" << std::endl; + } } + return res; + } +/** + * Connect to the device using unique smartcard:datacard id. + * Needs list_device_by_cpuID run first + * @param id + * @return + */ + bool NitrokeyManager::connect_with_ID(const std::string id) { + std::lock_guard lock(mex_dev_com_manager); + auto position = connected_devices_byID.find(id); + if (position == connected_devices_byID.end()) return false; + + auto d = connected_devices_byID[id]; + device = d; + + try{ + get_status(); + } + catch (const DeviceCommunicationException &){ + d->disconnect(); + connected_devices_byID[id] = nullptr; + connected_devices_byID.erase(position); + return false; + } + 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 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(); p->set_path(path); if(!p->connect()) return false; - connected_devices [path] = p; - device = p; + if(cache_connections){ + connected_devices [path] = p; + } + + device = p; //previous device will be disconnected automatically return true; } -- cgit v1.2.1 From 9300a50676c2dfabe7e63797c610b2d48d0065cf Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 8 Dec 2017 10:42:49 +0100 Subject: Do not disconnect device on getting status failure Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 4935076..e3e1730 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -336,7 +336,7 @@ using nitrokey::misc::strcpyT; return response.data(); } catch (DeviceSendingFailure &e){ - disconnect(); +// disconnect(); throw; } } -- cgit v1.2.1 From 8bede81660658a3675f4b7f68835ef3a623c696f Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 8 Dec 2017 10:59:42 +0100 Subject: Disconnect all devices before enumerating and discovering ids. Add log. Disconnection allows rediscovering devices. Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index e3e1730..b3c92a1 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -113,13 +113,25 @@ using nitrokey::misc::strcpyT; } std::vector NitrokeyManager::list_devices_by_cpuID(){ + //disconnect default device + disconnect(); + std::lock_guard 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 res; auto d = make_shared(); const auto v = d->enumerate(); + LOGD1("Discovering IDs"); for (auto & p: v){ d = make_shared(); + LOGD1( std::string("Found: ") + p ); d->set_path(p); try{ if (d->connect()){ @@ -131,13 +143,13 @@ using nitrokey::misc::strcpyT; auto id = std::to_string(sc_id) + ":" + std::to_string(sd_id); connected_devices_byID[id] = d; res.push_back(id); + LOGD1( std::string("Found: ") + p + " => " + id); } else{ - std::cout << "Could not connect to: " + p << std::endl; + LOGD1( std::string("Could not connect to: ") + p); } } catch (const DeviceCommunicationException &e){ - //ignore - std::cout << p << ": " << " Exception encountered" << std::endl; + LOGD1( std::string("Exception encountered: ") + p); } } return res; @@ -157,6 +169,7 @@ using nitrokey::misc::strcpyT; auto d = connected_devices_byID[id]; device = d; + //validate connection try{ get_status(); } -- cgit v1.2.1 From b9e72caeed17149cd20f146e895bf66523daeff5 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 8 Dec 2017 11:47:43 +0100 Subject: Return USB path as id, when device is running long operation Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index b3c92a1..162ad93 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -136,11 +136,18 @@ using nitrokey::misc::strcpyT; try{ if (d->connect()){ device = d; - const auto status = get_status_storage(); - const auto sc_id = status.ActiveSmartCardID_u32; - const auto sd_id = status.ActiveSD_CardID_u32; + std::string id; + try { + const auto status = get_status_storage(); + const auto sc_id = status.ActiveSmartCardID_u32; + const auto sd_id = status.ActiveSD_CardID_u32; + id = std::to_string(sc_id) + ":" + std::to_string(sd_id); + } + catch (const LongOperationInProgressException &e) { + LOGD1(std::string("Long operation in progress, setting ID to: ") + p); + id = p; + } - auto id = std::to_string(sc_id) + ":" + std::to_string(sd_id); connected_devices_byID[id] = d; res.push_back(id); LOGD1( std::string("Found: ") + p + " => " + id); @@ -173,6 +180,9 @@ using nitrokey::misc::strcpyT; try{ get_status(); } + catch (const LongOperationInProgressException &){ + //ignore + } catch (const DeviceCommunicationException &){ d->disconnect(); connected_devices_byID[id] = nullptr; -- cgit v1.2.1 From 38c3b4c58e6c6b86d6241183be1814bac2e037d2 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 16 Feb 2018 15:17:47 +0100 Subject: Log current device ID Allow logger to set global prefix Used to indicate current device Store USB path when used to connection as well Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 162ad93..f2518b1 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -171,10 +171,14 @@ using nitrokey::misc::strcpyT; std::lock_guard lock(mex_dev_com_manager); auto position = connected_devices_byID.find(id); - if (position == connected_devices_byID.end()) return false; + if (position == connected_devices_byID.end()) { + LOGD1(std::string("Could not find device ")+id); + return false; + } auto d = connected_devices_byID[id]; device = d; + current_device_id = id; //validate connection try{ @@ -185,10 +189,13 @@ using nitrokey::misc::strcpyT; } 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; } @@ -221,6 +228,9 @@ using nitrokey::misc::strcpyT; } device = p; //previous device will be disconnected automatically + current_device_id = path; + nitrokey::log::Log::setPrefix(path); + LOGD1("Device successfully changed"); return true; } @@ -1105,5 +1115,9 @@ using nitrokey::misc::strcpyT; return data.data().SD_Card_Size_u8; } + const string NitrokeyManager::get_current_device_id() const { + return current_device_id; + } + } -- cgit v1.2.1 From a1e081303dc7f7329e5452dad7e6cedf7efe3699 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 26 Feb 2018 15:37:13 +0100 Subject: Add to device's ID USB path. Convert ID to hex. Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index f2518b1..fa69ac6 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -113,6 +113,7 @@ using nitrokey::misc::strcpyT; } std::vector NitrokeyManager::list_devices_by_cpuID(){ + using misc::toHex; //disconnect default device disconnect(); @@ -139,9 +140,9 @@ using nitrokey::misc::strcpyT; std::string id; try { const auto status = get_status_storage(); - const auto sc_id = status.ActiveSmartCardID_u32; - const auto sd_id = status.ActiveSD_CardID_u32; - id = std::to_string(sc_id) + ":" + std::to_string(sd_id); + const auto sc_id = toHex(status.ActiveSmartCardID_u32); + const auto sd_id = toHex(status.ActiveSD_CardID_u32); + id = sc_id + ":" + sd_id + "_p_" + p; } catch (const LongOperationInProgressException &e) { LOGD1(std::string("Long operation in progress, setting ID to: ") + p); -- cgit v1.2.1 From f5da7b4cbd508faef38fcdfff659fab5c4649838 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 1 Mar 2018 11:29:57 +0100 Subject: Minor cleanup Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'NitrokeyManager.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index fa69ac6..e5f10df 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -142,7 +142,8 @@ using nitrokey::misc::strcpyT; 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 + "_p_" + p; + id += sc_id + ":" + sd_id; + id += "_p_" + p; } catch (const LongOperationInProgressException &e) { LOGD1(std::string("Long operation in progress, setting ID to: ") + p); @@ -162,18 +163,13 @@ using nitrokey::misc::strcpyT; } return res; } -/** - * Connect to the device using unique smartcard:datacard id. - * Needs list_device_by_cpuID run first - * @param id - * @return - */ + bool NitrokeyManager::connect_with_ID(const std::string id) { std::lock_guard 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); + LOGD1(std::string("Could not find device ")+id + ". Refresh devices list with list_devices_by_cpuID()."); return false; } -- cgit v1.2.1