From 4a7ce051bd4004fb62f1c7022d92efa2ce42b6ab Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:03:34 +0100 Subject: Change Device::enumerate return type to use DeviceInfo The return type of Device::enumerate is changed from std::vector to std::vector to expose the additional information contained in the DeviceInfo struct. --- device.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'device.cc') diff --git a/device.cc b/device.cc index 80e4b38..506a68c 100644 --- a/device.cc +++ b/device.cc @@ -171,14 +171,17 @@ int Device::recv(void *packet) { return status; } -std::vector Device::enumerate(){ +std::vector Device::enumerate(){ //TODO make static auto pInfo = hid_enumerate(m_vid, m_pid); auto pInfo_ = pInfo; - std::vector res; + std::vector res; while (pInfo != nullptr){ - std::string a (pInfo->path); - res.push_back(a); + std::string path(pInfo->path); + std::wstring serialNumber(pInfo->serial_number); + auto deviceModel = this->get_device_model(); + DeviceInfo info = { deviceModel, path, serialNumber }; + res.push_back(info); pInfo = pInfo->next; } -- cgit v1.2.3 From 6772dcf38e275b2ab9f962a87e86f89541c13a92 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:03:53 +0100 Subject: Extract vendor and product IDs into constants --- device.cc | 8 ++++++-- libnitrokey/device.h | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'device.cc') diff --git a/device.cc b/device.cc index 506a68c..74de0b3 100644 --- a/device.cc +++ b/device.cc @@ -38,6 +38,10 @@ using namespace nitrokey::device; using namespace nitrokey::log; using namespace std::chrono; +const uint16_t nitrokey::device::NITROKEY_VID = 0x20a0; +const uint16_t nitrokey::device::NITROKEY_PRO_PID = 0x4108; +const uint16_t nitrokey::device::NITROKEY_STORAGE_PID = 0x4109; + std::atomic_int Device::instances_count{0}; std::chrono::milliseconds Device::default_delay {0} ; @@ -246,14 +250,14 @@ void Device::set_retry_delay(const std::chrono::milliseconds delay){ } Stick10::Stick10(): - Device(0x20a0, 0x4108, DeviceModel::PRO, 100ms, 5, 100ms) + Device(NITROKEY_VID, NITROKEY_PRO_PID, DeviceModel::PRO, 100ms, 5, 100ms) { setDefaultDelay(); } Stick20::Stick20(): - Device(0x20a0, 0x4109, DeviceModel::STORAGE, 40ms, 55, 40ms) + Device(NITROKEY_VID, NITROKEY_STORAGE_PID, DeviceModel::STORAGE, 40ms, 55, 40ms) { setDefaultDelay(); } diff --git a/libnitrokey/device.h b/libnitrokey/device.h index 1a84402..477640f 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -50,6 +50,19 @@ enum class DeviceModel{ STORAGE }; +/** + * The USB vendor ID for Nitrokey devices. + */ +extern const uint16_t NITROKEY_VID; +/** + * The USB product ID for the Nitrokey Pro. + */ +extern const uint16_t NITROKEY_PRO_PID; +/** + * The USB product ID for the Nitrokey Storage. + */ +extern const uint16_t NITROKEY_STORAGE_PID; + /** * Information about a connected device. * -- cgit v1.2.3 From 6c52c50d59eafa5acc7ae650695f199b7a014841 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:04:12 +0100 Subject: Add product_id_to_model function --- device.cc | 12 ++++++++++++ libnitrokey/device.h | 7 +++++++ 2 files changed, 19 insertions(+) (limited to 'device.cc') diff --git a/device.cc b/device.cc index 74de0b3..d3f6e09 100644 --- a/device.cc +++ b/device.cc @@ -36,12 +36,24 @@ std::mutex mex_dev_com; using namespace nitrokey::device; using namespace nitrokey::log; +using namespace nitrokey::misc; using namespace std::chrono; const uint16_t nitrokey::device::NITROKEY_VID = 0x20a0; const uint16_t nitrokey::device::NITROKEY_PRO_PID = 0x4108; const uint16_t nitrokey::device::NITROKEY_STORAGE_PID = 0x4109; +Option nitrokey::device::product_id_to_model(uint16_t product_id) { + switch (product_id) { + case NITROKEY_PRO_PID: + return DeviceModel::PRO; + case NITROKEY_STORAGE_PID: + return DeviceModel::STORAGE; + default: + return {}; + } +} + std::atomic_int Device::instances_count{0}; std::chrono::milliseconds Device::default_delay {0} ; diff --git a/libnitrokey/device.h b/libnitrokey/device.h index 477640f..8fbb385 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -26,6 +26,7 @@ #include #include #include +#include "misc.h" #define HID_REPORT_SIZE 65 @@ -63,6 +64,12 @@ extern const uint16_t NITROKEY_PRO_PID; */ extern const uint16_t NITROKEY_STORAGE_PID; +/** + * Convert the given USB product ID to a Nitrokey model. If there is no model + * with that ID, return an absent value. + */ +misc::Option product_id_to_model(uint16_t product_id); + /** * Information about a connected device. * -- cgit v1.2.3 From 1751759356bd64cc78f8f71543c3edd5cdce8376 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:04:22 +0100 Subject: Make Device::enumerate static Device::enumerate does not need any instance data, therefore it is made static. Note that this not only changes the public API by making the method static. We also return all connected Nitrokey devices instead of only Storage devices. The NitrokeyManager method list_devices_by_cpuID is changed to check the device type so that they still only return Storage devices. The list_device method now returns both Storage and Pro devices. --- NitrokeyManager.cc | 10 +++++----- device.cc | 15 ++++++++------- libnitrokey/device.h | 5 ++--- unittest/test_multiple_devices.cc | 8 ++++++-- 4 files changed, 21 insertions(+), 17 deletions(-) (limited to 'device.cc') diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 8ca4698..3b57ba6 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -108,8 +108,7 @@ using nitrokey::misc::strcpyT; std::vector NitrokeyManager::list_devices(){ std::lock_guard lock(mex_dev_com_manager); - auto p = make_shared(); - return p->enumerate(); + return Device::enumerate(); } std::vector NitrokeyManager::list_devices_by_cpuID(){ @@ -127,12 +126,13 @@ using nitrokey::misc::strcpyT; LOGD1("Enumerating devices"); std::vector res; - auto d = make_shared(); - const auto v = d->enumerate(); + const auto v = Device::enumerate(); LOGD1("Discovering IDs"); for (auto & i: v){ + if (i.m_deviceModel != DeviceModel::STORAGE) + continue; auto p = i.m_path; - d = make_shared(); + auto d = make_shared(); LOGD1( std::string("Found: ") + p ); d->set_path(p); try{ diff --git a/device.cc b/device.cc index d3f6e09..58dc0e5 100644 --- a/device.cc +++ b/device.cc @@ -188,16 +188,17 @@ int Device::recv(void *packet) { } std::vector Device::enumerate(){ - //TODO make static - auto pInfo = hid_enumerate(m_vid, m_pid); + auto pInfo = hid_enumerate(NITROKEY_VID, 0); auto pInfo_ = pInfo; std::vector res; while (pInfo != nullptr){ - std::string path(pInfo->path); - std::wstring serialNumber(pInfo->serial_number); - auto deviceModel = this->get_device_model(); - DeviceInfo info = { deviceModel, path, serialNumber }; - res.push_back(info); + auto deviceModel = product_id_to_model(pInfo->product_id); + if (deviceModel.has_value()) { + std::string path(pInfo->path); + std::wstring serialNumber(pInfo->serial_number); + DeviceInfo info = { deviceModel.value(), path, serialNumber }; + res.push_back(info); + } pInfo = pInfo->next; } diff --git a/libnitrokey/device.h b/libnitrokey/device.h index 8fbb385..418d335 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -148,12 +148,11 @@ public: */ bool could_be_enumerated(); /** - * Returns a vector with all connected Nitrokey devices of the same device - * type as this device. + * Returns a vector with all connected Nitrokey devices. * * @return information about all connected devices */ - std::vector enumerate(); + static std::vector enumerate(); void show_stats(); diff --git a/unittest/test_multiple_devices.cc b/unittest/test_multiple_devices.cc index f9e9ad2..183af4f 100644 --- a/unittest/test_multiple_devices.cc +++ b/unittest/test_multiple_devices.cc @@ -35,9 +35,11 @@ using namespace nitrokey; TEST_CASE("List devices", "[BASIC]") { shared_ptr d = make_shared(); - auto v = d->enumerate(); + auto v = Device::enumerate(); REQUIRE(v.size() > 0); for (auto i : v){ + if (i.m_deviceModel != DeviceModel::STORAGE) + continue; auto a = i.m_path; std::cout << a; d->set_path(a); @@ -54,11 +56,13 @@ TEST_CASE("List devices", "[BASIC]") { TEST_CASE("Regenerate AES keys", "[BASIC]") { shared_ptr d = make_shared(); - auto v = d->enumerate(); + auto v = Device::enumerate(); REQUIRE(v.size() > 0); std::vector> devices; for (auto i : v){ + if (i.m_deviceModel != DeviceModel::STORAGE) + continue; auto a = i.m_path; std::cout << a << endl; d = make_shared(); -- cgit v1.2.3 From 14635f49813df1699569d3b13456ea33955de54b Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:04:31 +0100 Subject: Add Device::create static method The method makes it easier to create a std::shared_ptr from a model enum instance. --- device.cc | 11 +++++++++++ libnitrokey/device.h | 6 ++++++ 2 files changed, 17 insertions(+) (limited to 'device.cc') diff --git a/device.cc b/device.cc index 58dc0e5..aabcbfc 100644 --- a/device.cc +++ b/device.cc @@ -209,6 +209,17 @@ std::vector Device::enumerate(){ return res; } +std::shared_ptr Device::create(DeviceModel model) { + switch (model) { + case DeviceModel::PRO: + return std::make_shared(); + case DeviceModel::STORAGE: + return std::make_shared(); + default: + return {}; + } +} + bool Device::could_be_enumerated() { LOG(__FUNCTION__, Loglevel::DEBUG_L2); std::lock_guard lock(mex_dev_com); diff --git a/libnitrokey/device.h b/libnitrokey/device.h index 418d335..eab3888 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -24,6 +24,7 @@ #include #include "hidapi/hidapi.h" #include +#include #include #include #include "misc.h" @@ -154,6 +155,11 @@ public: */ static std::vector enumerate(); + /** + * Create a Device of the given model. + */ + static std::shared_ptr create(DeviceModel model); + void show_stats(); // ErrorCounters get_stats(){ return m_counters; } -- cgit v1.2.3 From 66763febd7990f35d34345175257b2ad9401e829 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:04:42 +0100 Subject: Implement operator<< for DeviceModel --- device.cc | 15 +++++++++++++++ libnitrokey/device.h | 3 +++ 2 files changed, 18 insertions(+) (limited to 'device.cc') diff --git a/device.cc b/device.cc index aabcbfc..35aefca 100644 --- a/device.cc +++ b/device.cc @@ -57,6 +57,21 @@ Option nitrokey::device::product_id_to_model(uint16_t product_id) { std::atomic_int Device::instances_count{0}; std::chrono::milliseconds Device::default_delay {0} ; +std::ostream& nitrokey::device::operator<<(std::ostream& stream, DeviceModel model) { + switch (model) { + case DeviceModel::PRO: + stream << "Pro"; + break; + case DeviceModel::STORAGE: + stream << "Storage"; + break; + default: + stream << "Unknown"; + break; + } + return stream; +} + Device::Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, const milliseconds send_receive_delay, const int retry_receiving_count, const milliseconds retry_timeout) diff --git a/libnitrokey/device.h b/libnitrokey/device.h index eab3888..4b1c239 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "misc.h" @@ -52,6 +53,8 @@ enum class DeviceModel{ STORAGE }; +std::ostream& operator<<(std::ostream& stream, DeviceModel model); + /** * The USB vendor ID for Nitrokey devices. */ -- cgit v1.2.3 From a80378e0c770a503ddaafc0c7aacb78cac667b8f Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sun, 13 Jan 2019 12:05:28 +0100 Subject: Change std::wstring to std::string in DeviceInfo For easier handling, we should use a std::string instead of std::wstring for the serial number in DeviceInfo. For the conversion, I assume that the serial number is valid UTF-8. As it should be alphanumeric and ASCII only, this should be true. --- device.cc | 6 +++++- libnitrokey/device.h | 2 +- unittest/test_multiple_devices.cc | 10 ++++------ 3 files changed, 10 insertions(+), 8 deletions(-) (limited to 'device.cc') diff --git a/device.cc b/device.cc index 35aefca..bc42965 100644 --- a/device.cc +++ b/device.cc @@ -20,7 +20,9 @@ */ #include +#include #include +#include #include #include #include @@ -210,7 +212,9 @@ std::vector Device::enumerate(){ auto deviceModel = product_id_to_model(pInfo->product_id); if (deviceModel.has_value()) { std::string path(pInfo->path); - std::wstring serialNumber(pInfo->serial_number); + std::wstring serialNumberW(pInfo->serial_number); + std::wstring_convert> converter; + std::string serialNumber = converter.to_bytes(serialNumberW); DeviceInfo info = { deviceModel.value(), path, serialNumber }; res.push_back(info); } diff --git a/libnitrokey/device.h b/libnitrokey/device.h index 4b1c239..d50080d 100644 --- a/libnitrokey/device.h +++ b/libnitrokey/device.h @@ -92,7 +92,7 @@ struct DeviceInfo { /** * The serial number of the device. */ - std::wstring m_serialNumber; + std::string m_serialNumber; }; #include diff --git a/unittest/test_multiple_devices.cc b/unittest/test_multiple_devices.cc index d644cfd..bc1b60b 100644 --- a/unittest/test_multiple_devices.cc +++ b/unittest/test_multiple_devices.cc @@ -42,9 +42,8 @@ TEST_CASE("List devices", "[BASIC]") { std::cout << "Could not create device with model " << i.m_deviceModel << "\n"; continue; } - std::cout << i.m_deviceModel << " " << i.m_path << " "; - std::wcout << i.m_serialNumber; - std::cout << " |"; + std::cout << i.m_deviceModel << " " << i.m_path << " " + << i.m_serialNumber << " |"; d->set_path(i.m_path); d->connect(); auto res = GetStatus::CommandTransaction::run(d); @@ -116,9 +115,8 @@ TEST_CASE("Use API", "[BASIC]") { REQUIRE(v.size() > 0); for (auto i : v) { - std::cout << "Connect with: " << i.m_deviceModel << " " << i.m_path << " "; - std::wcout << i.m_serialNumber; - std::cout << " | " << std::boolalpha << nm->connect_with_path(i.m_path) << " |"; + std::cout << "Connect with: " << i.m_deviceModel << " " << i.m_path << " " + << i.m_serialNumber << " | " << std::boolalpha << nm->connect_with_path(i.m_path) << " |"; try { auto status = nm->get_status(); std::cout << " " << status.card_serial_u32 << " " -- cgit v1.2.3