summaryrefslogtreecommitdiff
path: root/patches/wownero/0007-add-dummy-device-for-ledger.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/wownero/0007-add-dummy-device-for-ledger.patch')
-rw-r--r--patches/wownero/0007-add-dummy-device-for-ledger.patch619
1 files changed, 619 insertions, 0 deletions
diff --git a/patches/wownero/0007-add-dummy-device-for-ledger.patch b/patches/wownero/0007-add-dummy-device-for-ledger.patch
new file mode 100644
index 0000000..7fd3100
--- /dev/null
+++ b/patches/wownero/0007-add-dummy-device-for-ledger.patch
@@ -0,0 +1,619 @@
+From be6bbe3958304e17566b2bc601255b0d6cec119f Mon Sep 17 00:00:00 2001
+From: Czarek Nakamoto <cyjan@mrcyjanek.net>
+Date: Wed, 26 Jun 2024 15:04:38 +0200
+Subject: [PATCH 07/16] add dummy device for ledger
+
+---
+ CMakeLists.txt | 19 +++--
+ src/device/CMakeLists.txt | 6 +-
+ src/device/device.cpp | 10 ++-
+ src/device/device.hpp | 12 +--
+ src/device/device_io_dummy.cpp | 133 ++++++++++++++++++++++++++++++
+ src/device/device_io_dummy.hpp | 74 +++++++++++++++++
+ src/device/device_ledger.cpp | 6 +-
+ src/device/device_ledger.hpp | 7 +-
+ src/wallet/api/wallet.cpp | 94 +++++++++++++++++++++
+ src/wallet/api/wallet.h | 18 ++++
+ src/wallet/api/wallet2_api.h | 12 +++
+ src/wallet/api/wallet_manager.cpp | 12 ++-
+ 12 files changed, 372 insertions(+), 31 deletions(-)
+ create mode 100644 src/device/device_io_dummy.cpp
+ create mode 100644 src/device/device_io_dummy.hpp
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index c439e5300..86af78f10 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -693,16 +693,21 @@ include_directories(${LMDB_INCLUDE})
+ include_directories(${LIBUNWIND_INCLUDE})
+ link_directories(${LIBUNWIND_LIBRARY_DIRS})
+
+-# Final setup for hid
+-if (HIDAPI_FOUND)
+- message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
+- add_definitions(-DHAVE_HIDAPI)
+- include_directories(${HIDAPI_INCLUDE_DIR})
+- link_directories(${LIBHIDAPI_LIBRARY_DIRS})
++if (HIDAPI_DUMMY)
++ add_definitions(-DHIDAPI_DUMMY)
+ else()
+- message(STATUS "Could not find HIDAPI")
++ # Final setup for hid
++ if (HIDAPI_FOUND)
++ message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}")
++ add_definitions(-DHAVE_HIDAPI)
++ include_directories(${HIDAPI_INCLUDE_DIR})
++ link_directories(${LIBHIDAPI_LIBRARY_DIRS})
++ else()
++ message(STATUS "Could not find HIDAPI")
++ endif()
+ endif()
+
++
+ # Trezor support check
+ include(CheckTrezor)
+
+diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
+index e4f1159b5..14d398f87 100644
+--- a/src/device/CMakeLists.txt
++++ b/src/device/CMakeLists.txt
+@@ -29,10 +29,11 @@
+ set(device_sources
+ device.cpp
+ device_default.cpp
++ device_io_dummy.cpp
+ log.cpp
+ )
+
+-if(HIDAPI_FOUND)
++if(HIDAPI_FOUND OR HIDAPI_DUMMY)
+ set(device_sources
+ ${device_sources}
+ device_ledger.cpp
+@@ -45,10 +46,11 @@ set(device_headers
+ device_io.hpp
+ device_default.hpp
+ device_cold.hpp
++ device_io_dummy.hpp
+ log.hpp
+ )
+
+-if(HIDAPI_FOUND)
++if(HIDAPI_FOUND OR HIDAPI_DUMMY)
+ set(device_headers
+ ${device_headers}
+ device_ledger.hpp
+diff --git a/src/device/device.cpp b/src/device/device.cpp
+index e6cd358b6..dd0701e0c 100644
+--- a/src/device/device.cpp
++++ b/src/device/device.cpp
+@@ -29,7 +29,7 @@
+
+ #include "device.hpp"
+ #include "device_default.hpp"
+-#ifdef WITH_DEVICE_LEDGER
++#if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
+ #include "device_ledger.hpp"
+ #endif
+ #include "misc_log_ex.h"
+@@ -57,7 +57,7 @@ namespace hw {
+
+ device_registry::device_registry(){
+ hw::core::register_all(registry);
+- #ifdef WITH_DEVICE_LEDGER
++ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
+ hw::ledger::register_all(registry);
+ #endif
+ atexit(clear_device_registry);
+@@ -83,11 +83,13 @@ namespace hw {
+
+ auto device = registry.find(device_descriptor_lookup);
+ if (device == registry.end()) {
+- MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: ");
++ std::stringstream ss("Device not found in registry: '" + device_descriptor + "'. Known devices: ");
++ MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: \n");
+ for( const auto& sm_pair : registry ) {
++ ss << "\n- " + sm_pair.first;
+ MERROR(" - " << sm_pair.first);
+ }
+- throw std::runtime_error("device not found: " + device_descriptor);
++ throw std::runtime_error("device not found: " + device_descriptor + "\n" + ss.str());
+ }
+ return *device->second;
+ }
+diff --git a/src/device/device.hpp b/src/device/device.hpp
+index 392703a24..ffd419779 100644
+--- a/src/device/device.hpp
++++ b/src/device/device.hpp
+@@ -34,17 +34,7 @@
+ #include "ringct/rctTypes.h"
+ #include "cryptonote_config.h"
+
+-
+-#ifndef USE_DEVICE_LEDGER
+-#define USE_DEVICE_LEDGER 1
+-#endif
+-
+-#if !defined(HAVE_HIDAPI)
+-#undef USE_DEVICE_LEDGER
+-#define USE_DEVICE_LEDGER 0
+-#endif
+-
+-#if USE_DEVICE_LEDGER
++#if defined(HAVE_HIDAPI) || defined(HIDAPI_DUMMY)
+ #define WITH_DEVICE_LEDGER
+ #endif
+
+diff --git a/src/device/device_io_dummy.cpp b/src/device/device_io_dummy.cpp
+new file mode 100644
+index 000000000..f91e10651
+--- /dev/null
++++ b/src/device/device_io_dummy.cpp
+@@ -0,0 +1,133 @@
++// Copyright (c) 2017-2022, The Monero Project
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without modification, are
++// permitted provided that the following conditions are met:
++//
++// 1. Redistributions of source code must retain the above copyright notice, this list of
++// conditions and the following disclaimer.
++//
++// 2. Redistributions in binary form must reproduce the above copyright notice, this list
++// of conditions and the following disclaimer in the documentation and/or other
++// materials provided with the distribution.
++//
++// 3. Neither the name of the copyright holder nor the names of its contributors may be
++// used to endorse or promote products derived from this software without specific
++// prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
++// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
++// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
++// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++//
++
++// device_io_dummy
++// Main goal of device_io_dummy is to emulate a hw::io::device_io without the need to actually
++// connect a device.
++// Many operating systems do not support giving raw USB access to a process (android), or don't
++// support that at all (hi iOS), therefore other means of connection can be used, either USB
++// abstraction provided by the OS (monerujo), or BLE (also monerujo).
++// Monerujo implementation is written in Java, which makes it a nice fit for iOS, but makes the
++// code extremely unportable, so for this reason the code in here is written in CPP.
++// Data transport is made available in wallet2_api.h, so wallet developers can easily plug their
++// own USB/BLE/other transport layer.
++
++#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
++#include <boost/scope_exit.hpp>
++#include "log.hpp"
++#include "device_io_dummy.hpp"
++#include "device_ledger.hpp"
++
++
++bool hw::io::device_io_dummy::stateIsConnected = false;
++unsigned char* hw::io::device_io_dummy::sendToDevice = {};
++size_t hw::io::device_io_dummy::sendToDeviceLength = 0;
++unsigned char* hw::io::device_io_dummy::receivedFromDevice = {};
++size_t hw::io::device_io_dummy::receivedFromDeviceLength = 0;
++bool hw::io::device_io_dummy::waitsForDeviceSend = false;
++bool hw::io::device_io_dummy::waitsForDeviceReceive = false;
++
++namespace hw {
++ namespace io {
++
++#undef MONERO_DEFAULT_LOG_CATEGORY
++#define MONERO_DEFAULT_LOG_CATEGORY "device.io_dummy"
++ device_io_dummy::device_io_dummy(int a, int b, int c, int d) {
++ MDEBUG("device_io_dummy(a: " << a << ", b: " << b << ", c: " << c << ", d: " << d <<")");
++ }
++
++ void device_io_dummy::init() {
++ MDEBUG("init()");
++ }
++
++ void device_io_dummy::connect(void *params) {
++ MDEBUG("connect(" << params << ")");
++ stateIsConnected = true;
++ }
++
++ void device_io_dummy::connect(const std::vector<hw::io::hid_conn_params>& known_devices) {
++ MDEBUG("connect([");
++ for (const auto &item: known_devices) {
++ MDEBUG("{ interface_number: " << item.interface_number);
++ MDEBUG(" pid : " << item.pid);
++ MDEBUG(" usage_page : " << item.usage_page);
++ MDEBUG(" vid : " << item.vid << " },");
++ }
++ MDEBUG("])");
++ stateIsConnected = true;
++ }
++
++ bool device_io_dummy::connected() const {
++ MDEBUG("connected()");
++ return stateIsConnected;
++ }
++
++ int device_io_dummy::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) {
++ MDEBUG("exchange(): locking mutex");
++ boost::unique_lock<boost::mutex> lock(mutex);
++ sendToDevice = command;
++ sendToDeviceLength = cmd_len;
++ waitsForDeviceSend = true;
++ waitsForDeviceReceive = true;
++ MDEBUG("exchange(): waitsForDeviceSend");
++ // NOTE: waitsForDeviceSend should be changed by external code
++ while (waitsForDeviceSend) {
++ std::this_thread::sleep_for(std::chrono::microseconds(1000));
++ MDEBUG("exchange(): waitsForDeviceSend (still)");
++ }
++
++ MDEBUG("exchange(): waitsForDeviceReceive");
++ while (waitsForDeviceReceive) {
++ std::this_thread::sleep_for(std::chrono::microseconds(1000));
++ MDEBUG("exchange(): waitsForDeviceReceive (still)");
++ }
++
++ if (receivedFromDeviceLength > max_resp_len) {
++ MDEBUG("exchange(): receivedFromDeviceLength ("<<receivedFromDeviceLength<<") is larger than max_resp_len ("<<max_resp_len<<")");
++ return 1;
++ }
++
++ memset(response,0,max_resp_len);
++ memcpy(response, receivedFromDevice, receivedFromDeviceLength);
++ return receivedFromDeviceLength;
++ }
++
++ void device_io_dummy::disconnect() {
++ MDEBUG("disconnect()");
++ }
++
++ void device_io_dummy::release() {
++ MDEBUG("release()");
++ }
++
++
++
++ }
++}
++#endif // HAVE_HIDAPI
+\ No newline at end of file
+diff --git a/src/device/device_io_dummy.hpp b/src/device/device_io_dummy.hpp
+new file mode 100644
+index 000000000..a1733616d
+--- /dev/null
++++ b/src/device/device_io_dummy.hpp
+@@ -0,0 +1,74 @@
++// Copyright (c) 2017-2022, The Monero Project
++//
++// All rights reserved.
++//
++// Redistribution and use in source and binary forms, with or without modification, are
++// permitted provided that the following conditions are met:
++//
++// 1. Redistributions of source code must retain the above copyright notice, this list of
++// conditions and the following disclaimer.
++//
++// 2. Redistributions in binary form must reproduce the above copyright notice, this list
++// of conditions and the following disclaimer in the documentation and/or other
++// materials provided with the distribution.
++//
++// 3. Neither the name of the copyright holder nor the names of its contributors may be
++// used to endorse or promote products derived from this software without specific
++// prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
++// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
++// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
++// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++//
++#ifdef HIDAPI_DUMMY
++
++#pragma once
++
++#include "device_io.hpp"
++#include "device_io_hid.hpp"
++
++namespace hw {
++ namespace io {
++ struct hid_conn_params {
++ unsigned int vid;
++ unsigned int pid;
++ int interface_number;
++ unsigned short usage_page;
++ };
++ class device_io_dummy : device_io {
++ private:
++ boost::mutex mutex;
++
++ public:
++ static bool stateIsConnected;
++ static unsigned char* sendToDevice;
++ static size_t sendToDeviceLength;
++ static unsigned char* receivedFromDevice;
++ static size_t receivedFromDeviceLength;
++ static bool waitsForDeviceSend;
++ static bool waitsForDeviceReceive;
++
++ device_io_dummy() = default;
++ device_io_dummy(int a, int b, int c, int d);
++ ~device_io_dummy() = default;
++
++ void init();
++ void release();
++
++ void connect(void *parms);
++ void connect(const std::vector<hw::io::hid_conn_params>& known_devices);
++ void disconnect();
++ bool connected() const;
++
++ int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input);
++ };
++ };
++};
++
++#endif // HAVE_HIDAPI
+diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
+index e1bfa7041..0139f1577 100644
+--- a/src/device/device_ledger.cpp
++++ b/src/device/device_ledger.cpp
+@@ -41,7 +41,7 @@ namespace hw {
+
+ namespace ledger {
+
+- #ifdef WITH_DEVICE_LEDGER
++ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
+
+ #undef MONERO_DEFAULT_LOG_CATEGORY
+ #define MONERO_DEFAULT_LOG_CATEGORY "device.ledger"
+@@ -299,7 +299,7 @@ namespace hw {
+
+ device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) {
+ this->id = device_id++;
+- this->reset_buffer();
++ this->reset_buffer();
+ this->mode = NONE;
+ this->has_view_key = false;
+ this->tx_in_progress = false;
+@@ -533,7 +533,9 @@ namespace hw {
+
+ bool device_ledger::connect(void) {
+ this->disconnect();
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
+ hw_device.connect(known_devices);
++ #endif
+ this->reset();
+ #ifdef DEBUG_HWDEVICE
+ cryptonote::account_public_address pubkey;
+diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
+index 03058c4f1..39454ca6d 100644
+--- a/src/device/device_ledger.hpp
++++ b/src/device/device_ledger.hpp
+@@ -35,6 +35,7 @@
+ #include "device.hpp"
+ #include "log.hpp"
+ #include "device_io_hid.hpp"
++#include "device_io_dummy.hpp"
+ #include <boost/thread/mutex.hpp>
+ #include <boost/thread/recursive_mutex.hpp>
+
+@@ -56,7 +57,7 @@ namespace hw {
+
+ void register_all(std::map<std::string, std::unique_ptr<device>> &registry);
+
+- #ifdef WITH_DEVICE_LEDGER
++ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
+
+ // Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
+ #define SW_OK 0x9000
+@@ -148,7 +149,11 @@ namespace hw {
+ mutable boost::mutex command_locker;
+
+ //IO
++#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
++ hw::io::device_io_dummy hw_device;
++#else
+ hw::io::device_io_hid hw_device;
++#endif
+ unsigned int length_send;
+ unsigned char buffer_send[BUFFER_SEND_SIZE];
+ unsigned int length_recv;
+diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
+index e04205e48..aec76ffc0 100644
+--- a/src/wallet/api/wallet.cpp
++++ b/src/wallet/api/wallet.cpp
+@@ -48,6 +48,9 @@
+ #include <boost/locale.hpp>
+ #include <boost/filesystem.hpp>
+ #include "bc-ur/src/bc-ur.hpp"
++#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
++#include "device/device_io_dummy.hpp"
++#endif
+
+ using namespace std;
+ using namespace cryptonote;
+@@ -3178,4 +3181,95 @@ uint64_t WalletImpl::getBytesSent()
+ return m_wallet->get_bytes_sent();
+ }
+
++
++// HIDAPI_DUMMY
++bool WalletImpl::getStateIsConnected() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return false;
++ #else
++ return hw::io::device_io_dummy::stateIsConnected;
++ #endif
++}
++
++unsigned char* WalletImpl::getSendToDevice() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return {};
++ #else
++ return hw::io::device_io_dummy::sendToDevice;
++ #endif
++}
++
++size_t WalletImpl::getSendToDeviceLength() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return -1;
++ #else
++ return hw::io::device_io_dummy::sendToDeviceLength;
++ #endif
++}
++
++unsigned char* WalletImpl::getReceivedFromDevice() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return {};
++ #else
++ return hw::io::device_io_dummy::receivedFromDevice;
++ #endif
++}
++
++size_t WalletImpl::getReceivedFromDeviceLength() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return -1;
++ #else
++ return hw::io::device_io_dummy::receivedFromDeviceLength;
++ #endif
++}
++
++bool WalletImpl::getWaitsForDeviceSend() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return false;
++ #else
++ return hw::io::device_io_dummy::receivedFromDeviceLength;
++ #endif
++}
++
++bool WalletImpl::getWaitsForDeviceReceive() {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return false;
++ #else
++ return hw::io::device_io_dummy::waitsForDeviceReceive;
++ #endif
++}
++
++void WalletImpl::setDeviceReceivedData(unsigned char* data, size_t len) {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return;
++ #else
++ hw::io::device_io_dummy::receivedFromDevice = static_cast<unsigned char *>(malloc(len));
++ hw::io::device_io_dummy::receivedFromDeviceLength = len;
++ memset(hw::io::device_io_dummy::receivedFromDevice, 0, len);
++ memcpy(hw::io::device_io_dummy::receivedFromDevice, data, len);
++ hw::io::device_io_dummy::waitsForDeviceReceive = false;
++ #endif
++}
++
++void WalletImpl::setDeviceSendData(unsigned char* data, size_t len) {
++ #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))
++ setStatusError("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))");
++ return;
++ #else
++ hw::io::device_io_dummy::sendToDevice = static_cast<unsigned char *>(malloc(len));
++ hw::io::device_io_dummy::sendToDeviceLength = len;
++ memset(hw::io::device_io_dummy::sendToDevice, 0, len);
++ memcpy(hw::io::device_io_dummy::sendToDevice, data, len);
++ hw::io::device_io_dummy::waitsForDeviceSend = false;
++ #endif
++}
++
+ } // namespace
+diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
+index edf8bb8ce..4e9c21ecb 100644
+--- a/src/wallet/api/wallet.h
++++ b/src/wallet/api/wallet.h
+@@ -301,6 +301,24 @@ private:
+ // cache connection status to avoid unnecessary RPC calls
+ mutable std::atomic<bool> m_is_connected;
+ boost::optional<epee::net_utils::http::login> m_daemon_login{};
++
++ bool getStateIsConnected();
++
++ unsigned char *getSendToDevice();
++
++ size_t getSendToDeviceLength();
++
++ unsigned char *getReceivedFromDevice();
++
++ size_t getReceivedFromDeviceLength();
++
++ bool getWaitsForDeviceSend();
++
++ bool getWaitsForDeviceReceive();
++
++ void setDeviceReceivedData(unsigned char *data, size_t len);
++
++ void setDeviceSendData(unsigned char *data, size_t len);
+ };
+
+
+diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
+index 764adbfbf..53ec4abfc 100644
+--- a/src/wallet/api/wallet2_api.h
++++ b/src/wallet/api/wallet2_api.h
+@@ -1150,6 +1150,18 @@ struct Wallet
+
+ //! get bytes sent
+ virtual uint64_t getBytesSent() = 0;
++
++ // HIDAPI_DUMMY
++ virtual bool getStateIsConnected() = 0;
++ virtual unsigned char* getSendToDevice() = 0;
++ virtual size_t getSendToDeviceLength() = 0;
++ virtual unsigned char* getReceivedFromDevice() = 0;
++ virtual size_t getReceivedFromDeviceLength() = 0;
++ virtual bool getWaitsForDeviceSend() = 0;
++ virtual bool getWaitsForDeviceReceive() = 0;
++
++ virtual void setDeviceReceivedData(unsigned char* data, size_t len) = 0;
++ virtual void setDeviceSendData(unsigned char* data, size_t len) = 0;
+ };
+
+ /**
+diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
+index e81b8f83a..277be6ac9 100644
+--- a/src/wallet/api/wallet_manager.cpp
++++ b/src/wallet/api/wallet_manager.cpp
+@@ -188,10 +188,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name,
+
+ bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const
+ {
+- hw::device::device_type type;
+- bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
+- device_type = static_cast<Wallet::Device>(type);
+- return r;
++ try {
++ hw::device::device_type type;
++ bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
++ device_type = static_cast<Wallet::Device>(type);
++ return r;
++ } catch (...) {
++ return false;
++ }
+ }
+
+ std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
+--
+2.51.0
+