Skip to content

Commit

Permalink
Framed transport header data stored in MessageBuffer
Browse files Browse the repository at this point in the history
Signed-off-by: Cervenka Dusan <cervenka@acrios.com>
  • Loading branch information
Hadatko committed Aug 28, 2023
1 parent 26bd600 commit b3cf59f
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 251 deletions.
2 changes: 1 addition & 1 deletion erpc_c/infra/erpc_arbitrated_client_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ArbitratedClientManager::performClientRequest(RequestContext &request)
// Send the request.
if (request.getCodec()->isStatusOk() == true)
{
err = m_arbitrator->send(request.getCodec()->getBuffer());
err = m_arbitrator->send(&request.getCodec()->getBufferRef());
request.getCodec()->updateStatus(err);
}

Expand Down
15 changes: 8 additions & 7 deletions erpc_c/infra/erpc_client_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void ClientManager::performClientRequest(RequestContext &request)
// Send invocation request to server.
if (request.getCodec()->isStatusOk() == true)
{
err = m_transport->send(request.getCodec()->getBuffer());
err = m_transport->send(&request.getCodec()->getBufferRef());
request.getCodec()->updateStatus(err);
}

Expand All @@ -88,7 +88,7 @@ void ClientManager::performClientRequest(RequestContext &request)
if (request.getCodec()->isStatusOk() == true)
{
// Receive reply.
err = m_transport->receive(request.getCodec()->getBuffer());
err = m_transport->receive(&request.getCodec()->getBufferRef());
request.getCodec()->updateStatus(err);
}

Expand Down Expand Up @@ -126,7 +126,7 @@ void ClientManager::performNestedClientRequest(RequestContext &request)
// Send invocation request to server.
if (request.getCodec()->isStatusOk() == true)
{
err = m_transport->send(request.getCodec()->getBuffer());
err = m_transport->send(&request.getCodec()->getBufferRef());
request.getCodec()->updateStatus(err);
}

Expand Down Expand Up @@ -167,7 +167,7 @@ void ClientManager::verifyReply(RequestContext &request)

// Some transport layers change the request's message buffer pointer (for things like zero
// copy support), so inCodec must be reset to work with correct buffer.
request.getCodec()->reset();
request.getCodec()->reset(m_transport->reserveHeaderSize());

