1
0
forked from fsfw/fsfw

message arriving.

big clean up in tcdistribution folder
This commit is contained in:
2020-07-08 02:20:38 +02:00
parent 399fc0e287
commit 2efcda735f
12 changed files with 253 additions and 174 deletions

View File

@ -1,6 +1,7 @@
#include <framework/osal/linux/TcUnixUdpPollingTask.h>
#include <framework/globalfunctions/arrayprinter.h>
TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId,
TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId,
object_id_t tmtcUnixUdpBridge, size_t frameSize,
double timeoutSeconds): SystemObject(objectId),
tmtcBridgeId(tmtcUnixUdpBridge) {
@ -23,23 +24,13 @@ TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId,
else {
receptionTimeout = timevalOperations::toTimeval(timeoutSeconds);
}
// Set receive timeout.
int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO,
&receptionTimeout, sizeof(receptionTimeout));
if(result == -1) {
sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting receive"
"timeout failed with " << strerror(errno) << std::endl;
return;
}
}
TcSocketPollingTask::~TcSocketPollingTask() {
TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {
}
ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) {
// Poll for new data permanently. The call will block until the specified
// length of bytes has been received or a timeout occured.
ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) {
// Poll for new UDP datagrams in permanent loop.
while(1) {
//! Sender Address is cached here.
struct sockaddr_in senderAddress;
@ -48,21 +39,34 @@ ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) {
receptionBuffer.data(), frameSize, receptionFlags,
reinterpret_cast<sockaddr*>(&senderAddress), &senderSockLen);
if(bytesReceived < 0) {
//handle error
// handle error
sif::error << "TcSocketPollingTask::performOperation: recvfrom "
"failed with " << strerror(errno) << std::endl;
if(errno == EAGAIN or errno == EWOULDBLOCK) {
sif::info << "timeout" << std::endl;
}
continue;
}
sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived
<< " bytes received" << std::endl;
ReturnValue_t result = handleSuccessfullTcRead();
ReturnValue_t result = handleSuccessfullTcRead(bytesReceived);
if(result != HasReturnvaluesIF::RETURN_FAILED) {
}
tmtcBridge->checkAndSetClientAddress(senderAddress);
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TcSocketPollingTask::initialize() {
ReturnValue_t TcUnixUdpPollingTask::initialize() {
tcStore = objectManager->get<StorageManagerIF>(objects::TC_STORE);
if (tcStore == nullptr) {
sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!"
<< std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
tmtcBridge = objectManager->get<TmTcUnixUdpBridge>(tmtcBridgeId);
if(tmtcBridge == nullptr) {
sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid"
@ -70,10 +74,41 @@ ReturnValue_t TcSocketPollingTask::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
targetTcDestination = tmtcBridge->getReportReceptionQueue();
serverUdpSocket = tmtcBridge->serverSocket;
// Set receive timeout.
// int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO,
// &receptionTimeout, sizeof(receptionTimeout));
// if(result == -1) {
// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting "
// "receive timeout failed with " << strerror(errno) << std::endl;
// return ObjectManagerIF::CHILD_INIT_FAILED;
// }
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TcSocketPollingTask::handleSuccessfullTcRead() {
return HasReturnvaluesIF::RETURN_OK;
ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) {
store_address_t storeId = 0;
ReturnValue_t result = tcStore->addData(&storeId,
receptionBuffer.data(), bytesRead);
// arrayprinter::print(receptionBuffer.data(), bytesRead);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data "
"storage failed" << std::endl;
sif::debug << "Packet size: " << bytesRead << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
TmTcMessage message(storeId);
result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Serial Polling: Sending message to queue failed"
<< std::endl;
tcStore->deleteData(storeId);
}
return result;
}

View File

@ -1,5 +1,6 @@
#ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_
#define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_
#include <framework/objectmanager/SystemObject.h>
#include <framework/osal/linux/TmTcUnixUdpBridge.h>
#include <framework/tasks/ExecutableObjectIF.h>
@ -16,7 +17,7 @@
* This class caches the IP address of the sender. It is assumed there
* is only one sender for now.
*/
class TcSocketPollingTask: public SystemObject,
class TcUnixUdpPollingTask: public SystemObject,
public ExecutableObjectIF {
friend class TmTcUnixUdpBridge;
public:
@ -24,17 +25,21 @@ public:
//! 0.5 default milliseconds timeout for now.
static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500};
TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge,
size_t frameSize = 0, double timeoutSeconds = -1);
virtual~ TcSocketPollingTask();
virtual~ TcUnixUdpPollingTask();
virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual ReturnValue_t initialize() override;
protected:
StorageManagerIF* tcStore = nullptr;
private:
//! TMTC bridge is cached.
object_id_t tmtcBridgeId = objects::NO_OBJECT;
TmTcUnixUdpBridge* tmtcBridge = nullptr;
MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE;
//! Reception flags: https://linux.die.net/man/2/recvfrom.
int receptionFlags = 0;
@ -47,7 +52,7 @@ private:
size_t frameSize = 0;
timeval receptionTimeout;
ReturnValue_t handleSuccessfullTcRead();
ReturnValue_t handleSuccessfullTcRead(size_t bytesRead);
};

View File

@ -101,7 +101,7 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) {
void TmTcUnixUdpBridge::handleBindError() {
// See: https://man7.org/linux/man-pages/man2/bind.2.html
switch(errno) {
case(EACCES):
case(EACCES): {
/*
Ephermeral ports can be shown with following command:
sysctl -A | grep ip_local_port_range
@ -110,7 +110,8 @@ void TmTcUnixUdpBridge::handleBindError() {
"Ports 1-1024 are reserved on UNIX systems and require root "
"rights while ephermeral ports should not be used as well."
<< std::endl;
break;
}
break;
case(EADDRINUSE):
case(EBADF):
case(EINVAL):
@ -122,15 +123,17 @@ void TmTcUnixUdpBridge::handleBindError() {
case(ENOENT):
case(ENOMEM):
case(ENOTDIR):
case(EROFS):
case(EROFS): {
sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed"
<< " with " << strerror(errno) << std::endl;
<< " with " << strerror(errno) << std::endl;
break;
default:
}
default: {
sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error"
<< std::endl;
<< std::endl;
break;
}
}
}

View File

@ -7,7 +7,7 @@
#include <netinet/udp.h>
class TmTcUnixUdpBridge: public TmTcBridge {
friend class TcSocketPollingTask;
friend class TcUnixUdpPollingTask;
public:
// The ports chosen here should not be used by any other process.
// List of used ports on Linux: /etc/services