Use latest version of conf.d/templates submodule.
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_class.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 the UNICENS API.
25  */
26
27 /*------------------------------------------------------------------------------------------------*/
28 /* Includes                                                                                       */
29 /*------------------------------------------------------------------------------------------------*/
30 #include "ucs_class.h"
31 #include "ucs_misc.h"
32 #include "ucs_trace.h"
33 #include "ucs_ams.h"
34 #include "ucs_cmd.h"
35
36 /*------------------------------------------------------------------------------------------------*/
37 /* Macros                                                                                         */
38 /*------------------------------------------------------------------------------------------------*/
39 /*! \def     UCS_NUM_INSTANCES
40  *  \brief   Number of API instances which can be created by function Ucs_CreateInstance().
41  *  \details One API instance is used to communicate with one local INIC. In this case the application
42  *           is connected to one network.
43  *           It is possible access multiple networks by having multiple API instances. Each API instance
44  *           requires communication with an exclusive INIC.
45  *           Valid values: 1..10. Default Value: 1.
46  *  \ingroup G_UCS_INIT_AND_SRV
47  */ 
48 #ifndef UCS_NUM_INSTANCES
49 # define UCS_NUM_INSTANCES 1
50 # define UCS_API_INSTANCES 1U                   /* default value */
51 #elif (UCS_NUM_INSTANCES > 10)
52 # define UCS_API_INSTANCES 10U
53 #elif (UCS_NUM_INSTANCES < 1)
54 # define UCS_API_INSTANCES 1U
55 #else
56 # define UCS_API_INSTANCES ((uint8_t)UCS_NUM_INSTANCES)
57 #endif
58
59 /*! \cond UCS_INTERNAL_DOC
60  *  \addtogroup G_UCS_CLASS
61  *  @{
62  */
63
64 /*------------------------------------------------------------------------------------------------*/
65 /* Internal Prototypes                                                                            */
66 /*------------------------------------------------------------------------------------------------*/
67 static bool Ucs_CheckInitData(const Ucs_InitData_t *init_ptr);
68 static void Ucs_Ctor(CUcs* self, uint8_t ucs_inst_id, void *api_user_ptr);
69 static void Ucs_InitComponents(CUcs* self);
70 static void Ucs_InitFactoryComponent(CUcs *self);
71 static void Ucs_InitBaseComponent(CUcs *self);
72 static void Ucs_InitPmsComponentConfig(CUcs *self);
73 static void Ucs_InitNetComponent(CUcs *self);
74 static void Ucs_InitLocalInicComponent(CUcs *self);
75 static void Ucs_InitRoutingComponent(CUcs *self);
76 static void Ucs_InitAtsClass(CUcs *self);
77 static void Ucs_InitExcComponent(CUcs *self);
78 static void Ucs_InitSysDiagComponent(CUcs *self);
79 static void Ucs_InitNodeDiscovery(CUcs *self);
80 static void Ucs_InitBackChannelDiagnosis(CUcs *self);
81 static void Ucs_InitProgramming(CUcs *self);
82 static void Ucs_InitManager(CUcs *self);
83 static void Ucs_InitResultCb(void *self, void *result_ptr);
84 static void Ucs_UninitResultCb(void *self, void *error_code_ptr);
85 static void Ucs_OnRxRcm(void *self, Msg_MostTel_t *tel_ptr);
86 static bool Ucs_OnRxMsgFilter(void *self, Msg_MostTel_t *tel_ptr);
87 static void Ucs_OnGetTickCount(void *self, void *tick_count_value_ptr);
88 static void Ucs_OnSetApplicationTimer(void *self, void *new_time_value_ptr);
89 static void Ucs_OnServiceRequest(void *self, void *result_ptr);
90 static void Ucs_OnGeneralError(void *self, void *result_ptr);
91 static void Ucs_Most_PortStatusCb(void *self, void *result_ptr);
92 static void Ucs_StartAppNotification(CUcs *self);
93 static void Ucs_StopAppNotification(CUcs *self);
94 static void Ucs_Inic_OnDeviceStatus(void *self, void *data_ptr);
95 static void Ucs_NetworkStartupResult(void *self, void *result_ptr);
96 static void Ucs_NetworkShutdownResult(void *self, void *result_ptr);
97 static void Ucs_NetworkForceNAResult(void *self, void *result_ptr);
98 static void Ucs_NetworkFrameCounterResult(void *self, void *result_ptr);
99 static void Ucs_NetworkStatus(void *self, void *result_ptr);
100 static void Ucs_InitPmsComponent(CUcs *self);
101 static void Ucs_InitPmsComponentApp(CUcs *self);
102 static void Ucs_InitAmsComponent(CUcs *self);
103 static void Ucs_AmsRx_Callback(void *self);
104 static void Ucs_AmsTx_FreedCallback(void *self, void *data_ptr);
105 static bool Ucs_McmRx_FilterCallback(void *self, Msg_MostTel_t *tel_ptr);
106 static Ucs_Nd_CheckResult_t Ucs_OnNdEvaluate(void *self, Ucs_Signature_t *signature_ptr);
107 static void Ucs_OnNdReport(void *self, Ucs_Nd_ResCode_t code, Ucs_Signature_t *signature_ptr);
108
109 /*------------------------------------------------------------------------------------------------*/
110 /* Public Methods                                                                                 */
111 /*------------------------------------------------------------------------------------------------*/
112 extern Ucs_Inst_t* Ucs_CreateInstance(void)
113 {
114     static CUcs api_instances[UCS_API_INSTANCES];
115     static uint8_t next_index = 0U;
116     Ucs_Inst_t *inst_ptr = NULL;
117
118     if (next_index < UCS_API_INSTANCES)
119     {
120         CUcs *ucs_ptr = &api_instances[next_index];
121         ucs_ptr->ucs_inst_id = next_index + 1U;                         /* start with instance id "1" */
122         TR_INFO((ucs_ptr->ucs_user_ptr, "[API]", "Ucs_CreateInstance(): returns 0x%p", 1U, ucs_ptr));
123         inst_ptr = (Ucs_Inst_t*)(void*)ucs_ptr;                         /* convert API pointer to abstract data type */
124         next_index++;
125     }
126     else
127     {
128         TR_INFO((0U, "[API]", "Ucs_CreateInstance(): failed!", 0U));
129     }
130
131     return inst_ptr;
132 }
133
134
135 /*------------------------------------------------------------------------------------------------*/
136 /* Initialization structure                                                                       */
137 /*------------------------------------------------------------------------------------------------*/
138 extern Ucs_Return_t Ucs_SetDefaultConfig(Ucs_InitData_t *init_ptr)
139 {
140     Ucs_Return_t ret = UCS_RET_ERR_PARAM;
141
142     if (init_ptr != NULL)
143     {
144         MISC_MEM_SET(init_ptr, 0, sizeof(*init_ptr));
145         /* -- add default values here -- */
146         init_ptr->general.inic_watchdog_enabled = true;
147         init_ptr->ams.enabled = true;
148         init_ptr->network.status.notification_mask = 0xFFFFU;           /* Initialize notification masks for NET callbacks */
149         init_ptr->mgr.packet_bw = MGR_PACKET_BW_DEFAULT;
150         init_ptr->mgr.enabled = false;
151         ret = UCS_RET_SUCCESS;
152     }
153
154     TR_INFO((0U, "[API]", "Ucs_SetDefaultConfig(init_ptr: 0x%p): called", 1U, init_ptr));
155     return ret;
156 }
157
158 /*! \brief  Checks if the given initialization data is valid
159  *  \param  init_ptr    Reference to initialization data
160  *  \return Returns \c true if the given initialization data is valid, otherwise \c false.
161  */
162 static bool Ucs_CheckInitData(const Ucs_InitData_t *init_ptr)
163 {
164     bool ret_val = true;
165
166     if ((init_ptr == NULL) ||                                                   /* General NULL pointer checks */
167         (init_ptr->general.get_tick_count_fptr == NULL) ||
168         (init_ptr->lld.start_fptr == NULL) ||
169         (init_ptr->lld.stop_fptr == NULL) ||
170         (init_ptr->lld.tx_transmit_fptr == NULL)
171       )
172     {
173         TR_ERROR((0U, "[API]", "Initialization failed. Required initialization data contains a NULL pointer.", 0U));
174         ret_val = false;
175     }
176     else if (((init_ptr->general.set_application_timer_fptr == NULL) && (init_ptr->general.request_service_fptr != NULL)) ||
177              ((init_ptr->general.set_application_timer_fptr != NULL) && (init_ptr->general.request_service_fptr == NULL)))
178     {
179         TR_ERROR((0U, "[API]", "Initialization failed. To run UCS in event driven service mode, both callback functions must be assigned.", 0U));
180         ret_val = false;
181     }
182     else if ((init_ptr->mgr.enabled != false) && ((init_ptr->nd.eval_fptr != NULL) || (init_ptr->nd.report_fptr != NULL)))
183     {
184         TR_INFO((0U, "[API]", "Ambiguous initialization structure. NodeDiscovery callback functions are not effective if 'mgr.enabled' is 'true'.", 0U));
185     }
186
187     return ret_val;
188 }
189
190 /*------------------------------------------------------------------------------------------------*/
191 /* Class initialization                                                                           */
192 /*------------------------------------------------------------------------------------------------*/
193 /*! \brief Constructor of API. Values are reset, initialization must be triggered via Ucs_Init().
194  *  \param self         The instance
195  *  \param ucs_inst_id  The ID of the instance
196  *  \param api_user_ptr The user reference for API callback functions
197  */
198 static void Ucs_Ctor(CUcs* self, uint8_t ucs_inst_id, void *api_user_ptr)
199 {
200     MISC_MEM_SET(self, 0, sizeof(*self));                       /* reset memory and backup/restore instance id */
201     self->ucs_inst_id = ucs_inst_id;
202     self->ucs_user_ptr = api_user_ptr;
203 }
204
205 extern Ucs_Return_t Ucs_Init(Ucs_Inst_t* self, const Ucs_InitData_t *init_ptr, Ucs_InitResultCb_t init_result_fptr)
206 {
207     CUcs *self_ = (CUcs*)(void*)self;
208     Ucs_Return_t ret = UCS_RET_ERR_PARAM;
209
210     /* Note: "self_->ucs_inst_id" is already set to the correct value in Ucs_CreateInstance(), do not overwrite it */
211     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_Init(init_ptr: 0x%p): called", 1U, init_ptr));
212
213     if (Ucs_CheckInitData(init_ptr))
214     {
215         Ucs_Ctor(self_, self_->ucs_inst_id, init_ptr->user_ptr);/* initialize object */
216         self_->init_result_fptr = init_result_fptr;             /* backup result callback function */
217
218         self_->init_data = *init_ptr;                           /* backup init data */
219         Ucs_InitComponents(self_);                              /* call constructors and link all components */
220                                                                 /* create init-complete observer */
221         Sobs_Ctor(&self_->init_result_obs, self, &Ucs_InitResultCb);
222         Ats_Start(&self_->inic.attach, &self_->init_result_obs);/* Start attach process */
223         ret = UCS_RET_SUCCESS;
224     }
225                                                                 /* register observer related to Ucs_Stop() */
226     Mobs_Ctor(&self_->uninit_result_obs, self, (EH_E_UNSYNC_COMPLETE | EH_E_UNSYNC_FAILED), &Ucs_UninitResultCb);
227     return ret;
228 }
229
230 extern void Ucs_Service(Ucs_Inst_t* self)
231 {
232     CUcs *self_ = (CUcs*)(void*)self;
233     bool pending_events = false;
234
235     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_Service(): called", 0U));
236     Scd_Service(&self_->general.base.scd);                              /* Run the scheduler */
237     pending_events = Scd_AreEventsPending(&self_->general.base.scd);    /* Check if events are still pending? */
238
239     if (pending_events != false)                                        /* At least one event is pending? */
240     {
241         if (self_->general.request_service_fptr != NULL)
242         {
243             self_->general.request_service_fptr(self_->ucs_user_ptr);   /* Trigger UCS service call immediately */
244         }
245     }
246
247     Tm_CheckForNextService(&self_->general.base.tm);                    /* If UCS timers are running: What is the next time that  
248                                                                          * the timer management must be serviced again? */   
249 }
250
251 extern void Ucs_ReportTimeout(Ucs_Inst_t* self)
252 {
253     CUcs *self_ = (CUcs*)(void*)self;
254     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_ReportTimeout(): called", 0U));
255     Tm_TriggerService(&self_->general.base.tm);                         /* Trigger TM service call */
256 }
257
258 extern Ucs_Return_t Ucs_Stop(Ucs_Inst_t* self, Ucs_StdResultCb_t stopped_fptr)
259 {
260     CUcs *self_ = (CUcs*)(void*)self;
261     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
262
263     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_Stop() called", 0U));
264
265     if ((self_->uninit_result_fptr == NULL) && (self_->init_complete != false))
266     {
267         if (stopped_fptr !=  NULL)
268         {
269             self_->uninit_result_fptr = stopped_fptr;
270             Eh_DelObsrvPublicError(&self_->general.base.eh);
271             Eh_AddObsrvInternalEvent(&self_->general.base.eh, &self_->uninit_result_obs);
272             ret_val = UCS_RET_SUCCESS;
273             Fifos_ConfigureSyncParams(&self_->fifos, FIFOS_UNSYNC_RETRIES, FIFOS_UNSYNC_TIMEOUT);
274             Fifos_Unsynchronize(&self_->fifos, true, false);
275         }
276     }
277     else
278     {
279         ret_val = UCS_RET_ERR_API_LOCKED;         /* termination is already running */
280     }
281
282     return ret_val;
283 }
284
285 /*------------------------------------------------------------------------------------------------*/
286 /* Connection Routing Management                                                                  */
287 /*------------------------------------------------------------------------------------------------*/
288 Ucs_Return_t Ucs_Rm_Start(Ucs_Inst_t *self, Ucs_Rm_Route_t *routes_list, uint16_t list_size)
289 {
290     CUcs *self_ = (CUcs*)(void*)self;
291
292     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
293
294     if (self_->init_complete != false)
295     {
296         ret_val = Rtm_StartProcess (&self_->rtm, routes_list, list_size);
297     }
298
299     return ret_val;
300 }
301
302 Ucs_Return_t Ucs_Rm_SetRouteActive (Ucs_Inst_t *self, Ucs_Rm_Route_t *route_ptr, bool active)
303 {
304     CUcs *self_ = (CUcs*)(void*)self;
305
306     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM; 
307
308     if ((self_ != NULL) && (route_ptr != NULL))
309     {
310         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
311         if (self_->init_complete != false)
312         {
313             if (!active)
314             {
315                 ret_val = Rtm_DeactivateRoute(&self_->rtm, route_ptr);
316             }
317             else
318             {
319                 ret_val = Rtm_ActivateRoute(&self_->rtm, route_ptr);
320             }
321         }
322     }
323
324     return ret_val;
325 }
326
327 Ucs_Return_t Ucs_Xrm_Stream_SetPortConfig(Ucs_Inst_t *self, 
328                                           uint16_t destination_address,
329                                           uint8_t index,
330                                           Ucs_Stream_PortOpMode_t op_mode,
331                                           Ucs_Stream_PortOption_t port_option,
332                                           Ucs_Stream_PortClockMode_t clock_mode,
333                                           Ucs_Stream_PortClockDataDelay_t clock_data_delay,
334                                           Ucs_Xrm_Stream_PortCfgResCb_t result_fptr)
335 {
336     CUcs *self_ = (CUcs*)(void*)self;
337     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
338
339     if (self_ != NULL)
340     {
341         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
342         if (self_->init_complete != false)
343         {
344             ret_val = Xrm_Stream_SetPortConfig(Fac_GetXrmLegacy(&self_->factory, destination_address, self_->init_data.rm.xrm.check_unmute_fptr),
345                                                index,
346                                                op_mode,
347                                                port_option,
348                                                clock_mode,
349                                                clock_data_delay,
350                                                result_fptr);
351         }
352     }
353
354     return ret_val;
355 }
356
357 Ucs_Return_t Ucs_Xrm_Stream_GetPortConfig(Ucs_Inst_t *self, uint16_t destination_address, uint8_t index,
358                                           Ucs_Xrm_Stream_PortCfgResCb_t result_fptr)
359 {
360     CUcs *self_ = (CUcs*)(void*)self;
361     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
362
363     if (self_ != NULL)
364     {
365         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
366         if (self_->init_complete != false)
367         {
368             ret_val = Xrm_Stream_GetPortConfig(Fac_GetXrmLegacy(&self_->factory, destination_address, self_->init_data.rm.xrm.check_unmute_fptr),
369                                                index, result_fptr);
370         }
371     }
372
373     return ret_val;
374 }
375
376 /*------------------------------------------------------------------------------------------------*/
377 /* Node Management                                                                                */
378 /*------------------------------------------------------------------------------------------------*/
379 Ucs_Return_t Ucs_Rm_SetNodeAvailable(Ucs_Inst_t *self, Ucs_Rm_Node_t *node_ptr, bool available)
380 {
381     CUcs *self_ = (CUcs*)(void*)self;
382     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
383
384     if ((self_ != NULL) && (node_ptr != NULL))
385     {
386         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
387         if (self_->init_complete != false)
388         {
389             ret_val = Rtm_SetNodeAvailable(&self_->rtm, node_ptr, available);
390         }
391     }
392
393     return ret_val;
394 }
395
396 bool Ucs_Rm_GetNodeAvailable (Ucs_Inst_t *self, Ucs_Rm_Node_t *node_ptr)
397 {
398     CUcs *self_ = (CUcs*)(void*)self;
399     bool ret_val = false;
400
401     if ((self_ != NULL) && (node_ptr != NULL))
402     {
403         ret_val = Rtm_GetNodeAvailable(&self_->rtm, node_ptr);
404     }
405
406     return ret_val;
407 }
408
409 Ucs_Return_t Ucs_Rm_GetAttachedRoutes (Ucs_Inst_t *self, Ucs_Rm_EndPoint_t * ep_inst, 
410                                          Ucs_Rm_Route_t * ls_found_routes[], uint16_t ls_size)
411 {
412     CUcs *self_ = (CUcs*)(void*)self;
413     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
414
415     if (self_ != NULL)
416     {
417         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
418         if (self_->init_complete != false)
419         {
420             ret_val = Rtm_GetAttachedRoutes(&self_->rtm, ep_inst, ls_found_routes, ls_size);
421         }
422     }
423
424     return ret_val;
425 }
426
427 uint16_t Ucs_Rm_GetConnectionLabel(Ucs_Inst_t *self, Ucs_Rm_Route_t *route_ptr)
428 {
429     uint16_t ret_value = 0U;
430     CUcs *self_ = (CUcs*)(void*)self;
431
432     if ((self_ != NULL) && (self_->init_complete != false) && (route_ptr != NULL))
433     {
434         ret_value = Rtm_GetConnectionLabel(&self_->rtm, route_ptr);
435     }
436
437     return ret_value;
438 }
439
440 /*------------------------------------------------------------------------------------------------*/
441 /* Node Scripting Management                                                                      */
442 /*------------------------------------------------------------------------------------------------*/
443 Ucs_Return_t Ucs_Ns_Run (Ucs_Inst_t *self, Ucs_Rm_Node_t * node_ptr, Ucs_Ns_ResultCb_t result_fptr)
444 {
445     CUcs *self_ = (CUcs*)(void*)self;
446     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
447
448     if ((self_ != NULL) && (node_ptr != NULL) && (node_ptr->signature_ptr != NULL))
449     {
450         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
451         if (self_->init_complete != false)
452         {
453             CNodeScriptManagement * nsm_inst = Fac_GetNsm(&self_->factory, node_ptr->signature_ptr->node_address);
454
455             ret_val = UCS_RET_ERR_NOT_AVAILABLE;
456             if (nsm_inst != NULL)
457             {
458                 ret_val = Nsm_Run_Pb(nsm_inst, node_ptr, result_fptr);
459             }
460         }
461     }
462
463     return ret_val;
464 }
465
466 /*------------------------------------------------------------------------------------------------*/
467 /* GPIO and I2C Peripheral Bus Interfaces                                                         */
468 /*------------------------------------------------------------------------------------------------*/
469 Ucs_Return_t Ucs_Gpio_CreatePort(Ucs_Inst_t *self, uint16_t destination_address, uint8_t index, uint16_t debounce_time, Ucs_Gpio_CreatePortResCb_t result_fptr)
470 {
471     CUcs *self_ = (CUcs*)(void*)self;
472     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
473
474     if (self_ != NULL)
475     {
476         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
477         if (self_->init_complete != false)
478         {
479             ret_val = Gpio_CreatePort(Fac_GetGpio(&self_->factory, destination_address, self_->init_data.gpio.trigger_event_status_fptr), 
480                                       index, 
481                                       debounce_time, 
482                                       result_fptr);
483         }
484     }
485
486     return ret_val;
487 }
488
489 Ucs_Return_t Ucs_Gpio_SetPinMode(Ucs_Inst_t *self, uint16_t destination_address, uint16_t gpio_port_handle, 
490                                  uint8_t pin, Ucs_Gpio_PinMode_t mode, Ucs_Gpio_ConfigPinModeResCb_t result_fptr)
491 {
492     CUcs *self_ = (CUcs*)(void*)self;
493     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
494
495     if (self_ != NULL)
496     {
497         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
498         if (self_->init_complete != false)
499         {
500             ret_val = Gpio_SetPinModeConfig(Fac_GetGpio(&self_->factory, destination_address, self_->init_data.gpio.trigger_event_status_fptr),
501                                             gpio_port_handle, 
502                                             pin,
503                                             mode,
504                                             result_fptr);
505         }
506     }
507
508     return ret_val;
509 }
510
511 Ucs_Return_t Ucs_Gpio_GetPinMode(Ucs_Inst_t *self, uint16_t destination_address, uint16_t gpio_port_handle, Ucs_Gpio_ConfigPinModeResCb_t result_fptr)
512 {
513     CUcs *self_ = (CUcs*)(void*)self;
514     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
515
516     if (self_ != NULL)
517     {
518         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
519         if (self_->init_complete != false)
520         {
521             ret_val = Gpio_GetPinModeConfig(Fac_GetGpio(&self_->factory, destination_address, self_->init_data.gpio.trigger_event_status_fptr),
522                                             gpio_port_handle, 
523                                             result_fptr);
524         }
525     }
526
527     return ret_val;
528 }
529
530 Ucs_Return_t Ucs_Gpio_WritePort(Ucs_Inst_t *self, uint16_t destination_address, uint16_t gpio_port_handle, 
531                                 uint16_t mask, uint16_t data, Ucs_Gpio_PinStateResCb_t result_fptr)
532 {
533     CUcs *self_ = (CUcs*)(void*)self;
534     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
535
536     if (self_ != NULL)
537     {
538         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
539         if (self_->init_complete != false)
540         {
541             ret_val = Gpio_SetPinStateConfig(Fac_GetGpio(&self_->factory, destination_address, self_->init_data.gpio.trigger_event_status_fptr),
542                                              gpio_port_handle,
543                                              mask, 
544                                              data,
545                                              result_fptr);
546         }
547     }
548
549     return ret_val;
550 }
551
552 Ucs_Return_t Ucs_Gpio_ReadPort(Ucs_Inst_t *self, uint16_t destination_address, uint16_t gpio_port_handle, Ucs_Gpio_PinStateResCb_t result_fptr)
553 {
554     CUcs *self_ = (CUcs*)(void*)self;
555     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
556
557     if (self_ != NULL)
558     {
559         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
560         if (self_->init_complete != false)
561         {
562             ret_val = Gpio_GetPinStateConfig(Fac_GetGpio(&self_->factory, destination_address, self_->init_data.gpio.trigger_event_status_fptr),
563                                              gpio_port_handle,
564                                              result_fptr);
565         }
566     }
567
568     return ret_val;
569 }
570
571 Ucs_Return_t Ucs_I2c_CreatePort(Ucs_Inst_t *self, uint16_t destination_address, uint8_t index, Ucs_I2c_Speed_t speed, 
572                                 uint8_t i2c_int_mask, Ucs_I2c_CreatePortResCb_t result_fptr)
573 {
574     CUcs *self_ = (CUcs*)(void*)self;
575     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
576
577     if (self_ != NULL)
578     {
579         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
580         if (self_->init_complete != false)
581         {
582             ret_val = I2c_CreatePort(Fac_GetI2c(&self_->factory, destination_address, self_->init_data.i2c.interrupt_status_fptr),
583                                      index,
584                                      speed,
585                                      i2c_int_mask,
586                                      result_fptr);
587         }
588     }
589
590     return ret_val;
591 }
592
593 Ucs_Return_t Ucs_I2c_WritePort(Ucs_Inst_t *self, uint16_t destination_address, uint16_t port_handle, Ucs_I2c_TrMode_t mode, uint8_t block_count, 
594                                uint8_t slave_address, uint16_t timeout, uint8_t data_len, uint8_t * data_ptr, 
595                                Ucs_I2c_WritePortResCb_t result_fptr)
596 {
597     CUcs *self_ = (CUcs*)(void*)self;
598     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
599
600     if (self_ != NULL)
601     {
602         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
603         if (self_->init_complete != false)
604         {
605             ret_val = I2c_WritePort(Fac_GetI2c(&self_->factory, destination_address, self_->init_data.i2c.interrupt_status_fptr),
606                                     port_handle,
607                                     mode,
608                                     block_count,
609                                     slave_address,
610                                     timeout,
611                                     data_len,
612                                     data_ptr,
613                                     result_fptr);
614         }
615     }
616
617     return ret_val;
618 }
619
620 Ucs_Return_t Ucs_I2c_ReadPort(Ucs_Inst_t *self, uint16_t destination_address, uint16_t port_handle, uint8_t slave_address, uint8_t data_len, 
621                               uint16_t timeout, Ucs_I2c_ReadPortResCb_t result_fptr)
622 {
623     CUcs *self_ = (CUcs*)(void*)self;
624     Ucs_Return_t ret_val = UCS_RET_ERR_PARAM;
625
626     if (self_ != NULL)
627     {
628         ret_val = UCS_RET_ERR_NOT_INITIALIZED;
629         if (self_->init_complete != false)
630         {
631             ret_val = I2c_ReadPort(Fac_GetI2c(&self_->factory, destination_address, self_->init_data.i2c.interrupt_status_fptr),
632                                    port_handle,
633                                    slave_address,
634                                    data_len,
635                                    timeout,
636                                    result_fptr);
637         }
638     }
639
640     return ret_val;
641 }
642
643 /*------------------------------------------------------------------------------------------------*/
644 /* Components                                                                                     */
645 /*------------------------------------------------------------------------------------------------*/
646 /*! \brief Initializes all UCS core components
647  *  \param self     The instance
648  */
649 static void Ucs_InitComponents(CUcs* self)
650 {
651     Ucs_InitBaseComponent(self);
652     Ucs_InitFactoryComponent(self);
653     Ucs_InitLocalInicComponent(self);
654     Ucs_InitNetComponent(self);
655     Ucs_InitPmsComponent(self);
656     Ucs_InitAmsComponent(self);
657     Ucs_InitRoutingComponent(self);
658     Ucs_InitAtsClass(self);
659
660     Ucs_InitExcComponent(self);
661     Ucs_InitSysDiagComponent(self);
662     Ucs_InitNodeDiscovery(self);
663     Ucs_InitBackChannelDiagnosis(self);
664     Ucs_InitProgramming(self);
665     Ucs_InitManager(self);      /* shall be called as last one due to re-configuration work */
666 }
667
668 /*! \brief Initializes the factory component
669  *  \param self     The instance
670  */
671 static void Ucs_InitFactoryComponent(CUcs *self)
672 {
673     Fac_InitData_t fac_init_data;
674     fac_init_data.base_ptr = &self->general.base;
675     fac_init_data.net_ptr  = &self->net.inst;
676     fac_init_data.xrmp_ptr = &self->xrmp;
677     fac_init_data.icm_transceiver = &self->icm_transceiver;
678     fac_init_data.rcm_transceiver = &self->rcm_transceiver;
679     Fac_Ctor(&self->factory, &fac_init_data);
680 }
681
682 /*! \brief Initializes the the base component
683  *  \param self     The instance
684  */
685 static void Ucs_InitBaseComponent(CUcs *self)
686 {
687     Base_InitData_t base_init_data;
688
689     if (self->init_data.general.request_service_fptr != NULL)   /* pointer may be NULL for termination */
690     {
691         self->general.request_service_fptr = self->init_data.general.request_service_fptr;
692         Sobs_Ctor(&self->general.service_request_obs, self, &Ucs_OnServiceRequest);
693         base_init_data.scd.service_request_obs_ptr = &self->general.service_request_obs;
694     }
695     else
696     {
697         base_init_data.scd.service_request_obs_ptr = NULL;
698     }
699
700     self->general.get_tick_count_fptr = self->init_data.general.get_tick_count_fptr;
701     Sobs_Ctor(&self->general.get_tick_count_obs, self, &Ucs_OnGetTickCount);
702     base_init_data.tm.get_tick_count_obs_ptr = &self->general.get_tick_count_obs;
703     if (self->init_data.general.set_application_timer_fptr != NULL)
704     {
705         self->general.set_application_timer_fptr = self->init_data.general.set_application_timer_fptr;
706         Sobs_Ctor(&self->general.set_application_timer_obs, self, &Ucs_OnSetApplicationTimer);
707         base_init_data.tm.set_application_timer_obs_ptr = &self->general.set_application_timer_obs;
708     }
709     else
710     {
711         base_init_data.tm.set_application_timer_obs_ptr = NULL;
712     }
713     base_init_data.ucs_inst_id = self->ucs_inst_id;
714     base_init_data.ucs_user_ptr = self->ucs_user_ptr;
715     Base_Ctor(&self->general.base, &base_init_data);
716 }
717
718 /*! \brief Initializes the port message service
719  *  \param self     The instance
720  */
721 static void Ucs_InitPmsComponent(CUcs *self)
722 {
723     CPmFifo * mcm_fifo_ptr = NULL;
724         
725     if (self->init_data.ams.enabled == true)
726     {
727         mcm_fifo_ptr = &self->msg.mcm_fifo;
728     }
729     
730     Ucs_InitPmsComponentConfig(self);
731     Ucs_InitPmsComponentApp(self);
732
733     Fifos_Ctor(&self->fifos, &self->general.base, &self->pmch, &self->icm_fifo, mcm_fifo_ptr, &self->rcm_fifo);
734     Pmev_Ctor(&self->pme, &self->general.base, &self->fifos);       /* initialize event handler */
735 }
736
737 /*! \brief Initializes the port message service
738  *  \param self     The instance
739  */
740 static void Ucs_InitPmsComponentConfig(CUcs *self)
741 {
742     Pmch_InitData_t pmch_init_data;
743     Fifo_InitData_t icm_init;
744     Fifo_Config_t icm_config;
745     Fifo_InitData_t rcm_init;
746     Fifo_Config_t rcm_config;
747
748     /* Initialize port message service */
749     pmch_init_data.ucs_user_ptr = self->ucs_user_ptr;
750     pmch_init_data.tx_release_fptr = &Fifo_TxOnRelease;
751     pmch_init_data.lld_iface = self->init_data.lld;
752     Pmch_Ctor(&self->pmch, &pmch_init_data);
753
754     /* Initialize the ICM channel */
755     icm_init.base_ptr = &self->general.base;
756     icm_init.channel_ptr = &self->pmch;
757     icm_init.rx_cb_fptr = &Trcv_RxOnMsgComplete;
758     icm_init.rx_cb_inst = &self->icm_transceiver;
759     icm_init.tx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
760     icm_init.rx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
761     icm_config.fifo_id = PMP_FIFO_ID_ICM;
762     icm_config.tx_wd_timeout = 0U;
763     icm_config.tx_wd_timer_value = 0U;
764     icm_config.rx_ack_timeout = 10U;
765     icm_config.rx_busy_allowed = 0xFU;
766     icm_config.rx_credits = PMCH_FIFO_CREDITS;
767     icm_config.rx_threshold = PMCH_FIFO_THRESHOLD;
768     if (self->init_data.general.inic_watchdog_enabled == false)
769     {
770         icm_config.rx_ack_timeout = 0U;
771     }
772     Fifo_Ctor(&self->icm_fifo, &icm_init, &icm_config);
773
774     /* Initialize the RCM channel */
775     rcm_init.base_ptr = &self->general.base;
776     rcm_init.channel_ptr = &self->pmch;
777     rcm_init.rx_cb_fptr = &Trcv_RxOnMsgComplete;
778     rcm_init.rx_cb_inst = &self->rcm_transceiver;
779     rcm_init.tx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
780     rcm_init.rx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
781     rcm_config.fifo_id = PMP_FIFO_ID_RCM;
782     rcm_config.tx_wd_timeout = 10U;             /* Watchdog timeout: 1s */
783     rcm_config.tx_wd_timer_value = 600U;        /* Watchdog trigger every 600 ms */
784     rcm_config.rx_ack_timeout = 10U;            /* Acknowledge timeout: 10 ms */
785     rcm_config.rx_busy_allowed = 0xFU;
786     rcm_config.rx_credits = PMCH_FIFO_CREDITS;
787     rcm_config.rx_threshold = PMCH_FIFO_THRESHOLD;
788     if (self->init_data.general.inic_watchdog_enabled == false)
789     {
790         /* Disable INIC watchdog */
791         rcm_config.tx_wd_timeout = 0U;          /* Watchdog timeout:    0 -> infinite */
792         rcm_config.tx_wd_timer_value = 0U;      /* Watchdog timer:      0 -> no timer */
793         rcm_config.rx_ack_timeout = 0U;         /* Acknowledge timeout: 0 -> infinite */
794     }
795     Fifo_Ctor(&self->rcm_fifo, &rcm_init, &rcm_config);
796 #if 0
797     Fifos_Ctor(&self->fifos, &self->general.base, &self->pmch, &self->icm_fifo, NULL/*MCM*/, &self->rcm_fifo);
798     Pmev_Ctor(&self->pme, &self->general.base, &self->fifos);       /* initialize event handler */
799 #endif
800
801     /* initialize transceivers and set reference to FIFO instance */
802     Trcv_Ctor(&self->icm_transceiver, &self->icm_fifo, MSG_ADDR_EHC_CFG, self->ucs_user_ptr, PMP_FIFO_ID_ICM);
803     Trcv_RxAssignFilter(&self->icm_transceiver, &Ucs_OnRxMsgFilter, self);
804     Trcv_RxAssignReceiver(&self->icm_transceiver, &Inic_OnIcmRx, self->inic.local_inic);
805     Trcv_Ctor(&self->rcm_transceiver, &self->rcm_fifo, MSG_ADDR_EHC_CFG, self->ucs_user_ptr, PMP_FIFO_ID_RCM);
806     /* Assign RX filter and receiver function to the RCM transceiver */
807     Trcv_RxAssignFilter(&self->rcm_transceiver, &Ucs_OnRxMsgFilter, self);
808     Trcv_RxAssignReceiver(&self->rcm_transceiver, &Ucs_OnRxRcm, self);
809 }
810
811 /*! \brief Initializes the network management component
812  *  \param self     The instance
813  */
814 static void Ucs_InitNetComponent(CUcs *self)
815 {
816     Net_InitData_t net_init_data;
817
818     Sobs_Ctor(&self->net.startup_obs, self, &Ucs_NetworkStartupResult);
819     Sobs_Ctor(&self->net.shutdown_obs, self, &Ucs_NetworkShutdownResult);
820     Sobs_Ctor(&self->net.force_na_obs, self, &Ucs_NetworkForceNAResult);
821     Sobs_Ctor(&self->net.frame_counter_obs, self, &Ucs_NetworkFrameCounterResult);
822     net_init_data.base_ptr = &self->general.base;
823     net_init_data.inic_ptr = self->inic.local_inic;
824     Net_Ctor(&self->net.inst, &net_init_data);
825 }
826
827 /*! \brief Initializes the FBlock INIC
828  *  \param self     The instance
829  */
830 static void Ucs_InitLocalInicComponent(CUcs *self)
831 {
832     self->inic.local_inic = Fac_GetInic(&self->factory, UCS_ADDR_LOCAL_INIC);
833     Obs_Ctor(&self->inic.device_status_obs, self, &Ucs_Inic_OnDeviceStatus);
834 }
835
836 /*! \brief Initializes the Routing components
837  *  \param self     The instance
838  */
839 static void Ucs_InitRoutingComponent(CUcs *self)
840 {
841     Epm_InitData_t epm_init;
842     Rtm_InitData_t rtm_init;
843
844     /* Initialize the unique XRM Pool Instance */
845     Xrmp_Ctor(&self->xrmp);
846
847     /* Initialize the EndPoint Management Instance */
848     epm_init.base_ptr = &self->general.base;
849     epm_init.fac_ptr  = &self->factory;
850     epm_init.res_debugging_fptr = self->init_data.rm.debug_resource_status_fptr;
851     epm_init.check_unmute_fptr  = self->init_data.rm.xrm.check_unmute_fptr;
852     Epm_Ctor (&self->epm, &epm_init);
853
854     /* Initialize the Routes Management Instance */
855     rtm_init.base_ptr = &self->general.base;
856     rtm_init.epm_ptr  = &self->epm;
857     rtm_init.net_ptr  = &self->net.inst;
858     rtm_init.report_fptr = self->init_data.rm.report_fptr;
859     Rtm_Ctor(&self->rtm, &rtm_init);
860 }
861
862 /*! \brief Initializes the attach service
863  *  \param self     The instance
864  */
865 static void Ucs_InitAtsClass(CUcs *self)
866 {
867     Ats_InitData_t ats_init_data;
868     ats_init_data.base_ptr = &self->general.base;
869     ats_init_data.fifos_ptr = &self->fifos;
870     ats_init_data.inic_ptr = self->inic.local_inic;
871     ats_init_data.pme_ptr = &self->pme;
872     Ats_Ctor(&self->inic.attach, &ats_init_data);
873 }
874
875 /*! \brief Initializes the FBlock ExtendedNetworkControl API
876  *  \param self The instance
877  */
878 static void Ucs_InitExcComponent(CUcs *self)
879 {
880     /* Create the FBlock ExtendedNetworkControl instance */
881     Exc_Ctor(&self->exc, &self->general.base, &self->rcm_transceiver);
882 }
883
884 /*! \brief Initializes the SystemDiagnosis component
885  *  \param self The instance
886  */
887 static void Ucs_InitSysDiagComponent(CUcs *self)
888 {
889     /* Create the System Diagnosis instance */
890     SysDiag_Ctor(&self->sys_diag, self->inic.local_inic, &self->general.base, &self->exc);
891 }
892
893
894 static void Ucs_InitNodeDiscovery(CUcs *self)
895 {
896     Nd_InitData_t nd_init_data;
897
898     if (self->init_data.mgr.enabled == false)
899     {
900         nd_init_data.inst_ptr = self;
901         nd_init_data.report_fptr = &Ucs_OnNdReport;
902         nd_init_data.eval_fptr = &Ucs_OnNdEvaluate;
903     }
904     else
905     {
906         nd_init_data.inst_ptr = &self->nobs;
907         nd_init_data.report_fptr = &Nobs_OnNdReport;
908         nd_init_data.eval_fptr = &Nobs_OnNdEvaluate;
909     }
910
911     Nd_Ctor(&self->nd, self->inic.local_inic, &self->general.base, &self->exc, &nd_init_data);
912
913 }
914
915 static void Ucs_InitBackChannelDiagnosis(CUcs *self)
916 {
917     Bcd_Ctor(&self->bcd, self->inic.local_inic, &self->general.base, &self->exc);
918 }
919
920 static void Ucs_InitProgramming(CUcs *self)
921 {
922     Prg_Ctor(&self->prg, self->inic.local_inic, &self->general.base, &self->exc);
923 }
924
925
926 /*! \brief      Initializes the Manager class
927  *  \details    This function shall be called as the latest initialization function since
928  *              it may disable some of the conventional API.
929  *  \param self The instance
930  */
931 static void Ucs_InitManager(CUcs *self)
932 {
933     if (self->init_data.mgr.enabled == true)
934     {
935         Mgr_Ctor(&self->mgr, &self->general.base, self->inic.local_inic, &self->net.inst, &self->nd, self->init_data.mgr.packet_bw);
936         Nobs_Ctor(&self->nobs, &self->general.base, &self->nd, &self->rtm, &self->init_data.mgr);
937     }
938 }
939
940
941 /*! \brief Callback function which announces the result of the attach process
942  *  \param self         The instance
943  *  \param result_ptr   Result of the initialization process. Result must be casted into data type 
944  *                      Ucs_InitResult_t. Possible return values are shown in the table below.
945  *         Result Code                   | Description 
946  *         ----------------------------- | ----------------------------------------------------
947  *         UCS_INIT_RES_SUCCESS          | Initialization succeeded
948  *         UCS_INIT_RES_ERR_BUF_OVERFLOW | No message buffer available
949  *         UCS_INIT_RES_ERR_PMS_INIT     | PMS Initialization failed
950  *         UCS_INIT_RES_ERR_INIC_VERSION | INIC device version check failed
951  *         UCS_INIT_RES_ERR_DEV_ATT_CFG  | Device attach failed due to an configuration error
952  *         UCS_INIT_RES_ERR_DEV_ATT_PROC | Device attach failed due to a system error
953  *         UCS_INIT_RES_ERR_NET_CFG      | Network configuration failed
954  *         UCS_INIT_RES_ERR_TIMEOUT      | Initialization timeout occurred
955  */
956 static void Ucs_InitResultCb(void *self, void *result_ptr)
957 {
958     CUcs *self_ = (CUcs*)self;
959     Ucs_InitResult_t *result_ptr_ = (Ucs_InitResult_t *)result_ptr;
960
961     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_InitResultCb(): Ucs_Init() completed, internal event code: %u", 1U, *result_ptr_));
962     if (*result_ptr_ != UCS_INIT_RES_SUCCESS)
963     {
964         Ucs_StopAppNotification(self_);
965     }
966
967     if (self_->init_result_fptr != NULL)
968     {
969         self_->init_result_fptr(*result_ptr_, self_->ucs_user_ptr);
970     }
971
972     /* Start notification if initialization succeeded */
973     if (*result_ptr_ == UCS_INIT_RES_SUCCESS)
974     {
975         self_->init_complete = true;
976         Ucs_StartAppNotification(self_);
977     }
978 }
979
980 /*! \brief Callback function which announces the result of Ucs_Stop()
981  *  \param self             The instance
982  *  \param error_code_ptr   Reference to the error code
983  */
984 static void Ucs_UninitResultCb(void *self, void *error_code_ptr)
985 {
986     CUcs *self_ = (CUcs*)self;
987     uint32_t error_code = *((uint32_t *)error_code_ptr);
988     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_UninitResultCb(): Ucs_Stop() completed, internal event code: %u", 1U, error_code));
989
990     self_->init_complete = false;
991     Eh_DelObsrvInternalEvent(&self_->general.base.eh, &self_->uninit_result_obs);
992
993     Ucs_StopAppNotification(self_);
994
995     if (self_->uninit_result_fptr != NULL)
996     {
997         Ucs_StdResult_t result;
998
999         result.code      = UCS_RES_SUCCESS;
1000         result.info_ptr  = NULL;
1001         result.info_size = 0U;
1002
1003         if (error_code != EH_E_UNSYNC_COMPLETE)
1004         {
1005             result.code     = UCS_RES_ERR_TIMEOUT;
1006         }
1007
1008         self_->uninit_result_fptr(result, self_->ucs_user_ptr);
1009         self_->uninit_result_fptr = NULL;
1010     }
1011 }
1012
1013 /*! \brief Starts the notification after the initialization has succeeded
1014  *  \param self     The instance
1015  */
1016 static void Ucs_StartAppNotification(CUcs *self)
1017 {
1018     self->general.general_error_fptr = self->init_data.general.error_fptr;          /* assign general error notification */
1019     Sobs_Ctor(&self->general.general_error_obs, self, &Ucs_OnGeneralError);
1020     Eh_AddObsrvPublicError(&self->general.base.eh, &self->general.general_error_obs);
1021
1022     if (self->init_data.network.status.cb_fptr != NULL)                             /* Start notification of Network Status */
1023     {
1024         self->net.status_fptr = self->init_data.network.status.cb_fptr;
1025         Mobs_Ctor(&self->net.status_obs,
1026                   self,
1027                   (uint32_t)self->init_data.network.status.notification_mask,
1028                   &Ucs_NetworkStatus);
1029         Net_AddObserverNetworkStatus(&self->net.inst, &self->net.status_obs);
1030     }
1031
1032     if ((self->init_data.ams.tx.message_freed_fptr != NULL) && (self->msg.ams_tx_alloc_failed != false))
1033     {
1034         self->msg.ams_tx_alloc_failed = false;
1035         self->init_data.ams.tx.message_freed_fptr(self->ucs_user_ptr);
1036     }
1037
1038     if (self->init_data.inic.power_state_fptr != NULL)
1039     {
1040         self->inic.power_state = Inic_GetDevicePowerState(self->inic.local_inic);   /* remember the current value */
1041         self->init_data.inic.power_state_fptr(self->inic.power_state, self->ucs_user_ptr);
1042         Inic_AddObsvrDeviceStatus(self->inic.local_inic, &self->inic.device_status_obs);
1043     }
1044     
1045     if(self->init_data.rm.xrm.most_port_status_fptr != NULL)                        /* Initialize callback pointer for MOST port status callback */
1046     {
1047         self->xrm.most_port_status_fptr = self->init_data.rm.xrm.most_port_status_fptr;
1048         Obs_Ctor(&self->xrm.most_port_status_obs, self, &Ucs_Most_PortStatusCb);
1049         Inic_AddObsrvMostPortStatus(self->inic.local_inic, &self->xrm.most_port_status_obs);
1050     }
1051 }
1052
1053 /*! \brief Stops application events for timer management and event service
1054  *  \param self     The instance
1055  */
1056 static void Ucs_StopAppNotification(CUcs *self)
1057 {
1058     self->general.request_service_fptr = NULL;      /* clear service request to avoid any pending events to be called again */
1059     Tm_StopService(&self->general.base.tm);         /* stop timer service */
1060 }
1061
1062 /*------------------------------------------------------------------------------------------------*/
1063 /* Message Routing                                                                                */
1064 /*------------------------------------------------------------------------------------------------*/
1065 /*! \brief  Callback function to receive RCM Rx messages
1066  *  \param  self     The UCS instance
1067  *  \param  tel_ptr  The received RCM Rx message object 
1068  *  \return Returns \c true to discard the message and free it to the pool (no-pass).
1069  *          Otherwise, returns \c false (pass).
1070  */
1071 static void Ucs_OnRxRcm(void *self, Msg_MostTel_t *tel_ptr)
1072 {
1073     CUcs *self_ = (CUcs*)self;
1074
1075     if (tel_ptr->id.fblock_id == FB_EXC)
1076     {
1077         Exc_OnRcmRxFilter(&(self_->exc), tel_ptr);
1078     }
1079     else if (tel_ptr->id.fblock_id == FB_INIC)
1080     {
1081         if (!Nsm_OnRcmRxFilter(Fac_FindNsm(&self_->factory, tel_ptr->source_addr), tel_ptr))
1082         {
1083             CInic * inic_ptr = Fac_FindInic(&self_->factory, tel_ptr->source_addr);
1084             if (inic_ptr != NULL)
1085             {
1086                 Inic_OnRcmRxFilter(inic_ptr, tel_ptr);
1087             }
1088         }
1089     }
1090
1091     Trcv_RxReleaseMsg(&self_->rcm_transceiver, tel_ptr); /* free Rx telegram */
1092 }
1093
1094 /*! \brief  Callback function which filters Control Rx messages
1095  *  \param  self     The UCS instance
1096  *  \param  tel_ptr  The received Rx message object 
1097  *  \return Returns \c true to discard the message and free it to the pool (no-pass).
1098  *          Otherwise, returns \c false (pass).
1099  */
1100 static bool Ucs_OnRxMsgFilter(void *self, Msg_MostTel_t *tel_ptr)
1101 {
1102     CUcs *self_ = (CUcs*)self;
1103     bool ret = false;                   /* just pass - do not discard message */
1104
1105     if (self_->rx_filter_fptr != NULL)
1106     {
1107         ret = self_->rx_filter_fptr(tel_ptr, self_->ucs_user_ptr);
1108     }
1109
1110     if (ret == false)
1111     {
1112         if ((tel_ptr->id.op_type == UCS_OP_ERROR) || (tel_ptr->id.op_type == UCS_OP_ERRORACK))
1113         {
1114             if (self_->init_data.general.debug_error_msg_fptr != NULL)
1115             {
1116                 self_->init_data.general.debug_error_msg_fptr(tel_ptr, self_->ucs_user_ptr);
1117             }
1118         }
1119     }
1120     else
1121     {
1122         TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_OnRxMsgFilter(): message discarded by unit test", 0U));
1123     }
1124
1125     return ret;
1126 }
1127
1128 /*------------------------------------------------------------------------------------------------*/
1129 /* Internal Observers / Basic API                                                                 */
1130 /*------------------------------------------------------------------------------------------------*/
1131 /*! \brief Callback function which is invoked to request the current tick count value
1132  *  \param self                     The instance
1133  *  \param tick_count_value_ptr     Reference to the requested tick count value. The pointer must 
1134  *                                  be casted into data type uint16_t.
1135  */
1136 static void Ucs_OnGetTickCount(void *self, void *tick_count_value_ptr)
1137 {
1138     CUcs *self_ = (CUcs*)self;
1139     *((uint16_t *)tick_count_value_ptr) = self_->general.get_tick_count_fptr(self_->ucs_user_ptr);
1140 }
1141
1142 /*! \brief  Callback function which is invoked to start the application timer when the UNICENS service
1143  *          is implemented event driven         
1144  *  \param  self                The instance
1145  *  \param  new_time_value_ptr  Reference to the new timer value. The pointer must be casted into 
1146  *                              data type uint16_t.
1147  */
1148 static void Ucs_OnSetApplicationTimer(void *self, void *new_time_value_ptr)
1149 {
1150     CUcs *self_ = (CUcs*)self;
1151     TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_OnSetApplicationTimer(%d)", 1U, *((uint16_t *)new_time_value_ptr)));
1152     self_->general.set_application_timer_fptr(*((uint16_t *)new_time_value_ptr), self_->ucs_user_ptr);
1153 }
1154
1155 /*! \brief Callback function which is invoked to announce a request for service
1156  *  \param self         The instance
1157  *  \param result_ptr   Result pointer (not used)
1158  */
1159 static void Ucs_OnServiceRequest(void *self, void *result_ptr)
1160 {
1161     CUcs *self_ = (CUcs*)self;
1162
1163     TR_ASSERT(self_->ucs_user_ptr, "[API]", self_->init_data.general.request_service_fptr != NULL);
1164     self_->general.request_service_fptr(self_->ucs_user_ptr);   /* Call application callback */
1165     MISC_UNUSED(result_ptr);
1166 }
1167
1168 /*! \brief Callback function which announces a general error
1169  *  \param self         The instance
1170  *  \param result_ptr   Reference to the result. Must be casted into Eh_PublicErrorData_t.
1171  */
1172 static void Ucs_OnGeneralError(void *self, void *result_ptr)
1173 {
1174     CUcs *self_ = (CUcs*)self;
1175     Ucs_Error_t error_code = *((Ucs_Error_t *)result_ptr);
1176
1177     self_->init_complete = false;                               /* General error occurred -> Lock UCS API */
1178     Ucs_StopAppNotification(self_);
1179
1180     if (self_->general.general_error_fptr != NULL)              /* callback is not assigned during initialization  */
1181     {
1182         self_->general.general_error_fptr(error_code, self_->ucs_user_ptr); 
1183     }
1184 }
1185
1186 /*! \brief Observer callback for Inic_MostPortStatus_Status/Error(). Casts the result and 
1187  *         invokes the application result callback.
1188  *  \param self         Instance pointer
1189  *  \param result_ptr   Reference to result
1190  */
1191 static void Ucs_Most_PortStatusCb(void *self, void *result_ptr)
1192 {
1193     CUcs *self_ = (CUcs*)self;
1194     if(self_->xrm.most_port_status_fptr != NULL)
1195     {
1196         Inic_MostPortStatus_t status = *((Inic_MostPortStatus_t *)result_ptr);
1197         self_->xrm.most_port_status_fptr(status.most_port_handle,
1198                                          status.availability,
1199                                          status.avail_info,
1200                                          status.freestreaming_bw,
1201                                          self_->ucs_user_ptr);
1202     }
1203 }
1204
1205 /*------------------------------------------------------------------------------------------------*/
1206 /* INIC                                                                                           */
1207 /*------------------------------------------------------------------------------------------------*/
1208 /*! \brief   Observer callback function for INICs device status
1209  *  \param   self       The instance
1210  *  \param   data_ptr   Pointer to structure Inic_DeviceStatus_t
1211  */
1212 static void Ucs_Inic_OnDeviceStatus(void *self, void *data_ptr)
1213 {
1214     CUcs *self_ = (CUcs*)self;
1215     Ucs_Inic_PowerState_t pws = ((Inic_DeviceStatus_t *)data_ptr)->power_state;
1216
1217     if ((self_->init_data.inic.power_state_fptr != NULL) && (pws != self_->inic.power_state))
1218     {
1219         self_->init_data.inic.power_state_fptr(pws, self_->ucs_user_ptr);
1220     }
1221
1222     self_->inic.power_state = pws;
1223 }
1224
1225 /*------------------------------------------------------------------------------------------------*/
1226 /* Network Management                                                                             */
1227 /*------------------------------------------------------------------------------------------------*/
1228 Ucs_Return_t Ucs_Network_Startup(Ucs_Inst_t* self, uint16_t packet_bw, uint16_t forced_na_timeout,
1229                                  Ucs_StdResultCb_t result_fptr)
1230 {
1231     CUcs *self_ = (CUcs*)(void*)self;
1232
1233     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1234     if (self_->init_complete != false)
1235     {
1236         ret_val = Inic_NwStartup(self_->inic.local_inic, forced_na_timeout,
1237                                  packet_bw, &self_->net.startup_obs);
1238         if (ret_val == UCS_RET_SUCCESS)
1239         {
1240             self_->net.startup_fptr = result_fptr;
1241         }
1242     }
1243     return ret_val;
1244 }
1245
1246 /*! \brief  Callback function which announces the result of Ucs_Network_Startup()
1247  *  \param  self         The instance
1248  *  \param  result_ptr   Reference to result. Must be casted into Inic_StdResult_t.
1249  */
1250 static void Ucs_NetworkStartupResult(void *self, void *result_ptr)
1251 {
1252     CUcs *self_ = (CUcs*)self;
1253     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
1254
1255     if (self_->net.startup_fptr != NULL)
1256     {
1257         self_->net.startup_fptr(result_ptr_->result, self_->ucs_user_ptr);
1258     }
1259 }
1260
1261 Ucs_Return_t Ucs_Network_Shutdown(Ucs_Inst_t *self, Ucs_StdResultCb_t result_fptr)
1262 {
1263     CUcs *self_ = (CUcs*)(void*)self;
1264     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1265     if (self_->init_complete != false)
1266     {
1267         ret_val = Inic_NwShutdown(self_->inic.local_inic, &self_->net.shutdown_obs);
1268         if (ret_val == UCS_RET_SUCCESS)
1269         {
1270             self_->net.shutdown_fptr = result_fptr;
1271         }
1272     }
1273     return ret_val;
1274 }
1275
1276 /*! \brief  Callback function which announces the result of Ucs_Network_Shutdown()
1277  *  \param  self        The instance
1278  *  \param  result_ptr  Reference to result. Must be casted into Inic_StdResult_t.
1279  */
1280 static void Ucs_NetworkShutdownResult(void *self, void *result_ptr)
1281 {
1282     CUcs *self_ = (CUcs*)self;
1283     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
1284
1285     if (self_->net.shutdown_fptr != NULL)
1286     {
1287         self_->net.shutdown_fptr(result_ptr_->result, self_->ucs_user_ptr);
1288     }
1289 }
1290
1291 Ucs_Return_t Ucs_Network_ForceNotAvailable(Ucs_Inst_t *self, bool force, Ucs_StdResultCb_t result_fptr)
1292 {
1293     CUcs *self_ = (CUcs*)(void*)self;
1294     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1295     if (self_->init_complete != false)
1296     {
1297         ret_val = Inic_NwForceNotAvailable(self_->inic.local_inic, force, &self_->net.force_na_obs);
1298         if (ret_val == UCS_RET_SUCCESS)
1299         {
1300             self_->net.force_na_fptr = result_fptr;
1301         }
1302     }
1303     return ret_val;
1304 }
1305
1306 /*! \brief  Callback function which announces the result of Network_ForceNotAvailable()
1307  *  \param  self        The instance
1308  *  \param  result_ptr  Reference to result. Must be casted into Inic_StdResult_t.
1309  */
1310 static void Ucs_NetworkForceNAResult(void *self, void *result_ptr)
1311 {
1312     CUcs *self_ = (CUcs*)self;
1313     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
1314
1315     if (self_->net.force_na_fptr != NULL)
1316     {
1317         self_->net.force_na_fptr(result_ptr_->result, self_->ucs_user_ptr);
1318     }
1319 }
1320
1321 Ucs_Return_t Ucs_Network_GetFrameCounter(Ucs_Inst_t *self, uint32_t reference, Ucs_Network_FrameCounterCb_t result_fptr)
1322 {
1323     CUcs *self_ = (CUcs*)(void*)self;
1324     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1325     if (self_->init_complete != false)
1326     {
1327         ret_val = Inic_NwFrameCounter_Get(self_->inic.local_inic, reference, &self_->net.frame_counter_obs);
1328         if (ret_val == UCS_RET_SUCCESS)
1329         {
1330             self_->net.frame_counter_fptr = result_fptr;
1331         }
1332     }
1333     return ret_val;
1334 }
1335
1336
1337 /*! \brief Callback function which announces the result of Ucs_Network_GetFrameCounter()
1338  *  \param self         The instance
1339  *  \param result_ptr   Reference to result. Must be casted into Inic_StdResult_t and data_info 
1340  *                      must be casted into Inic_FrameCounterStatus_t.
1341  */
1342 static void Ucs_NetworkFrameCounterResult(void *self, void *result_ptr)
1343 {
1344     CUcs *self_ = (CUcs*)self;
1345
1346     if (self_->net.frame_counter_fptr != NULL)
1347     {
1348         Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
1349         uint32_t reference;
1350         uint32_t frame_counter;
1351         uint8_t  lock;
1352
1353         if (result_ptr_->data_info != NULL)
1354         {
1355             Inic_FrameCounterStatus_t *frame_counter_result_data_ptr = (Inic_FrameCounterStatus_t *)result_ptr_->data_info;
1356             reference     = frame_counter_result_data_ptr->reference;
1357             frame_counter = frame_counter_result_data_ptr->frame_counter;
1358             lock          = frame_counter_result_data_ptr->lock;
1359         }
1360         else
1361         {
1362             reference     = 0U;
1363             frame_counter = 0U;
1364             lock          = 0U;  
1365         }
1366
1367         self_->net.frame_counter_fptr(reference, frame_counter, lock, result_ptr_->result, self_->ucs_user_ptr);
1368     }
1369 }
1370
1371 /*! \brief  Observer callback which monitors the network status
1372  *  \param  self        The instance
1373  *  \param  result_ptr  Reference to result. Must be casted into Net_NetworkStatusParam_t.
1374  */
1375 static void Ucs_NetworkStatus(void *self, void *result_ptr)
1376 {
1377     CUcs *self_ = (CUcs*)self;
1378     Net_NetworkStatusParam_t *result_ptr_ = (Net_NetworkStatusParam_t *)result_ptr;
1379
1380     if (self_->net.status_fptr != NULL)
1381     {
1382         self_->net.status_fptr( result_ptr_->change_mask,
1383                                 result_ptr_->events,
1384                                 result_ptr_->availability,
1385                                 result_ptr_->avail_info,
1386                                 result_ptr_->avail_trans_cause,
1387                                 result_ptr_->node_address,
1388                                 result_ptr_->node_position,
1389                                 result_ptr_->max_position,
1390                                 result_ptr_->packet_bw,
1391                                 self_->ucs_user_ptr);
1392     }
1393 }
1394
1395 uint8_t Ucs_Network_GetNodesCount(Ucs_Inst_t *self)
1396 {
1397     CUcs *self_ = (CUcs*)(void*)self;
1398     return Inic_GetNumberOfNodes(self_->inic.local_inic);
1399 }
1400
1401
1402 /*------------------------------------------------------------------------------------------------*/
1403 /* Node Discovery                                                                                 */
1404 /*------------------------------------------------------------------------------------------------*/
1405 Ucs_Return_t Ucs_Nd_Start(Ucs_Inst_t* self)
1406 {
1407     CUcs *self_ = (CUcs*)(void*)self;
1408     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1409
1410     if (self_->init_complete != false)
1411     {
1412         ret_val = Nd_Start(&self_->nd);
1413     }
1414     return ret_val;
1415 }
1416
1417
1418 Ucs_Return_t Ucs_Nd_Stop(Ucs_Inst_t* self)
1419 {
1420     CUcs *self_ = (CUcs*)(void*)self;
1421     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1422
1423     if (self_->init_complete != false)
1424     {
1425         ret_val = Nd_Stop(&self_->nd);
1426     }
1427     return ret_val;
1428 }
1429
1430
1431 Ucs_Return_t Ucs_Nd_InitAll(Ucs_Inst_t* self)
1432 {
1433     CUcs *self_ = (CUcs*)(void*)self;
1434     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1435
1436     if (self_->init_complete != false)
1437     {
1438         Nd_InitAll(&self_->nd);
1439         ret_val = UCS_RET_SUCCESS;
1440     }
1441     return ret_val;
1442
1443 }
1444
1445 /*! \brief  Callback function to proxy the user callback for node evaluation
1446  *  \param  self            The instance
1447  *  \param  signature_ptr   Reference to the node signature
1448  *  \return The evaluation return value which defines how to proceed with the node.
1449  */
1450 static Ucs_Nd_CheckResult_t Ucs_OnNdEvaluate(void *self, Ucs_Signature_t *signature_ptr)
1451 {
1452     CUcs *self_ = (CUcs*)(void*)self;
1453     Ucs_Nd_CheckResult_t ret_val = UCS_ND_CHK_UNKNOWN;
1454
1455     if (self_->init_data.nd.eval_fptr != NULL)
1456     {
1457         ret_val = self_->init_data.nd.eval_fptr(signature_ptr, self_->ucs_user_ptr);
1458     }
1459
1460     return ret_val;
1461 }
1462
1463 /*! \brief  Callback function to proxy the user callback for node evaluation
1464  *  \param  self            The instance
1465  *  \param  code            The report code 
1466  *  \param  signature_ptr   Reference to the node signature or NULL if no signature applies.
1467  */
1468 static void Ucs_OnNdReport(void *self, Ucs_Nd_ResCode_t code, Ucs_Signature_t *signature_ptr)
1469 {
1470     CUcs *self_ = (CUcs*)(void*)self;
1471
1472     if (self_->init_data.nd.report_fptr != NULL)
1473     {
1474         self_->init_data.nd.report_fptr(code, signature_ptr, self_->ucs_user_ptr);
1475     }
1476 }
1477
1478
1479 /*------------------------------------------------------------------------------------------------*/
1480 /* BackChannel Diagnosis                                                                          */
1481 /*------------------------------------------------------------------------------------------------*/
1482 Ucs_Return_t Ucs_Bcd_Start(Ucs_Inst_t* self, Ucs_Bcd_ReportCb_t report_fptr)
1483 {
1484     CUcs *self_ = (CUcs*)(void*)self;
1485     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1486
1487     if (report_fptr == NULL)
1488     {
1489         ret_val = UCS_RET_ERR_PARAM;
1490     }
1491     else if (self_->init_complete != false)
1492     {
1493         Bcd_Start(&self_->bcd, report_fptr);
1494         ret_val = UCS_RET_SUCCESS;
1495     }
1496     return ret_val;
1497 }
1498
1499
1500 /*------------------------------------------------------------------------------------------------*/
1501 /*  Programming service                                                                              */
1502 /*------------------------------------------------------------------------------------------------*/
1503 Ucs_Return_t Ucs_Prog_Start(Ucs_Inst_t *self, 
1504                             uint16_t node_id, 
1505                             Ucs_Signature_t *signature, 
1506                             Ucs_Prg_SessionType_t session_type, 
1507                             Ucs_Prg_Command_t* command_list, 
1508                             Ucs_Prg_ReportCb_t result_fptr)
1509 {
1510     CUcs *self_ = (CUcs*)(void*)self;
1511     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1512
1513     if (result_fptr == NULL)
1514     {
1515         ret_val = UCS_RET_ERR_PARAM;
1516     }
1517     else if (self_->init_complete != false)
1518     {
1519         Prg_Start(&self_->prg, node_id, signature, session_type, command_list, result_fptr);
1520         ret_val = UCS_RET_SUCCESS;
1521     }
1522
1523     return ret_val;
1524 }
1525
1526 /*------------------------------------------------------------------------------------------------*/
1527 /* Message Handling                                                                               */
1528 /*------------------------------------------------------------------------------------------------*/
1529 /*! \brief Initializes the port message service for application interface (MCM)
1530  *  \param self     The instance
1531  */
1532 static void Ucs_InitPmsComponentApp(CUcs *self)
1533 {
1534     Fifo_InitData_t mcm_init;
1535     Fifo_Config_t mcm_config;
1536
1537     /* Initialize the MCM channel */
1538     mcm_init.base_ptr = &self->general.base;
1539     mcm_init.channel_ptr = &self->pmch;
1540     mcm_init.rx_cb_fptr = &Trcv_RxOnMsgComplete;
1541     mcm_init.rx_cb_inst = &self->msg.mcm_transceiver;
1542     mcm_init.tx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
1543     mcm_init.rx_encoder_ptr = Enc_GetEncoder(ENC_CONTENT_00);
1544
1545     /* Enable INIC watchdog */
1546     mcm_config.fifo_id = PMP_FIFO_ID_MCM;
1547     mcm_config.tx_wd_timeout = 10U;             /* Watchdog timeout: 1s */
1548     mcm_config.tx_wd_timer_value = 600U;        /* Watchdog trigger every 600 ms */
1549     mcm_config.rx_ack_timeout = 10U;            /* Acknowledge timeout: 10 ms */
1550     mcm_config.rx_busy_allowed = 0xFU;
1551     mcm_config.rx_credits = PMCH_MCM_CREDITS;
1552     mcm_config.rx_threshold = PMCH_MCM_THRESHOLD;
1553     if (self->init_data.general.inic_watchdog_enabled == false)
1554     {
1555         /* Disable INIC watchdog */
1556         mcm_config.tx_wd_timeout = 0U;          /* Watchdog timeout:    0 -> infinite */
1557         mcm_config.tx_wd_timer_value = 0U;      /* Watchdog timer:      0 -> no timer */
1558         mcm_config.rx_ack_timeout = 0U;         /* Acknowledge timeout: 0 -> infinite */
1559     }
1560     Fifo_Ctor(&self->msg.mcm_fifo,&mcm_init, &mcm_config);
1561 #if 0
1562     Fifos_Ctor(&self->fifos, &self->general.base, &self->pmch, NULL, &self->msg.mcm_fifo, NULL);
1563     Pmev_Ctor(&self->pme, &self->general.base, &self->fifos);       /* initialize event handler */
1564 #endif
1565
1566     /* initialize transceivers and set reference to FIFO instance */
1567     Trcv_Ctor(&self->msg.mcm_transceiver, &self->msg.mcm_fifo, MSG_ADDR_EHC_APP, self->ucs_user_ptr, PMP_FIFO_ID_MCM);
1568     Trcv_RxAssignFilter(&self->msg.mcm_transceiver, &Ucs_McmRx_FilterCallback, self);
1569 }
1570
1571 static void Ucs_InitAmsComponent(CUcs *self)
1572 {
1573     Smm_Ctor(&self->msg.smm, self->ucs_user_ptr);
1574     (void)Smm_LoadPlugin(&self->msg.smm, &self->msg.ams_allocator, SMM_SIZE_RX_MSG);
1575
1576     TR_ASSERT(self->ucs_user_ptr, "[API]", (self->msg.ams_allocator.alloc_fptr != NULL));
1577     TR_ASSERT(self->ucs_user_ptr, "[API]", (self->msg.ams_allocator.free_fptr != NULL));
1578
1579     Amsp_Ctor(&self->msg.ams_pool, &self->msg.ams_allocator, self->ucs_user_ptr);
1580     Ams_Ctor(&self->msg.ams, &self->general.base, &self->msg.mcm_transceiver, NULL, &self->msg.ams_pool,
1581              SMM_SIZE_RX_MSG);
1582     Ams_TxSetDefaultRetries(&self->msg.ams, self->init_data.ams.tx.default_llrbc);
1583
1584     Amd_Ctor(&self->msg.amd, &self->general.base, &self->msg.ams);
1585     Amd_AssignReceiver(&self->msg.amd, &Ucs_AmsRx_Callback, self);
1586     /* Amd_RxAssignModificator(&self->amd, &Mnsa_AmdRx_Modificator, self); */
1587
1588     self->msg.ams_tx_alloc_failed = false;
1589     Obs_Ctor(&self->msg.ams_tx_freed_obs, self, &Ucs_AmsTx_FreedCallback);
1590     if (self->init_data.ams.tx.message_freed_fptr != NULL)
1591     {
1592         Ams_TxAssignMsgFreedObs(&self->msg.ams, &self->msg.ams_tx_freed_obs);
1593     }
1594
1595     Cmd_Ctor(&self->msg.cmd, &self->general.base);
1596 }
1597
1598 extern Ucs_AmsTx_Msg_t* Ucs_AmsTx_AllocMsg(Ucs_Inst_t *self, uint16_t data_size)
1599 {
1600     CUcs *self_ = (CUcs*)(void*)self;
1601     Ucs_AmsTx_Msg_t *ret_ptr = NULL;
1602
1603     if ((self_->init_complete != false) && (self_->init_data.ams.enabled == true))
1604     {
1605         ret_ptr = Ams_TxGetMsg(&self_->msg.ams, data_size);
1606     }
1607
1608     self_->msg.ams_tx_alloc_failed = (ret_ptr == NULL) ? true : false;
1609     return ret_ptr;
1610 }
1611
1612 extern Ucs_Return_t Ucs_AmsTx_SendMsg(Ucs_Inst_t *self, Ucs_AmsTx_Msg_t *msg_ptr, Ucs_AmsTx_CompleteCb_t tx_complete_fptr)
1613 {
1614     CUcs *self_ = (CUcs*)(void*)self;
1615     Ucs_Return_t ret_val = UCS_RET_ERR_NOT_INITIALIZED;
1616
1617     if ((self_->init_complete != false) && (self_->init_data.ams.enabled == true))
1618     {
1619         ret_val = Ams_TxSendMsg(&self_->msg.ams, msg_ptr, NULL, tx_complete_fptr, self_->ucs_user_ptr);
1620     }
1621
1622     return ret_val;
1623 }
1624
1625 extern void Ucs_AmsTx_FreeUnusedMsg(Ucs_Inst_t *self, Ucs_AmsTx_Msg_t *msg_ptr)
1626 {
1627     CUcs *self_ = (CUcs*)(void*)self;
1628
1629     if (msg_ptr != NULL)
1630     {
1631         Ams_TxFreeUnusedMsg(&self_->msg.ams, msg_ptr);
1632     }
1633 }
1634
1635 extern Ucs_AmsRx_Msg_t* Ucs_AmsRx_PeekMsg(Ucs_Inst_t *self)
1636 {
1637     CUcs *self_ = (CUcs*)(void*)self;
1638     Ucs_AmsRx_Msg_t *ret = NULL;
1639
1640     if ((self_->init_complete != false) && (self_->init_data.ams.enabled == true))
1641     {
1642         ret = Amd_RxPeekMsg(&self_->msg.amd);
1643     }
1644
1645     return ret;
1646 }
1647
1648 extern void Ucs_AmsRx_ReleaseMsg(Ucs_Inst_t *self)
1649 {
1650     CUcs *self_ = (CUcs*)(void*)self;
1651
1652     if ((self_->init_complete != false) && (self_->init_data.ams.enabled == true))
1653     {
1654         Amd_RxReleaseMsg(&self_->msg.amd);
1655     }
1656 }
1657
1658 extern uint16_t Ucs_AmsRx_GetMsgCnt(Ucs_Inst_t *self)
1659 {
1660     CUcs *self_ = (CUcs*)(void*)self;
1661     uint16_t ret = 0U;
1662
1663     if ((self_->init_complete != false) && (self_->init_data.ams.enabled == true))
1664     {
1665         ret = Amd_RxGetMsgCnt(&self_->msg.amd);
1666     }
1667     return ret;
1668 }
1669
1670 /*! \brief  Callback function which announces that a new application message
1671  *          is added to the Rx queue
1672  *  \param  self     The instance
1673  */
1674 static void Ucs_AmsRx_Callback(void *self)
1675 {
1676     CUcs *self_ = (CUcs*)self;
1677
1678     if (self_->init_data.ams.rx.message_received_fptr != NULL)
1679     {
1680         self_->init_data.ams.rx.message_received_fptr(self_->ucs_user_ptr);
1681     }
1682 }
1683
1684 /*! \brief  Callback function which announces that the AMS Tx Pool provides again a Tx message object
1685  *          after a prior allocation has failed.
1686  *  \param  self     The instance
1687  *  \param  data_ptr Not used (always \c NULL)
1688  */
1689 static void Ucs_AmsTx_FreedCallback(void *self, void *data_ptr)
1690 {
1691     CUcs *self_ = (CUcs*)self;
1692     MISC_UNUSED(data_ptr);
1693
1694     if ((self_->msg.ams_tx_alloc_failed != false) && (self_->init_complete != false))
1695     {
1696         self_->msg.ams_tx_alloc_failed = false;
1697         self_->init_data.ams.tx.message_freed_fptr(self_->ucs_user_ptr); 
1698     }
1699 }
1700
1701 /*! \brief  Callback function which filters MCM Rx messages
1702  *  \param  self     The instance
1703  *  \param  tel_ptr  The received Rx message object 
1704  *  \return Returns \c true to discard the message and free it to the pool (no-pass).
1705  *          Otherwise, returns \c false (pass).
1706  */
1707 static bool Ucs_McmRx_FilterCallback(void *self, Msg_MostTel_t *tel_ptr)
1708 {
1709     CUcs *self_ = (CUcs*)self;
1710     bool ret = false;                           /* default: pass the message */
1711
1712     if ((tel_ptr->id.fblock_id != MSG_DEF_FBLOCK_ID) || (tel_ptr->id.op_type != MSG_DEF_OP_TYPE) ||
1713         ((tel_ptr->id.function_id & (uint16_t)0x000FU) != MSG_DEF_FUNC_ID_LSN))
1714     {
1715         TR_INFO((self_->ucs_user_ptr, "[API]", "Ucs_McmRx_FilterCallback(): discarding Rx message with signature %02X.%02X.%03X.%X ", 4U, tel_ptr->id.fblock_id, tel_ptr->id.instance_id, tel_ptr->id.function_id, tel_ptr->id.op_type));
1716         ret = true;
1717     }
1718
1719     MISC_UNUSED(self_);
1720
1721     return ret;
1722 }
1723
1724 /*------------------------------------------------------------------------------------------------*/
1725 /* Message decoding                                                                               */
1726 /*------------------------------------------------------------------------------------------------*/
1727 Ucs_Cmd_Return_t Ucs_Cmd_AddMsgIdTable(Ucs_Inst_t *self, Ucs_Cmd_MsgId_t *msg_id_tab_ptr)
1728 {
1729     Ucs_Cmd_Return_t ret_val;
1730     CUcs *self_ = (CUcs*)(void*)self;
1731
1732     if (msg_id_tab_ptr != NULL)
1733     {
1734         ret_val = Cmd_AddMsgIdTable(&(self_->msg.cmd), msg_id_tab_ptr);
1735     }
1736     else
1737     {
1738         ret_val = UCS_CMD_RET_ERR_NULL_PTR;
1739     }
1740
1741     return ret_val;
1742 }
1743
1744
1745 Ucs_Cmd_Return_t Ucs_Cmd_RemoveMsgIdTable(Ucs_Inst_t *self)
1746 {
1747     Ucs_Cmd_Return_t ret_val;
1748     CUcs *self_ = (CUcs*)(void*)self;
1749
1750     ret_val = Cmd_RemoveMsgIdTable(&(self_->msg.cmd));
1751
1752     return ret_val;
1753 }
1754
1755
1756 Ucs_Cmd_Return_t Ucs_Cmd_DecodeMsg(Ucs_Inst_t *self, Ucs_AmsRx_Msg_t *msg_rx_ptr)
1757 {
1758     Ucs_Cmd_Return_t ret_val;
1759     CUcs *self_ = (CUcs*)(void*)self;
1760
1761     if(msg_rx_ptr != NULL)
1762     {
1763         ret_val = Cmd_DecodeMsg(&(self_->msg.cmd), msg_rx_ptr);
1764     }
1765     else
1766     {
1767         ret_val = UCS_CMD_RET_ERR_NULL_PTR;
1768     }
1769
1770     return ret_val;
1771 }
1772
1773 /*------------------------------------------------------------------------------------------------*/
1774 /* Unit tests only                                                                                */
1775 /*------------------------------------------------------------------------------------------------*/
1776 extern void Ucs_AssignRxFilter(Ucs_Inst_t *self, Ucs_RxFilterCb_t callback_fptr)
1777 {
1778     CUcs *self_ = (CUcs*)(void*)self;
1779     self_->rx_filter_fptr = callback_fptr;
1780 }
1781
1782
1783 /*!
1784  * @}
1785  * \endcond
1786  */
1787 /*------------------------------------------------------------------------------------------------*/
1788 /* End of file                                                                                    */
1789 /*------------------------------------------------------------------------------------------------*/
1790