// Extract the reply header.
request.getCodec()->startReadMessage(msgType, service, requestNumber, sequence);
Expand All @@ -186,13 +186,14 @@ Codec *ClientManager::createBufferAndCodec(void)
{
Codec *codec = m_codecFactory->create();
MessageBuffer message;
uint8_t reservedMessageSpace = m_transport->reserveHeaderSize();

if (codec != NULL)
{
message = m_messageFactory->create();
message = m_messageFactory->create(reservedMessageSpace);
if (NULL != message.get())
{
codec->setBuffer(message);
codec->setBuffer(message, reservedMessageSpace);
}
else
{
Expand All @@ -209,7 +210,7 @@ void ClientManager::releaseRequest(RequestContext &request)
{
if (request.getCodec() != NULL)
{
m_messageFactory->dispose(request.getCodec()->getBuffer());
m_messageFactory->dispose(&request.getCodec()->getBufferRef());
m_codecFactory->dispose(request.getCodec());
}
}
Expand Down
4 changes: 2 additions & 2 deletions erpc_c/infra/erpc_client_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ class ClientManager : public ClientServerCommon
#endif

protected:
uint32_t m_sequence; //!< Sequence number.
client_error_handler_t m_errorHandler; //!< Pointer to function error handler.
uint32_t m_sequence; //!< Sequence number.
client_error_handler_t m_errorHandler; //!< Pointer to function error handler.
#if ERPC_NESTED_CALLS
Server *m_server; //!< Server used for nested calls.
Thread::thread_id_t m_serverThreadId; //!< Thread in which server run function is called.
Expand Down
27 changes: 16 additions & 11 deletions erpc_c/infra/erpc_codec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ class Codec
* This function initializes object attributes.
*/
Codec(void)
: m_buffer()
, m_cursor()
: m_cursor()
, m_status(kErpcStatus_Success)
{
}
Expand All @@ -75,24 +74,31 @@ class Codec
*
* @return Pointer to used message buffer.
*/
MessageBuffer *getBuffer(void) { return &m_buffer; }
MessageBuffer getBuffer(void) { return m_cursor.getBuffer(); }

MessageBuffer &getBufferRef(void) { return m_cursor.getBufferRef(); }

/*!
* @brief Prototype for set message buffer used for read and write data.
*
* @param[in] buf Message buffer to set.
* @param[in] skip How many bytes to skip from reading.
*/
virtual void setBuffer(MessageBuffer &buf)
virtual void setBuffer(MessageBuffer &buf, uint8_t skip = 0)
{
m_buffer = buf;
m_cursor.set(&m_buffer);
m_cursor.setBuffer(buf, skip);
m_status = kErpcStatus_Success;
}

/*! @brief Reset the codec to initial state. */
virtual void reset(void)
/*!
* @brief Reset the codec to initial state.
*
* @param[in] skip How many bytes to skip from reading.
*/
virtual void reset(uint8_t skip = 0)
{
m_cursor.set(&m_buffer);
MessageBuffer buffer=m_cursor.getBuffer();
m_cursor.setBuffer(buffer, skip);
m_status = kErpcStatus_Success;
}

Expand Down Expand Up @@ -428,8 +434,7 @@ class Codec
virtual void readCallback(funPtr callbacks1, funPtr *callback2) = 0;

protected:
MessageBuffer m_buffer; /*!< Message buffer object */
MessageBuffer::Cursor m_cursor; /*!< Copy data to message buffers. */
Cursor m_cursor; /*!< Copy data to message buffers. */
erpc_status_t m_status; /*!< Status of serialized data. */
};

Expand Down
70 changes: 48 additions & 22 deletions erpc_c/infra/erpc_framed_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ FramedTransport::FramedTransport(void)

FramedTransport::~FramedTransport(void) {}

uint8_t FramedTransport::reserveHeaderSize(void)
{
return sizeof(FramedTransport::Header::m_crcHeader) + sizeof(FramedTransport::Header::m_messageSize) +
sizeof(FramedTransport::Header::m_crcBody);
}

void FramedTransport::setCrc16(Crc16 *crcImpl)
{
erpc_assert(crcImpl);
Expand All @@ -47,36 +53,51 @@ Crc16 *FramedTransport::getCrc16(void)

erpc_status_t FramedTransport::receive(MessageBuffer *message)
{
Header h;
Header h = { 0, 0, 0 };
erpc_status_t retVal;
uint16_t computedCrc;
uint8_t offset = 0;

erpc_assert((m_crcImpl != NULL) && ("Uninitialized Crc16 object." != NULL));

if (message->getLength() < reserveHeaderSize())
{
retVal = kErpcStatus_MemoryError;
}
else
{
#if !ERPC_THREADS_IS(NONE)
Mutex::Guard lock(m_receiveLock);
#endif

// Receive header first.
retVal = underlyingReceive((uint8_t *)&h, sizeof(h));
retVal = underlyingReceive(message->get(), reserveHeaderSize());
static_cast<void>(memcpy(&h.m_crcHeader, message->get(), sizeof(h.m_crcHeader)));
offset = sizeof(h.m_crcHeader);
static_cast<void>(memcpy(&h.m_messageSize, &message->get()[offset], sizeof(h.m_messageSize)));
offset += sizeof(h.m_messageSize);
static_cast<void>(memcpy(&h.m_crcBody, &message->get()[offset], sizeof(h.m_crcBody)));
offset += sizeof(h.m_crcBody);

if (retVal == kErpcStatus_Success)
{
ERPC_READ_AGNOSTIC_16(h.m_crcHeader);
ERPC_READ_AGNOSTIC_16(h.m_messageSize);
ERPC_READ_AGNOSTIC_16(h.m_crc);
ERPC_READ_AGNOSTIC_16(h.m_crcBody);

// received size can't be zero.
if (h.m_messageSize == 0U)
computedCrc =
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)) +
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody));
if (computedCrc != h.m_crcHeader)
{
retVal = kErpcStatus_ReceiveFailed;
retVal = kErpcStatus_CrcCheckFailed;
}
}

if (retVal == kErpcStatus_Success)
{
// received size can't be larger then buffer length.
if (h.m_messageSize > message->getLength())
if ((h.m_messageSize + reserveHeaderSize()) > message->getLength())
{
retVal = kErpcStatus_ReceiveFailed;
}
Expand All @@ -85,17 +106,17 @@ erpc_status_t FramedTransport::receive(MessageBuffer *message)
if (retVal == kErpcStatus_Success)
{
// Receive rest of the message now we know its size.
retVal = underlyingReceive(message->get(), h.m_messageSize);
retVal = underlyingReceive(&message->get()[offset], h.m_messageSize);
}
}

if (retVal == kErpcStatus_Success)
{
// Verify CRC.
computedCrc = m_crcImpl->computeCRC16(message->get(), h.m_messageSize);
if (computedCrc == h.m_crc)
computedCrc = m_crcImpl->computeCRC16(&message->get()[offset], h.m_messageSize);
if (computedCrc == h.m_crcBody)
{
message->setUsed(h.m_messageSize);
message->setUsed(h.m_messageSize + reserveHeaderSize());
}
else
{
Expand All @@ -111,27 +132,32 @@ erpc_status_t FramedTransport::send(MessageBuffer *message)
erpc_status_t ret;
uint16_t messageLength;
Header h;
uint8_t offset;

erpc_assert((m_crcImpl != NULL) && ("Uninitialized Crc16 object." != NULL));

#if !ERPC_THREADS_IS(NONE)
Mutex::Guard lock(m_sendLock);
#endif

messageLength = message->getUsed();
messageLength = message->getUsed() - reserveHeaderSize();

// Send header first.
h.m_messageSize = messageLength;
h.m_crc = m_crcImpl->computeCRC16(message->get(), messageLength);
h.m_crcBody = m_crcImpl->computeCRC16(&message->get()[reserveHeaderSize()], messageLength);
h.m_crcHeader =
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)) +
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody));

