MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/communication/service/BufferedCommunicationLink.cpp
2024-06-07 11:12:56 +03:00

153 lines
4.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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) {}