Initial Commit
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_amd.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 Application Message Distributor
25  *
26  * \cond UCS_INTERNAL_DOC
27  * \addtogroup  G_AMD
28  * @{
29  */
30
31 /*------------------------------------------------------------------------------------------------*/
32 /* Includes                                                                                       */
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_amd.h"
35 #include "ucs_misc.h"
36
37 /*! \brief Priority of the Application Message Distribution */
38 static const uint8_t AMD_SRV_PRIO           = 248U; /* parasoft-suppress  MISRA2004-8_7 "configuration property" */
39 /*! \brief Event which starts the Rx message distribution */
40 static const Srv_Event_t AMD_EV_NOTIFY_RX   = 1U;
41 /*! \brief Event triggers notification of messages in tx_notify_queue */
42 static const Srv_Event_t AMD_EV_NOTIFY_TX   = 2U;
43 /*! \brief FBlockID of FBlock NetBlock */
44 static const uint8_t AMD_FB_NETBLOCK        = 1U;
45 /*! \brief FBlockID of FBlock NetworkMaster */
46 static const uint8_t AMD_FB_NETWORKMASTER   = 2U;
47
48 /*------------------------------------------------------------------------------------------------*/
49 /* Internal prototypes                                                                            */
50 /*------------------------------------------------------------------------------------------------*/
51 static void Amd_Service(void *self);
52 static void Amd_OnAmsComplete(void* self, Ucs_AmsRx_Msg_t* msg_ptr);
53 static void Amd_OnEvent(void *self, void *error_code_ptr);
54 static void Amd_OnTerminateEvent(void *self, void *error_code_ptr);
55 static void Amd_RxFlush(CAmd *self, CDlList *list_ptr);
56 #ifdef AMD_TX_DISTRIB
57 static bool Amd_TxIsRcmMsg(Ucs_AmsTx_Msg_t *msg_ptr);
58 static bool Amd_TxReceiveInternal(CAmd *self, Ucs_AmsTx_Msg_t *msg_ptr);
59 static void Amd_TxProcessNotifyQueue(CAmd *self);
60 #endif
61
62 /*------------------------------------------------------------------------------------------------*/
63 /* Initialization                                                                                 */
64 /*------------------------------------------------------------------------------------------------*/
65 /*! \brief Constructor of class CAmd
66  *  \param self     The instance
67  *  \param base_ptr Reference to base services
68  *  \param ams_ptr  Reference to the AMS
69  */
70 void Amd_Ctor(CAmd *self, CBase *base_ptr, CAms *ams_ptr)
71 {
72     MISC_MEM_SET((void *)self, 0, sizeof(*self));                 /* reset members to "0" */
73
74     self->base_ptr = base_ptr;
75     self->ams_ptr = ams_ptr;
76
77     self->started = false;
78     Srv_Ctor(&self->service, AMD_SRV_PRIO, self, &Amd_Service);   /* register service */
79     (void)Scd_AddService(&self->base_ptr->scd, &self->service);
80
81     Dl_Ctor(&self->pre_queue, self->base_ptr->ucs_user_ptr);       /* init preprocessor queue */
82     Dl_Ctor(&self->rx_queue, self->base_ptr->ucs_user_ptr);        /* init Rx queue */
83                                                                   /* register event observer */
84     Mobs_Ctor(&self->event_observer, self, EH_E_INIT_SUCCEEDED, &Amd_OnEvent);
85     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->event_observer);
86                                                                   /* register termination events */
87     Mobs_Ctor(&self->terminate_observer, self, EH_M_TERMINATION_EVENTS, &Amd_OnTerminateEvent);
88     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->terminate_observer);
89
90     Ams_RxAssignReceiver(self->ams_ptr, &Amd_OnAmsComplete, self);
91 }
92
93
94 #ifdef AMD_TX_DISTRIB
95 /*! \brief Constructor of class CAmd
96  *  \param self     The instance
97  *  \param base_ptr Reference to base services
98  *  \param ams_ptr  Reference to the AMS
99  *  \param pool_ptr Reference to the AMS message pool
100  *  \param inic_ptr Reference to the INIC
101  *  \param net_ptr  Reference to the network management
102  */
103 void Amd_Ctor(CAmd *self, CBase *base_ptr, CAms *ams_ptr, CAmsMsgPool *pool_ptr, CInic *inic_ptr, CNetworkManagement *net_ptr)
104 {
105     MISC_MEM_SET((void *)self, 0, sizeof(*self));                 /* reset members to "0" */
106
107     self->base_ptr = base_ptr;
108     self->ams_ptr = ams_ptr;
109     self->pool_ptr = pool_ptr;
110     self->inic_ptr = inic_ptr;
111     self->net_ptr = net_ptr;
112
113     self->started = false;
114     Srv_Ctor(&self->service, AMD_SRV_PRIO, self, &Amd_Service);   /* register service */
115     (void)Scd_AddService(&self->base_ptr->scd, &self->service);
116
117     Dl_Ctor(&self->tx_notify_queue, self->base_ptr->ucs_inst_id); /* init queues */
118     Dl_Ctor(&self->pre_queue, self->base_ptr->ucs_inst_id);       /* init preprocessor queue */
119     Dl_Ctor(&self->rx_queue, self->base_ptr->ucs_inst_id);        /* init Rx queue */
120                                                                   /* register event observer */
121     Mobs_Ctor(&self->event_observer, self, EH_E_INIT_SUCCEEDED, &Amd_OnEvent);
122     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->event_observer);
123                                                                   /* register termination events */
124     Mobs_Ctor(&self->terminate_observer, self, EH_M_TERMINATION_EVENTS, &Amd_OnTerminateEvent);
125     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->terminate_observer);
126
127     Ams_RxAssignReceiver(self->ams_ptr, &Amd_OnAmsComplete, self);
128     Ams_TxAssignTrcvSelector(self->ams_ptr, &Amd_TxIsRcmMsg);
129 }
130 #endif
131
132 /*! \brief   Assigns a pre-processor callback function for Rx messages
133  *  \details This function must be called during initialization time.
134  *           The AMS shall not already run.
135  *  \param   self          The instance
136  *  \param   callback_fptr Reference to the callback function
137  *  \param   inst_ptr      Reference to the pre-processor
138  */
139 void Amd_AssignPreprocessor(CAmd *self, Amd_RxMsgCompleteCb_t callback_fptr, void *inst_ptr)
140 {
141     if (callback_fptr != NULL)
142     {
143         self->preprocess_fptr = callback_fptr;
144         self->preprocess_inst_ptr = inst_ptr;
145
146         self->first_receive_fptr = callback_fptr;
147         self->first_receive_inst_ptr = inst_ptr;
148         self->first_q_ptr = &self->pre_queue;
149     }
150 }
151
152 /*! \brief   Assigns a receiver callback function for Rx messages
153  *  \details This function must be called during initialization time.
154  *           The AMS shall not already run.
155  *  \param   self          The instance
156  *  \param   callback_fptr Reference to the callback function
157  *  \param   inst_ptr      Reference to the receiver
158  */
159 void Amd_AssignReceiver(CAmd *self, Amd_RxMsgCompleteCb_t callback_fptr, void *inst_ptr)
160 {
161     if (callback_fptr != NULL)
162     {
163         self->receive_fptr = callback_fptr;
164         self->receive_inst_ptr = inst_ptr;
165
166         if (self->first_receive_fptr == NULL)
167         {
168             self->first_receive_fptr = callback_fptr;
169             self->first_receive_inst_ptr = inst_ptr;
170             self->first_q_ptr = &self->rx_queue;
171         }
172     }
173 }
174
175 /*! \brief   Assigns as callback function which is able to read and modify the Rx message
176  *  \param   self          The instance
177  *  \param   callback_fptr Reference to the callback function
178  *  \param   inst_ptr      Reference to the instance (owner of the callback function)
179  */
180 void Amd_RxAssignModificator(CAmd *self, Amd_RxModificationCb_t callback_fptr, void *inst_ptr)
181 {
182     if (callback_fptr != NULL)
183     {
184         self->rx_modification_fptr = callback_fptr;
185         self->rx_modification_inst_ptr = inst_ptr;
186     }
187 }
188
189 /*! \brief   Service function of CAmd
190  *  \details The processing of the Rx queues shall be started asynchronously
191  *           after the initialization has succeeded.
192  *  \param   self          The instance
193  */
194 static void Amd_Service(void *self)
195 {
196     CAmd *self_ = (CAmd*)self;
197     Srv_Event_t event_mask;
198     Srv_GetEvent(&self_->service, &event_mask);
199
200     if((event_mask & AMD_EV_NOTIFY_RX) == AMD_EV_NOTIFY_RX)     /* triggered on internal transmission */
201     {
202         Srv_ClearEvent(&self_->service, AMD_EV_NOTIFY_RX);
203         if ((self_->started != false) && (self_->first_receive_fptr != NULL))
204         {
205             uint16_t size = Dl_GetSize(self_->first_q_ptr);
206             if (size > 0U)
207             {
208                 self_->first_receive_fptr(self_->first_receive_inst_ptr);
209             }
210         }
211     }
212
213 #ifdef AMD_TX_DISTRIB
214     if((event_mask & AMD_EV_NOTIFY_TX) == AMD_EV_NOTIFY_TX)     /* notify Tx distribution failure asynchronously */
215     {
216         Srv_ClearEvent(&self_->service, AMD_EV_NOTIFY_TX);
217         Amd_TxProcessNotifyQueue(self_);
218     }
219 #endif
220 }
221
222 /*------------------------------------------------------------------------------------------------*/
223 /* Events                                                                                         */
224 /*------------------------------------------------------------------------------------------------*/
225 /*! \brief  Callback function which is invoked on completed application message reception
226  *  \param  self        The instance
227  *  \param  msg_ptr     Reference to the completed application message
228  */
229 static void Amd_OnAmsComplete(void *self, Ucs_AmsRx_Msg_t *msg_ptr)
230 {
231     CAmd *self_ = (CAmd*)self;
232
233     if (self_->rx_modification_fptr != NULL)
234     {
235         self_->rx_modification_fptr(self_->rx_modification_inst_ptr, msg_ptr);
236     }
237
238     if (self_->first_receive_fptr != NULL)
239     {
240         Amsg_RxEnqueue(msg_ptr, self_->first_q_ptr);
241
242         if (self_->started != false)
243         {
244             self_->first_receive_fptr(self_->first_receive_inst_ptr);
245         }
246     }
247     else
248     {
249         Ams_RxFreeMsg(self_->ams_ptr, msg_ptr);
250     }
251 }
252
253 /*! \brief  Callback function if an events leads to the termination of the MNS
254  *  \param  self            The instance
255  *  \param  error_code_ptr  Reference to the error code
256  */
257 static void Amd_OnTerminateEvent(void *self, void *error_code_ptr)
258 {
259     CAmd *self_ = (CAmd*)self;
260     MISC_UNUSED(error_code_ptr);
261
262     TR_INFO((self_->base_ptr->ucs_user_ptr, "[AMD]", "Starting AMD Cleanup", 0U));
263     Amd_RxFlush(self_, &self_->pre_queue);
264     Amd_RxFlush(self_, &self_->rx_queue);
265 #ifdef AMD_TX_DISTRIB
266     Amd_TxProcessNotifyQueue(self_);
267 #endif
268     TR_INFO((self_->base_ptr->ucs_user_ptr, "[AMD]", "Finished AMD Cleanup", 0U));
269 }
270
271 /*! \brief  Callback function which is invoked if the initialization is complete
272  *  \param  self            The instance
273  *  \param  error_code_ptr  Reference to the error code
274  */
275 static void Amd_OnEvent(void *self, void *error_code_ptr)
276 {
277     CAmd *self_ = (CAmd*)self;
278     MISC_UNUSED(error_code_ptr);
279
280     TR_INFO((self_->base_ptr->ucs_user_ptr, "[AMD]", "Received init complete event", 0U));
281     self_->started = true;
282     Srv_SetEvent(&self_->service, AMD_EV_NOTIFY_RX);
283 }
284
285 /*! \brief  Flushes a given application Rx message queue
286  *  \param  self        The instance
287  *  \param  list_ptr    Reference to a list containing application Rx message objects
288  */
289 static void Amd_RxFlush(CAmd *self, CDlList *list_ptr)
290 {
291     Ucs_AmsRx_Msg_t *msg_ptr;
292
293     for (msg_ptr = Amsg_RxDequeue(list_ptr); msg_ptr != NULL; msg_ptr = Amsg_RxDequeue(list_ptr))
294     {
295         Ams_RxFreeMsg(self->ams_ptr, msg_ptr);
296     }
297 }
298
299 /*------------------------------------------------------------------------------------------------*/
300 /* Pre-processor methods                                                                          */
301 /*------------------------------------------------------------------------------------------------*/
302 /*! \brief  Peeks the front-most application message from the preprocessing queue
303  *  \param  self        The instance
304  *  \return Returns a reference to the front-most application message or \c NULL if the queue
305  *          is empty.
306  */
307 Ucs_AmsRx_Msg_t* Amd_PrePeekMsg(CAmd *self)
308 {
309     return (Ucs_AmsRx_Msg_t*)(void*)Amsg_RxPeek(&self->pre_queue);
310 }
311
312 /*! \brief  Removes the front-most application message from the preprocessing queue and frees it
313  *  \param  self        The instance
314  */
315 void Amd_PreReleaseMsg(CAmd *self)
316 {
317     Ucs_AmsRx_Msg_t *msg_ptr = Amsg_RxDequeue(&self->pre_queue);
318
319     if (msg_ptr != NULL)
320     {
321         Ams_RxFreeMsg(self->ams_ptr, msg_ptr);
322     }
323 }
324
325 /*! \brief  Forwards the front-most application message from the preprocessing queue to the Rx queue
326  *  \param  self        The instance
327  */
328 void Amd_PreForwardMsg(CAmd *self)
329 {
330     Ucs_AmsRx_Msg_t *msg_ptr = Amsg_RxDequeue(&self->pre_queue);
331
332     if (msg_ptr != NULL)
333     {
334         if (self->receive_fptr != NULL)
335         {
336             Amsg_RxEnqueue(msg_ptr, &self->rx_queue);
337             self->receive_fptr(self->receive_inst_ptr);
338         }
339         else
340         {
341             Ams_RxFreeMsg(self->ams_ptr, msg_ptr);
342         }
343     }
344 }
345
346 /*------------------------------------------------------------------------------------------------*/
347 /* Receiver methods                                                                               */
348 /*------------------------------------------------------------------------------------------------*/
349 /*! \brief  Peeks the front-most application message from the Rx queue
350  *  \param  self        The instance
351  *  \return Returns a reference to the front-most application message or \c NULL if the queue
352  *          is empty.
353  */
354 Ucs_AmsRx_Msg_t* Amd_RxPeekMsg(CAmd *self)
355 {
356     return (Ucs_AmsRx_Msg_t*)(void*)Amsg_RxPeek(&self->rx_queue);
357 }
358
359 /*! \brief  Removes the front-most application message from the Rx queue and frees it
360  *  \param  self        The instance
361  */
362 void Amd_RxReleaseMsg(CAmd *self)
363 {
364     Ucs_AmsRx_Msg_t *msg_ptr = Amsg_RxDequeue(&self->rx_queue);
365
366     if (msg_ptr != NULL)
367     {
368         Ams_RxFreeMsg(self->ams_ptr, msg_ptr);
369     }
370 }
371
372 /*! \brief  Retrieves the number of messages which are appended to the Rx queue
373  *  \param  self        The instance
374  *  \return Returns the number of messages.
375  */
376 uint16_t Amd_RxGetMsgCnt(CAmd *self)
377 {
378     return Dl_GetSize(&self->rx_queue);
379 }
380
381 #ifdef AMD_TX_DISTRIB
382 /*------------------------------------------------------------------------------------------------*/
383 /* Transmitter methods                                                                            */
384 /*------------------------------------------------------------------------------------------------*/
385 /*! \brief  Distributes a Tx message internally as Rx message
386  *  \param  self                    The instance
387  *  \param  msg_ptr                 The Tx message
388  *  \param  tx_complete_sia_fptr    Single instance API callback function which is invoked as soon as 
389  *                                  the transmission was finished.
390  *  \param  tx_complete_fptr        Multi instance callback function which is invoked as soon as 
391  *                                  the transmission was finished.
392  *  \param  tx_complete_inst_ptr    Instance pointer which is referred when tx_complete_fptr is invoked. 
393  *  \return Returns \c UCS_RET_SUCCESS if the message accepted for transmission.
394  *          Returns \c UCS_RET_ERR_PARAM if the message is refused due to invalid message attributes.
395  */
396 Ucs_Return_t Amd_TxSendMsg(CAmd *self, Ucs_AmsTx_Msg_t *msg_ptr, Amsg_TxCompleteSiaCb_t tx_complete_sia_fptr, 
397                            Amsg_TxCompleteCb_t tx_complete_fptr, void* tx_complete_inst_ptr)
398 {
399     Ucs_Return_t ret = UCS_RET_SUCCESS;
400     bool tx_internal = false;
401     bool tx_network = false;
402     bool tx_ignore_nw_failure = false;
403     bool tx_check_ni = true;                                    /* if false, transmit to INIC even during NET_OFF  */
404
405     if (Ams_TxIsValidMessage(msg_ptr) != false)
406     {
407         Net_IsOwnAddrResult_t addr_type = Net_IsOwnAddress(self->net_ptr, msg_ptr->destination_address);
408
409         TR_ASSERT(self->base_ptr->ucs_user_ptr, "[AMS]", (((tx_complete_sia_fptr != NULL) && (tx_complete_fptr != NULL)) == false));
410         Amsg_TxSetCompleteCallback(msg_ptr, tx_complete_sia_fptr, tx_complete_fptr, tx_complete_inst_ptr);
411
412         if (msg_ptr->destination_address == UCS_ADDR_INTERNAL)
413         {
414             tx_internal = true;                                 /* do not forward internal messages to INIC */
415         }
416         else if ((msg_ptr->fblock_id == AMD_FB_NETBLOCK) || (msg_ptr->fblock_id == AMD_FB_NETWORKMASTER))
417         {
418             if (addr_type == NET_IS_OWN_ADDR_NODE)              /* replace own node address by "1" to force INIC internal routing */
419             {                                                   /* do not replace multicast addresses (these are static and handled by INIC) */
420                 Amsg_TxReplaceDestinationAddr(msg_ptr, MSG_ADDR_INIC);
421             }
422             else if ((addr_type == NET_IS_OWN_ADDR_GROUP) ||
423                      (msg_ptr->destination_address == UCS_ADDR_BROADCAST_BLOCKING) ||
424                      (msg_ptr->destination_address == UCS_ADDR_BROADCAST_UNBLOCKING))
425             {
426                 tx_ignore_nw_failure = true;
427             }
428
429             tx_network = true;                                  /* route FBlocks NB and NWM to INIC */
430             tx_check_ni = false;                                /* INIC performs checks independent from NI state */
431         }
432         else if ((msg_ptr->destination_address == UCS_ADDR_BROADCAST_BLOCKING) ||
433                 (msg_ptr->destination_address == UCS_ADDR_BROADCAST_UNBLOCKING))
434         {
435             tx_internal = true;                                 /* forward broadcast messages to INIC and distribute internally */
436             tx_network = true;
437         }
438         else
439         { 
440             switch (addr_type)
441             {
442                 case NET_IS_OWN_ADDR_NODE:
443                     tx_internal = true;
444                     break;
445                 case NET_IS_OWN_ADDR_GROUP:
446                     tx_internal = true;
447                     tx_network = true;
448                     break;
449                 case NET_IS_OWN_ADDR_NONE:
450                 default:
451                     tx_network = true;
452                     break;
453             }
454         }
455
456         if ((Inic_GetAvailability(self->inic_ptr) == UCS_NW_NOT_AVAILABLE) && (tx_check_ni == true))
457         { 
458             tx_network = false;                                 /* abort network transmission */
459             Amsg_TxUpdateResult(msg_ptr, UCS_MSG_STAT_ERROR_NA_OFF);
460         }
461
462         if (tx_internal != false)
463         {
464             if (Amd_TxReceiveInternal(self, msg_ptr) == false)
465             {                                                   /* internal transmission failed */
466                 Amsg_TxUpdateInternalResult(msg_ptr, AMSG_TX_INTRES_ERRBUF);
467             }
468             else
469             {                                                   /* internal transmission succeeded */
470                 Amsg_TxUpdateInternalResult(msg_ptr, AMSG_TX_INTRES_SUCCESS);
471             }
472         }
473         else if (tx_ignore_nw_failure != false)
474         {                                                       /* INIC routing will succeed while NW transmission fails */
475             Amsg_TxUpdateInternalResult(msg_ptr, AMSG_TX_INTRES_SUCCESS);
476         }
477
478         if (tx_network == false)
479         {                                                       /* enqueue message to notification queue and set event */
480             Amsg_TxEnqueue(msg_ptr, &self->tx_notify_queue);
481             Srv_SetEvent(&self->service, AMD_EV_NOTIFY_TX);
482         }
483         else
484         {
485             Ams_TxSendMsgDirect(self->ams_ptr, msg_ptr);
486         }
487     }
488     else
489     {
490         ret = UCS_RET_ERR_PARAM;                                /* invalid message parameters */
491     }
492
493     return ret;
494 }
495
496 /*! \brief  Decides whether to root a message to MCM or RCM FIFO
497  *  \param  msg_ptr                 The Tx message object 
498  *  \return Returns \c true if a Tx message shall be routed to RCM FIFO, otherwise returns \c false.
499  */
500 static bool Amd_TxIsRcmMsg(Ucs_AmsTx_Msg_t *msg_ptr)
501 {
502     bool ret = false;
503     if (((msg_ptr->fblock_id == AMD_FB_NETBLOCK) && (msg_ptr->op_type <= UCS_OP_STARTACK))        /* is NB.Command */
504        || ((msg_ptr->fblock_id == AMD_FB_NETWORKMASTER) && (msg_ptr->op_type > UCS_OP_STARTACK))) /* or NWM.Report?*/
505     {
506         ret = true;
507     }
508
509     return ret;
510 }
511
512 /*! \brief  Distributes a Tx message internally as Rx message
513  *  \param  self        The instance
514  *  \param  msg_ptr     The Tx message
515  *  \return Returns \c true if the message distributed successfully.
516  *          Returns \c false if the allocation of the Rx message has failed.
517  */
518 static bool Amd_TxReceiveInternal(CAmd *self, Ucs_AmsTx_Msg_t *msg_ptr)
519 {
520     bool ret = false;
521     Ucs_AmsRx_Msg_t *rx_ptr = Amsp_AllocRxObj(self->pool_ptr, msg_ptr->data_size);
522
523     if (rx_ptr != NULL)
524     {
525         uint16_t src_addr = UCS_ADDR_INTERNAL;
526         if (msg_ptr->destination_address != UCS_ADDR_INTERNAL)
527         {
528             src_addr = Inic_GetNodeAddress(self->inic_ptr);
529         }
530         Amsg_RxBuildFromTx(rx_ptr, msg_ptr, src_addr);
531         if (self->first_q_ptr != NULL)
532         {
533             Amsg_RxEnqueue(rx_ptr, self->first_q_ptr);
534             Srv_SetEvent(&self->service, AMD_EV_NOTIFY_RX);
535             ret = true;
536         }
537         else
538         {
539             Amsp_FreeRxObj(self->pool_ptr, rx_ptr);
540             TR_FAILED_ASSERT(self->base_ptr->ucs_user_ptr, "[AMD]");
541         }
542     }
543
544     return ret;
545 }
546
547 /*! \brief  Notifies the transmission result for all messages in the tx_notify_queue
548  *  \param  self        The instance
549  */
550 static void Amd_TxProcessNotifyQueue(CAmd *self)
551 {
552     Ucs_AmsTx_Msg_t *tx_ptr = NULL;
553
554     for (tx_ptr = Amsg_TxDequeue(&self->tx_notify_queue); tx_ptr != NULL; tx_ptr = Amsg_TxDequeue(&self->tx_notify_queue))
555     {
556         /* just just notify completion, the object is automatically freed to the pool */
557         Amsg_TxNotifyComplete(tx_ptr, Amsg_TxGetResultCode(tx_ptr), Amsg_TxGetResultInfo(tx_ptr));
558     }
559 }
560 #endif
561
562 /*!
563  * @}
564  * \endcond
565  */
566
567 /*------------------------------------------------------------------------------------------------*/
568 /* End of file                                                                                    */
569 /*------------------------------------------------------------------------------------------------*/
570