1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#include "minicom_client.h"
CMinicomClient::CMinicomClient(boost::asio::io_service& io_service, unsigned int baud, const std::string& device,
serial_port::parity::type parity, serial_port::stop_bits::type stop_bits)
: m_active(true),
m_io_service(io_service),
m_serial_port(io_service, device),
m_operation_in_progress(false)
{
if (!m_serial_port.is_open() )
{
std::cerr << "Failed to open serial port\n";
return;
}
m_serial_port.set_option( boost::asio::serial_port::baud_rate(baud ) );
m_serial_port.set_option( boost::asio::serial_port::flow_control (boost::asio::serial_port::flow_control::none ) );
m_serial_port.set_option( boost::asio::serial_port::parity (parity) );
m_serial_port.set_option( boost::asio::serial_port::stop_bits (stop_bits) );
m_serial_port.set_option( boost::asio::serial_port::character_size ( 8 ) );
read_start();
}
CMinicomClient::~CMinicomClient()
{
}
void CMinicomClient::Write(const char msg)
{
m_io_service.post(boost::bind(&CMinicomClient::do_write, this, msg));
}
void CMinicomClient::Close()
{
m_io_service.post(boost::bind(&CMinicomClient::do_close, this, boost::system::error_code()));
}
bool CMinicomClient::Active()
{
return m_active;
}
void CMinicomClient::read_start(void)
{
// Start an asynchronous read and call read_complete when it completes or fails
m_serial_port.async_read_some(boost::asio::buffer(m_read_msg, max_read_length),
boost::bind(&CMinicomClient::read_complete,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void CMinicomClient::read_complete(const boost::system::error_code& error, size_t bytes_transferred)
{
// the asynchronous read operation has now completed or failed and returned an error
m_operation_in_progress = false;
if (!error)
{ // read completed, so process the data
m_new_message_signal(m_read_msg, bytes_transferred);
read_start(); // start waiting for another asynchronous read again
}
else
do_close(error);
}
void CMinicomClient::do_write(const char msg)
{
// callback to handle write call from outside this class
bool write_in_progress = !m_write_msgs.empty(); // is there anything currently being written?
m_write_msgs.push_back(msg); // store in write buffer
if (!write_in_progress) // if nothing is currently being written, then start
write_start();
}
void CMinicomClient::write_start(void)
{
// Start an asynchronous write and call write_complete when it completes or fails
m_operation_in_progress = true;
boost::asio::async_write(m_serial_port,
boost::asio::buffer(&m_write_msgs.front(), 1),
boost::bind(&CMinicomClient::write_complete,
this,
boost::asio::placeholders::error));
}
void CMinicomClient::write_complete(const boost::system::error_code& error)
{
// the asynchronous read operation has now completed or failed and returned an error
if (!error)
{ // write completed, so send next write data
m_write_msgs.pop_front(); // remove the completed data
if (!m_write_msgs.empty()) // if there is anthing left to be written
write_start(); // then start sending the next item in the buffer
}
else
{
do_close(error);
}
}
void CMinicomClient::do_close(const boost::system::error_code& error)
{
// something has gone wrong, so close the socket & make this object inactive
if (error == boost::asio::error::operation_aborted) // if this call is the result of a timer cancel()
return; // ignore it because the connection cancelled the timer
if (error)
std::cerr << "Error: " << error.message() << std::endl; // show the error message
else
std::cout << "Error: Connection did not succeed.\n";
std::cout << "Press Enter to exit\n";
m_serial_port.close();
m_active = false;
}
void CMinicomClient::WritePacket(const std::vector<char>& vect)
{
// Lock writing
m_operation_in_progress = true;
// Write packet
for (auto iter = vect.begin(); iter != vect.end(); ++iter)
{
Write(*iter);
}
}
boost::signals2::connection CMinicomClient::OnNewData(const msg_signal::slot_type& slot)
{
return m_new_message_signal.connect(slot);
} |
Partager