Skip to content

Commit f7596f9

Browse files
committed
Framed transport header data stored in MessageBuffer
Signed-off-by: Cervenka Dusan <[email protected]>
1 parent 26bd600 commit f7596f9

18 files changed

+154
-70
lines changed

erpc_c/infra/erpc_client_manager.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void ClientManager::verifyReply(RequestContext &request)
167167

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

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

190191
if (codec != NULL)
191192
{
192-
message = m_messageFactory->create();
193+
message = m_messageFactory->create(reservedMessageSpace);
193194
if (NULL != message.get())
194195
{
195-
codec->setBuffer(message);
196+
codec->setBuffer(message, reservedMessageSpace);
196197
}
197198
else
198199
{

erpc_c/infra/erpc_client_manager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ class ClientManager : public ClientServerCommon
130130
#endif
131131

132132
protected:
133-
uint32_t m_sequence; //!< Sequence number.
134-
client_error_handler_t m_errorHandler; //!< Pointer to function error handler.
133+
uint32_t m_sequence; //!< Sequence number.
134+
client_error_handler_t m_errorHandler; //!< Pointer to function error handler.
135135
#if ERPC_NESTED_CALLS
136136
Server *m_server; //!< Server used for nested calls.
137137
Thread::thread_id_t m_serverThreadId; //!< Thread in which server run function is called.

erpc_c/infra/erpc_codec.hpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ class Codec
5959
* This function initializes object attributes.
6060
*/
6161
Codec(void)
62-
: m_buffer()
63-
, m_cursor()
62+
: m_cursor()
6463
, m_status(kErpcStatus_Success)
6564
{
6665
}
@@ -75,24 +74,28 @@ class Codec
7574
*
7675
* @return Pointer to used message buffer.
7776
*/
78-
MessageBuffer *getBuffer(void) { return &m_buffer; }
77+
MessageBuffer *getBuffer(void) { return m_cursor.getBuffer(); }
7978

8079
/*!
8180
* @brief Prototype for set message buffer used for read and write data.
8281
*
8382
* @param[in] buf Message buffer to set.
83+
* @param[in] skip How many bytes to skip from reading.
8484
*/
85-
virtual void setBuffer(MessageBuffer &buf)
85+
virtual void setBuffer(MessageBuffer &buf, uint8_t skip = 0)
8686
{
87-
m_buffer = buf;
88-
m_cursor.set(&m_buffer);
87+
m_cursor.setBuffer(&buf, skip);
8988
m_status = kErpcStatus_Success;
9089
}
9190

92-
/*! @brief Reset the codec to initial state. */
93-
virtual void reset(void)
91+
/*!
92+
* @brief Reset the codec to initial state.
93+
*
94+
* @param[in] skip How many bytes to skip from reading.
95+
*/
96+
virtual void reset(uint8_t skip = 0)
9497
{
95-
m_cursor.set(&m_buffer);
98+
m_cursor.setBuffer(m_cursor.getBuffer(), skip);
9699
m_status = kErpcStatus_Success;
97100
}
98101

@@ -428,7 +431,6 @@ class Codec
428431
virtual void readCallback(funPtr callbacks1, funPtr *callback2) = 0;
429432

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

erpc_c/infra/erpc_framed_transport.cpp

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ FramedTransport::FramedTransport(void)
3434

3535
FramedTransport::~FramedTransport(void) {}
3636

37+
uint8_t FramedTransport::reserveHeaderSize(void)
38+
{
39+
return sizeof(FramedTransport::Header::m_crcHeader) + sizeof(FramedTransport::Header::m_messageSize) +
40+
sizeof(FramedTransport::Header::m_crcBody);
41+
}
42+
3743
void FramedTransport::setCrc16(Crc16 *crcImpl)
3844
{
3945
erpc_assert(crcImpl);
@@ -47,36 +53,51 @@ Crc16 *FramedTransport::getCrc16(void)
4753

4854
erpc_status_t FramedTransport::receive(MessageBuffer *message)
4955
{
50-
Header h;
56+
Header h = { 0, 0, 0 };
5157
erpc_status_t retVal;
5258
uint16_t computedCrc;
59+
uint8_t offset = 0;
5360

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

63+
if (message->getLength() < reserveHeaderSize())
64+
{
65+
retVal = kErpcStatus_MemoryError;
66+
}
67+
else
5668
{
5769
#if !ERPC_THREADS_IS(NONE)
5870
Mutex::Guard lock(m_receiveLock);
5971
#endif
6072

6173
// Receive header first.
62-
retVal = underlyingReceive((uint8_t *)&h, sizeof(h));
74+
retVal = underlyingReceive(message->get(), sizeof(h));
75+
static_cast<void>(memcpy(&h.m_crcHeader, message->get(), sizeof(h.m_crcHeader)));
76+
offset = sizeof(h.m_crcHeader);
77+
static_cast<void>(memcpy(&h.m_messageSize, &message->get()[offset], sizeof(h.m_messageSize)));
78+
offset += sizeof(h.m_messageSize);
79+
static_cast<void>(memcpy(&h.m_crcBody, &message->get()[offset], sizeof(h.m_crcBody)));
80+
offset += sizeof(h.m_crcBody);
6381

6482
if (retVal == kErpcStatus_Success)
6583
{
84+
ERPC_READ_AGNOSTIC_16(h.m_crcHeader);
6685
ERPC_READ_AGNOSTIC_16(h.m_messageSize);
67-
ERPC_READ_AGNOSTIC_16(h.m_crc);
86+
ERPC_READ_AGNOSTIC_16(h.m_crcBody);
6887

69-
// received size can't be zero.
70-
if (h.m_messageSize == 0U)
88+
computedCrc =
89+
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)) +
90+
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody));
91+
if (computedCrc != h.m_crcHeader)
7192
{
72-
retVal = kErpcStatus_ReceiveFailed;
93+
retVal = kErpcStatus_CrcCheckFailed;
7394
}
7495
}
7596

7697
if (retVal == kErpcStatus_Success)
7798
{
7899
// received size can't be larger then buffer length.
79-
if (h.m_messageSize > message->getLength())
100+
if ((h.m_messageSize + reserveHeaderSize()) > message->getLength())
80101
{
81102
retVal = kErpcStatus_ReceiveFailed;
82103
}
@@ -85,17 +106,17 @@ erpc_status_t FramedTransport::receive(MessageBuffer *message)
85106
if (retVal == kErpcStatus_Success)
86107
{
87108
// Receive rest of the message now we know its size.
88-
retVal = underlyingReceive(message->get(), h.m_messageSize);
109+
retVal = underlyingReceive(&message->get()[offset], h.m_messageSize);
89110
}
90111
}
91112

92113
if (retVal == kErpcStatus_Success)
93114
{
94115
// Verify CRC.
95-
computedCrc = m_crcImpl->computeCRC16(message->get(), h.m_messageSize);
96-
if (computedCrc == h.m_crc)
116+
computedCrc = m_crcImpl->computeCRC16(&message->get()[offset], h.m_messageSize);
117+
if (computedCrc == h.m_crcBody)
97118
{
98-
message->setUsed(h.m_messageSize);
119+
message->setUsed(h.m_messageSize + reserveHeaderSize());
99120
}
100121
else
101122
{
@@ -111,27 +132,32 @@ erpc_status_t FramedTransport::send(MessageBuffer *message)
111132
erpc_status_t ret;
112133
uint16_t messageLength;
113134
Header h;
135+
uint8_t offset;
114136

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

117-
#if !ERPC_THREADS_IS(NONE)
118-
Mutex::Guard lock(m_sendLock);
119-
#endif
120-
121-
messageLength = message->getUsed();
139+
messageLength = message->getUsed() - reserveHeaderSize();
122140

123141
// Send header first.
124142
h.m_messageSize = messageLength;
125-
h.m_crc = m_crcImpl->computeCRC16(message->get(), messageLength);
143+
h.m_crcBody = m_crcImpl->computeCRC16(message->get(), messageLength);
144+
h.m_crcHeader =
145+
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)) +
146+
m_crcImpl->computeCRC16(reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody));
126147

148+
ERPC_WRITE_AGNOSTIC_16(h.m_crcHeader);
127149
ERPC_WRITE_AGNOSTIC_16(h.m_messageSize);
128150
ERPC_WRITE_AGNOSTIC_16(h.m_crc);
129151

130-
ret = underlyingSend((uint8_t *)&h, sizeof(h));
131-
if (ret == kErpcStatus_Success)
132-
{
133-
ret = underlyingSend(message->get(), messageLength);
134-
}
152+
static_cast<void>(memcpy(message->get(), reinterpret_cast<const uint8_t *>(&h.m_crcHeader), sizeof(h.m_crcHeader)));
153+
offset = sizeof(h.m_crcHeader);
154+
static_cast<void>(
155+
memcpy(&message->get()[offset], reinterpret_cast<const uint8_t *>(&h.m_messageSize), sizeof(h.m_messageSize)));
156+
offset += sizeof(h.m_messageSize);
157+
static_cast<void>(
158+
memcpy(&message->get()[offset], reinterpret_cast<const uint8_t *>(&h.m_crcBody), sizeof(h.m_crcBody)));
159+
160+
ret = underlyingSend(message->get(), message->getUsed());
135161

136162
return ret;
137163
}

erpc_c/infra/erpc_framed_transport.hpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ namespace erpc {
5656
class FramedTransport : public Transport
5757
{
5858
public:
59+
/*! @brief Contents of the header that prefixes each message. */
60+
struct Header
61+
{
62+
uint16_t m_crcHeader; //!< CRC-16 over this header structure data
63+
uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header.
64+
uint16_t m_crcBody; //!< CRC-16 over the message data.
65+
};
66+
5967
/*!
6068
* @brief Constructor.
6169
*/
@@ -66,6 +74,13 @@ class FramedTransport : public Transport
6674
*/
6775
virtual ~FramedTransport(void);
6876

77+
/**
78+
* @brief Size of data placed in MessageBuffer before serializing eRPC data.
79+
*
80+
* @return uint8_t Amount of bytes, reserved before serialized data.
81+
*/
82+
virtual uint8_t reserveHeaderSize(void) override;
83+
6984
/*!
7085
* @brief Receives an entire message.
7186
*
@@ -95,13 +110,6 @@ class FramedTransport : public Transport
95110
*/
96111
virtual erpc_status_t send(MessageBuffer *message) override;
97112

98-
/*! @brief Contents of the header that prefixes each message. */
99-
struct Header
100-
{
101-
uint16_t m_messageSize; //!< Size in bytes of the message, excluding the header.
102-
uint16_t m_crc; //!< CRC-16 over the message data.
103-
};
104-
105113
/*!
106114
* @brief This functions sets the CRC-16 implementation.
107115
*

erpc_c/infra/erpc_message_buffer.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,20 @@ void MessageBuffer::swap(MessageBuffer *other)
100100
m_buf = temp.m_buf;
101101
}
102102

103-
void MessageBuffer::Cursor::set(MessageBuffer *buffer)
103+
void MessageBuffer::Cursor::setBuffer(MessageBuffer *buffer, uint8_t reserved)
104104
{
105105
erpc_assert(buffer != NULL);
106106

107107
m_buffer = buffer;
108108
// RPMSG when nested calls are enabled can set NULL buffer.
109109
// erpc_assert(buffer->get() && "Data buffer wasn't set to MessageBuffer.");
110110
// receive function should return err if it couldn't set data buffer.
111-
m_pos = buffer->get();
111+
m_pos = buffer->get() + reserved;
112+
}
113+
114+
MessageBuffer *MessageBuffer::Cursor::getBuffer(void)
115+
{
116+
return m_buffer;
112117
}
113118

114119
uint8_t &MessageBuffer::Cursor::operator[](int index)
@@ -221,8 +226,17 @@ erpc_status_t MessageBuffer::Cursor::write(const void *data, uint32_t length)
221226
return err;
222227
}
223228

224-
erpc_status_t MessageBufferFactory::prepareServerBufferForSend(MessageBuffer *message)
229+
MessageBuffer MessageBufferFactory::create(uint8_t reserveHeaderSize)
230+
{
231+
MessageBuffer messageBuffer = create();
232+
233+
messageBuffer.setUsed(reserveHeaderSize);
234+
235+
return messageBuffer;
236+
}
237+
238+
erpc_status_t MessageBufferFactory::prepareServerBufferForSend(MessageBuffer *message, uint8_t reserveHeaderSize)
225239
{
226-
message->setUsed(0);
240+
message->setUsed(reserveHeaderSize);
227241
return kErpcStatus_Success;
228242
}

erpc_c/infra/erpc_message_buffer.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,14 @@ class MessageBuffer
217217
* @brief Set message buffer.
218218
*
219219
* @param[in] buffer Message buffer to set.
220+
* @param[in] reserved Moved cursor position outside of reserved memory.
220221
*/
221-
void set(MessageBuffer *buffer);
222+
void setBuffer(MessageBuffer *buffer, uint8_t reserved = 0);
223+
224+
/*!
225+
* @brief Get message buffer.
226+
*/
227+
MessageBuffer *getBuffer(void);
222228

223229
/*!
224230
* @brief Return position in buffer.
@@ -368,6 +374,17 @@ class MessageBufferFactory
368374
*/
369375
virtual MessageBuffer create(void) = 0;
370376

377+
/*!
378+
* @brief This function creates new message buffer with reserved bytes at the beginning
379+
*
380+
* Reserved bytes can be used by transport to write transport related header file data.
381+
*
382+
* @param[in] reserveHeaderSize Reserved amount of bytes at the beginning of message buffer.
383+
*
384+
* @return New created MessageBuffer.
385+
*/
386+
MessageBuffer create(uint8_t reserveHeaderSize);
387+
371388
/*!
372389
* @brief This function informs server if it has to create buffer for received message.
373390
*
@@ -382,8 +399,9 @@ class MessageBufferFactory
382399
* In case of using new buffer function has to free given buffer.
383400
*
384401
* @param[in] message MessageBuffer which can be reused.
402+
* @param[in] reserveHeaderSize Reserved amount of bytes at the beginning of message buffer.
385403
*/
386-
virtual erpc_status_t prepareServerBufferForSend(MessageBuffer *message);
404+
virtual erpc_status_t prepareServerBufferForSend(MessageBuffer *message, uint8_t reserveHeaderSize = 0);
387405

388406
/*!
389407
* @brief This function disposes message buffer.

erpc_c/infra/erpc_server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ erpc_status_t Server::processMessage(Codec *codec, message_type_t msgType, uint3
9191

9292
if (err == kErpcStatus_Success)
9393
{
94-
err = service->handleInvocation(methodId, sequence, codec, m_messageFactory);
94+
err = service->handleInvocation(methodId, sequence, codec, m_messageFactory, m_transport);
9595
}
9696

9797
return err;

erpc_c/infra/erpc_server.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class Service
8787
* @return Based on handleInvocation implementation.
8888
*/
8989
virtual erpc_status_t handleInvocation(uint32_t methodId, uint32_t sequence, Codec *codec,
90-
MessageBufferFactory *messageFactory) = 0;
90+
MessageBufferFactory *messageFactory, Transport *transport) = 0;
9191

9292
protected:
9393
uint32_t m_serviceId; /*!< Service unique id. */

erpc_c/infra/erpc_simple_server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff,
103103

104104
if (err == kErpcStatus_Success)
105105
{
106-
(*codec)->setBuffer(buff);
106+
(*codec)->setBuffer(buff, m_transport->reserveHeaderSize());
107107

108108
err = readHeadOfMessage(*codec, msgType, serviceId, methodId, sequence);
109109
if (err != kErpcStatus_Success)

0 commit comments

Comments
 (0)