39 #ifndef HDLCD_CLIENT_H 40 #define HDLCD_CLIENT_H 42 #include <boost/asio.hpp> 69 m_IOService(a_IOService),
70 m_SerialPortName(a_SerialPortName),
71 m_HdlcdSessionDescriptor(a_HdlcdSessionDescriptor),
73 m_TcpSocketData(a_IOService),
74 m_TcpSocketCtrl(a_IOService),
75 m_eTcpSocketDataState(SOCKET_STATE_ERROR),
76 m_eTcpSocketCtrlState(SOCKET_STATE_ERROR) {
84 void AsyncConnect(boost::asio::ip::tcp::resolver::iterator a_EndpointIterator, std::function<
void(
bool a_bSuccess)> a_OnConnectedCallback) {
86 assert(a_OnConnectedCallback);
87 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
88 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
91 m_OnConnectedCallback = a_OnConnectedCallback;
92 m_eTcpSocketDataState = SOCKET_STATE_CONNECTING;
93 boost::asio::async_connect(m_TcpSocketData, a_EndpointIterator, [
this](boost::system::error_code a_ErrorCode, boost::asio::ip::tcp::resolver::iterator) {
94 if (a_ErrorCode == boost::asio::error::operation_aborted)
return;
96 OnTcpSocketDataConnected(
false);
98 OnTcpSocketDataConnected(
true);
103 m_eTcpSocketCtrlState = SOCKET_STATE_CONNECTING;
104 boost::asio::async_connect(m_TcpSocketCtrl, a_EndpointIterator, [
this](boost::system::error_code a_ErrorCode, boost::asio::ip::tcp::resolver::iterator) {
105 if (a_ErrorCode == boost::asio::error::operation_aborted)
return;
107 OnTcpSocketCtrlConnected(
false);
109 OnTcpSocketCtrlConnected(
true);
119 m_OnDataCallback =
nullptr;
120 m_OnCtrlCallback =
nullptr;
121 m_OnClosedCallback =
nullptr;
130 if (m_PacketEndpointData) {
131 m_PacketEndpointData->Shutdown();
134 if (m_PacketEndpointCtrl) {
135 m_PacketEndpointCtrl->Shutdown();
144 if (m_bClosed ==
false) {
146 if (m_PacketEndpointData) {
147 m_PacketEndpointData->Close();
148 m_PacketEndpointData.reset();
150 m_TcpSocketData.cancel();
151 m_TcpSocketData.close();
154 if (m_PacketEndpointCtrl) {
155 m_PacketEndpointCtrl->Close();
156 m_PacketEndpointCtrl.reset();
158 m_TcpSocketCtrl.cancel();
159 m_TcpSocketCtrl.close();
162 if (m_OnClosedCallback) {
163 m_OnClosedCallback();
175 m_OnDataCallback = a_OnDataCallback;
185 m_OnCtrlCallback = a_OnCtrlCallback;
195 m_OnClosedCallback = a_OnClosedCallback;
210 bool l_bRetVal =
false;
211 if (m_PacketEndpointData) {
212 l_bRetVal = m_PacketEndpointData->Send(a_PacketData, a_OnSendDoneCallback);
214 if (a_OnSendDoneCallback) {
215 m_IOService.post([a_OnSendDoneCallback](){ a_OnSendDoneCallback(); });
234 bool l_bRetVal =
false;
235 if (m_PacketEndpointCtrl) {
236 l_bRetVal= m_PacketEndpointCtrl->Send(a_PacketCtrl, a_OnSendDoneCallback);
238 if (a_OnSendDoneCallback) {
239 m_IOService.post([a_OnSendDoneCallback](){ a_OnSendDoneCallback(); });
253 void OnTcpSocketDataConnected(
bool l_bSuccess) {
255 assert(m_eTcpSocketDataState == SOCKET_STATE_CONNECTING);
257 m_eTcpSocketDataState = SOCKET_STATE_CONNECTED;
259 m_eTcpSocketDataState = SOCKET_STATE_ERROR;
262 OnTcpSocketConnected();
271 void OnTcpSocketCtrlConnected(
bool l_bSuccess) {
273 assert(m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING);
275 m_eTcpSocketCtrlState = SOCKET_STATE_CONNECTED;
277 m_eTcpSocketCtrlState = SOCKET_STATE_ERROR;
280 OnTcpSocketConnected();
287 void OnTcpSocketConnected() {
289 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTING) && (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING)) {
295 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTED) && (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTED)) {
298 m_PacketEndpointData = std::make_shared<HdlcdPacketEndpoint>(m_IOService, std::make_shared<FrameEndpoint>(m_IOService, m_TcpSocketData));
299 m_PacketEndpointData->SetOnDataCallback([
this](std::shared_ptr<const HdlcdPacketData> a_PacketData){
return OnDataReceived(a_PacketData); });
300 m_PacketEndpointData->SetOnClosedCallback([
this](){ OnClosed(); });
301 m_PacketEndpointData->Start();
305 m_PacketEndpointCtrl = std::make_shared<HdlcdPacketEndpoint>(m_IOService, std::make_shared<FrameEndpoint>(m_IOService, m_TcpSocketCtrl));
306 m_PacketEndpointCtrl->SetOnCtrlCallback([
this](
const HdlcdPacketCtrl& a_PacketCtrl){
return OnCtrlReceived(a_PacketCtrl); });
307 m_PacketEndpointCtrl->SetOnClosedCallback([
this](){ OnClosed(); });
308 m_PacketEndpointCtrl->Start();
310 m_OnConnectedCallback(
true);
314 if ((m_eTcpSocketDataState == SOCKET_STATE_CONNECTING) || (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTING)) {
320 if (m_eTcpSocketDataState == SOCKET_STATE_CONNECTED) {
322 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
323 m_eTcpSocketDataState = SOCKET_STATE_ERROR;
324 m_TcpSocketData.close();
325 m_OnConnectedCallback(
false);
329 if (m_eTcpSocketCtrlState == SOCKET_STATE_CONNECTED) {
331 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
332 m_eTcpSocketCtrlState = SOCKET_STATE_ERROR;
333 m_TcpSocketCtrl.close();
334 m_OnConnectedCallback(
false);
339 assert(m_eTcpSocketDataState == SOCKET_STATE_ERROR);
340 assert(m_eTcpSocketCtrlState == SOCKET_STATE_ERROR);
341 m_OnConnectedCallback(
false);
355 bool OnDataReceived(std::shared_ptr<const HdlcdPacketData> a_PacketData) {
356 if (m_OnDataCallback) {
357 m_OnDataCallback(*(a_PacketData.get()));
371 if (m_OnCtrlCallback) {
372 m_OnCtrlCallback(a_PacketCtrl);
385 boost::asio::io_service& m_IOService;
386 const std::string m_SerialPortName;
390 std::function<void(bool a_bSuccess)> m_OnConnectedCallback;
391 boost::asio::ip::tcp::socket m_TcpSocketData;
392 boost::asio::ip::tcp::socket m_TcpSocketCtrl;
394 SOCKET_STATE_ERROR = 0,
395 SOCKET_STATE_CONNECTING = 1,
396 SOCKET_STATE_CONNECTED = 2,
398 E_SOCKET_STATE m_eTcpSocketDataState;
399 E_SOCKET_STATE m_eTcpSocketCtrlState;
401 std::shared_ptr<HdlcdPacketEndpoint> m_PacketEndpointData;
402 std::shared_ptr<HdlcdPacketEndpoint> m_PacketEndpointCtrl;
405 std::function<void(const HdlcdPacketData&)> m_OnDataCallback;
406 std::function<void(const HdlcdPacketCtrl&)> m_OnCtrlCallback;
407 std::function<void()> m_OnClosedCallback;
410 #endif // HDLCD_CLIENT_H
This file contains the header declaration of class FrameEndpoint.
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.
Port status only, no data exchange, port status read and write.
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.
Class HdlcdSessionDescriptor.