Electroneum
mms::message_transporter Class Reference

#include <message_transporter.h>

Public Member Functions

 message_transporter ()
 
void set_options (const std::string &bitmessage_address, const epee::wipeable_string &bitmessage_login)
 
bool send_message (const transport_message &message)
 
bool receive_messages (const std::vector< std::string > &destination_transport_addresses, std::vector< transport_message > &messages)
 
bool delete_message (const std::string &transport_id)
 
void stop ()
 
std::string derive_transport_address (const std::string &seed)
 
std::string derive_and_receive_transport_address (const std::string &seed)
 
bool delete_transport_address (const std::string &transport_address)
 

Detailed Description

Definition at line 83 of file message_transporter.h.

Constructor & Destructor Documentation

◆ message_transporter()

mms::message_transporter::message_transporter ( )

Definition at line 83 of file message_transporter.cpp.

84 {
85  m_run = true;
86 }

Member Function Documentation

◆ delete_message()

bool mms::message_transporter::delete_message ( const std::string &  transport_id)

Definition at line 184 of file message_transporter.cpp.

185 {
186  std::string request;
187  start_xml_rpc_cmd(request, "trashMessage");
188  add_xml_rpc_string_param(request, transport_id);
189  end_xml_rpc_cmd(request);
190  std::string answer;
191  post_request(request, answer);
192  return true;
193 }
::std::string string
Definition: gtest-port.h:1097

◆ delete_transport_address()

bool mms::message_transporter::delete_transport_address ( const std::string &  transport_address)

Definition at line 232 of file message_transporter.cpp.

233 {
234  std::string request;
235  start_xml_rpc_cmd(request, "deleteAddress");
236  add_xml_rpc_string_param(request, transport_address);
237  end_xml_rpc_cmd(request);
238  std::string answer;
239  return post_request(request, answer);
240 }
::std::string string
Definition: gtest-port.h:1097
Here is the caller graph for this function:

◆ derive_and_receive_transport_address()

std::string mms::message_transporter::derive_and_receive_transport_address ( const std::string &  seed)

Definition at line 214 of file message_transporter.cpp.

215 {
216  // We need to call both "get_deterministic_address" AND "createDeterministicAddresses"
217  // because we won't get back the address from the latter call if it exists already
219 
220  std::string request;
221  start_xml_rpc_cmd(request, "createDeterministicAddresses");
222  add_xml_rpc_base64_param(request, seed);
223  add_xml_rpc_integer_param(request, 1); // numberOfAddresses
224  add_xml_rpc_integer_param(request, 4); // addressVersionNumber
225  end_xml_rpc_cmd(request);
226  std::string answer;
227  post_request(request, answer);
228 
229  return address;
230 }
::std::string string
Definition: gtest-port.h:1097
std::string derive_transport_address(const std::string &seed)
const char * address
Definition: multisig.cpp:37

◆ derive_transport_address()

std::string mms::message_transporter::derive_transport_address ( const std::string &  seed)

Definition at line 198 of file message_transporter.cpp.

199 {
200  std::string request;
201  start_xml_rpc_cmd(request, "getDeterministicAddress");
202  add_xml_rpc_base64_param(request, seed);
203  add_xml_rpc_integer_param(request, 4); // addressVersionNumber
204  add_xml_rpc_integer_param(request, 1); // streamNumber
205  end_xml_rpc_cmd(request);
206  std::string answer;
207  post_request(request, answer);
208  std::string address = get_str_between_tags(answer, "<string>", "</string>");
209  return address;
210 }
::std::string string
Definition: gtest-port.h:1097
const char * address
Definition: multisig.cpp:37

◆ receive_messages()

bool mms::message_transporter::receive_messages ( const std::vector< std::string > &  destination_transport_addresses,
std::vector< transport_message > &  messages 
)

Definition at line 102 of file message_transporter.cpp.

