|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
#include "UartComIF.h"
|
|
|
|
|
#include "OBSWConfig.h"
|
|
|
|
|
|
|
|
|
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
|
|
|
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
@ -15,12 +16,12 @@ UartComIF::~UartComIF() {}
|
|
|
|
|
|
|
|
|
|
ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) {
|
|
|
|
|
|
|
|
|
|
std::string deviceFile;
|
|
|
|
|
UartDeviceMapIter uartDeviceMapIter;
|
|
|
|
|
std::string deviceFile;
|
|
|
|
|
UartDeviceMapIter uartDeviceMapIter;
|
|
|
|
|
|
|
|
|
|
if(cookie == nullptr) {
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
if(cookie == nullptr) {
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
|
|
|
|
if (uartCookie == nullptr) {
|
|
|
|
@ -31,32 +32,32 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) {
|
|
|
|
|
deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
|
|
|
|
|
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
|
|
|
|
if(uartDeviceMapIter == uartDeviceMap.end()) {
|
|
|
|
|
int fileDescriptor = configureUartPort(uartCookie);
|
|
|
|
|
if (fileDescriptor < 0) {
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
size_t maxReplyLen = uartCookie->getMaxReplyLen();
|
|
|
|
|
UartElements uartElements = {fileDescriptor, std::vector<uint8_t>(maxReplyLen), 0};
|
|
|
|
|
auto status = uartDeviceMap.emplace(deviceFile, uartElements);
|
|
|
|
|
if(uartDeviceMapIter == uartDeviceMap.end()) {
|
|
|
|
|
int fileDescriptor = configureUartPort(uartCookie);
|
|
|
|
|
if (fileDescriptor < 0) {
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
size_t maxReplyLen = uartCookie->getMaxReplyLen();
|
|
|
|
|
UartElements uartElements = {fileDescriptor, std::vector<uint8_t>(maxReplyLen), 0};
|
|
|
|
|
auto status = uartDeviceMap.emplace(deviceFile, uartElements);
|
|
|
|
|
if (status.second == false) {
|
|
|
|
|
sif::warning << "UartComIF::initializeInterface: Failed to insert device " <<
|
|
|
|
|
deviceFile << "to UART device map" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sif::warning << "UartComIF::initializeInterface: UART device " << deviceFile <<
|
|
|
|
|
" already in use" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sif::warning << "UartComIF::initializeInterface: UART device " << deviceFile <<
|
|
|
|
|
" already in use" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|
|
|
|
|
|
|
|
|
struct termios options;
|
|
|
|
|
struct termios options = {};
|
|
|
|
|
|
|
|
|
|
std::string deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
int fd = open(deviceFile.c_str(), O_RDWR);
|
|
|
|
@ -78,6 +79,9 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
|
|
|
|
|
setStopBitOptions(&options, uartCookie);
|
|
|
|
|
setDatasizeOptions(&options, uartCookie);
|
|
|
|
|
setFixedOptions(&options);
|
|
|
|
|
if(uartCookie->getInputShouldBeFlushed()) {
|
|
|
|
|
tcflush(fd, TCIFLUSH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sets uart to non-blocking mode. Read returns immediately when there are no data available */
|
|
|
|
|
options.c_cc[VTIME] = 0;
|
|
|
|
@ -255,46 +259,46 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
|
|
|
|
|
ReturnValue_t UartComIF::sendMessage(CookieIF *cookie,
|
|
|
|
|
const uint8_t *sendData, size_t sendLen) {
|
|
|
|
|
|
|
|
|
|
int fd = 0;
|
|
|
|
|
std::string deviceFile;
|
|
|
|
|
UartDeviceMapIter uartDeviceMapIter;
|
|
|
|
|
int fd = 0;
|
|
|
|
|
std::string deviceFile;
|
|
|
|
|
UartDeviceMapIter uartDeviceMapIter;
|
|
|
|
|
|
|
|
|
|
if(sendData == nullptr) {
|
|
|
|
|
if(sendData == nullptr) {
|
|
|
|
|
sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(sendLen == 0) {
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
if(sendLen == 0) {
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
|
|
|
|
if(uartCookie == nullptr) {
|
|
|
|
|
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
|
|
|
|
if(uartCookie == nullptr) {
|
|
|
|
|
sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
|
|
|
|
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
|
|
|
|
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile <<
|
|
|
|
|
"not in UART map" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
|
|
|
|
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
|
|
|
|
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile <<
|
|
|
|
|
"not in UART map" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fd = uartDeviceMapIter->second.fileDescriptor;
|
|
|
|
|
fd = uartDeviceMapIter->second.fileDescriptor;
|
|
|
|
|
|
|
|
|
|
if (write(fd, sendData, sendLen) != (int)sendLen) {
|
|
|
|
|
sif::error << "UartComIF::sendMessage: Failed to send data with error code " <<
|
|
|
|
|
errno << ": Error description: " << strerror(errno) << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if (write(fd, sendData, sendLen) != (int)sendLen) {
|
|
|
|
|
sif::error << "UartComIF::sendMessage: Failed to send data with error code " <<
|
|
|
|
|
errno << ": Error description: " << strerror(errno) << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReturnValue_t UartComIF::getSendSuccess(CookieIF *cookie) {
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
|
|
|
|
@ -325,10 +329,53 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
|
|
|
|
|
fd = uartDeviceMapIter->second.fileDescriptor;
|
|
|
|
|
bufferPtr = uartDeviceMapIter->second.replyBuffer.data();
|
|
|
|
|
if (uartMode == UartModes::CANONICAL) {
|
|
|
|
|
int bytesRead = read(fd, bufferPtr, uartCookie->getMaxReplyLen());
|
|
|
|
|
uartDeviceMapIter->second.replyLen = bytesRead;
|
|
|
|
|
uint8_t maxReadCycles = uartCookie->getReadCycles();
|
|
|
|
|
uint8_t currentReadCycles = 0;
|
|
|
|
|
int bytesRead = 0;
|
|
|
|
|
size_t currentBytesRead = 0;
|
|
|
|
|
size_t maxReplySize = uartCookie->getMaxReplyLen();
|
|
|
|
|
do {
|
|
|
|
|
size_t allowedReadSize = 0;
|
|
|
|
|
if(currentBytesRead >= maxReplySize) {
|
|
|
|
|
// Overflow risk. Emit warning, trigger event and break. If this happens,
|
|
|
|
|
// the reception buffer is not large enough or data is not polled often enough.
|
|
|
|
|
// TODO: Emit event
|
|
|
|
|
// TODO: Return error?
|
|
|
|
|
#if OBSW_VERBOSE_LEVEL >= 1
|
|
|
|
|
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
|
|
|
|
|
<< std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
allowedReadSize = maxReplySize - currentBytesRead;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bytesRead = read(fd, bufferPtr, allowedReadSize);
|
|
|
|
|
if (bytesRead < 0) {
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
else if (bytesRead != static_cast<int>(requestLen)) {
|
|
|
|
|
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead <<
|
|
|
|
|
" of " << requestLen << " bytes" << std::endl;
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
else if(bytesRead > 0) {
|
|
|
|
|
uartDeviceMapIter->second.replyLen += bytesRead;
|
|
|
|
|
bufferPtr += bytesRead;
|
|
|
|
|
currentBytesRead += bytesRead;
|
|
|
|
|
}
|
|
|
|
|
currentReadCycles++;
|
|
|
|
|
} while(bytesRead > 0 and currentReadCycles < maxReadCycles);
|
|
|
|
|
}
|
|
|
|
|
else if (uartMode == UartModes::NON_CANONICAL) {
|
|
|
|
|
// Size check to prevent buffer overflow
|
|
|
|
|
if(requestLen > uartCookie->getMaxReplyLen()) {
|
|
|
|
|
// TODO: Emit warning
|
|
|
|
|
// TODO: Emit event
|
|
|
|
|
// TODO: Better returnvalue
|
|
|
|
|
return HasReturnvaluesIF::RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
int bytesRead = read(fd, bufferPtr, requestLen);
|
|
|
|
|
if (bytesRead < 0) {
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
@ -346,18 +393,18 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie,
|
|
|
|
|
uint8_t **buffer, size_t* size) {
|
|
|
|
|
uint8_t **buffer, size_t* size) {
|
|
|
|
|
|
|
|
|
|
std::string deviceFile;
|
|
|
|
|
UartDeviceMapIter uartDeviceMapIter;
|
|
|
|
|
|
|
|
|
|
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
|
|
|
|
if(uartCookie == nullptr) {
|
|
|
|
|
if(uartCookie == nullptr) {
|
|
|
|
|
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
return NULLPOINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
deviceFile = uartCookie->getDeviceFile();
|
|
|
|
|
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
|
|
|
|
|
if (uartDeviceMapIter == uartDeviceMap.end()) {
|
|
|
|
|
sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile <<
|
|
|
|
@ -365,13 +412,13 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie,
|
|
|
|
|
return RETURN_FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*buffer = uartDeviceMapIter->second.replyBuffer.data();
|
|
|
|
|
*size = uartDeviceMapIter->second.replyLen;
|
|
|
|
|
*buffer = uartDeviceMapIter->second.replyBuffer.data();
|
|
|
|
|
*size = uartDeviceMapIter->second.replyLen;
|
|
|
|
|
|
|
|
|
|
/* Length is reset to 0 to prevent reading the same data twice */
|
|
|
|
|
uartDeviceMapIter->second.replyLen = 0;
|
|
|
|
|
/* Length is reset to 0 to prevent reading the same data twice */
|
|
|
|
|
uartDeviceMapIter->second.replyLen = 0;
|
|
|
|
|
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
return RETURN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UartComIF::setUartMode(struct termios *options, UartCookie &uartCookie) {
|
|
|
|
|