153 lines
4.2 KiB
C++
153 lines
4.2 KiB
C++
|
|
/*
|
|||
|
|
* BufferedCommunicationLink.cpp
|
|||
|
|
*
|
|||
|
|
* Created on: 23 апр. 2020 г.
|
|||
|
|
* Author: LeonidTitov
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#include "BufferedCommunicationLink.hh"
|
|||
|
|
#include <climits>
|
|||
|
|
|
|||
|
|
communication::service::BufferedCommunicationLink::BufferedCommunicationLink(
|
|||
|
|
driver::ISlipCommunication & isc, std::pmr::memory_resource * memory, systemic::time_t timeout ) :
|
|||
|
|
communication(isc), free_counter(0), series(isc), subscribers( std::less<PacketId>(), memory ),
|
|||
|
|
timeout_after_send(timeout) {
|
|||
|
|
|
|||
|
|
series_timeout.start(timeout_after_send);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool communication::service::BufferedCommunicationLink::registerMessageHandler(
|
|||
|
|
IMessageHandler * handler, std::size_t packet_id ) {
|
|||
|
|
|
|||
|
|
Subscribers::iterator subscriber = subscribers.find( packet_id );
|
|||
|
|
if( subscriber == subscribers.end() ) {
|
|||
|
|
|
|||
|
|
subscribers.insert( subscriber, std::pair<const PacketId, IMessageHandler *>( packet_id, handler ) );
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void communication::service::BufferedCommunicationLink::process() {
|
|||
|
|
|
|||
|
|
std::pair<bool, unsigned short> packet_info = communication.isPacketAvailable();
|
|||
|
|
|
|||
|
|
if( packet_info.first ) {
|
|||
|
|
|
|||
|
|
free_counter++;
|
|||
|
|
|
|||
|
|
PacketId packet_id = packet_info.second;
|
|||
|
|
|
|||
|
|
Subscribers::iterator subscriber = subscribers.find( packet_id );
|
|||
|
|
|
|||
|
|
if( subscriber != subscribers.end() ) {
|
|||
|
|
MessageLink packet_handler( packet_id, communication, series );
|
|||
|
|
subscriber->second->handler( &packet_handler );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
communication.recieveReset();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( communication.isPacketSent() and series_timeout.delayFinished() ) {
|
|||
|
|
series.update();
|
|||
|
|
series_timeout.start(timeout_after_send);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
communication::IMessageSeriesLink::ostream & communication::service::BufferedCommunicationLink::Series::sendData(
|
|||
|
|
std::size_t size ) {
|
|||
|
|
|
|||
|
|
data_sent = communication.sendHead( message_id | 0x8000u, size * ( CHAR_BIT / 8 ) );
|
|||
|
|
return communication;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool communication::service::BufferedCommunicationLink::Series::charge(
|
|||
|
|
PacketId id, std::size_t num_messages, IMessageSeriesHandler * handler ) {
|
|||
|
|
|
|||
|
|
if( not message_remain ) {
|
|||
|
|
|
|||
|
|
message_id = id;
|
|||
|
|
series_handler = handler;
|
|||
|
|
message_remain = num_messages;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void communication::service::BufferedCommunicationLink::Series::update() {
|
|||
|
|
|
|||
|
|
if( series_handler and message_remain ) {
|
|||
|
|
|
|||
|
|
series_handler->handler( this );
|
|||
|
|
|
|||
|
|
if( data_sent ) {
|
|||
|
|
communication.sendEnd();
|
|||
|
|
--message_remain;
|
|||
|
|
data_sent = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
driver::IRxLink & communication::service::BufferedCommunicationLink::MessageLink::getData() {
|
|||
|
|
|
|||
|
|
return communication;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
driver::ITxLink & communication::service::BufferedCommunicationLink::MessageLink::createMessage( std::size_t size ) {
|
|||
|
|
//todo: x2???
|
|||
|
|
message_answered = communication.sendHead( message_id | 0x8000u, size * ( CHAR_BIT / 8 ) );
|
|||
|
|
return communication;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::size_t communication::service::BufferedCommunicationLink::MessageLink::transmitBuffCapacity() const {
|
|||
|
|
|
|||
|
|
return communication.transmitBuffCapacity();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::size_t communication::service::BufferedCommunicationLink::MessageLink::receiveBuffCapacity() const {
|
|||
|
|
|
|||
|
|
return communication.receiveBuffCapacity();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool communication::service::BufferedCommunicationLink::MessageLink::createMessageSeries(
|
|||
|
|
std::size_t num_messages, IMessageSeriesHandler * handler ) {
|
|||
|
|
|
|||
|
|
return series.charge(message_id, num_messages, handler);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
communication::service::BufferedCommunicationLink::MessageLink::MessageLink(
|
|||
|
|
PacketId id, driver::ISlipCommunication & com, Series & ser ) : message_id(id), communication(com), series(ser), message_answered(false) {}
|
|||
|
|
|
|||
|
|
communication::service::BufferedCommunicationLink::MessageLink::~MessageLink() noexcept {
|
|||
|
|
|
|||
|
|
if( not message_answered )
|
|||
|
|
communication.sendHead( message_id | 0x8000u, 0 );
|
|||
|
|
|
|||
|
|
communication.sendEnd();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float communication::service::BufferedCommunicationLink::getPacketCounter() const {
|
|||
|
|
|
|||
|
|
return free_counter;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
communication::service::BufferedCommunicationLink::Series::Series(
|
|||
|
|
driver::ISlipCommunication & com ) :
|
|||
|
|
communication(com), data_sent(false), message_id(), message_remain(0), series_handler(nullptr) {}
|