33 HdlcdServerHandler::HdlcdServerHandler(boost::asio::io_service& a_IOService, std::weak_ptr<HdlcdServerHandlerCollection> a_HdlcdServerHandlerCollection, boost::asio::ip::tcp::socket& a_TcpSocket): m_IOService(a_IOService), m_HdlcdServerHandlerCollection(a_HdlcdServerHandlerCollection) {
36 m_bDeliverInitialState =
true;
38 m_bDeliverSent =
false;
39 m_bDeliverRcvd =
false;
40 m_bDeliverInvalidData =
false;
41 m_bSerialPortHandlerAwaitsPacket =
false;
44 m_FrameEndpoint = std::make_shared<FrameEndpoint>(a_IOService, a_TcpSocket);
46 m_FrameEndpoint->SetOnFrameCallback([
this](std::shared_ptr<Frame> a_Frame)->
bool{
return OnFrame(a_Frame); });
47 m_FrameEndpoint->SetOnClosedCallback ([
this](){ OnClosed(); });
52 bool l_bDeliver = (a_eBufferType == m_eBufferType);
53 if ((a_bWasSent && !m_bDeliverSent) || (!a_bWasSent && !m_bDeliverRcvd)) {
57 if ((m_bDeliverInvalidData ==
false) && (a_bInvalid)) {
67 bool l_bDeliverChangedState = m_bDeliverInitialState;
68 m_bDeliverInitialState =
false;
71 if (l_bDeliverChangedState) {
79 assert(a_bQueryReliable || a_bQueryUnreliable);
86 if (m_PendingIncomingPacketData) {
87 bool l_bDeliver = (a_bQueryReliable && m_PendingIncomingPacketData->GetReliable());
88 l_bDeliver |= (a_bQueryUnreliable && !m_PendingIncomingPacketData->GetReliable());
90 m_SerialPortHandler->DeliverPayloadToHDLC(m_PendingIncomingPacketData->GetData(), m_PendingIncomingPacketData->GetReliable());
91 m_PendingIncomingPacketData.reset();
92 m_PacketEndpoint->TriggerNextDataPacket();
96 m_bSerialPortHandlerAwaitsPacket =
true;
97 m_PacketEndpoint->TriggerNextDataPacket();
102 assert(m_Registered ==
false);
103 assert(a_SerialPortHandlerCollection);
104 m_SerialPortHandlerCollection = a_SerialPortHandlerCollection;
105 if (
auto lock = m_HdlcdServerHandlerCollection.lock()) {
107 m_bSerialPortHandlerAwaitsPacket =
true;
108 lock->RegisterHdlcdServerHandler(shared_from_this());
114 m_FrameEndpoint->Start();
119 auto self(shared_from_this());
120 m_SerialPortHandler.reset();
122 m_Registered =
false;
123 m_bSerialPortHandlerAwaitsPacket =
false;
124 if (m_PacketEndpoint) {
125 assert(!m_FrameEndpoint);
126 m_PacketEndpoint->Close();
127 m_PacketEndpoint.reset();
129 m_FrameEndpoint->Shutdown();
130 m_FrameEndpoint->Close();
131 m_FrameEndpoint.reset();
134 if (
auto lock = m_HdlcdServerHandlerCollection.lock()) {
135 lock->DeregisterHdlcdServerHandler(
self);
140 bool HdlcdServerHandler::OnFrame(
const std::shared_ptr<Frame> a_Frame) {
143 assert(m_FrameEndpoint);
144 assert(!m_PacketEndpoint);
148 if (l_HdlcdSessionHeader) {
151 switch (l_SAP & 0xF0) {
174 std::cerr <<
"Unknown session type rejected: " << (int)(l_SAP & 0xF0) << std::endl;
182 std::cerr <<
"Invalid reserved bit within SAP specifier of session header: " << (int)l_SAP << std::endl;
188 m_bDeliverInvalidData = (l_SAP & 0x04);
189 m_bDeliverSent = (l_SAP & 0x02);
190 m_bDeliverRcvd = (l_SAP & 0x01);
193 m_PacketEndpoint = std::make_shared<HdlcdPacketEndpoint>(m_IOService, m_FrameEndpoint);
194 m_PacketEndpoint->SetOnDataCallback([
this](std::shared_ptr<const HdlcdPacketData> a_PacketData){
return OnDataReceived(a_PacketData); });
195 m_PacketEndpoint->SetOnCtrlCallback([
this](
const HdlcdPacketCtrl& a_PacketCtrl){ OnCtrlReceived(a_PacketCtrl); });
196 m_PacketEndpoint->SetOnClosedCallback([
this](){ OnClosed(); });
197 m_FrameEndpoint.reset();
198 auto l_SerialPortHandlerStopper = m_SerialPortHandlerCollection->GetSerialPortHandler(l_HdlcdSessionHeader->GetSerialPortName(), shared_from_this());
199 if (l_SerialPortHandlerStopper) {
200 m_SerialPortHandlerStopper = l_SerialPortHandlerStopper;
201 m_SerialPortHandler = (*m_SerialPortHandlerStopper.get());
202 m_LockGuard.
Init(m_SerialPortHandler);
203 m_SerialPortHandler->PropagateSerialPortState();
204 m_PacketEndpoint->Start();
218 bool HdlcdServerHandler::OnDataReceived(std::shared_ptr<const HdlcdPacketData> a_PacketData) {
220 assert(a_PacketData);
221 assert(!m_PendingIncomingPacketData);
224 m_PendingIncomingPacketData = a_PacketData;
225 if (m_bSerialPortHandlerAwaitsPacket) {
227 m_bSerialPortHandlerAwaitsPacket =
false;
228 m_SerialPortHandler->DeliverPayloadToHDLC(m_PendingIncomingPacketData->GetData(), m_PendingIncomingPacketData->GetReliable());
229 m_PendingIncomingPacketData.reset();
237 void HdlcdServerHandler::OnCtrlReceived(
const HdlcdPacketCtrl& a_PacketCtrl) {
252 m_PacketEndpoint->Send(a_PacketCtrl);
257 m_SerialPortHandler->Stop();
265 void HdlcdServerHandler::OnClosed() {
The HDLC Deamon implements the HDLC protocol to easily talk to devices connected via serial communica...
This file contains the header declaration of class FrameEndpoint.
The HDLC Deamon implements the HDLC protocol to easily talk to devices connected via serial communica...
static HdlcdPacketData CreatePacket(const std::vector< unsigned char > a_Payload, bool a_bReliable, bool a_bInvalid=false, bool a_bWasSent=false)
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 Start(std::shared_ptr< SerialPortHandlerCollection > a_SerialPortHandlerCollection)
bool IsLockedByOthers() const
Query whether the serial device is currently "locked" by at least one other AccessClient entity...
bool UpdateSerialPortState(bool a_bAlive)
Change the serial port state.
bool IsAlive() const
Query whether the related serial port is currently alive.
bool IsLockedBySelf() const
Query whether the serial device is currently "locked" by the responsible AccessClient entity...
bool GetDesiredLockState() const
bool UpdateSerialPortState(size_t a_LockHolders)
Update the effective lock state of the related serial port.
static HdlcdPacketCtrl CreatePortStatusResponse(bool a_bIsAlive, bool a_bIsLockedByOthers, bool a_bIsLockedBySelf)
void Init(std::shared_ptr< SerialPortHandler > a_SerialPortHandler)
Initializer method to register subsequent objects.
E_CTRL_TYPE GetPacketType() const
void QueryForPayload(bool a_bQueryReliable, bool a_bQueryUnreliable)
void DeliverBufferToClient(E_BUFFER_TYPE a_eBufferType, const std::vector< unsigned char > &a_Payload, bool a_bReliable, bool a_bInvalid, bool a_bWasSent)
HdlcdServerHandler(boost::asio::io_service &a_IOService, std::weak_ptr< HdlcdServerHandlerCollection > a_HdlcdServerHandlerCollection, boost::asio::ip::tcp::socket &a_TcpSocket)
The HDLC Deamon implements the HDLC protocol to easily talk to devices connected via serial communica...
void UpdateSerialPortState(bool a_bAlive, size_t a_LockHolders)
The HDLC Deamon implements the HDLC protocol to easily talk to devices connected via serial communica...
void AcquireLock()
Method to aquire a lock.
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.
void ReleaseLock()
Method to release a lock.