30 #ifndef ELECTRONEUM_TRANSPORT_H 31 #define ELECTRONEUM_TRANSPORT_H 34 #include <boost/asio.hpp> 35 #include <boost/asio/deadline_timer.hpp> 36 #include <boost/array.hpp> 37 #include <boost/utility/string_ref.hpp> 40 #include <type_traits> 51 #include "messages/messages.pb.h" 52 #include "messages/messages-common.pb.h" 53 #include "messages/messages-management.pb.h" 54 #include "messages/messages-electroneum.pb.h" 76 template<
class t_req,
class t_res,
class t_transport>
77 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))
83 additional_params.push_back(std::make_pair(
"Origin",
"https://electroneum.trezor.io"));
84 additional_params.push_back(std::make_pair(
"Content-Type",
"application/json; charset=utf-8"));
87 if(!
transport.invoke(uri, method, req_param, timeout, &pri,
std::move(additional_params)))
89 MERROR(
"Failed to invoke http request to " << uri);
95 MERROR(
"Failed to invoke http request to " << uri <<
", internal error (null response ptr)");
101 MERROR(
"Failed to invoke http request to " << uri <<
", wrong response code: " << pri->
m_response_code 102 <<
" Response Body: " << pri->
m_body);
121 virtual void read(
Transport &
transport, std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)= 0;
130 void read(
Transport &
transport, std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
142 virtual bool ping() {
return false; };
147 virtual void write(
const google::protobuf::Message & req) =0;
148 virtual void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr) =0;
149 virtual std::shared_ptr<Transport>
find_debug() {
return nullptr; };
152 virtual size_t read_chunk(
void * buff,
size_t size) {
return 0; };
153 virtual std::ostream&
dump(std::ostream& o)
const {
return o <<
"Transport<>"; }
165 boost::optional<std::string> device_path = boost::none,
166 boost::optional<std::string> bridge_host = boost::none);
175 void open()
override;
176 void close()
override;
178 void write(
const google::protobuf::Message &req)
override;
179 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
182 std::ostream&
dump(std::ostream& o)
const override;
187 boost::optional<std::string> m_device_path;
188 boost::optional<std::string> m_session;
189 boost::optional<std::string> m_response;
190 boost::optional<json> m_device_info;
194 using boost::asio::ip::udp;
200 boost::optional<std::string> device_path=boost::none,
201 boost::optional<std::shared_ptr<Protocol>> proto=boost::none);
209 bool ping()
override;
213 void open()
override;
214 void close()
override;
215 std::shared_ptr<Transport>
find_debug()
override;
217 void write(
const google::protobuf::Message &req)
override;
218 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
220 void write_chunk(
const void * buff,
size_t size)
override;
221 size_t read_chunk(
void * buff,
size_t size)
override;
223 std::ostream&
dump(std::ostream& o)
const override;
226 void require_socket();
227 ssize_t receive(
void * buff,
size_t size, boost::system::error_code * error_code=
nullptr,
bool no_throw=
false, boost::posix_time::time_duration timeout=boost::posix_time::seconds(10));
228 void check_deadline();
229 static void handle_receive(
const boost::system::error_code& ec, std::size_t length,
230 boost::system::error_code* out_ec, std::size_t* out_length);
231 bool ping_int(boost::posix_time::time_duration timeout=boost::posix_time::milliseconds(1500));
233 std::shared_ptr<Protocol> m_proto;
237 std::unique_ptr<udp::socket> m_socket;
238 boost::asio::io_service m_io_service;
239 boost::asio::deadline_timer m_deadline;
240 udp::endpoint m_endpoint;
243 #ifdef WITH_DEVICE_TREZOR_WEBUSB 246 class WebUsbTransport :
public Transport {
249 explicit WebUsbTransport(
250 boost::optional<libusb_device_descriptor*> descriptor = boost::none,
251 boost::optional<std::shared_ptr<Protocol>> proto = boost::none
254 virtual ~WebUsbTransport();
256 static const char * PATH_PREFIX;
261 void open()
override;
262 void close()
override;
263 std::shared_ptr<Transport> find_debug()
override;
265 void write(
const google::protobuf::Message &req)
override;
266 void read(std::shared_ptr<google::protobuf::Message> & msg, messages::MessageType * msg_type=
nullptr)
override;
268 void write_chunk(
const void * buff,
size_t size)
override;
269 size_t read_chunk(
void * buff,
size_t size)
override;
271 std::ostream& dump(std::ostream& o)
const override;
274 void require_device()
const;
275 void require_connected()
const;
276 int get_interface()
const;
277 unsigned char get_endpoint()
const;
279 std::shared_ptr<Protocol> m_proto;
281 libusb_context *m_usb_session;
282 libusb_device *m_usb_device;
283 libusb_device_handle *m_usb_device_handle;
284 std::unique_ptr<libusb_device_descriptor> m_usb_device_desc;
285 std::vector<uint8_t> m_port_numbers;
289 #ifdef WITH_TREZOR_DEBUGGING 318 template<
class t_transport=Transport>
325 return std::dynamic_pointer_cast<t_transport>(t);
333 std::shared_ptr<google::protobuf::Message>
recvMsg;
339 const std::shared_ptr<google::protobuf::Message> &
recvMsg)
360 hw::trezor::messages::MessageType
m_type;
361 std::shared_ptr<google::protobuf::Message>
m_msg;
371 template<
class t_message=google::protobuf::Message>
372 std::shared_ptr<t_message>
374 boost::optional<messages::MessageType> resp_type = boost::none)
383 std::shared_ptr<google::protobuf::Message> msg_resp;
384 hw::trezor::messages::MessageType msg_resp_type;
385 transport.read(msg_resp, &msg_resp_type);
388 messages::MessageType required_type = resp_type ? resp_type.get() : MessageMapper::get_message_wire_number<t_message>();
390 if (msg_resp_type == required_type) {
391 return message_ptr_retype<t_message>(msg_resp);
392 }
else if (msg_resp_type == messages::MessageType_Failure){
400 std::ostream& operator<<(std::ostream& o, std::shared_ptr<hw::trezor::Transport>
const& t);
404 #endif //ELECTRONEUM_TRANSPORT_H
const std::string DEFAULT_BRIDGE
hw::trezor::messages::MessageType m_type
void enumerate(t_transport_vect &res)
virtual std::string get_path() const
virtual void write(const google::protobuf::Message &req)=0
boost::optional< std::string > reason
std::list< std::pair< std::string, std::string > > fields_list
void read(Transport &transport, 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
void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr) override
rapidjson::Value json_val
std::shared_ptr< google::protobuf::Message > m_msg
std::shared_ptr< t_message > exchange_message(Transport &transport, const google::protobuf::Message &req, boost::optional< messages::MessageType > resp_type=boost::none)
bool t_serialize(const std::string &in, std::string &out)
virtual void session_end(Transport &transport)
virtual ~BridgeTransport()=default
virtual void read(Transport &transport, std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr)=0
void write(Transport &transport, const google::protobuf::Message &req) override
const boost::optional< json > & device_info() const
std::shared_ptr< t_transport > transport_typed(const std::string &path)
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
virtual void read(std::shared_ptr< google::protobuf::Message > &msg, messages::MessageType *msg_type=nullptr)=0
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.
virtual void write(Transport &transport, const google::protobuf::Message &req)=0
virtual ~Protocol()=default
virtual ~ProtocolV1()=default
void enumerate(t_transport_vect &res) override
virtual ~Transport()=default
virtual ~UdpTransport()=default
void throw_failure_exception(const messages::common::Failure *failure)
void sort_transports_by_env(t_transport_vect &res)
void write_chunk(const void *buff, size_t size) override
virtual std::ostream & dump(std::ostream &o) const
virtual std::shared_ptr< Transport > find_debug()
virtual void enumerate(t_transport_vect &res)
UnexpectedMessageException()
uint64_t pack_version(uint32_t major, uint32_t minor, uint32_t patch)
std::shared_ptr< google::protobuf::Message > recvMsg
bool t_deserialize(const std::string &in, std::string &out)
std::string get_path() const override
const T & move(const T &t)
std::shared_ptr< Transport > find_debug() override
void write(const google::protobuf::Message &req) override
UnexpectedMessageException(hw::trezor::messages::MessageType recvType, const std::shared_ptr< google::protobuf::Message > &recvMsg)
void enumerate(t_transport_vect &res) override
const GenericPointer< typename T::ValueType > T2 value
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)
virtual void session_begin(Transport &transport)
static const int DEFAULT_PORT
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
std::string get_path() const override
std::ostream & operator<<(std::ostream &o, hw::trezor::Transport const &t)
hw::trezor::messages::MessageType recvType
static const char * DEFAULT_HOST
virtual void write_chunk(const void *buff, size_t size)
virtual size_t read_chunk(void *buff, size_t size)
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)