Updated GDB ini file to load binding symbols directly from SDK
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_attach.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 CAttachService class
25  *
26  * \cond UCS_INTERNAL_DOC
27  * \addtogroup  G_ATS
28  * @{
29  */
30
31 /*------------------------------------------------------------------------------------------------*/
32 /* Includes                                                                                       */
33 /*------------------------------------------------------------------------------------------------*/
34 #include "ucs_attach.h"
35 #include "ucs_pmevent.h"
36 #include "ucs_misc.h"
37
38 /*------------------------------------------------------------------------------------------------*/
39 /* Service parameters                                                                             */
40 /*------------------------------------------------------------------------------------------------*/
41 /*! Priority of the ATS service used by scheduler */
42 static const uint8_t ATS_SRV_PRIO = 254U;   /* parasoft-suppress  MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
43 /*! Main event for the ATS service */
44 static const Srv_Event_t ATS_EVENT_SERVICE = 1U;
45
46 /*------------------------------------------------------------------------------------------------*/
47 /* Internal constants                                                                             */
48 /*------------------------------------------------------------------------------------------------*/
49 /*! \brief Initialization timeout in milliseconds (t = 3s) */
50 static const uint16_t ATS_INIT_TIMEOUT = 3000U; /* parasoft-suppress  MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
51
52 /*------------------------------------------------------------------------------------------------*/
53 /* Internal definitions                                                                           */
54 /*------------------------------------------------------------------------------------------------*/
55 #define ATS_NUM_STATES     11U      /*!< \brief Number of state machine states */
56 #define ATS_NUM_EVENTS      5U      /*!< \brief Number of state machine events */
57
58 /*------------------------------------------------------------------------------------------------*/
59 /* Internal enumerators                                                                           */
60 /*------------------------------------------------------------------------------------------------*/
61 /*! \brief Possible events of the attach state machine */
62 typedef enum Ats_Events_
63 {
64     ATS_E_NIL             = 0,      /*!< \brief NIL Event */
65     ATS_E_NEXT            = 1,      /*!< \brief Go to next state */
66     ATS_E_RETRY           = 2,      /*!< \brief Retry current action */
67     ATS_E_ERROR           = 3,      /*!< \brief An error has been occurred */
68     ATS_E_TIMEOUT         = 4       /*!< \brief An timeout has been occurred */
69
70 } Ats_Events_t;
71
72 /*! \brief States of the attach state machine */
73 typedef enum Ats_State_
74 {
75     ATS_S_START           =  0,     /*!< \brief Start state */
76     ATS_S_PMS_UNSYNC      =  1,     /*!< \brief Initially un-synchronizes all FIFOs */
77     ATS_S_PMS_INIT        =  2,     /*!< \brief PMS initialization state */
78     ATS_S_VERS_CHK        =  3,     /*!< \brief Version check state */
79     ATS_S_INIC_OVHL       =  4,     /*!< \brief INIC overhaul state */
80     ATS_S_DEV_ATT_STAGE_1 =  5,     /*!< \brief Device attach state 1 (wait for first condition) */
81     ATS_S_DEV_ATT_STAGE_2 =  6,     /*!< \brief Device attach state 2 (wait for second condition) */
82     ATS_S_DEV_ATT_STAGE_3 =  7,     /*!< \brief Device attach state 3 (wait for third condition) */
83     ATS_S_NW_CONFIG       =  8,     /*!< \brief Retrieve network configuration */
84     ATS_S_INIT_CPL        =  9,     /*!< \brief Initialization complete state */
85     ATS_S_ERROR           = 10      /*!< \brief Error state */
86
87 } Ats_State_t;
88
89 /*------------------------------------------------------------------------------------------------*/
90 /* Internal prototypes                                                                            */
91 /*------------------------------------------------------------------------------------------------*/
92 static void Ats_TimeoutCb(void *self);
93 static void Ats_Service(void *self);
94 static void Ats_ResetObservers(CAttachService *self);
95 static void Ats_StartPmsUnsync(void *self);
96 static void Ats_StartPmsInit(void *self);
97 static void Ats_StartVersChk(void *self);
98 static void Ats_StartInicOvhl(void *self);
99 static void Ats_StartDevAtt(void *self);
100 static void Ats_StartNwConfig(void *self);
101 static void Ats_InitCpl(void *self);
102 static void Ats_HandleInternalErrors(void *self, void *error_code_ptr);
103 static void Ats_HandleError(void *self);
104 static void Ats_HandleTimeout(void *self);
105 static void Ats_InvalidTransition(void *self);
106 static void Ats_CheckPmsUnsyncResult(void *self, void *result_ptr);
107 static void Ats_CheckPmsInitResult(void *self, void *result_ptr);
108 static void Ats_CheckVersChkResult(void *self, void *result_ptr);
109 static void Ats_CheckNetworkStatusReceived(void *self, void *result_ptr);
110 static void Ats_CheckDeviceStatusReceived(void *self, void *data_ptr);
111 static void Ats_CheckDevAttResult(void *self, void *result_ptr);
112 static void Ats_CheckNwConfigStatus(void *self, void *result_ptr);
113
114 /*------------------------------------------------------------------------------------------------*/
115 /* State transition table (used by finite state machine)                                          */
116 /*------------------------------------------------------------------------------------------------*/
117 /*! \brief State transition table */
118 static const Fsm_StateElem_t ats_trans_tab[ATS_NUM_STATES][ATS_NUM_EVENTS] =    /* parasoft-suppress  MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
119 {
120 /* |--------------------------------|------------------------------------------------|------------------------------------------------|--------------------------------------|----------------------------------------|
121  * |   ATS_E_NIL                    | ATS_E_NEXT                                     | ATS_E_RETRY                                    | ATS_E_ERROR                          | ATS_E_TIMEOUT                          |
122  * |--------------------------------|------------------------------------------------|------------------------------------------------|--------------------------------------|----------------------------------------|
123  */ 
124     { {NULL, ATS_S_START          }, {&Ats_StartPmsUnsync,    ATS_S_PMS_UNSYNC     }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
125     { {NULL, ATS_S_PMS_UNSYNC     }, {&Ats_StartPmsInit,      ATS_S_PMS_INIT       }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
126     { {NULL, ATS_S_PMS_INIT       }, {&Ats_StartVersChk,      ATS_S_VERS_CHK       }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
127     { {NULL, ATS_S_VERS_CHK       }, {&Ats_StartInicOvhl,     ATS_S_INIC_OVHL      }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
128     { {NULL, ATS_S_INIC_OVHL      }, {&Ats_StartDevAtt,       ATS_S_DEV_ATT_STAGE_1}, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
129     { {NULL, ATS_S_DEV_ATT_STAGE_1}, {NULL,                   ATS_S_DEV_ATT_STAGE_2}, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
130     { {NULL, ATS_S_DEV_ATT_STAGE_2}, {NULL,                   ATS_S_DEV_ATT_STAGE_3}, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
131     { {NULL, ATS_S_DEV_ATT_STAGE_3}, {&Ats_StartNwConfig,     ATS_S_NW_CONFIG      }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
132     { {NULL, ATS_S_NW_CONFIG      }, {&Ats_InitCpl,           ATS_S_INIT_CPL       }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_HandleError,       ATS_S_ERROR}, {&Ats_HandleTimeout,     ATS_S_ERROR} },
133     { {NULL, ATS_S_INIT_CPL       }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR}, {&Ats_InvalidTransition, ATS_S_ERROR} },
134     { {NULL, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR          }, {&Ats_InvalidTransition, ATS_S_ERROR}, {&Ats_InvalidTransition, ATS_S_ERROR} }
135 };
136
137 /*------------------------------------------------------------------------------------------------*/
138 /* Implementation of class CAttachService                                                         */
139 /*------------------------------------------------------------------------------------------------*/
140 /*! \brief Constructor of the attach service class
141  *  \param self        Instance pointer
142  *  \param init_ptr    Reference to the initialization data
143  */
144 void Ats_Ctor(CAttachService *self, Ats_InitData_t *init_ptr)
145 {
146     MISC_MEM_SET(self, 0, sizeof(*self));
147     T_Ctor(&self->timer);
148     self->report_result = UCS_INIT_RES_SUCCESS;
149     self->init_data = *init_ptr;
150     Ssub_Ctor(&self->ats_result_subject, self->init_data.base_ptr->ucs_user_ptr);
151     Fsm_Ctor(&self->fsm, self, &(ats_trans_tab[0][0]), ATS_NUM_EVENTS, ATS_S_START);
152     /* Initialize ATS service */
153     Srv_Ctor(&self->ats_srv, ATS_SRV_PRIO, self, &Ats_Service);
154     /* Add ATS service to scheduler */
155     (void)Scd_AddService(&self->init_data.base_ptr->scd, &self->ats_srv);
156 }
157
158 /*! \brief Starts the attach process and the initialization timeout.
159  *  \param self     Instance pointer
160  *  \param obs_ptr  Reference to result observer
161  */
162 void Ats_Start(void *self, CSingleObserver *obs_ptr)
163 {
164     CAttachService *self_ = (CAttachService *)self;
165     /* Observe internal errors during the attach process */
166     Mobs_Ctor(&self_->internal_error_obs, self_, (EH_E_BIST_FAILED | EH_E_SYNC_LOST), &Ats_HandleInternalErrors);
167     Eh_AddObsrvInternalEvent(&self_->init_data.base_ptr->eh, &self_->internal_error_obs);
168     /* Set first event of attach state machine */
169     Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
170     Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
171     /* Start timeout timer used for attach process */
172     Tm_SetTimer(&self_->init_data.base_ptr->tm,
173                 &self_->timer,
174                 &Ats_TimeoutCb,
175                 self_,
176                 ATS_INIT_TIMEOUT,
177                 0U);
178     (void)Ssub_AddObserver(&self_->ats_result_subject, obs_ptr);
179 }
180
181 /*! \brief Timer callback used for initialization timeout.
182  *  \param self    Instance pointer
183  */
184 static void Ats_TimeoutCb(void *self)
185 {
186     CAttachService *self_ = (CAttachService *)self;
187     Fsm_SetEvent(&self_->fsm, ATS_E_TIMEOUT);
188     Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
189 }
190
191 /*! \brief Service function of the attach service.
192  *  \param self    Instance pointer
193  */
194 static void Ats_Service(void *self)
195 {
196     CAttachService *self_ = (CAttachService *)self;
197     Srv_Event_t event_mask;
198     Srv_GetEvent(&self_->ats_srv, &event_mask);
199     if (ATS_EVENT_SERVICE == (event_mask & ATS_EVENT_SERVICE))   /* Is event pending? */
200     {
201         Fsm_State_t result;
202         Srv_ClearEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
203         result = Fsm_Service(&self_->fsm);
204         TR_ASSERT(self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", (result != FSM_STATE_ERROR));
205         MISC_UNUSED(result);
206     }
207 }
208
209 /*! \brief Resets all module internal observers.
210  *  \param self    Instance pointer
211  */
212 static void Ats_ResetObservers(CAttachService *self)
213 {
214     Eh_DelObsrvInternalEvent(&self->init_data.base_ptr->eh, &self->internal_error_obs);
215     Sobs_Ctor(&self->sobs, NULL, NULL);
216     Obs_Ctor(&self->obs, NULL, NULL);
217     Obs_Ctor(&self->obs2, NULL, NULL);
218 }
219
220 /*------------------------------------------------------------------------------------------------*/
221 /* State machine actions                                                                          */
222 /*------------------------------------------------------------------------------------------------*/
223 /*! \brief un-synchronizes PMS and observes PM events
224  *  \param self    Instance pointer
225  */
226 static void Ats_StartPmsUnsync(void *self)
227 {
228     CAttachService *self_ = (CAttachService *)self;
229     Obs_Ctor(&self_->obs, self_, &Ats_CheckPmsUnsyncResult);
230     Fifos_ConfigureSyncParams(self_->init_data.fifos_ptr, FIFOS_SYNC_RETRIES, FIFOS_SYNC_TIMEOUT);
231     Fifos_Unsynchronize(self_->init_data.fifos_ptr, true, true);
232     Fifos_AddEventObserver(self_->init_data.fifos_ptr, &self_->obs);
233 }
234
235 /*! \brief Synchronizes PMS and observes PM events
236  *  \param self    Instance pointer
237  */
238 static void Ats_StartPmsInit(void *self)
239 {
240     CAttachService *self_ = (CAttachService *)self;
241     Obs_Ctor(&self_->obs, self_, &Ats_CheckPmsInitResult);
242     Pmev_Start(self_->init_data.pme_ptr);                               /* enables failure reporting to all modules */
243     Fifos_Synchronize(self_->init_data.fifos_ptr, false, true);         /* now synchronizes, counter is not reset to "0" */
244     Fifos_AddEventObserver(self_->init_data.fifos_ptr, &self_->obs);
245 }
246
247 /*! \brief Starts the request of the INIC firmware and hardware revisions.
248  *  \param self    Instance pointer
249  */
250 static void Ats_StartVersChk(void *self)
251 {
252     CAttachService *self_ = (CAttachService *)self;
253     Sobs_Ctor(&self_->sobs, self_, &Ats_CheckVersChkResult);
254     if (Inic_DeviceVersion_Get(self_->init_data.inic_ptr,
255                               &self_->sobs) != UCS_RET_SUCCESS)
256     {
257         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "INIC device version check failed!", 0U));
258         self_->report_result = UCS_INIT_RES_ERR_BUF_OVERFLOW;
259         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
260     }
261 }
262
263 /*! \brief Starts the overhaul process of the INIC.
264  *  \param self    Instance pointer
265  */
266 static void Ats_StartInicOvhl(void *self)
267 {
268     CAttachService *self_ = (CAttachService *)self;
269
270     Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
271 }
272
273 /*! \brief Starts the attach process between EHC and INIC.
274  *  \param self    Instance pointer
275  */
276 static void Ats_StartDevAtt(void *self)
277 {
278     CAttachService *self_ = (CAttachService *)self;
279
280     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_StartDevAtt()  called", 0U));
281     /* Assign observer to monitor the initial receipt of INIC message INIC.MOSTNetworkStatus */
282     Obs_Ctor(&self_->obs, self_, &Ats_CheckNetworkStatusReceived);
283     Inic_AddObsrvNwStatus(self_->init_data.inic_ptr, &self_->obs);
284     /* Assign observer to monitor the initial receipt of INIC message INIC.DeviceStatus */
285     Obs_Ctor(&self_->obs2, self_, &Ats_CheckDeviceStatusReceived);
286     Inic_AddObsvrDeviceStatus(self_->init_data.inic_ptr, &self_->obs2);
287
288     /* Start device attach process */
289     Sobs_Ctor(&self_->sobs, self_, &Ats_CheckDevAttResult);
290     if (Inic_DeviceAttach(self_->init_data.inic_ptr, &self_->sobs) != UCS_RET_SUCCESS)
291     {
292         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "INIC device attach failed!", 0U));
293         self_->report_result = UCS_INIT_RES_ERR_BUF_OVERFLOW;
294         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
295     }
296 }
297
298 /*! \brief Starts request of network configuration property required
299  *         to retrieve the own group address.
300  *  \param self    Instance pointer
301  */
302 static void Ats_StartNwConfig(void *self)
303 {
304     CAttachService *self_ = (CAttachService *)self;
305
306     /* Assign observer to monitor the initial receipt of INIC message INIC.MOSTNetworkConfigurarion */
307     Sobs_Ctor(&self_->sobs, self_, &Ats_CheckNwConfigStatus);
308
309     if (Inic_NwConfig_Get(self_->init_data.inic_ptr, &self_->sobs) != UCS_RET_SUCCESS)
310     {
311         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "INIC network configuration failed!", 0U));
312         self_->report_result = UCS_INIT_RES_ERR_BUF_OVERFLOW;
313         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
314     }
315 }
316
317 /*! \brief This method is called when the initialization has been completed.
318  *  \param self    Instance pointer
319  */
320 static void Ats_InitCpl(void *self)
321 {
322     CAttachService *self_ = (CAttachService *)self;
323     self_->report_result = UCS_INIT_RES_SUCCESS;
324     /* Attach process finished -> Reset observers and terminate state machine */
325     Ats_ResetObservers(self_);
326     Tm_ClearTimer(&self_->init_data.base_ptr->tm, &self_->timer);
327     Fsm_End(&self_->fsm);
328     Eh_ReportEvent(&self_->init_data.base_ptr->eh, EH_E_INIT_SUCCEEDED);
329     Ssub_Notify(&self_->ats_result_subject, &self_->report_result, true);
330     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_InitCpl() called", 0U));
331 }
332
333 /*! \brief Handles internal errors during the attach process.
334  *  \param self             Instance pointer
335  *  \param error_code_ptr   Reference to reported error code
336  */
337 static void Ats_HandleInternalErrors(void *self, void *error_code_ptr)
338 {
339     CAttachService *self_ = (CAttachService *)self;
340     uint32_t error_code = *((uint32_t *)error_code_ptr);
341     switch (error_code)
342     {
343         case EH_E_SYNC_LOST:
344             self_->report_result = UCS_INIT_RES_ERR_INIC_SYNC;
345             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "A control FiFo synchronization lost!", 0U));
346             break;
347         case EH_E_BIST_FAILED:
348             self_->report_result = UCS_INIT_RES_ERR_INIC_SYSTEM;
349             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "INIC Build-In-Self-Test failed!", 0U));
350             break;
351         default:
352             self_->report_result = UCS_INIT_RES_ERR_INTERNAL;
353             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Unknown internal error occurred! Error code: 0x%04X", 1U, error_code));
354             break;
355     }
356     /* Error occurred -> Reset observers and terminate state machine */
357     Ats_ResetObservers(self_);
358     Tm_ClearTimer(&self_->init_data.base_ptr->tm, &self_->timer);
359     Fsm_End(&self_->fsm);
360     Eh_ReportEvent(&self_->init_data.base_ptr->eh, EH_E_INIT_FAILED);
361     Ssub_Notify(&self_->ats_result_subject, &self_->report_result, true);
362 }
363
364 /*! \brief Handles general errors during the attach process.
365  *  \param self    Instance pointer
366  */
367 static void Ats_HandleError(void *self)
368 {
369     CAttachService *self_ = (CAttachService *)self;
370     /* Error occurred -> Reset observers and terminate state machine */
371     Ats_ResetObservers(self_);
372     Tm_ClearTimer(&self_->init_data.base_ptr->tm, &self_->timer);
373     Fsm_End(&self_->fsm);
374     Eh_ReportEvent(&self_->init_data.base_ptr->eh, EH_E_INIT_FAILED);
375     Ssub_Notify(&self_->ats_result_subject, &self_->report_result, true);
376     TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Error occurred during initialization!", 0U));
377 }
378
379 /*! \brief Handles timeouts during the attach process.
380  *  \param self    Instance pointer
381  */
382 static void Ats_HandleTimeout(void *self)
383 {
384     CAttachService *self_ = (CAttachService *)self;
385     self_->report_result = UCS_INIT_RES_ERR_TIMEOUT;
386     /* Error occurred -> Reset observers and terminate state machine */
387     Ats_ResetObservers(self_);
388     Fsm_End(&self_->fsm);
389     Eh_ReportEvent(&self_->init_data.base_ptr->eh, EH_E_INIT_FAILED);
390     Ssub_Notify(&self_->ats_result_subject, &self_->report_result, true);
391     TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Initialization timeout occurred!", 0U));
392 }
393
394 /*! \brief This method is invoked if an invalid state machine transition is executed.
395  *  \param self    Instance pointer
396  */
397 static void Ats_InvalidTransition(void *self)
398 {
399     CAttachService *self_ = (CAttachService *)self;
400     self_->report_result = UCS_INIT_RES_ERR_INTERNAL;
401     /* Invalid Transition -> Reset observers and terminate state machine */
402     Ats_ResetObservers(self_);
403     Tm_ClearTimer(&self_->init_data.base_ptr->tm, &self_->timer);
404     Fsm_End(&self_->fsm);
405     Eh_ReportEvent(&self_->init_data.base_ptr->eh, EH_E_INIT_FAILED);
406     Ssub_Notify(&self_->ats_result_subject, &self_->report_result, true);
407     TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Invalid transition within ATS state machine!", 0U));
408 }
409
410 /*------------------------------------------------------------------------------------------------*/
411 /* Implementation of the observer results                                                         */
412 /*------------------------------------------------------------------------------------------------*/
413 /*! \brief Result callback for action "PMS Initialization". This function is part of an
414  *         observer object and is invoked by Sub_Notify().
415  *  \param self        Instance pointer
416  *  \param result_ptr  Reference to the received PMS event. The pointer must be casted into 
417  *                     data type Fifos_Event_t.
418  */
419 static void Ats_CheckPmsUnsyncResult(void *self, void *result_ptr)
420 {
421     CAttachService *self_ = (CAttachService *)self;
422     Fifos_Event_t pms_event = *((Fifos_Event_t *)result_ptr);
423
424     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckPmsUnsyncResult() called", 0U));
425
426     if (pms_event == FIFOS_EV_UNSYNC_COMPLETE)
427     {
428         Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
429         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
430     }
431     else
432     {
433         self_->report_result = UCS_INIT_RES_ERR_INIC_SYNC;
434         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
435         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
436         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckPmsUnsyncResult(): un-sync failed, event=0x%02X", 1U, pms_event));
437     }
438     Fifos_RemoveEventObserver(self_->init_data.fifos_ptr, &self_->obs);
439 }
440
441 /*! \brief Result callback for action "PMS Initialization". This function is part of an
442  *         observer object and is invoked by Sub_Notify().
443  *  \param self        Instance pointer
444  *  \param result_ptr  Reference to the received PMS event. The pointer must be casted into 
445  *                     data type Fifos_Event_t.
446  */
447 static void Ats_CheckPmsInitResult(void *self, void *result_ptr)
448 {
449     CAttachService *self_ = (CAttachService *)self;
450     Fifos_Event_t pms_event = *((Fifos_Event_t *)result_ptr);
451
452     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckPmsInitResult() called", 0U));
453
454     if (pms_event == FIFOS_EV_SYNC_ESTABLISHED)
455     {
456         Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
457         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
458     }
459     else
460     {
461         self_->report_result = UCS_INIT_RES_ERR_INIC_SYNC;
462         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
463         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
464         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckPmsInitResult(): sync failed, event=0x%02X", 1U, pms_event));
465     }
466     Fifos_RemoveEventObserver(self_->init_data.fifos_ptr, &self_->obs);
467 }
468
469 /*! \brief Result callback for action "Version Check". This function is part of a single
470  *         observer object and is invoked by Ssub_Notify().
471  *  \param self        Instance pointer
472  *  \param result_ptr  Reference to the received version check result. The pointer must be casted
473  *                     into data type Inic_StdResult_t.
474  */
475 static void Ats_CheckVersChkResult(void *self, void *result_ptr)
476 {
477     CAttachService *self_ = (CAttachService *)self;
478     Inic_StdResult_t *result_ptr_ = (Inic_StdResult_t *)result_ptr;
479     if (result_ptr_->result.code == UCS_RES_SUCCESS)
480     {
481         Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
482         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
483     }
484     else
485     {
486         self_->report_result = UCS_INIT_RES_ERR_INIC_VERSION;
487         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
488         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
489         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "INIC version check failed!", 0U));
490     }
491     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckVersChkResult() called", 0U));
492 }
493
494 /*! \brief Result callback which handles one of three conditions for action "Device Attach". The 
495  *         function is called if INIC message INIC.MOSTNetworkStatus was received. The function is 
496  *         part of an observer object and is invoked by Sub_Notify(). The property 
497  *         INIC.MOSTNetworkStatus.Status() is notified. Thus, there is no error condition available.
498  *  \param self        Instance pointer
499  *  \param result_ptr  Reference to the MOST Network Status. The pointer must be casted into data 
500  *                     type Inic_StdResult_t.
501  */
502 static void Ats_CheckNetworkStatusReceived(void *self, void *result_ptr)
503 {
504     CAttachService *self_ = (CAttachService *)self;
505     Inic_DelObsrvNwStatus(self_->init_data.inic_ptr, &self_->obs);
506     Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
507     Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
508     MISC_UNUSED(result_ptr);
509     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckNetworkStatusReceived() called", 0U));
510 }
511
512 /*! \brief Observer callback that is notified on received INIC.DeviceStatus
513  *  \param self        Instance pointer
514  *  \param data_ptr    The pointer to the current INIC.DeviceStatus structure
515  */
516 static void Ats_CheckDeviceStatusReceived(void *self, void *data_ptr)
517 {
518     CAttachService *self_ = (CAttachService *)self;
519     Inic_DelObsvrDeviceStatus(self_->init_data.inic_ptr, &self_->obs2);
520     Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
521     Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
522     MISC_UNUSED(data_ptr);
523     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckDeviceStatusReceived() called", 0U));
524 }
525
526 /*! \brief Result callback which handles one of two conditions for action "Device Attach". The 
527  *         function handles the result of the INIC method INIC.DeviceAttach. This function is part 
528  *         of a single-observer object and is invoked by Ssub_Notify().
529  *  \param self        Instance pointer
530  *  \param result_ptr  Reference to the received device attach result. The pointer must be casted 
531  *                     into data type Inic_StdResult_t.
532  */
533 static void Ats_CheckDevAttResult(void *self, void *result_ptr)
534 {
535     CAttachService *self_ = (CAttachService *)self;
536     Inic_StdResult_t error_data = *((Inic_StdResult_t *)result_ptr);
537     switch (error_data.result.code)
538     {
539         case UCS_RES_SUCCESS:
540             /* Operation succeeded */
541             Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
542             Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
543             break; 
544         case UCS_RES_ERR_CONFIGURATION:
545             /* Configuration error occurred -> attach process failed! */
546             self_->report_result = UCS_INIT_RES_ERR_DEV_ATT_CFG;
547             Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
548             Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
549             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Device attach failed due to an configuration error!", 0U));
550             TR_ERROR_INIC_RESULT(self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", error_data.result.info_ptr, error_data.result.info_size);
551             break;
552         case UCS_RES_ERR_SYSTEM:
553             /* INIC is still attached -> attach process failed! */
554             self_->report_result = UCS_INIT_RES_ERR_DEV_ATT_PROC;
555             Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
556             Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
557             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "EHC is already attached to the INIC!", 0U));
558             break;
559         default:
560             /* INIC reports an unexpected error -> attach process failed! */
561             self_->report_result = UCS_INIT_RES_ERR_DEV_ATT_PROC;
562             Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
563             Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
564             TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Device attach failed! Unexpected error code = 0x%02X", 1U, error_data.result.code));
565             TR_ERROR_INIC_RESULT(self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", error_data.result.info_ptr, error_data.result.info_size);
566             break;
567     }
568     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckDevAttResult() called", 0U));
569 }
570
571 /*! \brief Result callback for INIC network configuration
572  *  \param self        Instance pointer
573  *  \param result_ptr  Reference to the received network configuration status event. 
574  *                     The pointer must be casted into data type Inic_StdResult_t.
575  */
576 static void Ats_CheckNwConfigStatus(void *self, void *result_ptr)
577 {
578     CAttachService *self_ = (CAttachService *)self;
579     Inic_StdResult_t error_data = *((Inic_StdResult_t *)result_ptr);
580
581     if (error_data.result.code == UCS_RES_SUCCESS)
582     {
583         /* Operation succeeded */
584         Fsm_SetEvent(&self_->fsm, ATS_E_NEXT);
585         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
586     }
587     else
588     {
589         /* INIC reports an unexpected error -> attach process failed! */
590         self_->report_result = UCS_INIT_RES_ERR_NET_CFG;
591         Fsm_SetEvent(&self_->fsm, ATS_E_ERROR);
592         Srv_SetEvent(&self_->ats_srv, ATS_EVENT_SERVICE);
593         TR_ERROR((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Network configuration failed! Unexpected error code = 0x%02X", 1U, error_data.result.code));
594         TR_ERROR_INIC_RESULT(self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", error_data.result.info_ptr, error_data.result.info_size);
595     }
596     TR_INFO((self_->init_data.base_ptr->ucs_user_ptr, "[ATS]", "Ats_CheckNwConfigStatus() called", 0U));
597 }
598
599 /*!
600  * @}
601  * \endcond
602  */
603
604 /*------------------------------------------------------------------------------------------------*/
605 /* End of file                                                                                    */
606 /*------------------------------------------------------------------------------------------------*/
607