#include #include #include #include #include "SerialClient.hpp" #include "ByteSink.hpp" #include "ByteSource.hpp" SerialClient::SerialClient( std::string const& port, boost::shared_ptr handler ) : m_port( m_service, port ) , m_handler( handler ) , m_serviceThread( boost::bind( &SerialClient::ServiceThread, this ) ) { if( !m_port.is_open() ) { throw std::exception( "Failed to open specified COM port" ); } // Start continuous reads on the port m_service.post( boost::bind( &SerialClient::DoRead, this ) ); } SerialClient::~SerialClient() { m_serviceThread.interrupt(); m_serviceThread.join(); } void SerialClient::Write( ByteSink& data ) { m_service.post( boost::bind( &SerialClient::DoWrite, this, data ) ); } void SerialClient::DoWrite( ByteSink& data ) { boost::asio::async_write( m_port, boost::asio::buffer( data.GetContainer() ), boost::bind( &SerialClient::WriteCompleted, this, boost::asio::placeholders::error ) ); } void SerialClient::WriteCompleted( boost::system::error_code const& error ) { if( error ) { m_handler->WriteFailed(); } else { m_handler->WriteCompleted(); } } void SerialClient::ServiceThread() { for(;;) { boost::this_thread::sleep( boost::posix_time::milliseconds( 20 ) ); m_service.run(); } } void SerialClient::DoRead() { using boost::asio::placeholders::error; using boost::asio::placeholders::bytes_transferred; ByteSource source; m_port.async_read_some( boost::asio::buffer( source.GetContainer() ), boost::bind( &SerialClient::ReadCompleted, this, source, error, bytes_transferred ) ); } void SerialClient::ReadCompleted( ByteSource& source, boost::system::error_code const& error, std::size_t bytes_transferred ) { if( !error ) { if( bytes_transferred ) { m_handler->ReadCompleted( source ); } //m_service.post( boost::bind( &SerialClient::DoRead, this ) ); } else { m_handler->ReadFailed(); } }