ERPC_WRITE_AGNOSTIC_16(h.m_crcHeader);
ERPC_WRITE_AGNOSTIC_16(h.m_messageSize);
ERPC_WRITE_AGNOSTIC_16(h.m_crc);

ret = underlyingSend((uint8_t *)&h, sizeof(h));
if (ret == kErpcStatus_Success)
{
ret = underlyingSend(message->get(), messageLength);
}
static_cast<void>(memcpy(message->get(), reinterpret_cast<const uint8_t *>(&h.m_crcHeader), sizeof(h.m_crcHeader)));
offset = sizeof(h.m_crcHeader);
static_cast<void>(
memcpy(&message->get()[offset], reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)));
offset += sizeof(h.m_messageSize);
static_cast<void>(
memcpy(&message->get()[offset], reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody)));

ret = underlyingSend(message->get(), message->getUsed());

return ret;
}
22 changes: 15 additions & 7 deletions erpc_c/infra/erpc_framed_transport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ namespace erpc {
class FramedTransport : public Transport
{
public:
/*! @brief Contents of the header that prefixes each message. */
struct Header
{
uint16_t m_crcHeader; //!< CRC-16 over this header structure data
uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header.
uint16_t m_crcBody; //!< CRC-16 over the message data.
};

/*!
* @brief Constructor.
*/
Expand All @@ -66,6 +74,13 @@ class FramedTransport : public Transport
*/
virtual ~FramedTransport(void);

/**
* @brief Size of data placed in MessageBuffer before serializing eRPC data.
*
* @return uint8_t Amount of bytes, reserved before serialized data.
*/
virtual uint8_t reserveHeaderSize(void) override;

/*!
* @brief Receives an entire message.
*
Expand Down Expand Up @@ -95,13 +110,6 @@ class FramedTransport : public Transport
*/
virtual erpc_status_t send(MessageBuffer *message) override;

/*! @brief Contents of the header that prefixes each message. */
struct Header
{
uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header.
uint16_t m_crc; //!< CRC-16 over the message data.
};

/*!
* @brief This functions sets the CRC-16 implementation.
*
Expand Down
Loading

0 comments on commit b3cf59f

Please sign in to comment.