Satellite-Gateway
HdlcdClientHandler.cpp
Go to the documentation of this file.
1 
24 #include "HdlcdClientHandler.h"
27 #include "HdlcdClient.h"
28 #include <assert.h>
29 
30 HdlcdClientHandler::HdlcdClientHandler(boost::asio::io_service& a_IOService, std::shared_ptr<ConfigServerHandlerCollection> a_ConfigServerHandlerCollection,
31  std::shared_ptr<GatewayClientHandlerCollection> a_GatewayClientHandlerCollection, const std::string& a_RemoteAddress,
32  uint16_t a_TcpPortNbr, uint16_t a_SerialPortNbr): m_IOService(a_IOService), m_ConfigServerHandlerCollection(a_ConfigServerHandlerCollection),
33  m_GatewayClientHandlerCollection(a_GatewayClientHandlerCollection), m_HdlcdClientConnectGuard(a_ConfigServerHandlerCollection, a_SerialPortNbr),
34  m_RemoteAddress(a_RemoteAddress), m_TcpPortNbr(a_TcpPortNbr), m_SerialPortNbr(a_SerialPortNbr), m_Resolver(a_IOService), m_ConnectionRetryTimer(a_IOService) {
35  // Checks
36  assert(m_ConfigServerHandlerCollection);
37  assert(m_GatewayClientHandlerCollection);
38 
39  // Trigger activity
40  m_bSuspendSerialPort = false;
41  ResolveDestination();
42 }
43 
45  // Drop all shared pointers
46  m_ConfigServerHandlerCollection.reset();
47  m_GatewayClientHandlerCollection.reset();
48 }
49 
51  // Send a control packet to the HDLC daemon to suspend the serial device
52  m_bSuspendSerialPort = true;
53  if (m_HdlcdClient) {
54  // No problem if sent multiple times
55  m_HdlcdClient->Send(HdlcdPacketCtrl::CreatePortStatusRequest(true));
56  } // if
57 }
58 
60  // Send a control packet to the HDLC daemon to resume the serial device
61  m_bSuspendSerialPort = false;
62  if (m_HdlcdClient) {
63  // No problem if sent multiple times
64  m_HdlcdClient->Send(HdlcdPacketCtrl::CreatePortStatusRequest(false));
65  } // if
66 }
67 
68 void HdlcdClientHandler::SendPacket(const std::vector<unsigned char> &a_Payload) {
69  // Send a data packet to the HDLC daemon to deliver the payload via an HDLC I-frame
70  if ((m_HdlcdClient) && (!m_bSuspendSerialPort)) {
71  // Deliver
72  m_HdlcdClient->Send(HdlcdPacketData::CreatePacket(a_Payload, true));
73  } else {
74  // Drop silently
75  } // else
76 }
77 
78 void HdlcdClientHandler::ResolveDestination() {
79  std::stringstream l_OStream;
80  l_OStream << m_TcpPortNbr;
81  m_Resolver.async_resolve({m_RemoteAddress, l_OStream.str()}, [this](const boost::system::error_code& a_ErrorCode, boost::asio::ip::tcp::resolver::iterator a_EndpointIterator) {
82  if (a_ErrorCode) {
83  std::cout << "Failed to resolve host name: " << m_RemoteAddress << std::endl;
84  m_ConnectionRetryTimer.expires_from_now(boost::posix_time::seconds(2));
85  m_ConnectionRetryTimer.async_wait([this](const boost::system::error_code& a_ErrorCode) {
86  if (!a_ErrorCode) {
87  // Reestablish the connection to the HDLC Daemon
88  ResolveDestination();
89  } // if
90  }); // async_wait
91  } else {
92  // Start the HDLCd access client. On any error, restart after a short delay
93  std::stringstream l_OStream;
94  l_OStream << "/dev/ttyUSB" << m_SerialPortNbr;
95  m_HdlcdClient = std::make_shared<HdlcdClient>(m_IOService, l_OStream.str(), HdlcdSessionDescriptor(SESSION_TYPE_TRX_ALL, SESSION_FLAGS_DELIVER_RCVD));
96  m_HdlcdClient->SetOnClosedCallback([this]() {
97  m_HdlcdClientConnectGuard.IsDisconnected();
98  m_ConnectionRetryTimer.expires_from_now(boost::posix_time::seconds(2));
99  m_ConnectionRetryTimer.async_wait([this](const boost::system::error_code& a_ErrorCode) {
100  if (!a_ErrorCode) {
101  // Reestablish the connection to the HDLC Daemon
102  ResolveDestination();
103  } // if
104  }); // async_wait
105  }); // SetOnClosedCallback
106 
107  m_HdlcdClient->SetOnDataCallback([this](const HdlcdPacketData& a_PacketData) {
108  // Deliver the payload
109  m_GatewayClientHandlerCollection->SendPacket(m_SerialPortNbr, a_PacketData.GetData());
110  }); // SetOnDataCallback
111 
112  m_HdlcdClient->SetOnCtrlCallback([this](const HdlcdPacketCtrl& a_PacketCtrl) {
114  // Update the state of the serial port
115  m_HdlcdClientConnectGuard.IsConnected();
116  m_ConfigServerHandlerCollection->HdlcdClientNewStatus(m_SerialPortNbr, ((!a_PacketCtrl.GetIsLockedBySelf()) && (!a_PacketCtrl.GetIsLockedByOthers())), a_PacketCtrl.GetIsAlive());
117  } // if
118  }); // SetOnCtrlCallback
119 
120  // Connect
121  m_HdlcdClient->AsyncConnect(a_EndpointIterator, [this](bool a_bSuccess) {
122  if (a_bSuccess) {
123  if (m_bSuspendSerialPort) {
124  // Immediately send a serial port suspend request message to the HDLC daemon
125  m_HdlcdClient->Send(HdlcdPacketCtrl::CreatePortStatusRequest(true));
126  } // if
127  } else {
128  // Failed to connect to the HDLCd
129  m_HdlcdClientConnectGuard.IsDisconnected();
130  m_ConnectionRetryTimer.expires_from_now(boost::posix_time::seconds(2));
131  m_ConnectionRetryTimer.async_wait([this](const boost::system::error_code& a_ErrorCode) {
132  if (!a_ErrorCode) {
133  // Reestablish the connection to the HDLC Daemon
134  ResolveDestination();
135  } // if
136  }); // async_wait
137  } // else
138  }); // AsyncConnect
139  } // else
140  }); // async_resolve
141 }
bool GetIsAlive() const
static HdlcdPacketData CreatePacket(const std::vector< unsigned char > a_Payload, bool a_bReliable, bool a_bInvalid=false, bool a_bWasSent=false)
Deliver data packets sent by the device and received by the HDLCd.
Payload, data read and write, port status read and write.
const std::vector< unsigned char > & GetData() const
static HdlcdPacketCtrl CreatePortStatusRequest(bool a_bLockSerialPort)
HdlcdClientHandler(boost::asio::io_service &a_IOService, std::shared_ptr< ConfigServerHandlerCollection > a_ConfigServerHandlerCollection, std::shared_ptr< GatewayClientHandlerCollection > a_GatewayClientHandlerCollection, const std::string &a_RemoteAddress, uint16_t a_TcpPortNbr, uint16_t a_SerialPortNbr)
This file contains the header declaration of class HdlcdClient.
E_CTRL_TYPE GetPacketType() const
bool GetIsLockedBySelf() const
void SendPacket(const std::vector< unsigned char > &a_Payload)
bool GetIsLockedByOthers() const
Class HdlcdSessionDescriptor.