104 {
105  // The message body of the Bitmessage message is basically the transport message, as JSON (and nothing more).
106  // Weeding out other, non-MMS messages is done in a simple way: If it deserializes without error, it's an MMS message
107  // That JSON is Base64-encoded by the MMS because the Electroneum epee JSON serializer does not escape anything and happily
108  // includes even 0 (NUL) in strings, which might confuse Bitmessage or at least display confusingly in the client.
109  // There is yet another Base64-encoding of course as part of the Bitmessage API for the message body parameter
110  // The Bitmessage API call "getAllInboxMessages" gives back a JSON array with all the messages (despite using
111  // XML-RPC for the calls, and not JSON-RPC ...)
112  m_run.store(true, std::memory_order_relaxed);
113  std::string request;
114  start_xml_rpc_cmd(request, "getAllInboxMessages");
115  end_xml_rpc_cmd(request);
116  std::string answer;
117  post_request(request, answer);
118 
119  std::string json = get_str_between_tags(answer, "<string>", "</string>");
121  if (!epee::serialization::load_t_from_json(bitmessage_res, json))
122  {
123  MERROR("Failed to deserialize messages");
124  return true;
125  }
126  size_t size = bitmessage_res.inboxMessages.size();
127  messages.clear();
128 
129  for (size_t i = 0; i < size; ++i)
130  {
131  if (!m_run.load(std::memory_order_relaxed))
132  {
133  // Stop was called, don't waste time processing any more messages
134  return false;
135  }
136  const bitmessage_rpc::message_info &message_info = bitmessage_res.inboxMessages[i];
137  if (std::find(destination_transport_addresses.begin(), destination_transport_addresses.end(), message_info.toAddress) != destination_transport_addresses.end())
138  {
140  bool is_mms_message = false;
141  try
142  {
143  // First Base64-decoding: The message body is Base64 in the Bitmessage API
145  // Second Base64-decoding: The MMS uses Base64 to hide non-textual data in its JSON from Bitmessage
148  MERROR("Failed to deserialize message");
149  else
150  is_mms_message = true;
151  }
152  catch(const std::exception& e)
153  {
154  }
155  if (is_mms_message)
156  {
157  message.transport_id = message_info.msgid;
158  messages.push_back(message);
159  }
160  }
161  }
162 
163  return true;
164 }
#define MERROR(x)
Definition: misc_log_ex.h:73
epee::misc_utils::struct_init< inbox_messages_response_t > inbox_messages_response
::std::string string
Definition: gtest-port.h:1097
bool load_t_from_json(t_struct &out, const std::string &json_buff)
std::string message("Message requiring signing")
epee::misc_utils::struct_init< message_info_t > message_info
epee::misc_utils::struct_init< transport_message_t > transport_message
std::string base64_decode(std::string const &encoded_string)
rapidjson::Document json
Definition: transport.cpp:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_message()

bool mms::message_transporter::send_message ( const transport_message message)

Definition at line 166 of file message_transporter.cpp.

167 {
168  // <toAddress> <fromAddress> <subject> <message> [encodingType [TTL]]
169  std::string request;
170  start_xml_rpc_cmd(request, "sendMessage");
171  add_xml_rpc_string_param(request, message.destination_transport_address);
172  add_xml_rpc_string_param(request, message.source_transport_address);
173  add_xml_rpc_base64_param(request, message.subject);
175  std::string message_body = epee::string_encoding::base64_encode(json); // See comment in "receive_message" about reason for (double-)Base64 encoding
176  add_xml_rpc_base64_param(request, message_body);
177  add_xml_rpc_integer_param(request, 2);
178  end_xml_rpc_cmd(request);
179  std::string answer;
180  post_request(request, answer);
181  return true;
182 }
std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len)
::std::string string
Definition: gtest-port.h:1097
bool store_t_to_json(t_struct &str_in, std::string &json_buff, size_t indent=0, bool insert_newlines=true)
std::string message("Message requiring signing")
rapidjson::Document json
Definition: transport.cpp:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_options()

void mms::message_transporter::set_options ( const std::string &  bitmessage_address,
const epee::wipeable_string bitmessage_login 
)

Definition at line 88 of file message_transporter.cpp.

89 {
90  m_bitmessage_url = bitmessage_address;
91  epee::net_utils::http::url_content address_parts{};
92  epee::net_utils::parse_url(m_bitmessage_url, address_parts);
93  if (address_parts.port == 0)
94  {
95  address_parts.port = PYBITMESSAGE_DEFAULT_API_PORT;
96  }
97  m_bitmessage_login = bitmessage_login;
98 
99  m_http_client.set_server(address_parts.host, std::to_string(address_parts.port), boost::none);
100 }
bool set_server(const std::string &address, boost::optional< login > user, ssl_options_t ssl_options=ssl_support_t::e_ssl_support_autodetect)
Definition: http_client.h:302
bool parse_url(const std::string url_str, http::url_content &content)
#define PYBITMESSAGE_DEFAULT_API_PORT
std::string to_string(t_connection_type type)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stop()

void mms::message_transporter::stop ( )
inline

Definition at line 92 of file message_transporter.h.

92 { m_run.store(false, std::memory_order_relaxed); }
Here is the caller graph for this function:

The documentation for this class was generated from the following files: