1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491 */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG. */
5 /* This program is free software: you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation, either version 2 of the License, or */
8 /* (at your option) any later version. */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU General Public License for more details. */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* You may also obtain this software under a propriety license from Microchip. */
19 /* Please contact Microchip for further information. */
20 /*------------------------------------------------------------------------------------------------*/
24 * \brief Implementation of class message
26 * \cond UCS_INTERNAL_DOC
27 * \addtogroup G_MESSAGE
31 /*------------------------------------------------------------------------------------------------*/
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_message.h"
37 /*------------------------------------------------------------------------------------------------*/
38 /* Internal constants */
39 /*------------------------------------------------------------------------------------------------*/
41 /*------------------------------------------------------------------------------------------------*/
43 /*------------------------------------------------------------------------------------------------*/
44 /*! \brief Constructor of common MOST message class
45 * \param self The instance
47 void Msg_Ctor(CMessage *self)
49 MISC_MEM_SET(self, 0, sizeof(*self));
51 Dln_Ctor(&self->node, self);
53 self->rsvd_memory.allocator_ptr = NULL;
54 self->rsvd_memory.mem_info_ptr = NULL;
55 self->rsvd_memory.public_buffer.next_buffer_ptr = NULL;
56 self->rsvd_memory.public_buffer.data_ptr = &self->rsvd_buffer[0];
57 self->rsvd_memory.public_buffer.data_size = MSG_SIZE_RSVD_BUFFER;
58 self->rsvd_memory.public_buffer.total_size = MSG_SIZE_RSVD_BUFFER;
60 self->start_ptr = &self->rsvd_buffer[0];
61 self->pb_msg.tel.tel_data_ptr = &self->rsvd_buffer[0];
62 /* self->pb_msg.tel.tel_id = 0U;
63 self->pb_msg.tel.tel_cnt = 0U;
64 self->pb_msg.tel.tel_len = 0U; */
66 self->pb_msg.opts.llrbc = MSG_LLRBC_DEFAULT;
68 /* self->header_rsvd_sz = 0U;
69 self->header_curr_idx = 0U;
70 self->header_curr_sz = 0U;
71 self->ref_ptr = NULL; */
74 /*! \brief Prepares the message for re-usage
75 * \details In future this function has to take care that external memory
76 * has to be reinitialize properly.
77 * \param self The instance
79 void Msg_Cleanup(CMessage *self)
81 void *handle = self->lld_handle_ptr; /* restore associated LLD message object */
82 void *pool_ptr = self->pool_ptr; /* restore associated pool reference */
84 Msg_Ctor(self); /* simply call constructor now */
86 self->lld_handle_ptr = handle;
87 self->pool_ptr = pool_ptr;
90 /*! \brief Adds external message payload to the message
91 * \details The internally reserved message payload is no longer in in use.
92 * \param self The instance
93 * \param payload_ptr Pointer to externally allocated payload
94 * \param payload_sz Size of externally allocated payload
95 * \param mem_info_ptr Reference to additional memory information
97 void Msg_SetExtPayload(CMessage *self, uint8_t *payload_ptr, uint8_t payload_sz, void* mem_info_ptr)
99 self->pb_msg.tel.tel_data_ptr = payload_ptr;
100 self->pb_msg.tel.tel_len = payload_sz;
102 self->ext_memory.allocator_ptr = NULL;
103 self->ext_memory.mem_info_ptr = mem_info_ptr;
104 self->ext_memory.public_buffer.data_ptr = payload_ptr;
105 self->ext_memory.public_buffer.data_size = payload_sz;
106 self->ext_memory.public_buffer.total_size = payload_sz;
107 self->ext_memory.public_buffer.next_buffer_ptr = NULL;
110 /*! \brief Initially defines a header space in front of the data body
111 * \details Ensure that \c start_ptr is assigned correctly before calling
113 * \param self The instance
114 * \param header_sz Size of the header
116 void Msg_ReserveHeader(CMessage *self, uint8_t header_sz)
118 /* self->start_ptr stays */
119 self->header_rsvd_sz = header_sz;
120 self->header_curr_idx = header_sz;
121 self->header_curr_sz = 0U;
123 self->pb_msg.tel.tel_data_ptr = &self->start_ptr[header_sz];
126 /*! \brief Adds a defined header space in front of the current header
127 * \param self The instance
128 * \param header_sz Size of the header
130 void Msg_PullHeader(CMessage *self, uint8_t header_sz)
132 /* UCS_ASSERT(header_sz <= self->curr_header_sz); */
134 /* self->pb_msg.tel.tel_data_ptr = &self->rsvd_buffer[MSG_SIZE_RSVD_HEADER];*/
135 self->header_curr_idx -= header_sz;
136 self->header_curr_sz += header_sz;
139 /*! \brief Undoes a message header of a defined size
140 * \param self The instance
141 * \param header_sz Size of the header
143 void Msg_PushHeader(CMessage *self, uint8_t header_sz)
145 self->header_curr_idx += header_sz;
146 self->header_curr_sz -= header_sz;
149 /*------------------------------------------------------------------------------------------------*/
150 /* Class Properties (get/set) */
151 /*------------------------------------------------------------------------------------------------*/
152 /*! \brief Retrieves the reference to the containing MOST Telegrams structure
153 * \param self The instance
154 * \return Pointer to the internal MOST Telegram structure
156 Msg_MostTel_t* Msg_GetMostTel(CMessage *self)
158 return &self->pb_msg;
161 /*! \brief Retrieves the start of the current message header
162 * \param self The instance
163 * \return Pointer to the current header start
165 uint8_t* Msg_GetHeader(CMessage *self)
167 return &(self->rsvd_buffer[self->header_curr_idx]);
170 /*! \brief Retrieves the size of the current message header
171 * \param self The instance
172 * \return Size of the current header in bytes
174 uint8_t Msg_GetHeaderSize(CMessage * self)
176 return (self->header_curr_sz);
179 /*! \brief Retrieves the message buffer as memory structure
180 * \param self The instance
181 * \return Reference to the message memory structure
183 Ucs_Mem_Buffer_t* Msg_GetMemTx(CMessage *self)
185 self->rsvd_memory.public_buffer.data_ptr = &(self->rsvd_buffer[self->header_curr_idx]);
187 if (self->ext_memory.public_buffer.data_size == 0U)
189 self->rsvd_memory.public_buffer.next_buffer_ptr = NULL;
190 self->rsvd_memory.public_buffer.data_size = (uint16_t)self->header_curr_sz + (uint16_t)self->pb_msg.tel.tel_len;
191 self->rsvd_memory.public_buffer.total_size = (uint16_t)self->header_curr_sz + (uint16_t)self->pb_msg.tel.tel_len;
195 self->rsvd_memory.public_buffer.next_buffer_ptr = &self->ext_memory.public_buffer;
196 self->rsvd_memory.public_buffer.data_size = (uint16_t)self->header_curr_sz; /* only header is enclosed */
197 self->rsvd_memory.public_buffer.total_size = self->rsvd_memory.public_buffer.data_size
198 + self->ext_memory.public_buffer.data_size;
201 return &self->rsvd_memory.public_buffer;
204 /*! \brief Assigns a message status handler which is called as soon as the message is processed
205 * \param self The instance
206 * \param callback_fptr Reference to the status callback function
207 * \param inst_ptr The instance which implements the status callback
209 void Msg_SetTxStatusHandler(CMessage *self, Msg_TxStatusCb_t callback_fptr, void *inst_ptr)
211 self->tx_status_inst = inst_ptr;
212 self->tx_status_fptr = callback_fptr;
215 /*! \brief Marks the message as occupied by the LLD
216 * \param self The instance
217 * \param active Set to \c true if the message is occupied by the LLD, otherwise \c false.
219 void Msg_SetTxActive(CMessage *self, bool active)
221 self->tx_active = active;
224 /*! \brief Checks if the message as occupied by the LLD
225 * \param self The instance
226 * \return Returns \c true if the message is occupied by the LLD, otherwise \c false.
228 bool Msg_IsTxActive(CMessage *self)
230 return self->tx_active;
233 /*! \brief Marks the message as bypass message
234 * \param self The instance
235 * \param bypass Set to \c true if the message is supposed to be a bypass message, otherwise \c false.
237 void Msg_SetTxBypass(CMessage *self, bool bypass)
239 self->tx_bypass = bypass;
242 /*! \brief Checks if the message is marked as bypass message
243 * \param self The instance
244 * \return Returns \c true if the message is marked as bypass message, otherwise \c false.
246 bool Msg_IsTxBypass(CMessage *self)
248 return self->tx_bypass;
251 /*! \brief Fires a status notification for the message object
252 * \param self The instance
253 * \param status The transmission status
255 void Msg_NotifyTxStatus(CMessage *self, Ucs_MsgTxStatus_t status)
257 if (self->tx_status_fptr != NULL)
259 self->tx_status_fptr(self->tx_status_inst, &self->pb_msg, status);
263 /*! \brief Assigns a low-level driver message
264 * \param self The instance
265 * \param handle The reference to a low-level driver message object (Tx or Rx)
267 void Msg_SetLldHandle(CMessage *self, void *handle)
269 self->lld_handle_ptr = handle;
272 /*! \brief Retrieves the reference to a low-level driver message
273 * \param self The instance
274 * \return The reference to a low-level driver message object or \c NULL
275 * if no message is assigned.
277 void *Msg_GetLldHandle(CMessage *self)
279 return self->lld_handle_ptr;
282 /*! \brief Assigns a reference for the owning pool
283 * \param self The instance
284 * \param pool_ptr The reference to the owning pool
286 void Msg_SetPoolReference(CMessage *self, void *pool_ptr)
288 self->pool_ptr = pool_ptr;
291 /*! \brief Retrieves a reference for the owning pool
292 * \param self The instance
293 * \return The reference to the owning pool or \c NULL
294 * if no pool is assigned.
296 void *Msg_GetPoolReference(CMessage *self)
298 return self->pool_ptr;
301 /*! \brief Retrieves the reference to the internal node member
302 * \param self The instance
303 * \return The reference the internal list node
305 CDlNode *Msg_GetNode(CMessage *self)
310 /*! \brief Performs checks on length payload length
311 * \param self The instance
312 * \return Returns \c true if the verification succeeded. Otherwise \c false.
314 bool Msg_VerifyContent(CMessage *self)
316 bool success = (self->pb_msg.tel.tel_len <= MSG_MAX_SIZE_PAYLOAD) ? true : false;
321 /*! \brief Merges the alternate message id into a the most message id
322 * \param self The instance
323 * \return The alternate message id
325 uint16_t Msg_GetAltMsgId(CMessage *self)
328 msg_id = (uint16_t)(self->pb_msg.id.function_id >> 4);
329 msg_id = (uint16_t)((uint16_t)self->pb_msg.id.instance_id << 8) | msg_id;
333 /*! \brief Extracts the alternate message id from a the most message id
334 * \param self The instance
335 * \param alt_id The alternate message id
337 void Msg_SetAltMsgId(CMessage *self, uint16_t alt_id)
339 self->pb_msg.id.fblock_id = MSG_DEF_FBLOCK_ID;
340 self->pb_msg.id.instance_id = MISC_HB(alt_id);
341 self->pb_msg.id.function_id = (uint16_t)((((alt_id) & (uint16_t)0xFF)) << 4) | (uint16_t)MSG_DEF_FUNC_ID_LSN;
342 self->pb_msg.id.op_type = MSG_DEF_OP_TYPE;
350 /*------------------------------------------------------------------------------------------------*/
352 /*------------------------------------------------------------------------------------------------*/