30 #ifdef WITH_DEVICE_TREZOR_WEBUSB 36 #include <boost/endian/conversion.hpp> 37 #include <boost/asio/io_service.hpp> 38 #include <boost/asio/ip/udp.hpp> 39 #include <boost/date_time/posix_time/posix_time_types.hpp> 40 #include <boost/format.hpp> 43 #include "messages/messages-common.pb.h" 45 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 46 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "device.trezor.transport" 62 rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
80 if (out.Parse(in.c_str()).HasParseError()) {
93 const unsigned bits_1 = 16;
94 const unsigned bits_2 = 24;
95 const uint32_t mask_1 = (1 << bits_1) - 1;
96 const uint32_t mask_2 = (1 << bits_2) - 1;
98 return patch | (((
uint64_t)minor) << bits_2) | (((
uint64_t)major) << (bits_1 + bits_2));
108 static trezor_usb_desc_t TREZOR_DESC_T2 = {2, 0x1209, 0x53C1};
109 static trezor_usb_desc_t TREZOR_DESC_T2_BL = {3, 0x1209, 0x53C0};
111 static trezor_usb_desc_t TREZOR_DESCS[] = {
117 static size_t TREZOR_DESCS_LEN =
sizeof(TREZOR_DESCS)/
sizeof(TREZOR_DESCS[0]);
120 for(
size_t i = 0; i < TREZOR_DESCS_LEN; ++i){
121 if (TREZOR_DESCS[i].id_vendor == id_vendor && TREZOR_DESCS[i].id_product == id_product){
129 static bool is_device_supported(ssize_t device_idx){
135 #ifdef TREZOR_1_SUPPORTED 146 #define PROTO_HEADER_SIZE 6 148 static size_t message_size(
const google::protobuf::Message &req){
149 return static_cast<size_t>(req.ByteSize());
152 static size_t serialize_message_buffer_size(
size_t msg_size) {
156 static void serialize_message_header(
void * buff,
uint16_t tag,
uint32_t len){
157 uint16_t wire_tag = boost::endian::native_to_big(static_cast<uint16_t>(tag));
158 uint32_t wire_len = boost::endian::native_to_big(static_cast<uint32_t>(len));
159 memcpy(buff, (
void *) &wire_tag, 2);
163 static void deserialize_message_header(
const void * buff,
uint16_t & tag,
uint32_t & len){
166 memcpy(&wire_tag, buff, 2);
169 tag = boost::endian::big_to_native(wire_tag);
170 len = boost::endian::big_to_native(wire_len);
173 static void serialize_message(
const google::protobuf::Message &req,
size_t msg_size,
uint8_t * buff,
size_t buff_size) {
174 auto msg_wire_num = MessageMapper::get_message_wire_number(req);
175 const auto req_buffer_size = serialize_message_buffer_size(msg_size);
176 if (req_buffer_size > buff_size){
177 throw std::invalid_argument(
"Buffer too small");
180 serialize_message_header(buff, msg_wire_num, msg_size);
181 if (!req.SerializeToArray(buff + 6, msg_size)){
182 throw exc::EncodingException(
"Message serialization error");
193 const auto msg_size = message_size(req);
194 const auto buff_size = serialize_message_buffer_size(msg_size) + 2;
196 std::unique_ptr<uint8_t[]> req_buff(
new uint8_t[buff_size]);
197 uint8_t * req_buff_raw = req_buff.get();
198 req_buff_raw[0] =
'#';
199 req_buff_raw[1] =
'#';
201 serialize_message(req, msg_size, req_buff_raw + 2, buff_size - 2);
207 while(offset < buff_size){
208 auto to_copy = std::min((
size_t)(buff_size - offset), (
size_t)(
REPLEN - 1));
211 memcpy(chunk_buff + 1, req_buff_raw + offset, to_copy);
214 if (to_copy <
REPLEN - 1){
215 memset(chunk_buff + 1 + to_copy, 0,
REPLEN - 1 - to_copy);
223 void ProtocolV1::read(
Transport &
transport, std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type){
232 if (strncmp(chunk,
"?##", 3) != 0){
239 deserialize_message_header(chunk + 3, tag, len);
242 data_acc.reserve(len);
246 if (chunk[0] !=
'?'){
250 data_acc.append(chunk + 1, cur - 1);
255 *msg_type =
static_cast<messages::MessageType
>(tag);
262 std::shared_ptr<google::protobuf::Message> msg_wrap(MessageMapper::get_message(tag));
263 if (!msg_wrap->ParseFromArray(data_acc.c_str(), len)){
275 Transport::Transport(): m_open_counter(0) {
316 boost::optional<std::string> device_path,
317 boost::optional<std::string> bridge_host):
318 m_device_path(device_path),
320 m_response(
boost::none),
321 m_session(
boost::none),
322 m_device_info(
boost::none)
324 const char *env_bridge_port =
nullptr;
325 if (!bridge_host && (env_bridge_port = getenv(
"TREZOR_BRIDGE_PORT")) !=
nullptr)
329 assert_port_number(bridge_port);
332 MDEBUG(
"Bridge host: " << m_bridge_host);
344 return path + m_device_path.get();
357 auto element = itr->GetObject();
358 auto t = std::make_shared<BridgeTransport>(boost::make_optional(json_get_string(element[
"path"])));
360 auto itr_vendor = element.FindMember(
"vendor");
361 auto itr_product = element.FindMember(
"product");
362 if (itr_vendor != element.MemberEnd() && itr_product != element.MemberEnd()
363 && itr_vendor->value.IsNumber() && itr_product->value.IsNumber()){
365 const auto id_vendor = (
uint16_t) itr_vendor->value.GetUint64();
366 const auto id_product = (
uint16_t) itr_product->value.GetUint64();
367 const auto device_idx = get_device_idx(id_vendor, id_product);
368 if (!is_device_supported(device_idx)){
369 MDEBUG(
"Device with idx " << device_idx <<
" is not supported. Vendor: " << id_vendor <<
", product: " << id_product);
372 }
catch(
const std::exception &e){
373 MERROR(
"Could not detect vendor & product: " << e.what());
377 t->m_device_info.emplace();
378 t->m_device_info->CopyFrom(*itr, t->m_device_info->GetAllocator());
392 std::string uri =
"/acquire/" + m_device_path.get() +
"/null";
400 m_session = boost::make_optional(json_get_string(bridge_res[
"session"]));
409 MTRACE(
"Closing Trezor:BridgeTransport");
410 if (!m_device_path || !m_session){
422 m_session = boost::none;
426 m_response = boost::none;
428 const auto msg_size = message_size(req);
429 const auto buff_size = serialize_message_buffer_size(msg_size);
431 std::unique_ptr<uint8_t[]> req_buff(
new uint8_t[buff_size]);
432 uint8_t * req_buff_raw = req_buff.get();
434 serialize_message(req, msg_size, req_buff_raw, buff_size);
445 m_response = res_hex;
460 deserialize_message_header(bin_data.c_str(), msg_tag, msg_len);
461 if (bin_data.size() != msg_len + 6){
466 *msg_type =
static_cast<messages::MessageType
>(msg_tag);
470 if (!msg_wrap->ParseFromArray(bin_data.c_str() + 6, msg_len)){
477 return m_device_info;
481 return o <<
"BridgeTransport<path=" << (m_device_path ?
get_path() :
"None")
482 <<
", info=" << (m_device_info ?
t_serialize(m_device_info.get()) :
"None")
483 <<
", session=" << (m_session ? m_session.get() :
"None")
501 auto delim = path.find(
':');
502 if (delim == std::string::npos) {
505 host = path.substr(0, delim);
506 port = std::stoi(path.substr(delim + 1));
511 boost::optional<std::shared_ptr<Protocol>> proto) :
512 m_io_service(), m_deadline(m_io_service)
516 const char *env_trezor_path =
nullptr;
519 parse_udp_path(m_device_host, m_device_port, device_path.get());
520 }
else if ((env_trezor_path = getenv(
"TREZOR_PATH")) !=
nullptr && boost::starts_with(env_trezor_path,
UdpTransport::PATH_PREFIX)){
521 parse_udp_path(m_device_host, m_device_port,
std::string(env_trezor_path));
522 MDEBUG(
"Applied TREZOR_PATH: " << m_device_host <<
":" << m_device_port);
527 assert_port_number((
uint32_t)m_device_port);
528 if (m_device_host !=
"localhost" && m_device_host !=
DEFAULT_HOST){
529 throw std::invalid_argument(
"Local endpoint allowed only");
532 m_proto = proto ? proto.get() : std::make_shared<ProtocolV1>();
537 return path + m_device_host +
":" +
std::to_string(m_device_port);
540 void UdpTransport::require_socket(){
550 bool UdpTransport::ping_int(boost::posix_time::time_duration timeout){
556 m_socket->send_to(boost::asio::buffer(req.c_str(), req.size()), m_endpoint);
557 receive(
res, 8,
nullptr,
false, timeout);
559 return memcmp(
res,
"PONGPONG", 8) == 0;
567 std::shared_ptr<UdpTransport> t = std::make_shared<UdpTransport>();
568 bool t_works =
false;
587 udp::resolver resolver(m_io_service);
588 udp::resolver::query query(udp::v4(), m_device_host,
std::to_string(m_device_port));
589 m_endpoint = *resolver.resolve(query);
592 m_socket->open(udp::v4());
594 m_deadline.expires_at(boost::posix_time::pos_infin);
597 m_proto->session_begin(*
this);
606 MTRACE(
"Closing Trezor:UdpTransport");
611 m_proto->session_end(*
this);
617 #ifdef WITH_TREZOR_DEBUGGING 618 std::shared_ptr<UdpTransport> t = std::make_shared<UdpTransport>();
619 t->m_proto = std::make_shared<ProtocolV1>();
620 t->m_device_host = m_device_host;
621 t->m_device_port = m_device_port + 1;
624 MINFO(
"Debug link is disabled in production");
636 auto written = m_socket->send_to(boost::asio::buffer(buff, size), m_endpoint);
637 if (size != written){
645 throw std::invalid_argument(
"Buffer too small");
651 boost::system::error_code ec;
652 len = receive(buff, size, &ec,
true);
653 if (ec == boost::asio::error::operation_aborted) {
667 }
catch(std::exception
const& e){
668 MWARNING(
"Error reading chunk, reason: " << e.what());
673 return static_cast<size_t>(len);
676 ssize_t UdpTransport::receive(
void * buff,
size_t size, boost::system::error_code * error_code,
bool no_throw, boost::posix_time::time_duration timeout){
677 boost::system::error_code ec;
678 boost::asio::mutable_buffer buffer = boost::asio::buffer(buff, size);
683 m_deadline.expires_from_now(timeout);
690 ec = boost::asio::error::would_block;
691 std::size_t length = 0;
695 m_socket->async_receive_from(boost::asio::buffer(buffer), m_endpoint,
696 std::bind(&UdpTransport::handle_receive, std::placeholders::_1, std::placeholders::_2, &ec, &length));
700 m_io_service.run_one();
702 while (ec == boost::asio::error::would_block);
713 if (ec == boost::asio::error::operation_aborted){
714 throw exc::TimeoutException();
717 MWARNING(
"Reading from UDP socket failed: " << ec.message());
718 throw exc::CommunicationException();
726 m_proto->write(*
this, req);
729 void UdpTransport::read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type) {
730 m_proto->read(*
this, msg, msg_type);
733 void UdpTransport::check_deadline(){
741 if (m_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now())
753 m_deadline.expires_at(boost::posix_time::pos_infin);
757 m_deadline.async_wait(boost::bind(&UdpTransport::check_deadline,
this));
760 void UdpTransport::handle_receive(
const boost::system::error_code &ec, std::size_t length,
761 boost::system::error_code *out_ec, std::size_t *out_length) {
763 *out_length = length;
767 return o <<
"UdpTransport<path=" <<
get_path()
768 <<
", socket_alive=" << (m_socket ?
"true" :
"false")
772 #ifdef WITH_DEVICE_TREZOR_WEBUSB 774 static bool is_trezor1(libusb_device_descriptor *
info){
778 static bool is_trezor2(libusb_device_descriptor *
info){
782 static bool is_trezor2_bl(libusb_device_descriptor *
info){
786 static ssize_t get_trezor_dev_id(libusb_device_descriptor *
info){
788 return get_device_idx(
info->idVendor,
info->idProduct);
791 static void set_libusb_log(libusb_context *ctx){
795 #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000106) 796 # define TREZOR_LIBUSB_SET_DEBUG(ctx, level) libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) 798 # define TREZOR_LIBUSB_SET_DEBUG(ctx, level) libusb_set_debug(ctx, level) 802 TREZOR_LIBUSB_SET_DEBUG(ctx, 3);
804 TREZOR_LIBUSB_SET_DEBUG(ctx, 2);
806 TREZOR_LIBUSB_SET_DEBUG(ctx, 1);
808 #undef TREZOR_LIBUSB_SET_DEBUG 811 static int get_libusb_ports(libusb_device *dev, std::vector<uint8_t> &path){
813 int r = libusb_get_port_numbers(dev, tmp_path,
sizeof(tmp_path));
818 for (
int i = 0; i < r; i++){
819 path[i] = tmp_path[i];
826 std::stringstream ss;
827 ss << WebUsbTransport::PATH_PREFIX << (boost::format(
"%03d") % ((int)bus_id));
829 ss <<
":" << ((int)
port);
834 const char * WebUsbTransport::PATH_PREFIX =
"webusb:";
836 WebUsbTransport::WebUsbTransport(
837 boost::optional<libusb_device_descriptor*> descriptor,
838 boost::optional<std::shared_ptr<Protocol>> proto
839 ): m_usb_session(nullptr), m_usb_device(nullptr), m_usb_device_handle(nullptr),
840 m_bus_id(-1), m_device_addr(-1)
843 libusb_device_descriptor * desc =
new libusb_device_descriptor;
844 memcpy(desc, descriptor.get(),
sizeof(libusb_device_descriptor));
845 this->m_usb_device_desc.reset(desc);
848 m_proto = proto ? proto.get() : std::make_shared<ProtocolV1>();
850 #ifdef WITH_TREZOR_DEBUGGING 851 m_debug_mode =
false;
855 WebUsbTransport::~WebUsbTransport(){
861 libusb_exit(m_usb_session);
862 m_usb_session =
nullptr;
866 void WebUsbTransport::require_device()
const{
867 if (!m_usb_device_desc){
868 throw std::runtime_error(
"No USB device specified");
872 void WebUsbTransport::require_connected()
const{
874 if (!m_usb_device_handle){
875 throw std::runtime_error(
"USB Device not opened");
881 libusb_device **devs;
882 libusb_context *ctx =
nullptr;
884 r = libusb_init(&ctx);
889 ssize_t cnt = libusb_get_device_list(ctx, &devs);
892 throw std::runtime_error(
"Unable to enumerate libusb devices");
895 MTRACE(
"Libusb devices: " << cnt);
897 for(ssize_t i = 0; i < cnt; i++) {
898 libusb_device_descriptor desc{};
899 r = libusb_get_device_descriptor(devs[i], &desc);
901 MERROR(
"Unable to get libusb device descriptor " << i);
905 const auto trezor_dev_idx = get_trezor_dev_id(&desc);
906 if (!is_device_supported(trezor_dev_idx)){
910 MTRACE(
"Found Trezor device: " << desc.idVendor <<
":" << desc.idProduct <<
" dev_idx " << (
int)trezor_dev_idx);
912 auto t = std::make_shared<WebUsbTransport>(boost::make_optional(&desc));
913 t->m_bus_id = libusb_get_bus_number(devs[i]);
914 t->m_device_addr = libusb_get_device_address(devs[i]);
917 get_libusb_ports(devs[i], t->m_port_numbers);
922 libusb_free_device_list(devs, 1);
927 if (!m_usb_device_desc){
931 return get_usb_path(static_cast<uint8_t>(m_bus_id), m_port_numbers);
934 void WebUsbTransport::open() {
938 const int interface = get_interface();
940 #define TREZOR_DESTROY_SESSION() do { libusb_exit(m_usb_session); m_usb_session = nullptr; } while(0) 943 libusb_device **devs =
nullptr;
946 TREZOR_DESTROY_SESSION();
949 r = libusb_init(&m_usb_session);
951 set_libusb_log(m_usb_session);
956 ssize_t cnt = libusb_get_device_list(m_usb_session, &devs);
958 TREZOR_DESTROY_SESSION();
959 throw std::runtime_error(
"Unable to enumerate libusb devices");
962 for (ssize_t i = 0; i < cnt; i++) {
963 libusb_device_descriptor desc{};
964 r = libusb_get_device_descriptor(devs[i], &desc);
966 MERROR(
"Unable to get libusb device descriptor " << i);
970 const auto trezor_dev_idx = get_trezor_dev_id(&desc);
971 if (!is_device_supported(trezor_dev_idx)){
975 auto bus_id = libusb_get_bus_number(devs[i]);
976 std::vector<uint8_t> path;
979 get_libusb_ports(devs[i], path);
981 MTRACE(
"Found Trezor device: " << desc.idVendor <<
":" << desc.idProduct
982 <<
", dev_idx: " << (
int)trezor_dev_idx
983 <<
". path: " << get_usb_path(bus_id, path));
985 if (bus_id == m_bus_id && path == m_port_numbers) {
987 m_usb_device = devs[i];
988 open_res = libusb_open(m_usb_device, &m_usb_device_handle);
993 libusb_free_device_list(devs, 1);
996 TREZOR_DESTROY_SESSION();
997 throw exc::DeviceAcquireException(
"Device not found");
999 }
else if (found && open_res != 0) {
1000 m_usb_device_handle =
nullptr;
1001 m_usb_device =
nullptr;
1002 TREZOR_DESTROY_SESSION();
1003 throw exc::DeviceAcquireException(
"Unable to open libusb device");
1006 r = libusb_claim_interface(m_usb_device_handle, interface);
1009 libusb_close(m_usb_device_handle);
1010 m_usb_device_handle =
nullptr;
1011 m_usb_device =
nullptr;
1012 TREZOR_DESTROY_SESSION();
1013 throw exc::DeviceAcquireException(
"Unable to claim libusb device");
1017 m_proto->session_begin(*
this);
1019 #undef TREZOR_DESTROY_SESSION 1022 void WebUsbTransport::close() {
1027 MTRACE(
"Closing Trezor:WebUsbTransport");
1028 m_proto->session_end(*
this);
1030 int r = libusb_release_interface(m_usb_device_handle, get_interface());
1032 MERROR(
"Could not release libusb interface: " << r);
1035 m_usb_device =
nullptr;
1036 if (m_usb_device_handle) {
1037 libusb_close(m_usb_device_handle);
1038 m_usb_device_handle =
nullptr;
1041 if (m_usb_session) {
1042 libusb_exit(m_usb_session);
1043 m_usb_session =
nullptr;
1047 std::shared_ptr<Transport> WebUsbTransport::find_debug() {
1048 #ifdef WITH_TREZOR_DEBUGGING 1050 auto t = std::make_shared<WebUsbTransport>(boost::make_optional(m_usb_device_desc.get()));
1051 t->m_bus_id = m_bus_id;
1052 t->m_device_addr = m_device_addr;
1053 t->m_port_numbers = m_port_numbers;
1054 t->m_debug_mode =
true;
1057 MINFO(
"Debug link is disabled in production");
1062 int WebUsbTransport::get_interface()
const{
1063 const int INTERFACE_NORMAL = 0;
1064 #ifdef WITH_TREZOR_DEBUGGING 1065 const int INTERFACE_DEBUG = 1;
1066 return m_debug_mode ? INTERFACE_DEBUG : INTERFACE_NORMAL;
1068 return INTERFACE_NORMAL;
1072 unsigned char WebUsbTransport::get_endpoint()
const{
1073 const unsigned char ENDPOINT_NORMAL = 1;
1074 #ifdef WITH_TREZOR_DEBUGGING 1075 const unsigned char ENDPOINT_DEBUG = 2;
1076 return m_debug_mode ? ENDPOINT_DEBUG : ENDPOINT_NORMAL;
1078 return ENDPOINT_NORMAL;
1082 void WebUsbTransport::write(
const google::protobuf::Message &req) {
1083 m_proto->write(*
this, req);
1086 void WebUsbTransport::read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type) {
1087 m_proto->read(*
this, msg, msg_type);
1090 void WebUsbTransport::write_chunk(
const void * buff,
size_t size) {
1091 require_connected();
1093 throw exc::CommunicationException(
"Invalid chunk size: ");
1096 unsigned char endpoint = get_endpoint();
1097 endpoint = (endpoint & ~LIBUSB_ENDPOINT_DIR_MASK) | LIBUSB_ENDPOINT_OUT;
1099 int transferred = 0;
1100 int r = libusb_interrupt_transfer(m_usb_device_handle, endpoint, (
unsigned char*)buff, (
int)size, &transferred, 0);
1102 if (transferred != (
int)size){
1103 throw exc::CommunicationException(
"Could not transfer chunk");
1107 size_t WebUsbTransport::read_chunk(
void * buff,
size_t size) {
1108 require_connected();
1109 unsigned char endpoint = get_endpoint();
1110 endpoint = (endpoint & ~LIBUSB_ENDPOINT_DIR_MASK) | LIBUSB_ENDPOINT_IN;
1112 int transferred = 0;
1113 int r = libusb_interrupt_transfer(m_usb_device_handle, endpoint, (
unsigned char*)buff, (
int)size, &transferred, 0);
1115 if (transferred != (
int)size){
1116 throw exc::CommunicationException(
"Could not read the chunk");
1122 std::ostream& WebUsbTransport::dump(std::ostream& o)
const {
1123 o <<
"WebUsbTransport<path=" << get_path()
1124 <<
", vendorId=" << (m_usb_device_desc ?
std::to_string(m_usb_device_desc->idVendor) :
"?")
1125 <<
", productId=" << (m_usb_device_desc ?
std::
to_string(m_usb_device_desc->idProduct) :
"?")
1128 if (m_usb_device_desc){
1129 if (is_trezor1(m_usb_device_desc.get()))
1131 else if (is_trezor2(m_usb_device_desc.get()))
1133 else if (is_trezor2_bl(m_usb_device_desc.get()))
1142 #endif // WITH_DEVICE_TREZOR_WEBUSB 1148 }
catch (
const std::exception & e){
1149 MERROR(
"BridgeTransport enumeration failed:" << e.what());
1152 #ifdef WITH_DEVICE_TREZOR_WEBUSB 1153 hw::trezor::WebUsbTransport btw;
1156 }
catch (
const std::exception & e){
1157 MERROR(
"WebUsbTransport enumeration failed:" << e.what());
1161 #ifdef WITH_DEVICE_TREZOR_UDP 1165 }
catch (
const std::exception & e){
1166 MERROR(
"UdpTransport enumeration failed:" << e.what());
1172 const char *env_trezor_path = getenv(
"TREZOR_PATH");
1173 if (!env_trezor_path){
1179 std::vector<size_t> match_idx(
res.size());
1180 std::vector<size_t> path_permutation(
res.size());
1182 for(
size_t i = 0; i <
res.size(); ++i){
1183 auto cpath =
res[i]->get_path();
1188 if (s1->size() >= s2->size()){
1192 const auto mism = std::mismatch(s1->begin(), s1->end(), s2->begin());
1193 match_idx[i] = mism.first - s1->begin();
1194 path_permutation[i] = i;
1197 std::sort(path_permutation.begin(), path_permutation.end(), [&](
const size_t i0,
const size_t i1) {
1198 return match_idx[i0] > match_idx[i1];
1212 throw std::invalid_argument(
"Unknown Trezor device path: " + path);
1218 if (failure ==
nullptr){
1219 throw std::invalid_argument(
"Failure message cannot be null");
1222 boost::optional<std::string>
message = failure->has_message() ? boost::make_optional(failure->message()) : boost::none;
1223 boost::optional<uint32_t> code = failure->has_code() ? boost::make_optional(static_cast<uint32_t>(failure->code())) : boost::none;
1228 auto ecode = failure->code();
1229 if (ecode == messages::common::Failure_FailureType_Failure_UnexpectedMessage){
1231 }
else if (ecode == messages::common::Failure_FailureType_Failure_ActionCancelled){
1233 }
else if (ecode == messages::common::Failure_FailureType_Failure_PinExpected){
1235 }
else if (ecode == messages::common::Failure_FailureType_Failure_PinInvalid){
1237 }
else if (ecode == messages::common::Failure_FailureType_Failure_NotEnoughFunds){
1239 }
else if (ecode == messages::common::Failure_FailureType_Failure_NotInitialized){
1241 }
else if (ecode == messages::common::Failure_FailureType_Failure_FirmwareError){
1249 : m_type(m_type), m_msg(m_msg), m_empty(
false) {}
1255 std::ostream& operator<<(std::ostream& o, std::shared_ptr<hw::trezor::Transport>
const& t){
const std::string DEFAULT_BRIDGE
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
bool set_server(const std::string &address, boost::optional< login > user, ssl_options_t ssl_options=ssl_support_t::e_ssl_support_autodetect)
void enumerate(t_transport_vect &res)
void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
rapidjson::Value json_val
Information representing errors in application but application will keep running. ...
bool t_serialize(const std::string &in, std::string &out)
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Informational events most useful for developers to debug application.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
#define ELECTRONEUM_DEFAULT_LOG_CATEGORY
const boost::optional< json > & device_info() const
static const char * PATH_PREFIX
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
std::ostream & dump(std::ostream &o) const override
size_t read_chunk(void *buff, size_t size) override
bool invoke_bridge_http(const boost::string_ref uri, const t_req &out_struct, t_res &result_struct, t_transport &transport, const boost::string_ref method="POST", std::chrono::milliseconds timeout=std::chrono::seconds(180))
unsigned __int64 uint64_t
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
void enumerate(t_transport_vect &res) override
::google::protobuf::Message * get_message(int wire_number)
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
void throw_failure_exception(const messages::common::Failure *failure)
void sort_transports_by_env(t_transport_vect &res)
Useful when application has potentially harmful situtaions.
void write_chunk(const void *buff, size_t size) override
virtual std::ostream & dump(std::ostream &o) const
std::string message("Message requiring signing")
boost::endian::big_uint16_t port
uint64_t pack_version(uint32_t major, uint32_t minor, uint32_t patch)
bool t_deserialize(const std::string &in, json &out)
std::string get_path() const override
std::shared_ptr< Transport > find_debug() override
void write(const google::protobuf::Message &req) override
void enumerate(t_transport_vect &res) override
void * memcpy(void *a, const void *b, size_t c)
void write(const google::protobuf::Message &req) override
BridgeTransport(boost::optional< std::string > device_path=boost::none, boost::optional< std::string > bridge_host=boost::none)
std::string t_serialize(const json_val &in)
static std::string string(const span< const std::uint8_t > src)
#define PROTO_HEADER_SIZE
static const int DEFAULT_PORT
std::ostream & operator<<(std::ostream &o, std::shared_ptr< hw::trezor::Transport > const &t)
std::ostream & dump(std::ostream &o) const override
std::string to_string(t_connection_type type)
std::vector< std::shared_ptr< Transport > > t_transport_vect
static const char * PATH_PREFIX
void get(std::istream &input, bool &res)
std::string get_path() const override
static const char * DEFAULT_HOST
std::shared_ptr< Transport > transport(const std::string &path)
UdpTransport(boost::optional< std::string > device_path=boost::none, boost::optional< std::shared_ptr< Protocol >> proto=boost::none)