37 #ifndef HDLCD_CLIENT_H 38 #define HDLCD_CLIENT_H 40 #include <boost/asio.hpp> 65 m_IOService(a_IOService),
66 m_SerialPortName(a_SerialPortName),
67 m_HdlcdSessionDescriptor(a_HdlcdSessionDescriptor),
69 m_TcpSocketData(a_IOService),
70 m_TcpSocketCtrl(a_IOService),
71 m_eTcpSocketDataState(SOCKET_STATE_ERROR),
72 m_eTcpSocketCtrlState(SOCKET_STATE_ERROR) {
82 void AsyncConnect(boost::asio::ip::tcp::resolver::iterator a_EndpointIterator, std::function<
void(
bool a_bSuccess)> a_OnConnectedCallback) {
84 assert(a_OnConnectedCallback);
85 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
86 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
89 m_OnConnectedCallback = a_OnConnectedCallback;
90 m_eTcpSocketDataState = SOCKET_STATE_CONNECTING;
91 boost::asio::async_connect(m_TcpSocketData, a_EndpointIterator, [
this](boost::system::error_code a_ErrorCode, boost::asio::ip::tcp::resolver::iterator) {
92 if (a_ErrorCode == boost::asio::error::operation_aborted)
return;
94 OnTcpSocketDataConnected(
false);
96 OnTcpSocketDataConnected(
true);
101 m_eTcpSocketCtrlState = SOCKET_STATE_CONNECTING;
102 boost::asio::async_connect(m_TcpSocketCtrl, a_EndpointIterator, [
this](boost::system::error_code a_ErrorCode, boost::asio::ip::tcp::resolver::iterator) {
103 if (a_ErrorCode == boost::asio::error::operation_aborted)
return;
105 OnTcpSocketCtrlConnected(
false);
107 OnTcpSocketCtrlConnected(
true);
117 m_OnDataCallback =
nullptr;
118 m_OnCtrlCallback =
nullptr;
119 m_OnClosedCallback =
nullptr;
128 if (m_PacketEndpointData) {
129 m_PacketEndpointData->Shutdown();
132 if (m_PacketEndpointCtrl) {
133 m_PacketEndpointCtrl->Shutdown();
142 if (m_bClosed ==
false) {
144 if (m_PacketEndpointData) {
145 m_PacketEndpointData->Close();
146 m_PacketEndpointData.reset();
148 m_TcpSocketData.cancel();
149 m_TcpSocketData.close();
152 if (m_PacketEndpointCtrl) {
153 m_PacketEndpointCtrl->Close();
154 m_PacketEndpointCtrl.reset();
156 m_TcpSocketCtrl.cancel();
157 m_TcpSocketCtrl.close();
160 if (m_OnClosedCallback) {
161 m_OnClosedCallback();
173 m_OnDataCallback = a_OnDataCallback;
183 m_OnCtrlCallback = a_OnCtrlCallback;
193 m_OnClosedCallback = a_OnClosedCallback;
204 bool l_bRetVal =
false;
205 if (m_PacketEndpointData) {
206 l_bRetVal = m_PacketEndpointData->Send(a_PacketData, a_OnSendDoneCallback);
208 if (a_OnSendDoneCallback) {
209 m_IOService.post([a_OnSendDoneCallback](){ a_OnSendDoneCallback(); });
224 bool l_bRetVal =
false;
225 if (m_PacketEndpointCtrl) {
226 l_bRetVal= m_PacketEndpointCtrl->Send(a_PacketCtrl, a_OnSendDoneCallback);
228 if (a_OnSendDoneCallback) {
229 m_IOService.post([a_OnSendDoneCallback](){ a_OnSendDoneCallback(); });
243 void OnTcpSocketDataConnected(
bool l_bSuccess) {
245 assert(m_eTcpSocketDataState == SOCKET_STATE_CONNECTING);
247 m_eTcpSocketDataState = SOCKET_STATE_CONNECTED;
249 m_eTcpSocketDataState = SOCKET_STATE_ERROR;
252 OnTcpSocketConnected();
261 void OnTcpSocketCtrlConnected(
bool l_bSuccess) {
263 assert(m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING);
265 m_eTcpSocketCtrlState = SOCKET_STATE_CONNECTED;
267 m_eTcpSocketCtrlState = SOCKET_STATE_ERROR;
270 OnTcpSocketConnected();
277 void OnTcpSocketConnected() {
279 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTING) && (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING)) {
285 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTED) && (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTED)) {
288 m_PacketEndpointData = std::make_shared<HdlcdPacketEndpoint>(m_IOService, std::make_shared<FrameEndpoint>(m_IOService, m_TcpSocketData));
289 m_PacketEndpointData->SetOnDataCallback([
this](std::shared_ptr<const HdlcdPacketData> a_PacketData){
return OnDataReceived(a_PacketData); });
290 m_PacketEndpointData->SetOnClosedCallback([
this](){ OnClosed(); });
291 m_PacketEndpointData->Start();
295 m_PacketEndpointCtrl = std::make_shared<HdlcdPacketEndpoint>(m_IOService, std::make_shared<FrameEndpoint>(m_IOService, m_TcpSocketCtrl));
296 m_PacketEndpointCtrl->SetOnCtrlCallback([
this](
const HdlcdPacketCtrl& a_PacketCtrl){
return OnCtrlReceived(a_PacketCtrl); });
297 m_PacketEndpointCtrl->SetOnClosedCallback([
this](){ OnClosed(); });
298 m_PacketEndpointCtrl->Start();
300 m_OnConnectedCallback(
true);
304 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTING) || (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING)) {
310 if (m_eTcpSocketDataState == SOCKET_STATE_CONNECTED) {
312 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
313 m_eTcpSocketDataState = SOCKET_STATE_ERROR;
314 m_TcpSocketData.close();
315 m_OnConnectedCallback(
false);
319 if (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTED) {
321 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
322 m_eTcpSocketCtrlState = SOCKET_STATE_ERROR;
323 m_TcpSocketCtrl.close();
324 m_OnConnectedCallback(
false);
329 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
330 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
331 m_OnConnectedCallback(
false);
341 bool OnDataReceived(std::shared_ptr<const HdlcdPacketData> a_PacketData) {
342 if (m_OnDataCallback) {
343 m_OnDataCallback(*(a_PacketData.get()));
356 if (m_OnCtrlCallback) {
357 m_OnCtrlCallback(a_PacketCtrl);
370 boost::asio::io_service& m_IOService;
371 const std::string m_SerialPortName;
375 std::function<void(bool a_bSuccess)> m_OnConnectedCallback;
376 boost::asio::ip::tcp::socket m_TcpSocketData;
377 boost::asio::ip::tcp::socket m_TcpSocketCtrl;
379 SOCKET_STATE_ERROR = 0,
380 SOCKET_STATE_CONNECTING = 1,
381 SOCKET_STATE_CONNECTED = 2,
383 E_SOCKET_STATE m_eTcpSocketDataState;
384 E_SOCKET_STATE m_eTcpSocketCtrlState;
386 std::shared_ptr<HdlcdPacketEndpoint> m_PacketEndpointData;
387 std::shared_ptr<HdlcdPacketEndpoint> m_PacketEndpointCtrl;
390 std::function<void(const HdlcdPacketData&)> m_OnDataCallback;
391 std::function<void(const HdlcdPacketCtrl&)> m_OnCtrlCallback;
392 std::function<void()> m_OnClosedCallback;
395 #endif // HDLCD_CLIENT_H
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.
void AsyncConnect(boost::asio::ip::tcp::resolver::iterator a_EndpointIterator, std::function< void(bool a_bSuccess)> a_OnConnectedCallback)
Perform an asynchronous connect procedure regarding both TCP sockets.
bool Send(const HdlcdPacketData &a_PacketData, std::function< void()> a_OnSendDoneCallback=nullptr)
Send a single data packet to the peer entity.
~HdlcdClient()
The destructor of HdlcdClient objects.
void Shutdown()
Shuts all TCP connections down.
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.
void SetOnCtrlCallback(std::function< void(const HdlcdPacketCtrl &a_PacketCtrl)> a_OnCtrlCallback)
Provide a callback method to be called for received control packets.
void SetOnClosedCallback(std::function< void()> a_OnClosedCallback)
Provide a callback method to be called if this client entity is closing.
void SetOnDataCallback(std::function< void(const HdlcdPacketData &a_PacketData)> a_OnDataCallback)
Provide a callback method to be called for received data packets.
HdlcdClient(boost::asio::io_service &a_IOService, const std::string &a_SerialPortName, HdlcdSessionDescriptor a_HdlcdSessionDescriptor)
The constructor of HdlcdClient objects.
bool Send(const HdlcdPacketCtrl &a_PacketCtrl, std::function< void()> a_OnSendDoneCallback=nullptr)
Send a single control packet to the peer entity.
void Close()
Close the client entity.
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.