Updated GDB ini file to load binding symbols directly from SDK
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_message.c
1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491                                                                            */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG.                              */
4 /*                                                                                                */
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.                                                            */
9 /*                                                                                                */
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.                                                   */
14 /*                                                                                                */
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/>.                          */
17 /*                                                                                                */
18 /* You may also obtain this software under a propriety license from Microchip.                    */
19 /* Please contact Microchip for further information.                                              */
20 /*------------------------------------------------------------------------------------------------*/
21
22 /*!
23  * \file
24  * \brief Implementation of class message
25  *
26  * \cond UCS_INTERNAL_DOC
27  * \addtogroup  G_MESSAGE
28  * @{
29  */
30
31 /*------------------------------------------------------------------------------------------------*/
32 /* Includes                                                                                       */
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_message.h"
35 #include "ucs_misc.h"
36
37 /*------------------------------------------------------------------------------------------------*/
38 /* Internal constants                                                                             */
39 /*------------------------------------------------------------------------------------------------*/
40
41 /*------------------------------------------------------------------------------------------------*/
42 /* Implementation                                                                                 */
43 /*------------------------------------------------------------------------------------------------*/
44 /*! \brief  Constructor of common MOST message class
45  *  \param      self      The instance
46  */
47 void Msg_Ctor(CMessage *self)
48 {
49     MISC_MEM_SET(self, 0, sizeof(*self));
50
51     Dln_Ctor(&self->node, self);
52
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;
59
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; */
65
66     self->pb_msg.opts.llrbc     = MSG_LLRBC_DEFAULT;
67
68 /*  self->header_rsvd_sz           = 0U;
69     self->header_curr_idx          = 0U;
70     self->header_curr_sz           = 0U;
71     self->ref_ptr                  = NULL; */
72 }
73
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
78  */
79 void Msg_Cleanup(CMessage *self)
80 {
81     void *handle = self->lld_handle_ptr;       /* restore associated LLD message object */
82     void *pool_ptr = self->pool_ptr;           /* restore associated pool reference */
83
84     Msg_Ctor(self);                            /* simply call constructor now */
85
86     self->lld_handle_ptr = handle;
87     self->pool_ptr = pool_ptr;
88 }
89
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
96  */
97 void Msg_SetExtPayload(CMessage *self, uint8_t *payload_ptr, uint8_t payload_sz, void* mem_info_ptr)
98 {
99     self->pb_msg.tel.tel_data_ptr = payload_ptr;
100     self->pb_msg.tel.tel_len = payload_sz;
101
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;
108 }
109
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 
112  *              this functions.
113  *  \param      self        The instance
114  *  \param      header_sz   Size of the header
115  */
116 void Msg_ReserveHeader(CMessage *self, uint8_t header_sz)
117 {
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;
122
123     self->pb_msg.tel.tel_data_ptr = &self->start_ptr[header_sz];
124 }
125
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
129  */
130 void Msg_PullHeader(CMessage *self, uint8_t header_sz)
131 {
132 /*  UCS_ASSERT(header_sz <= self->curr_header_sz); */
133
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;
137 }
138
139 /*! \brief      Undoes a message header of a defined size
140  *  \param      self        The instance
141  *  \param      header_sz   Size of the header
142  */
143 void Msg_PushHeader(CMessage *self, uint8_t header_sz)
144 {
145     self->header_curr_idx += header_sz;
146     self->header_curr_sz  -= header_sz;
147 }
148
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
155  */
156 Msg_MostTel_t* Msg_GetMostTel(CMessage *self)
157 {
158     return &self->pb_msg;
159 }
160
161 /*! \brief  Retrieves the start of the current message header
162  *  \param  self    The instance
163  *  \return Pointer to the current header start 
164  */
165 uint8_t* Msg_GetHeader(CMessage *self)
166 {
167     return &(self->rsvd_buffer[self->header_curr_idx]);
168 }
169
170 /*! \brief  Retrieves the size of the current message header
171  *  \param  self    The instance
172  *  \return Size of the current header in bytes 
173  */
174 uint8_t Msg_GetHeaderSize(CMessage * self)
175 {
176     return (self->header_curr_sz);
177 }
178
179 /*! \brief  Retrieves the message buffer as memory structure
180  *  \param  self    The instance
181  *  \return Reference to the message memory structure
182  */
183 Ucs_Mem_Buffer_t* Msg_GetMemTx(CMessage *self)
184 {
185     self->rsvd_memory.public_buffer.data_ptr = &(self->rsvd_buffer[self->header_curr_idx]);
186
187     if (self->ext_memory.public_buffer.data_size == 0U)
188     {
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;
192     }
193     else
194     {
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;
199     }
200
201     return &self->rsvd_memory.public_buffer;
202 }
203
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
208  */
209 void Msg_SetTxStatusHandler(CMessage *self, Msg_TxStatusCb_t callback_fptr, void *inst_ptr)
210 {
211     self->tx_status_inst = inst_ptr;
212     self->tx_status_fptr = callback_fptr;
213 }
214
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.
218  */
219 void Msg_SetTxActive(CMessage *self, bool active)
220 {
221     self->tx_active = active;
222 }
223
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.
227  */
228 bool Msg_IsTxActive(CMessage *self)
229 {
230     return self->tx_active;
231 }
232
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.
236  */
237 void Msg_SetTxBypass(CMessage *self, bool bypass)
238 {
239     self->tx_bypass = bypass;
240 }
241
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.
245  */
246 bool Msg_IsTxBypass(CMessage *self)
247 {
248     return self->tx_bypass;
249 }
250
251 /*! \brief  Fires a status notification for the message object
252  *  \param  self    The instance
253  *  \param  status  The transmission status
254  */
255 void Msg_NotifyTxStatus(CMessage *self, Ucs_MsgTxStatus_t status)
256 {
257     if (self->tx_status_fptr != NULL)
258     {
259         self->tx_status_fptr(self->tx_status_inst, &self->pb_msg, status); 
260     }
261 }
262
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)
266  */
267 void Msg_SetLldHandle(CMessage *self, void *handle)
268 {
269     self->lld_handle_ptr = handle;
270 }
271
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.
276  */
277 void *Msg_GetLldHandle(CMessage *self)
278 {
279     return self->lld_handle_ptr;
280 }
281
282 /*! \brief  Assigns a reference for the owning pool
283  *  \param  self      The instance
284  *  \param  pool_ptr  The reference to the owning pool
285  */
286 void Msg_SetPoolReference(CMessage *self, void *pool_ptr)
287 {
288     self->pool_ptr = pool_ptr;
289 }
290
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.
295  */
296 void *Msg_GetPoolReference(CMessage *self)
297 {
298     return self->pool_ptr;
299 }
300
301 /*! \brief  Retrieves the reference to the internal node member
302  *  \param  self    The instance
303  *  \return The reference the internal list node 
304  */
305 CDlNode *Msg_GetNode(CMessage *self)
306 {
307     return &self->node;
308 }
309
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.
313  */
314 bool Msg_VerifyContent(CMessage *self)
315 {
316     bool success = (self->pb_msg.tel.tel_len <= MSG_MAX_SIZE_PAYLOAD) ? true : false;
317
318     return success;
319 }
320
321 /*! \brief  Merges the alternate message id into a the most message id
322  *  \param  self     The instance
323  *  \return The alternate message id
324  */
325 uint16_t Msg_GetAltMsgId(CMessage *self)
326 {
327     uint16_t msg_id;
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;
330     return msg_id;
331 }
332
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
336  */
337 void Msg_SetAltMsgId(CMessage *self, uint16_t alt_id)
338 {
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;
343 }
344
345 /*!
346  * @}
347  * \endcond
348  */
349
350 /*------------------------------------------------------------------------------------------------*/
351 /* End of file                                                                                    */
352 /*------------------------------------------------------------------------------------------------*/
353