Initial Commit
[apps/agl-service-unicens.git] / ucs2-lib / src / ucs_inic.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 FBlock INIC
25  * \details Contains the general, device an network management parts of INIC management
26  *
27  * \cond UCS_INTERNAL_DOC
28  * \addtogroup G_INIC
29  * @{
30  */
31
32 /*------------------------------------------------------------------------------------------------*/
33 /* Includes                                                                                       */
34 /*------------------------------------------------------------------------------------------------*/
35 #include "ucs_misc.h"
36 #include "ucs_ret_pb.h"
37 #include "ucs_inic.h"
38
39 /*------------------------------------------------------------------------------------------------*/
40 /* Internal constants                                                                             */
41 /*------------------------------------------------------------------------------------------------*/
42 /*! \brief List of all INIC messages */
43 static const Dec_FktOpIcm_t inic_handler[] =       /* parasoft-suppress  MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
44 {
45     { DEC_FKTOP(INIC_FID_NOTIFICATION,            UCS_OP_STATUS),     Inic_Notification_Status },
46     { DEC_FKTOP(INIC_FID_NOTIFICATION,            UCS_OP_ERROR),      Inic_Notification_Error },
47     { DEC_FKTOP(INIC_FID_DEVICE_STATUS,           UCS_OP_STATUS),     Inic_DeviceStatus_Status },
48     { DEC_FKTOP(INIC_FID_DEVICE_STATUS,           UCS_OP_ERROR),      Inic_DummyHandler },
49     { DEC_FKTOP(INIC_FID_DEVICE_VERSION,          UCS_OP_STATUS),     Inic_DeviceVersion_Status },
50     { DEC_FKTOP(INIC_FID_DEVICE_VERSION,          UCS_OP_ERROR),      Inic_DeviceVersion_Error },
51     { DEC_FKTOP(INIC_FID_DEVICE_POWER_OFF,        UCS_OP_STATUS),     Inic_DummyHandler },
52     { DEC_FKTOP(INIC_FID_DEVICE_POWER_OFF,        UCS_OP_ERROR),      Inic_DummyHandler },
53     { DEC_FKTOP(INIC_FID_DEVICE_ATTACH,           UCS_OP_RESULT),     Inic_DeviceAttach_Result },
54     { DEC_FKTOP(INIC_FID_DEVICE_ATTACH,           UCS_OP_ERROR),      Inic_DeviceAttach_Error },
55     { DEC_FKTOP(INIC_FID_DEVICE_SYNC,             UCS_OP_RESULT),     Inic_DeviceSync_Result },
56     { DEC_FKTOP(INIC_FID_DEVICE_SYNC,             UCS_OP_ERROR),      Inic_DeviceSync_Error },
57     { DEC_FKTOP(INIC_FID_MOST_NW_STATUS,          UCS_OP_STATUS),     Inic_NwStatus_Status },
58     { DEC_FKTOP(INIC_FID_MOST_NW_STATUS,          UCS_OP_ERROR),      Inic_DummyHandler },
59     { DEC_FKTOP(INIC_FID_MOST_NW_CFG,             UCS_OP_STATUS),     Inic_NwConfig_Status },
60     { DEC_FKTOP(INIC_FID_MOST_NW_CFG,             UCS_OP_ERROR),      Inic_NwConfig_Error },
61     { DEC_FKTOP(INIC_FID_MOST_NW_FRAME_COUNTER,   UCS_OP_STATUS),     Inic_NwFrameCounter_Status },
62     { DEC_FKTOP(INIC_FID_MOST_NW_FRAME_COUNTER,   UCS_OP_ERROR),      Inic_NwFrameCounter_Error },
63     { DEC_FKTOP(INIC_FID_MOST_NW_STARTUP,         UCS_OP_RESULT),     Inic_NwStartup_Result },
64     { DEC_FKTOP(INIC_FID_MOST_NW_STARTUP,         UCS_OP_ERROR),      Inic_NwStartup_Error },
65     { DEC_FKTOP(INIC_FID_MOST_NW_SHUTDOWN,        UCS_OP_RESULT),     Inic_NwShutdown_Result },
66     { DEC_FKTOP(INIC_FID_MOST_NW_SHUTDOWN,        UCS_OP_ERROR),      Inic_NwShutdown_Error },
67     { DEC_FKTOP(INIC_FID_MOST_NW_TRIGGER_RBD,     UCS_OP_RESULT),     Inic_NwTriggerRbd_Result },
68     { DEC_FKTOP(INIC_FID_MOST_NW_TRIGGER_RBD,     UCS_OP_ERROR),      Inic_NwTriggerRbd_Error },
69     { DEC_FKTOP(INIC_FID_MOST_NW_RBD_RESULT,      UCS_OP_STATUS),     Inic_NwRbdResult_Status },
70     { DEC_FKTOP(INIC_FID_MOST_NW_RBD_RESULT,      UCS_OP_ERROR),      Inic_NwRbdResult_Error },
71     { DEC_FKTOP(INIC_FID_MOST_NW_ATTACH,          UCS_OP_RESULT),     Inic_NwAttach_Result },
72     { DEC_FKTOP(INIC_FID_MOST_NW_ATTACH,          UCS_OP_ERROR),      Inic_NwAttach_Error },
73     { DEC_FKTOP(INIC_FID_MOST_NW_FORCE_NO_AVAIL,  UCS_OP_STATUS),     Inic_NwForceNotAvailable_Status },
74     { DEC_FKTOP(INIC_FID_MOST_NW_FORCE_NO_AVAIL,  UCS_OP_ERROR),      Inic_NwForceNotAvailable_Error },
75     { DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAGNOSIS,   UCS_OP_RESULT),     Inic_NwSysDiagnosis_Result },
76     { DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAGNOSIS,   UCS_OP_ERROR),      Inic_NwSysDiagnosis_Error },
77     { DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAG_END,    UCS_OP_RESULT),     Inic_NwSysDiagEnd_Result },
78     { DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAG_END,    UCS_OP_ERROR),      Inic_NwSysDiagEnd_Error },
79     { DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAGNOSIS,  UCS_OP_RESULT),     Inic_BCDiagnosis_Result },
80     { DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAGNOSIS,  UCS_OP_ERROR),      Inic_BCDiagnosis_Error },
81     { DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAG_END,   UCS_OP_RESULT),     Inic_BCDiagEnd_Result },
82     { DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAG_END,   UCS_OP_ERROR),      Inic_BCDiagEnd_Error },
83     { DEC_FKTOP(INIC_FID_MOST_PORT_STATUS,        UCS_OP_STATUS),     Inic_MostPortStatus_Status },
84     { DEC_FKTOP(INIC_FID_MOST_PORT_STATUS,        UCS_OP_ERROR),      Inic_MostPortStatus_Error },
85     { DEC_FKTOP(INIC_FID_MOST_SOCKET_CREATE,      UCS_OP_RESULT),     Inic_MostSocketCreate_Result },
86     { DEC_FKTOP(INIC_FID_MOST_SOCKET_CREATE,      UCS_OP_ERROR),      Inic_MostSocketCreate_Error },
87     { DEC_FKTOP(INIC_FID_MOST_SOCKET_STATUS,      UCS_OP_STATUS),     Inic_DummyHandler },
88     { DEC_FKTOP(INIC_FID_MOST_SOCKET_STATUS,      UCS_OP_ERROR),      Inic_DummyHandler },
89     { DEC_FKTOP(INIC_FID_MLB_PORT_CREATE,         UCS_OP_RESULT),     Inic_MlbPortCreate_Result },
90     { DEC_FKTOP(INIC_FID_MLB_PORT_CREATE,         UCS_OP_ERROR),      Inic_MlbPortCreate_Error },
91 /*  { DEC_FKTOP(INIC_FID_MLB_PORT_ALLOCATE_ONLY,  UCS_OP_RESULT),     Inic_DummyHandler },    */
92 /*  { DEC_FKTOP(INIC_FID_MLB_PORT_ALLOCATE_ONLY,  UCS_OP_ERROR),      Inic_DummyHandler },    */
93 /*  { DEC_FKTOP(INIC_FID_MLB_PORT_DEALLOC_ONLY,   UCS_OP_RESULT),     Inic_DummyHandler },    */
94 /*  { DEC_FKTOP(INIC_FID_MLB_PORT_DEALLOC_ONLY,   UCS_OP_ERROR),      Inic_DummyHandler },    */
95     { DEC_FKTOP(INIC_FID_MLB_SOCKET_CREATE,       UCS_OP_RESULT),     Inic_MlbSocketCreate_Result },
96     { DEC_FKTOP(INIC_FID_MLB_SOCKET_CREATE,       UCS_OP_ERROR),      Inic_MlbSocketCreate_Error },
97     { DEC_FKTOP(INIC_FID_SPI_PORT_CREATE,         UCS_OP_RESULT),     Inic_DummyHandler },
98     { DEC_FKTOP(INIC_FID_SPI_PORT_CREATE,         UCS_OP_ERROR),      Inic_DummyHandler },
99     { DEC_FKTOP(INIC_FID_SPI_SOCKET_CREATE,       UCS_OP_RESULT),     Inic_DummyHandler },
100     { DEC_FKTOP(INIC_FID_SPI_SOCKET_CREATE,       UCS_OP_ERROR),      Inic_DummyHandler },
101     { DEC_FKTOP(INIC_FID_USB_PORT_CREATE,         UCS_OP_RESULT),     Inic_UsbPortCreate_Result },
102     { DEC_FKTOP(INIC_FID_USB_PORT_CREATE,         UCS_OP_ERROR),      Inic_UsbPortCreate_Error },
103     { DEC_FKTOP(INIC_FID_USB_SOCKET_CREATE,       UCS_OP_RESULT),     Inic_UsbSocketCreate_Result },
104     { DEC_FKTOP(INIC_FID_USB_SOCKET_CREATE,       UCS_OP_ERROR),      Inic_UsbSocketCreate_Error },
105     { DEC_FKTOP(INIC_FID_STREAM_PORT_CONFIG,      UCS_OP_STATUS),     Inic_StreamPortConfig_Status },
106     { DEC_FKTOP(INIC_FID_STREAM_PORT_CONFIG,      UCS_OP_ERROR),      Inic_StreamPortConfig_Error },
107     { DEC_FKTOP(INIC_FID_STREAM_PORT_CREATE,      UCS_OP_RESULT),     Inic_StreamPortCreate_Result },
108     { DEC_FKTOP(INIC_FID_STREAM_PORT_CREATE,      UCS_OP_ERROR),      Inic_StreamPortCreate_Error },
109     { DEC_FKTOP(INIC_FID_STREAM_PORT_LOOPBACK,    UCS_OP_STATUS),     Inic_DummyHandler },
110     { DEC_FKTOP(INIC_FID_STREAM_PORT_LOOPBACK,    UCS_OP_ERROR),      Inic_DummyHandler },
111     { DEC_FKTOP(INIC_FID_STREAM_SOCKET_CREATE,    UCS_OP_RESULT),     Inic_StreamSocketCreate_Result },
112     { DEC_FKTOP(INIC_FID_STREAM_SOCKET_CREATE,    UCS_OP_ERROR),      Inic_StreamSocketCreate_Error },
113     { DEC_FKTOP(INIC_FID_RMCK_PORT_CREATE,        UCS_OP_RESULT),     Inic_RmckPortCreate_Result },
114     { DEC_FKTOP(INIC_FID_RMCK_PORT_CREATE,        UCS_OP_ERROR),      Inic_RmckPortCreate_Error },
115     { DEC_FKTOP(INIC_FID_I2C_PORT_CREATE,         UCS_OP_RESULT),     Inic_I2cPortCreate_Result },
116     { DEC_FKTOP(INIC_FID_I2C_PORT_CREATE,         UCS_OP_ERROR),      Inic_I2cPortCreate_Error },
117     { DEC_FKTOP(INIC_FID_I2C_PORT_READ,           UCS_OP_RESULT),     Inic_I2cPortRead_Result },
118     { DEC_FKTOP(INIC_FID_I2C_PORT_READ,           UCS_OP_ERROR),      Inic_I2cPortRead_Error },
119     { DEC_FKTOP(INIC_FID_I2C_PORT_WRITE,          UCS_OP_RESULT),     Inic_I2cPortWrite_Result },
120     { DEC_FKTOP(INIC_FID_I2C_PORT_WRITE,          UCS_OP_ERROR),      Inic_I2cPortWrite_Error },
121     { DEC_FKTOP(INIC_FID_PCI_PORT_CREATE,         UCS_OP_RESULT),     Inic_PciPortCreate_Result },
122     { DEC_FKTOP(INIC_FID_PCI_PORT_CREATE,         UCS_OP_ERROR),      Inic_PciPortCreate_Error },
123     { DEC_FKTOP(INIC_FID_PCI_SOCKET_CREATE,       UCS_OP_RESULT),     Inic_PciSocketCreate_Result },
124     { DEC_FKTOP(INIC_FID_PCI_SOCKET_CREATE,       UCS_OP_ERROR),      Inic_PciSocketCreate_Error },
125     { DEC_FKTOP(INIC_FID_GPIO_PORT_CREATE,        UCS_OP_RESULT),     Inic_GpioPortCreate_Result },
126     { DEC_FKTOP(INIC_FID_GPIO_PORT_CREATE,        UCS_OP_ERROR),      Inic_GpioPortCreate_Error },
127     { DEC_FKTOP(INIC_FID_MOST_PORT_ENABLE,        UCS_OP_RESULT),     Inic_MostPortEnable_Result },
128     { DEC_FKTOP(INIC_FID_MOST_PORT_ENABLE,        UCS_OP_ERROR),      Inic_MostPortEnable_Error },
129     { DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_MODE,      UCS_OP_STATUS),     Inic_GpioPortPinMode_Status },
130     { DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_MODE,      UCS_OP_ERROR),      Inic_GpioPortPinMode_Error },
131     { DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_STATE,     UCS_OP_STATUS),     Inic_GpioPortPinState_Status },
132     { DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_STATE,     UCS_OP_ERROR),      Inic_GpioPortPinState_Error },
133     { DEC_FKTOP(INIC_FID_GPIO_PORT_TRIGGER_EVENT, UCS_OP_STATUS),     Inic_GpioPortTrigger_Status },
134     { DEC_FKTOP(INIC_FID_GPIO_PORT_TRIGGER_EVENT, UCS_OP_ERROR),      Inic_GpioPortTrigger_Error },
135     { DEC_FKTOP(INIC_FID_RESOURCE_DESTROY,        UCS_OP_RESULT),     Inic_ResourceDestroy_Result },
136     { DEC_FKTOP(INIC_FID_RESOURCE_DESTROY,        UCS_OP_ERROR),      Inic_ResourceDestroy_Error },
137     { DEC_FKTOP(INIC_FID_RESOURCE_INVALID_LIST,   UCS_OP_STATUS),     Inic_ResourceInvalidList_Status },
138     { DEC_FKTOP(INIC_FID_RESOURCE_INVALID_LIST,   UCS_OP_ERROR),      Inic_ResourceInvalidList_Error },
139     { DEC_FKTOP(INIC_FID_RESOURCE_MONITOR,        UCS_OP_STATUS),     Inic_ResourceMonitor_Status },
140     { DEC_FKTOP(INIC_FID_RESOURCE_MONITOR,        UCS_OP_ERROR),      Inic_ResourceMonitor_Error },
141 /*  { DEC_FKTOP(INIC_FID_PACKET_ATTACH_SOCKETS,   UCS_OP_RESULT),     Inic_DummyHandler },   */   
142 /*  { DEC_FKTOP(INIC_FID_PACKET_ATTACH_SOCKETS,   UCS_OP_ERROR),      Inic_DummyHandler },   */   
143 /*  { DEC_FKTOP(INIC_FID_PACKET_DETACH_SOCKETS,   UCS_OP_RESULT),     Inic_DummyHandler },   */   
144 /*  { DEC_FKTOP(INIC_FID_PACKET_DETACH_SOCKETS,   UCS_OP_ERROR),      Inic_DummyHandler },   */   
145     { DEC_FKTOP(INIC_FID_QOS_CREATE,              UCS_OP_RESULT),     Inic_QoSCreate_Result },
146     { DEC_FKTOP(INIC_FID_QOS_CREATE,              UCS_OP_ERROR),      Inic_QoSCreate_Error },
147     { DEC_FKTOP(INIC_FID_AVP_CREATE,              UCS_OP_RESULT),     Inic_AvpCreate_Result },
148     { DEC_FKTOP(INIC_FID_AVP_CREATE,              UCS_OP_ERROR),      Inic_AvpCreate_Error },
149     { DEC_FKTOP(INIC_FID_SYNC_CREATE,             UCS_OP_RESULT),     Inic_SyncCreate_Result },
150     { DEC_FKTOP(INIC_FID_SYNC_CREATE,             UCS_OP_ERROR),      Inic_SyncCreate_Error },
151     { DEC_FKTOP(INIC_FID_SYNC_MUTE,               UCS_OP_RESULT),     Inic_SyncMute_Result },
152     { DEC_FKTOP(INIC_FID_SYNC_MUTE,               UCS_OP_ERROR),      Inic_SyncMute_Error },
153     { DEC_FKTOP(INIC_FID_SYNC_DEMUTE,             UCS_OP_RESULT),     Inic_SyncDemute_Result },
154     { DEC_FKTOP(INIC_FID_SYNC_DEMUTE,             UCS_OP_ERROR),      Inic_SyncDemute_Error },
155     { DEC_FKTOP(INIC_FID_DFIPHASE_CREATE,         UCS_OP_RESULT),     Inic_DfiPhaseCreate_Result },
156     { DEC_FKTOP(INIC_FID_DFIPHASE_CREATE,         UCS_OP_ERROR),      Inic_DfiPhaseCreate_Error },
157     { DEC_FKTOP(INIC_FID_IPC_CREATE,              UCS_OP_RESULT),     Inic_IpcCreate_Result },
158     { DEC_FKTOP(INIC_FID_IPC_CREATE,              UCS_OP_ERROR),      Inic_IpcCreate_Error },
159     { DEC_FKTOP(INIC_FID_COMBINER_CREATE,         UCS_OP_RESULT),     Inic_CombinerCreate_Result },
160     { DEC_FKTOP(INIC_FID_COMBINER_CREATE,         UCS_OP_ERROR),      Inic_CombinerCreate_Error },
161     { DEC_FKTOP(INIC_FID_SPLITTER_CREATE,         UCS_OP_RESULT),     Inic_SplitterCreate_Result },
162     { DEC_FKTOP(INIC_FID_SPLITTER_CREATE,         UCS_OP_ERROR),      Inic_SplitterCreate_Error },
163     { DEC_FKTOP_TERMINATION,                                          NULL }
164 };
165
166 /*------------------------------------------------------------------------------------------------*/
167 /* Internal definitions                                                                           */
168 /*------------------------------------------------------------------------------------------------*/
169 /*! \brief Bitmask for API method Inic_NwForceNotAvailable() used by API locking manager */
170 #define INIC_API_NW_FORCE_NA        0x01U
171 /*! \brief Bitmask for API method Inic_NwShutdown() used by API locking manager */
172 #define INIC_API_NW_SHUTDOWN        0x02U
173 /*! \brief Bitmask for API method Inic_NwFrameCounter_Get() used by API locking manager */
174 #define INIC_API_NW_FRAME_COUNTER   0x04U
175 /*! \brief Bitmask for API method Inic_NwTriggerRbd() used by API locking manager */
176 #define INIC_API_NW_TRIGGER_RBD     0x08U
177 /*! \brief Bitmask for API method Inic_NwRbdResult_Get() used by API locking manager */
178 #define INIC_API_NW_RBD_RESULT      0x10U
179 /*! \brief Bitmask for API method Inic_DeviceVersion_Get() used by API locking manager */
180 #define INIC_API_DEVICE_VERSION_GET 0x20U
181
182 /*------------------------------------------------------------------------------------------------*/
183 /* Internal prototypes                                                                            */
184 /*------------------------------------------------------------------------------------------------*/
185 static void Inic_HandleInternalErrors(void *self, void *error_code_ptr);
186 static void Inic_HandleApiTimeout(void *self, void *method_mask_ptr);
187 static void Inic_DecodeIcm(CInic *self, Msg_MostTel_t *msg_ptr);
188 static void Inic_MsgTxStatusCb(void *self, Msg_MostTel_t *tel_ptr, Ucs_MsgTxStatus_t status);
189
190 /*------------------------------------------------------------------------------------------------*/
191 /* Implementation                                                                                 */
192 /*------------------------------------------------------------------------------------------------*/
193
194 /*! \brief Constructor of class CInic.
195  *  \param self         Reference to CInic instance
196  *  \param init_ptr     Reference to initialization data
197  */
198 void Inic_Ctor(CInic *self, Inic_InitData_t *init_ptr)
199 {
200     uint8_t i;
201     MISC_MEM_SET((void *)self, 0, sizeof(*self));
202
203     self->base_ptr        = init_ptr->base_ptr;
204     self->xcvr_ptr        = init_ptr->xcvr_ptr;
205     self->fkt_op_list_ptr = &inic_handler[0];
206     self->target_address  = init_ptr->tgt_addr;
207
208     /* create instances of single-observers */
209     for(i=0U; i<INIC_NUM_SSUB; i++)
210     {
211         Ssub_Ctor(&self->ssubs[i], self->base_ptr->ucs_user_ptr);
212     }
213
214     /* create instances of "normal" observers */
215     for(i=0U; i<INIC_NUM_SUB; i++)
216     {
217         Sub_Ctor(&self->subs[i], self->base_ptr->ucs_user_ptr);
218     }
219
220     /* Observe internal errors and events */
221     Mobs_Ctor(&self->internal_error_obs, self, EH_M_TERMINATION_EVENTS, &Inic_HandleInternalErrors);
222     Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->internal_error_obs);
223
224     /* Initialize API locking mechanism */
225     Sobs_Ctor(&self->lock.observer, self, &Inic_HandleApiTimeout);
226     Al_Ctor(&self->lock.api, &self->lock.observer, self->base_ptr->ucs_user_ptr);
227     Alm_RegisterApi(&self->base_ptr->alm, &self->lock.api);
228
229     /* Initialize Resource Management part */
230     Inic_InitResourceManagement(self);
231 }
232
233 /*! \brief  Handles internal errors and events
234  *  \param  self            Instance pointer
235  *  \param  error_code_ptr  Reference to reported error code
236  */
237 static void Inic_HandleInternalErrors(void *self, void *error_code_ptr)
238 {
239     uint8_t i;
240     Inic_StdResult_t res_data;
241     CInic *self_ = (CInic *)self;
242     MISC_UNUSED(error_code_ptr);
243
244     res_data.data_info        = NULL;
245     res_data.result.code      = UCS_RES_ERR_SYSTEM;
246     res_data.result.info_ptr  = NULL;
247     res_data.result.info_size = 0U;
248
249     /* Internal error has been occurred => Cancel running jobs */
250     for(i=0U; i<INIC_NUM_SSUB; i++)
251     {
252         Ssub_Notify(&self_->ssubs[i], &res_data, true);
253     }
254 }
255
256 /*! \brief  Handles an API timeout
257  *  \param  self             Instance pointer
258  *  \param  method_mask_ptr  Bitmask to signal which API method has caused the timeout
259  */
260 static void Inic_HandleApiTimeout(void *self, void *method_mask_ptr)
261 {
262     CInic *self_ = (CInic *)self;
263     Alm_ModuleMask_t method_mask = *((Alm_ModuleMask_t *)method_mask_ptr);
264     Inic_StdResult_t res_data;
265
266     res_data.data_info       = NULL;
267     res_data.result.code     = UCS_RES_ERR_TIMEOUT;
268     res_data.result.info_ptr = NULL;
269
270     switch(method_mask)
271     {
272         case INIC_API_NW_SHUTDOWN:
273             Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
274             TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwShutdown().", 0U));
275             break;
276         case INIC_API_NW_FRAME_COUNTER:
277             Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true);
278             TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwFrameCounter_Get().", 0U));
279             break;
280         case INIC_API_NW_TRIGGER_RBD:
281             self_->lock.rbd_trigger_timeout_counter++;
282             if(self_->lock.rbd_trigger_timeout_counter < 5U)
283             {
284                 (void)Al_Lock(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
285             }
286             else
287             {
288                 Inic_StdResult_t rbd_result_data;
289                 Ucs_StdResult_t result    = {UCS_RES_ERR_TIMEOUT, NULL, 0U};
290                 rbd_result_data.data_info = NULL;
291                 rbd_result_data.result    = result;
292                 Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &rbd_result_data, true);
293                 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwTriggerRbd().", 0U));
294             }
295             break;
296         case INIC_API_NW_RBD_RESULT:
297             Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
298             TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwRbdResult_Get().", 0U));
299             break;
300         default:
301             TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "Unknown API locking bitmask detected. Mask: 0x%02X", 1U, method_mask));
302             break;
303     }
304 }
305
306 /*! \brief  Decode an ICM message
307  *  \param  self     Instance pointer to FBlock INIC 
308  *  \param  msg_ptr  pointer to the ICM message to decode
309  */
310 static void Inic_DecodeIcm(CInic *self, Msg_MostTel_t *msg_ptr)
311 {
312     Dec_Return_t result;
313     uint16_t     index;
314
315     result = Dec_SearchFktOpIcm(self->fkt_op_list_ptr, &index, msg_ptr->id.function_id, msg_ptr->id.op_type);
316
317     if (result == DEC_RET_SUCCESS)
318     {
319         self->fkt_op_list_ptr[index].handler_function_ptr(self, msg_ptr);
320     }
321     else
322     {
323         TR_ERROR((self->base_ptr->ucs_user_ptr, "[INIC]", "Unknown ICM received. FBlockId: 0x%02X, InstId: 0x%02X, FktId: 0x%04X, OPType: 0x%02X", 4U, msg_ptr->id.fblock_id, msg_ptr->id.instance_id, msg_ptr->id.function_id, msg_ptr->id.op_type));
324     }
325 }
326
327 /*! \brief Receives ICMs
328  *  \param  self     reference to INIC object
329  *  \param  tel_ptr  received message
330  */
331 void Inic_OnIcmRx(void *self, Msg_MostTel_t *tel_ptr)
332 {
333     CInic *self_ = (CInic *)self;
334
335     if ((tel_ptr->source_addr == MSG_ADDR_INIC) && (tel_ptr->destination_addr == MSG_ADDR_EHC_CFG))
336     {
337         Inic_DecodeIcm(self_, tel_ptr);
338     }
339
340     Trcv_RxReleaseMsg(self_->xcvr_ptr, tel_ptr); /* free Rx telegram */
341 }
342
343 /*! \brief   Filters RCM Rx messages
344  *  \details The filter function shall not release the message object
345  *  \param   self     Reference to INIC object
346  *  \param   tel_ptr  Reference to the RCM Rx message object
347  */
348 void Inic_OnRcmRxFilter(void *self, Msg_MostTel_t *tel_ptr)
349
350     uint16_t     index;
351     CInic *self_ = (CInic *)self;
352
353     if (Dec_SearchFktOpIcm(self_->fkt_op_list_ptr, &index, tel_ptr->id.function_id, tel_ptr->id.op_type) == DEC_RET_SUCCESS)
354     {
355         self_->fkt_op_list_ptr[index].handler_function_ptr(self, tel_ptr);
356     }
357 }
358
359 /*! \brief Handle message Tx status and free message objects
360  *  \param self     The instance
361  *  \param tel_ptr  Reference to transmitted message
362  *  \param status   Status of the transmitted message
363  */
364 static void Inic_MsgTxStatusCb(void *self, Msg_MostTel_t *tel_ptr, Ucs_MsgTxStatus_t status)
365 {
366     CInic *self_ = (CInic *)self;
367
368     if ((status != UCS_MSG_STAT_OK) && (tel_ptr->info_ptr != NULL))
369     {
370         Inic_StdResult_t res_data;
371         CSingleSubject *ssub_ptr = (CSingleSubject *)tel_ptr->info_ptr;
372
373         res_data.data_info        = &status;
374         res_data.result.code      = UCS_RES_ERR_TRANSMISSION;
375         res_data.result.info_ptr  = NULL;
376         res_data.result.info_size = 0U;
377         Ssub_Notify(ssub_ptr, &res_data, true);
378     }
379     Trcv_TxReleaseMsg(tel_ptr);
380
381     /* ICM messages pending? */
382     if (Sub_GetNumObservers(&self_->subs[INIC_SUB_TX_MSG_OBJ_AVAIL]) > 0U)
383     {
384         Sub_Notify(&self_->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], NULL);
385     }
386 }
387
388 /*! \brief Add an observer to be notified when a tx message object is available
389  *  \param  self     instance of CInic
390  *  \param  obs_ptr  pointer to observer to be informed
391  */
392 void Inic_AddObsrvOnTxMsgObjAvail(CInic *self, CObserver *obs_ptr)
393 {
394     (void)Sub_AddObserver(&self->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], obs_ptr);
395 }
396
397 /*! \brief Delete an observer set by Inic_AddObsrvOnTxMsgObjAvail()
398  *  \param  self     instance of CInic
399  *  \param  obs_ptr  pointer to observer to be removed
400  */
401 void Inic_DelObsrvOnTxMsgObjAvail(CInic *self, CObserver *obs_ptr)
402 {
403     (void)Sub_RemoveObserver(&self->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], obs_ptr);
404 }
405
406 /*! \brief Add an observer to the NetworkStatus subject
407  *  \param  self     instance of CInic
408  *  \param  obs_ptr  pointer to observer to be informed
409  */
410 void Inic_AddObsrvNwStatus(CInic *self, CObserver *obs_ptr)
411 {
412     (void)Sub_AddObserver(&self->subs[INIC_SUB_NW_STATUS], obs_ptr);
413 }
414
415 /*! \brief Delete an observer to the NetworkStatus subject
416  *  \param  self     instance of CInic
417  *  \param  obs_ptr  pointer to observer to be removed
418  */
419 void Inic_DelObsrvNwStatus(CInic *self, CObserver *obs_ptr)
420 {
421     (void)Sub_RemoveObserver(&self->subs[INIC_SUB_NW_STATUS], obs_ptr);
422 }
423
424 /*! \brief Add an observer to the NetworkConfiguration subject
425  *  \param  self     instance of CInic
426  *  \param  obs_ptr  pointer to observer to be informed
427  */
428 void Inic_AddObsvrNwConfig(CInic *self, CObserver *obs_ptr)
429 {
430     (void)Sub_AddObserver(&self->subs[INIC_SUB_NW_CONFIG], obs_ptr);
431 }
432
433 /*! \brief Delete an observer to the NetworkConfiguration subject
434  *  \param  self     instance of CInic
435  *  \param  obs_ptr  pointer to observer to be removed
436  */
437 void Inic_DelObsvrNwConfig(CInic *self, CObserver *obs_ptr)
438 {
439     (void)Sub_RemoveObserver(&self->subs[INIC_SUB_NW_CONFIG], obs_ptr);
440 }
441
442 /*! \brief   Add an observer to the DeviceStatus subject
443  *  \details The provided data points to a \ref Inic_DeviceStatus_t structure
444  *  \param   self     instance of CInic
445  *  \param   obs_ptr  pointer to observer to be informed
446  */
447 void Inic_AddObsvrDeviceStatus(CInic *self, CObserver *obs_ptr)
448 {
449     (void)Sub_AddObserver(&self->subs[INIC_SUB_DEVICE_STATUS], obs_ptr);
450 }
451
452 /*! \brief  Delete an observer to the DeviceStatus subject
453  *  \param  self     instance of CInic
454  *  \param  obs_ptr  pointer to observer to be removed
455  */
456 void Inic_DelObsvrDeviceStatus(CInic *self, CObserver *obs_ptr)
457 {
458     (void)Sub_RemoveObserver(&self->subs[INIC_SUB_DEVICE_STATUS], obs_ptr);
459 }
460
461 /*------------------------------------------------------------------------------------------------*/
462 /* Internal API                                                                                   */
463 /*------------------------------------------------------------------------------------------------*/
464 /*! \brief  This method requests the INIC version info
465  *  \param  self        Reference to CInic instance
466  *  \param  obs_ptr     Reference to an optional observer
467  *  \return UCS_RET_SUCCESS               message was created 
468  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available
469  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
470  */
471 Ucs_Return_t Inic_DeviceVersion_Get(CInic *self, CSingleObserver *obs_ptr)
472 {
473     Ucs_Return_t result = UCS_RET_SUCCESS;
474
475     if(Al_Lock(&self->lock.api, INIC_API_DEVICE_VERSION_GET) != false)
476     {
477         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
478
479         if (msg_ptr != NULL)
480         {
481             msg_ptr->destination_addr  = self->target_address;
482
483             msg_ptr->id.fblock_id   = FB_INIC;
484             msg_ptr->id.instance_id = 0U;
485             msg_ptr->id.function_id = INIC_FID_DEVICE_VERSION;
486             msg_ptr->id.op_type     = UCS_OP_GET;
487
488             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_DEVICE_VERSION];
489             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
490
491             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_DEVICE_VERSION], obs_ptr);
492         }
493         else
494         {
495             Al_Release(&self->lock.api, INIC_API_DEVICE_VERSION_GET);
496             result = UCS_RET_ERR_BUFFER_OVERFLOW;
497         }
498     }
499     else
500     {
501         result = UCS_RET_ERR_API_LOCKED;
502     }
503
504     return result;
505 }
506
507 /*! \brief  Attach EHC to the INIC
508  *  \param  self            Reference to CInic instance
509  *  \param  obs_ptr         Reference to an optional observer
510  *  \return UCS_RET_SUCCESS               message was created 
511  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
512  */
513 Ucs_Return_t Inic_DeviceAttach(CInic *self, CSingleObserver *obs_ptr)
514 {
515     Ucs_Return_t     result = UCS_RET_SUCCESS;
516     Msg_MostTel_t   *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
517
518     if (msg_ptr != NULL)
519     {
520         msg_ptr->destination_addr  = self->target_address;
521
522         msg_ptr->id.fblock_id   = FB_INIC;
523         msg_ptr->id.instance_id = 0U;
524         msg_ptr->id.function_id = INIC_FID_DEVICE_ATTACH;
525         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
526
527         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_DEVICE_ATTACH];
528         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
529
530         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_DEVICE_ATTACH], obs_ptr);
531     }
532     else
533     {
534         result = UCS_RET_ERR_BUFFER_OVERFLOW;
535     }
536
537     return result;
538 }
539
540 /*! \brief  Attaches the given PMS channel to the network
541  *  \param  self                Reference to CInic instance
542  *  \param  pmp_channel_handle  Port message channel resource handle
543  *  \param  obs_ptr             Reference to an optional observer
544  *  \return UCS_RET_SUCCESS               message was created 
545  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
546  */
547 Ucs_Return_t Inic_NwAttach(CInic *self,
548                            uint16_t pmp_channel_handle,
549                            CSingleObserver *obs_ptr)
550 {
551     Ucs_Return_t result = UCS_RET_SUCCESS;
552     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 2U);
553
554     if (msg_ptr != NULL)
555     {
556         msg_ptr->destination_addr  = self->target_address;
557
558         msg_ptr->id.fblock_id   = FB_INIC;
559         msg_ptr->id.instance_id = 0U;
560         msg_ptr->id.function_id = INIC_FID_MOST_NW_ATTACH;
561         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
562
563         msg_ptr->tel.tel_data_ptr[0] = MISC_HB(pmp_channel_handle);
564         msg_ptr->tel.tel_data_ptr[1] = MISC_LB(pmp_channel_handle);
565
566         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_ATTACH];
567         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
568
569         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_ATTACH], obs_ptr);
570     }
571     else
572     {
573         result = UCS_RET_ERR_BUFFER_OVERFLOW;
574     }
575
576     return result;
577 }
578
579
580 /*! \brief  Starts the System diagnosis
581  *  \param  self                Reference to CInic instance
582  *  \param  obs_ptr             Reference to an optional observer
583  *  \return UCS_RET_SUCCESS               message was created 
584  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
585  */
586 Ucs_Return_t Inic_NwSysDiagnosis(CInic *self, CSingleObserver *obs_ptr)
587 {
588     Ucs_Return_t result = UCS_RET_SUCCESS;
589     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
590
591     if (msg_ptr != NULL)
592     {
593         msg_ptr->destination_addr  = self->target_address;
594
595         msg_ptr->id.fblock_id   = FB_INIC;
596         msg_ptr->id.instance_id = 0U;
597         msg_ptr->id.function_id = INIC_FID_MOST_NW_SYS_DIAGNOSIS;
598         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
599
600         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS];
601         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
602
603         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], obs_ptr);
604     }
605     else
606     {
607         result = UCS_RET_ERR_BUFFER_OVERFLOW;
608     }
609
610     return result;
611 }
612
613 /*! \brief  Stops the System diagnosis
614  *  \param  self                Reference to CInic instance
615  *  \param  obs_ptr             Reference to an optional observer
616  *  \return UCS_RET_SUCCESS               message was created 
617  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
618  */
619 Ucs_Return_t Inic_NwSysDiagEnd(CInic *self, CSingleObserver *obs_ptr)
620 {
621     Ucs_Return_t result = UCS_RET_SUCCESS;
622     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
623
624     if (msg_ptr != NULL)
625     {
626         msg_ptr->destination_addr  = self->target_address;
627
628         msg_ptr->id.fblock_id   = FB_INIC;
629         msg_ptr->id.instance_id = 0U;
630         msg_ptr->id.function_id = INIC_FID_MOST_NW_SYS_DIAG_END;
631         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
632
633         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SYS_DIAGEND];
634         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
635
636         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SYS_DIAGEND], obs_ptr);
637     }
638     else
639     {
640         result = UCS_RET_ERR_BUFFER_OVERFLOW;
641     }
642
643     return result;
644 }
645
646 /*! \brief Starts the Backchannel Diagnosis Mode
647  *
648  *  \param *self         Reference to CInic instance
649  *  \param *obs_ptr      Reference to an optional observer
650  *  \return UCS_RET_SUCCESS               message was created 
651  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
652  */
653 Ucs_Return_t Inic_BCDiagnosis(CInic *self, CSingleObserver *obs_ptr)
654 {
655     Ucs_Return_t result = UCS_RET_SUCCESS;
656     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
657
658     if (msg_ptr != NULL)
659     {
660         msg_ptr->destination_addr  = MSG_ADDR_INIC;
661
662         msg_ptr->id.fblock_id   = FB_INIC;
663         msg_ptr->id.instance_id = 0U;
664         msg_ptr->id.function_id = INIC_FID_BACK_CHANNEL_DIAGNOSIS;
665         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
666
667         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_BC_DIAGNOSIS];
668         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
669
670         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_BC_DIAGNOSIS], obs_ptr);
671     }
672     else
673     {
674         result = UCS_RET_ERR_BUFFER_OVERFLOW;
675     }
676
677     return result;
678 }
679
680 /*! \brief Stops the Backchannel Diagnosis Mode
681  *
682  *  \param *self         Reference to CInic instance
683  *  \param *obs_ptr      Reference to an optional observer
684  *  \return UCS_RET_SUCCESS               message was created 
685  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
686  */
687 Ucs_Return_t Inic_BCDiagEnd(CInic *self, CSingleObserver *obs_ptr)
688 {
689     Ucs_Return_t result = UCS_RET_SUCCESS;
690     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
691
692     if (msg_ptr != NULL)
693     {
694         msg_ptr->destination_addr  = MSG_ADDR_INIC;
695
696         msg_ptr->id.fblock_id   = FB_INIC;
697         msg_ptr->id.instance_id = 0U;
698         msg_ptr->id.function_id = INIC_FID_BACK_CHANNEL_DIAG_END;
699         msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
700
701         msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_BC_DIAG_END];
702         Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
703
704         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_BC_DIAG_END], obs_ptr);
705     }
706     else
707     {
708         result = UCS_RET_ERR_BUFFER_OVERFLOW;
709     }
710
711     return result;
712 }
713
714
715 /*! \brief  Requests the INIC.MOSTNetworRBDResult.Status message
716  *  \param  self        Reference to CInic instance
717  *  \param  obs_ptr     Reference to an optional observer
718  *  \return UCS_RET_SUCCESS               message was created 
719  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
720  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
721  */
722 Ucs_Return_t  Inic_NwRbdResult_Get(CInic *self, CSingleObserver *obs_ptr)
723 {
724     Ucs_Return_t result = UCS_RET_SUCCESS;
725
726     if(Al_Lock(&self->lock.api, INIC_API_NW_RBD_RESULT) != false)
727     {
728         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
729
730         if (msg_ptr != NULL)
731         {
732             msg_ptr->destination_addr  = self->target_address;
733
734             msg_ptr->id.fblock_id   = FB_INIC;
735             msg_ptr->id.instance_id = 0U;
736             msg_ptr->id.function_id = INIC_FID_MOST_NW_RBD_RESULT;
737             msg_ptr->id.op_type     = UCS_OP_GET;
738
739             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_RBD_RESULT];
740             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
741
742             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_RBD_RESULT], obs_ptr);
743         }
744         else
745         {
746             Al_Release(&self->lock.api, INIC_API_NW_RBD_RESULT);
747             result = UCS_RET_ERR_BUFFER_OVERFLOW;
748         }
749     }
750     else
751     {
752         result = UCS_RET_ERR_API_LOCKED;
753     }
754
755     return result;
756 }
757
758
759 /*! \brief  This functions starts up the MOST network.
760  *  \param  self             Reference to CInic instance
761  *  \param  auto_forced_na   The delay time to shutdown the network after INIC has entered the 
762  *                           protected mode.
763  *  \param  packet_bandwidth The desired packed bandwidth
764  *  \param  obs_ptr          Reference to an optional observer. The result must be casted into type
765  *                           Inic_StdResult_t.
766  *  \return UCS_RET_SUCCESS               message was created 
767  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
768  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
769  */
770 Ucs_Return_t Inic_NwStartup(CInic *self, uint16_t auto_forced_na,
771                             uint16_t packet_bandwidth, CSingleObserver *obs_ptr)
772 {
773     Ucs_Return_t result = UCS_RET_SUCCESS;
774
775     if (self->startup_locked == false)
776     {
777         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 4U);
778
779         if (msg_ptr != NULL)
780         {
781             self->startup_locked = true;
782
783             msg_ptr->destination_addr    = self->target_address;
784             msg_ptr->id.fblock_id        = FB_INIC;
785             msg_ptr->id.instance_id      = 0U;
786             msg_ptr->id.function_id      = INIC_FID_MOST_NW_STARTUP;
787             msg_ptr->id.op_type          = UCS_OP_STARTRESULT;
788             msg_ptr->tel.tel_data_ptr[0] = MISC_HB(auto_forced_na);
789             msg_ptr->tel.tel_data_ptr[1] = MISC_LB(auto_forced_na);
790             msg_ptr->tel.tel_data_ptr[2] = MISC_HB(packet_bandwidth);
791             msg_ptr->tel.tel_data_ptr[3] = MISC_LB(packet_bandwidth);
792
793             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_STARTUP];
794             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
795
796             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_STARTUP], obs_ptr);
797         }
798         else
799         {
800             self->startup_locked = false;
801             result = UCS_RET_ERR_BUFFER_OVERFLOW;
802         }
803     }
804     else
805     {
806         result = UCS_RET_ERR_API_LOCKED;
807     }
808
809     return result;
810 }
811
812 /*! \brief  This function shuts down the entire MOST network.
813  *  \param  self            Reference to CInic instance
814  *  \param  obs_ptr         Reference to an optional observer. The result must be casted into type
815  *                          Inic_StdResult_t.
816  *  \return UCS_RET_SUCCESS               message was created 
817  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
818  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
819  */
820 Ucs_Return_t Inic_NwShutdown(CInic *self, CSingleObserver *obs_ptr)
821 {
822     Ucs_Return_t result = UCS_RET_SUCCESS;
823
824     if(Al_Lock(&self->lock.api, INIC_API_NW_SHUTDOWN) != false)
825     {
826         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
827
828         if (msg_ptr != NULL)
829         {
830             msg_ptr->destination_addr  = self->target_address;
831
832             msg_ptr->id.fblock_id   = FB_INIC;
833             msg_ptr->id.instance_id = 0U;
834             msg_ptr->id.function_id = INIC_FID_MOST_NW_SHUTDOWN;
835             msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
836
837             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SHUTDOWN];
838             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
839
840             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SHUTDOWN], obs_ptr);
841         }
842         else
843         {
844             Al_Release(&self->lock.api, INIC_API_NW_SHUTDOWN);
845             result = UCS_RET_ERR_BUFFER_OVERFLOW;
846         }
847     }
848     else
849     {
850         result = UCS_RET_ERR_API_LOCKED;
851     }
852
853     return result;
854 }
855
856 /*! \brief This function triggers the Ring Break Diagnosis.
857  *  \param self             Reference to CInic instance
858  *  \param type             Specifies if the INIC starts the RBD as a TimingMaster or TimingSlave.
859  *  \param obs_ptr          Reference to an optional observer. The result must be casted into type
860  *                          Inic_StdResult_t.
861  *  \return UCS_RET_SUCCESS               message was created 
862  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
863  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
864  */
865 Ucs_Return_t Inic_NwTriggerRbd(CInic *self, Ucs_Diag_RbdType_t type, CSingleObserver *obs_ptr)
866 {
867     Ucs_Return_t result = UCS_RET_SUCCESS;
868
869     if(Al_Lock(&self->lock.api, INIC_API_NW_TRIGGER_RBD) != false)
870     {
871         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
872
873         if (msg_ptr != NULL)
874         {
875             self->lock.rbd_trigger_timeout_counter = 0U;
876
877             msg_ptr->destination_addr  = self->target_address;
878
879             msg_ptr->id.fblock_id   = FB_INIC;
880             msg_ptr->id.instance_id = 0U;
881             msg_ptr->id.function_id = INIC_FID_MOST_NW_TRIGGER_RBD;
882             msg_ptr->id.op_type     = UCS_OP_STARTRESULT;
883
884             msg_ptr->tel.tel_data_ptr[0] = (uint8_t)type;
885
886             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_TRIGGER_RBD];
887             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
888
889             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_TRIGGER_RBD], obs_ptr);
890         }
891         else
892         {
893             Al_Release(&self->lock.api, INIC_API_NW_TRIGGER_RBD);
894             result = UCS_RET_ERR_BUFFER_OVERFLOW;
895         }
896     }
897     else
898     {
899         result = UCS_RET_ERR_API_LOCKED;
900     }
901
902     return result;
903 }
904
905 /*! \brief This function triggers the INIC to force the NotAvailable state
906  *  \param self             Reference to CInic instance
907  *  \param force            Is \c true if the INIC shall force the network in NotAvailable state. 
908  *                          If \c false the INIC shall no no longer force the network to NotAvailable state.
909  *  \param obs_ptr          Reference to an optional observer. The result must be casted into type
910  *                          Inic_StdResult_t.
911  *  \return UCS_RET_SUCCESS               message was created 
912  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
913  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
914  */
915 Ucs_Return_t Inic_NwForceNotAvailable(CInic *self, bool force, CSingleObserver *obs_ptr)
916 {
917     Ucs_Return_t result = UCS_RET_SUCCESS;
918
919     if (Al_Lock(&self->lock.api, INIC_API_NW_FORCE_NA) != false)
920     {
921         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
922
923         if (msg_ptr != NULL)
924         {
925             msg_ptr->destination_addr  = self->target_address;
926             msg_ptr->id.fblock_id   = FB_INIC;
927             msg_ptr->id.instance_id = 0U;
928             msg_ptr->id.function_id = INIC_FID_MOST_NW_FORCE_NO_AVAIL;
929             msg_ptr->id.op_type     = UCS_OP_SETGET;
930
931             if (force == false)
932             {
933                 msg_ptr->tel.tel_data_ptr[0] = 0U;
934             }
935             else
936             {
937                 msg_ptr->tel.tel_data_ptr[0] = 1U;
938             }
939
940             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_FORCE_NA];
941             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
942
943             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_FORCE_NA], obs_ptr);
944         }
945         else
946         {
947             Al_Release(&self->lock.api, INIC_API_NW_FORCE_NA);
948             result = UCS_RET_ERR_BUFFER_OVERFLOW;
949         }
950     }
951     else
952     {
953         result = UCS_RET_ERR_API_LOCKED;
954     }
955
956     return result;
957 }
958
959 /*! \brief  This function modifies the INIC network configuration.
960  *  \param  self    Reference to CInic instance
961  *  \param  mask    Allows to change a single, multiple, or all parameters
962  *  \param  config  Holds the parameter values
963  *  \param  obs_ptr Reference to an optional observer. The result must be casted into type
964  *                  Inic_StdResult_t.
965  *  \return UCS_RET_SUCCESS               message was created 
966  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
967  */
968 Ucs_Return_t Inic_NwConfig_SetGet(CInic *self, uint16_t mask, Inic_NetworkConfig_t config,
969                                   CSingleObserver *obs_ptr)
970 {
971     Ucs_Return_t result = UCS_RET_SUCCESS;
972     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 24U);
973
974     if (msg_ptr != NULL)
975     {
976         mask = mask & 7U;       /* allow only bit 0..2 */
977         msg_ptr->destination_addr  = self->target_address;
978
979         msg_ptr->id.fblock_id   = FB_INIC;
980         msg_ptr->id.instance_id = 0U;
981         msg_ptr->id.function_id = INIC_FID_MOST_NW_CFG;
982         msg_ptr->id.op_type     = UCS_OP_SETGET;
983
984         msg_ptr->tel.tel_data_ptr[0]  = MISC_HB(mask);
985         msg_ptr->tel.tel_data_ptr[1]  = MISC_LB(mask);
986         msg_ptr->tel.tel_data_ptr[2]  = MISC_HB(config.node_address);
987         msg_ptr->tel.tel_data_ptr[3]  = MISC_LB(config.node_address);
988         msg_ptr->tel.tel_data_ptr[4]  = MISC_HB(config.group_address);
989         msg_ptr->tel.tel_data_ptr[5]  = MISC_LB(config.group_address);
990         msg_ptr->tel.tel_data_ptr[6]  = config.llrbc;
991         MISC_MEM_SET(&msg_ptr->tel.tel_data_ptr[7], 0, 17U);
992
993         Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
994
995         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_CONFIG], obs_ptr);
996     }
997     else
998     {
999         result = UCS_RET_ERR_BUFFER_OVERFLOW;
1000     }
1001
1002     return result;
1003 }
1004
1005 /*! \brief  Requests the INIC.NetworkConfiguration.Status message
1006  *  \param  self        Reference to CInic instance
1007  *  \param  obs_ptr     Reference to an optional observer. The result must be casted into type
1008  *                      Inic_StdResult_t.
1009  *  \return UCS_RET_SUCCESS               message was created 
1010  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available
1011  */
1012 Ucs_Return_t Inic_NwConfig_Get(CInic *self, CSingleObserver *obs_ptr)
1013 {
1014     Ucs_Return_t result = UCS_RET_SUCCESS;
1015     Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
1016
1017     if (msg_ptr != NULL)
1018     {
1019         msg_ptr->destination_addr  = self->target_address;
1020
1021         msg_ptr->id.fblock_id   = FB_INIC;
1022         msg_ptr->id.instance_id = 0U;
1023         msg_ptr->id.function_id = INIC_FID_MOST_NW_CFG;
1024         msg_ptr->id.op_type     = UCS_OP_GET;
1025
1026         Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
1027
1028         (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_CONFIG], obs_ptr);
1029     }
1030     else
1031     {
1032         result = UCS_RET_ERR_BUFFER_OVERFLOW;
1033     }
1034
1035     return result;
1036 }
1037
1038 /*! \brief  Requests the INIC.MOSTNetworkFrameCounter.Status message
1039  *  \param  self        Reference to CInic instance
1040  *  \param  reference   Reference counter value 
1041  *  \param  obs_ptr     Reference to an optional observer
1042  *  \return UCS_RET_SUCCESS               message was created 
1043  *  \return UCS_RET_ERR_BUFFER_OVERFLOW   no message buffer available 
1044  *  \return UCS_RET_ERR_API_LOCKED        Resource API is already used by another command
1045  */
1046 Ucs_Return_t Inic_NwFrameCounter_Get(CInic *self, uint32_t reference, CSingleObserver *obs_ptr)
1047 {
1048     Ucs_Return_t result = UCS_RET_SUCCESS;
1049
1050     if(Al_Lock(&self->lock.api, INIC_API_NW_FRAME_COUNTER) != false)
1051     {
1052         Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 4U);
1053
1054         if (msg_ptr != NULL)
1055         {
1056             msg_ptr->destination_addr  = self->target_address;
1057
1058             msg_ptr->id.fblock_id   = FB_INIC;
1059             msg_ptr->id.instance_id = 0U;
1060             msg_ptr->id.function_id = INIC_FID_MOST_NW_FRAME_COUNTER;
1061             msg_ptr->id.op_type     = UCS_OP_GET;
1062
1063             msg_ptr->tel.tel_data_ptr[0]  = (uint8_t)(reference >> 24);
1064             msg_ptr->tel.tel_data_ptr[1]  = (uint8_t)(reference >> 16);
1065             msg_ptr->tel.tel_data_ptr[2]  = (uint8_t)(reference >>  8);
1066             msg_ptr->tel.tel_data_ptr[3]  = (uint8_t)reference;
1067
1068             msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_FRAME_COUNTER];
1069             Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
1070
1071             (void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_FRAME_COUNTER], obs_ptr);
1072         }
1073         else
1074         {
1075             Al_Release(&self->lock.api, INIC_API_NW_FRAME_COUNTER);
1076             result = UCS_RET_ERR_BUFFER_OVERFLOW;
1077         }
1078     }
1079     else
1080     {
1081         result = UCS_RET_ERR_API_LOCKED;
1082     }
1083
1084     return result;
1085 }
1086
1087
1088
1089
1090
1091 /*------------------------------------------------------------------------------------------------*/
1092 /* Handler functions                                                                              */
1093 /*------------------------------------------------------------------------------------------------*/
1094
1095 /*! \brief Dummy handler function for unused INIC functions
1096  *
1097  * \param  self     instance of CInic
1098  * \param msg_ptr   Pointer to received message
1099  */
1100 void Inic_DummyHandler(void *self, Msg_MostTel_t *msg_ptr)
1101 {
1102     MISC_UNUSED(self);
1103     MISC_UNUSED(msg_ptr);
1104 }
1105
1106 /*! \brief Handler function for INIC.DeviceStatus.Status
1107  *  \param self      Reference to CInic instance
1108  *  \param msg_ptr   Pointer to received message
1109  */
1110 void Inic_DeviceStatus_Status(void *self, Msg_MostTel_t *msg_ptr)
1111 {
1112     CInic *self_ = (CInic *)self;
1113
1114     if (msg_ptr->tel.tel_len > 0U)
1115     {
1116         TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_len == 5U));
1117         self_->device_status.config_iface_state= (Inic_AttachState_t)msg_ptr->tel.tel_data_ptr[0];
1118         self_->device_status.app_iface_state   = (Inic_AttachState_t)msg_ptr->tel.tel_data_ptr[1];
1119         self_->device_status.power_state       = (Ucs_Inic_PowerState_t)msg_ptr->tel.tel_data_ptr[2];
1120         self_->device_status.bist              = (Inic_Bist_t)msg_ptr->tel.tel_data_ptr[3];
1121         self_->device_status.last_reset_reason = (Ucs_Inic_LastResetReason_t)msg_ptr->tel.tel_data_ptr[4];
1122
1123         /* INIC BIST error detected */
1124         if (self_->device_status.bist == INIC_BIST_ERROR)
1125         {
1126             Eh_ReportEvent(&self_->base_ptr->eh, EH_E_BIST_FAILED);
1127         }
1128
1129         Sub_Notify(&self_->subs[INIC_SUB_DEVICE_STATUS], &self_->device_status);
1130     }
1131 }
1132
1133 /*! \brief Handler function for INIC.DeviceVersion.Status
1134  *  \param self      Reference to CInic instance
1135  *  \param msg_ptr   Pointer to received message
1136  */
1137 void Inic_DeviceVersion_Status(void *self, Msg_MostTel_t *msg_ptr)
1138 {
1139     CInic *self_ = (CInic *)self;
1140     Inic_StdResult_t res_data;
1141
1142     if (msg_ptr->tel.tel_len > 0U)
1143     {
1144         MISC_DECODE_DWORD(&(self_->device_version.product_identifier), &(msg_ptr->tel.tel_data_ptr[0]));
1145         self_->device_version.major_version = msg_ptr->tel.tel_data_ptr[4];
1146         self_->device_version.minor_version = msg_ptr->tel.tel_data_ptr[5];
1147         self_->device_version.release_version = msg_ptr->tel.tel_data_ptr[6];
1148         MISC_DECODE_DWORD(&(self_->device_version.build_version), &(msg_ptr->tel.tel_data_ptr[7]));
1149         self_->device_version.hw_revision = msg_ptr->tel.tel_data_ptr[11];
1150         MISC_DECODE_WORD(&(self_->device_version.diagnosis_id), &(msg_ptr->tel.tel_data_ptr[12]));
1151
1152         TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_data_ptr[14] == 0x01U)); /* ExtIdentifier == CFGS ? */
1153
1154         self_->device_version.cs_major_version = msg_ptr->tel.tel_data_ptr[15];
1155         self_->device_version.cs_minor_version = msg_ptr->tel.tel_data_ptr[16];
1156         self_->device_version.cs_release_version = msg_ptr->tel.tel_data_ptr[17];
1157
1158
1159         res_data.data_info       = &self_->device_version;
1160         res_data.result.code     = UCS_RES_SUCCESS;
1161         res_data.result.info_ptr = NULL;
1162
1163
1164         Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_VERSION], &res_data, true);
1165     }
1166     Al_Release(&self_->lock.api, INIC_API_DEVICE_VERSION_GET);
1167 }
1168
1169 /*! \brief Handler function for INIC.DeviceVersion.Error
1170  *  \param self      Reference to CInic instance
1171  *  \param msg_ptr   Pointer to received message
1172  */
1173 void Inic_DeviceVersion_Error(void *self, Msg_MostTel_t *msg_ptr)
1174 {
1175     CInic *self_ = (CInic *)self;
1176     Inic_StdResult_t res_data;
1177
1178     if (msg_ptr->tel.tel_len > 0U)
1179     {
1180         res_data.data_info = NULL;
1181         res_data.result = Inic_TranslateError(self_,
1182                                               &msg_ptr->tel.tel_data_ptr[0], 
1183                                               msg_ptr->tel.tel_len);
1184
1185         Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_VERSION], &res_data, true);
1186     }
1187     Al_Release(&self_->lock.api, INIC_API_DEVICE_VERSION_GET);
1188 }
1189
1190 /*! \brief Handler function for INIC.NetworkStatus.Status
1191  *  \param self      Reference to CInic instance
1192  *  \param msg_ptr   Pointer to received message
1193  */
1194 void Inic_NwStatus_Status(void *self, Msg_MostTel_t *msg_ptr)
1195 {
1196     CInic *self_ = (CInic *)self;
1197     Inic_StdResult_t res_data;
1198
1199     if (msg_ptr->tel.tel_len > 0U)
1200     {
1201         res_data.data_info       = &self_->network_status;
1202         res_data.result.code     = UCS_RES_SUCCESS;
1203         res_data.result.info_ptr = NULL;
1204
1205         TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_len == 11U));
1206         MISC_DECODE_WORD(&(self_->network_status.events), &(msg_ptr->tel.tel_data_ptr[0]));
1207         self_->network_status.availability      = (Ucs_Network_Availability_t)msg_ptr->tel.tel_data_ptr[2];
1208         self_->network_status.avail_info        = (Ucs_Network_AvailInfo_t)msg_ptr->tel.tel_data_ptr[3];
1209         self_->network_status.avail_trans_cause = (Ucs_Network_AvailTransCause_t)msg_ptr->tel.tel_data_ptr[4];
1210         MISC_DECODE_WORD(&(self_->network_status.node_address), &(msg_ptr->tel.tel_data_ptr[5]));
1211         self_->network_status.node_position     = msg_ptr->tel.tel_data_ptr[7];
1212         self_->network_status.max_position      = msg_ptr->tel.tel_data_ptr[8];
1213         MISC_DECODE_WORD(&(self_->network_status.packet_bw), &(msg_ptr->tel.tel_data_ptr[9]));
1214
1215         Sub_Notify(&self_->subs[INIC_SUB_NW_STATUS], &res_data);
1216     }
1217 }
1218
1219 /*! \brief Handler function for INIC.NetworkConfiguration.Status
1220  *  \param self      Reference to CInic instance
1221  *  \param msg_ptr   Pointer to received message
1222  */
1223 void Inic_NwConfig_Status(void *self, Msg_MostTel_t *msg_ptr)
1224 {
1225     CInic *self_ = (CInic *)self;
1226     Inic_StdResult_t res_data;
1227
1228     if (msg_ptr->tel.tel_len > 4U)
1229     {
1230         res_data.data_info       = &self_->network_config;
1231         res_data.result.code     = UCS_RES_SUCCESS;
1232         res_data.result.info_ptr = NULL;
1233
1234         MISC_DECODE_WORD(&(self_->network_config.node_address), &(msg_ptr->tel.tel_data_ptr[0]));
1235         MISC_DECODE_WORD(&(self_->network_config.group_address), &(msg_ptr->tel.tel_data_ptr[2]));
1236         self_->network_config.llrbc   = msg_ptr->tel.tel_data_ptr[4];
1237
1238         Sub_Notify(&self_->subs[INIC_SUB_NW_CONFIG], &res_data);
1239         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_CONFIG], &res_data, true);
1240     }
1241 }
1242
1243 /*! \brief Handler function for INIC.NetworkConfiguration.Error
1244  *  \param self      Reference to CInic instance
1245  *  \param msg_ptr   Pointer to received message
1246  */
1247 void Inic_NwConfig_Error(void *self, Msg_MostTel_t *msg_ptr)
1248 {
1249     CInic *self_ = (CInic *)self;
1250     Inic_StdResult_t res_data;
1251
1252     if (msg_ptr->tel.tel_len > 0U)
1253     {
1254         res_data.data_info = NULL;
1255         res_data.result = Inic_TranslateError(self_,
1256                                               &msg_ptr->tel.tel_data_ptr[0], 
1257                                               msg_ptr->tel.tel_len);
1258
1259         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_CONFIG], &res_data, true);
1260     }
1261 }
1262
1263 /*! \brief Handler function for INIC.MOSTNetworkFrameCounter.Status
1264  *  \param self      Reference to CInic instance
1265  *  \param msg_ptr   Pointer to received message
1266  */
1267 void Inic_NwFrameCounter_Status(void *self, Msg_MostTel_t *msg_ptr)
1268 {
1269     CInic *self_ = (CInic *)self;
1270     Inic_StdResult_t res_data;
1271     Inic_FrameCounterStatus_t frame_counter_status; 
1272
1273     if (msg_ptr->tel.tel_len > 0U)
1274     {
1275         MISC_DECODE_DWORD(&frame_counter_status.reference, &(msg_ptr->tel.tel_data_ptr[0]));
1276         MISC_DECODE_DWORD(&frame_counter_status.frame_counter, &(msg_ptr->tel.tel_data_ptr[4]));
1277         frame_counter_status.lock = msg_ptr->tel.tel_data_ptr[8];
1278         res_data.data_info        = &frame_counter_status;
1279         res_data.result.code      = UCS_RES_SUCCESS;
1280         res_data.result.info_ptr  = NULL;
1281
1282         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true);    /* provides pointer to Inic_StdResult_t structure */
1283     }
1284     Al_Release(&self_->lock.api, INIC_SSUB_NW_FRAME_COUNTER);
1285 }
1286
1287 /*! \brief Handler function for INIC.MOSTNetworkFrameCounter.Error
1288  *  \param self      Reference to CInic instance
1289  *  \param msg_ptr   Pointer to received message
1290  */
1291 void Inic_NwFrameCounter_Error(void *self, Msg_MostTel_t *msg_ptr)
1292 {
1293     CInic *self_ = (CInic *)self;
1294     Inic_StdResult_t res_data;
1295
1296     if (msg_ptr->tel.tel_len > 0U)
1297     {
1298         res_data.data_info = NULL;
1299         res_data.result = Inic_TranslateError(self_,
1300                                               &msg_ptr->tel.tel_data_ptr[0], 
1301                                               msg_ptr->tel.tel_len);
1302
1303         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true);    /* provides pointer to Inic_StdResult_t structure */
1304     }
1305     Al_Release(&self_->lock.api, INIC_SSUB_NW_FRAME_COUNTER);
1306 }
1307
1308 /*! \brief Handler function for INIC.MOSTNetworkStartup.ErrorAck
1309  *  \param self      Reference to CInic instance
1310  *  \param msg_ptr   Pointer to received message
1311  */
1312 void Inic_NwStartup_Error(void *self, Msg_MostTel_t *msg_ptr)
1313 {
1314     CInic *self_ = (CInic *)self;
1315     Inic_StdResult_t res_data;
1316
1317     self_->startup_locked = false;
1318     res_data.data_info = NULL;
1319     res_data.result = Inic_TranslateError(self_,
1320                                           &msg_ptr->tel.tel_data_ptr[0], 
1321                                           (msg_ptr->tel.tel_len));
1322     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_STARTUP], &res_data, true);
1323 }
1324
1325 /*! \brief Handler function for INIC.MOSTNetworkStartup.ResultAck
1326  *  \param self      Reference to CInic instance
1327  *  \param msg_ptr   Pointer to received message
1328  */
1329 void Inic_NwStartup_Result(void *self, Msg_MostTel_t *msg_ptr)
1330 {
1331     CInic *self_ = (CInic *)self;
1332     Inic_StdResult_t res_data;
1333     MISC_UNUSED(msg_ptr);
1334
1335     self_->startup_locked = false;
1336     res_data.data_info = NULL;
1337     res_data.result.code = UCS_RES_SUCCESS;
1338     res_data.result.info_ptr = NULL;
1339     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_STARTUP], &res_data, true);
1340 }
1341
1342 /*! \brief Handler function for INIC.MOSTNetworkShutdown.ErrorAck
1343  *  \param self      Reference to CInic instance
1344  *  \param msg_ptr   Pointer to received message
1345  */
1346 void Inic_NwShutdown_Error(void *self, Msg_MostTel_t *msg_ptr)
1347 {
1348     CInic *self_ = (CInic *)self;
1349     Inic_StdResult_t res_data;
1350
1351     if (msg_ptr->tel.tel_len > 0U)
1352     {
1353         res_data.data_info  = NULL;
1354         res_data.result = Inic_TranslateError(self_,
1355                                               &msg_ptr->tel.tel_data_ptr[0], 
1356                                               (msg_ptr->tel.tel_len));
1357         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
1358     }
1359     Al_Release(&self_->lock.api, INIC_API_NW_SHUTDOWN);
1360 }
1361
1362 /*! \brief Handler function for INIC.MOSTNetworkShutdown.ResultAck
1363  *  \param self      Reference to CInic instance
1364  *  \param msg_ptr   Pointer to received message
1365  */
1366 void Inic_NwShutdown_Result(void *self, Msg_MostTel_t *msg_ptr)
1367 {
1368     CInic *self_ = (CInic *)self;
1369     Inic_StdResult_t res_data;
1370     MISC_UNUSED(msg_ptr);
1371
1372     res_data.data_info       = NULL;
1373     res_data.result.code     = UCS_RES_SUCCESS;
1374     res_data.result.info_ptr = NULL;
1375     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
1376     Al_Release(&self_->lock.api, INIC_API_NW_SHUTDOWN);
1377 }
1378
1379 /*! \brief Handler function for INIC.MOSTNetworkTriggerRBD.ErrorAck
1380  *  \param self      Reference to CInic instance
1381  *  \param msg_ptr   Pointer to received message
1382  */
1383 void Inic_NwTriggerRbd_Error(void *self, Msg_MostTel_t *msg_ptr)
1384 {
1385     CInic *self_ = (CInic *)self;
1386     Inic_StdResult_t res_data;
1387
1388     if (msg_ptr->tel.tel_len > 0U)
1389     {
1390         res_data.data_info  = NULL;
1391         res_data.result = Inic_TranslateError(self_,
1392                                               &msg_ptr->tel.tel_data_ptr[0], 
1393                                               (msg_ptr->tel.tel_len));
1394         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &res_data, true);
1395     }
1396     Al_Release(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
1397 }
1398
1399 /*! \brief Handler function for INIC.MOSTNetworkTriggerRBD.ResultAck
1400  *  \param self      Reference to CInic instance
1401  *  \param msg_ptr   Pointer to received message
1402  */
1403 void Inic_NwTriggerRbd_Result(void *self, Msg_MostTel_t *msg_ptr)
1404 {
1405     CInic *self_ = (CInic *)self;
1406     Inic_StdResult_t res_data;
1407     MISC_UNUSED(msg_ptr);
1408
1409     res_data.data_info       = NULL;
1410     res_data.result.code     = UCS_RES_SUCCESS;
1411     res_data.result.info_ptr = NULL;
1412     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &res_data, true);
1413     Al_Release(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
1414 }
1415
1416 /*! \brief Handler function for INIC.MOSTNetworkForceNotAvailable.ErrorAck
1417  *  \param self      Reference to CInic instance
1418  *  \param msg_ptr   Pointer to received message
1419  */
1420 void Inic_NwForceNotAvailable_Error(void *self, Msg_MostTel_t *msg_ptr)
1421 {
1422     CInic *self_ = (CInic *)self;
1423     Inic_StdResult_t res_data;
1424
1425     if (msg_ptr->tel.tel_len > 0U)
1426     {
1427         res_data.data_info  = NULL;
1428         res_data.result = Inic_TranslateError(self_,
1429                                               &msg_ptr->tel.tel_data_ptr[0], 
1430                                               (msg_ptr->tel.tel_len));
1431         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FORCE_NA], &res_data, true);
1432     }
1433     Al_Release(&self_->lock.api, INIC_API_NW_FORCE_NA);
1434 }
1435
1436 /*! \brief Handler function for INIC.MOSTNetworkForceNotAvailable.ResultAck
1437  *  \param self      Reference to CInic instance
1438  *  \param msg_ptr   Pointer to received message
1439  */
1440 void Inic_NwForceNotAvailable_Status(void *self, Msg_MostTel_t *msg_ptr)
1441 {
1442     CInic *self_ = (CInic *)self;
1443     Inic_StdResult_t res_data;
1444     MISC_UNUSED(msg_ptr);
1445
1446     res_data.data_info       = NULL;
1447     res_data.result.code     = UCS_RES_SUCCESS;
1448     res_data.result.info_ptr = NULL;
1449     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FORCE_NA], &res_data, true);
1450     Al_Release(&self_->lock.api, INIC_API_NW_FORCE_NA);
1451 }
1452
1453 /*! \brief Handler function for INIC.DeviceAttach.Error
1454  * \param  self     reference to INIC object
1455  * \param  msg_ptr  received message
1456  */
1457 void Inic_DeviceAttach_Error(void *self, Msg_MostTel_t *msg_ptr)
1458 {
1459     CInic *self_ = (CInic *)self;
1460     Inic_StdResult_t res_data;
1461
1462     if (msg_ptr->tel.tel_len > 0U)
1463     {
1464         res_data.data_info  = NULL;
1465         res_data.result = Inic_TranslateError(self_,
1466                                               &msg_ptr->tel.tel_data_ptr[0], 
1467                                               (msg_ptr->tel.tel_len));
1468         Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_ATTACH], &res_data, true);
1469     }
1470 }
1471
1472 /*! \brief Handler function for INIC.DeviceAttach.Result
1473  * \param  self     reference to INIC object
1474  * \param  msg_ptr  received message
1475  */
1476 void Inic_DeviceAttach_Result(void *self, Msg_MostTel_t *msg_ptr)
1477 {
1478     CInic *self_ = (CInic *)self;
1479     Inic_StdResult_t res_data;
1480
1481     MISC_UNUSED(msg_ptr);
1482
1483     res_data.data_info       = NULL;
1484     res_data.result.code     = UCS_RES_SUCCESS;
1485     res_data.result.info_ptr = NULL;
1486     Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_ATTACH], &res_data, true);
1487 }
1488
1489 /*! \brief Handler function for INIC.NetworkAttach.ErrorAck
1490  * \param  self     reference to INIC object
1491  * \param  msg_ptr  received message
1492  */
1493 void Inic_NwAttach_Error(void *self, Msg_MostTel_t *msg_ptr)
1494 {
1495     CInic *self_ = (CInic *)self;
1496     Inic_StdResult_t res_data;
1497
1498     if (msg_ptr->tel.tel_len > 0U)
1499     {
1500         res_data.data_info = NULL;
1501         res_data.result = Inic_TranslateError(self_,
1502                                               &msg_ptr->tel.tel_data_ptr[0], 
1503                                               (msg_ptr->tel.tel_len));
1504         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_ATTACH], &res_data, true);
1505     }
1506 }
1507
1508 /*! \brief Handler function for INIC.NetworkAttach.ResultAck
1509  * \param  self     reference to INIC object
1510  * \param  msg_ptr  received message
1511  */
1512 void Inic_NwAttach_Result(void *self, Msg_MostTel_t *msg_ptr)
1513 {
1514     CInic *self_ = (CInic *)self;
1515     Inic_StdResult_t res_data;
1516
1517     MISC_UNUSED(msg_ptr);
1518
1519     res_data.data_info       = NULL;
1520     res_data.result.code     = UCS_RES_SUCCESS;
1521     res_data.result.info_ptr = NULL;
1522     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_ATTACH], &res_data, true);
1523 }
1524
1525
1526
1527
1528 /*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosis.Error
1529  * \param  self     reference to INIC object
1530  * \param  msg_ptr  received message
1531  */
1532 void Inic_NwSysDiagnosis_Error(void *self, Msg_MostTel_t *msg_ptr)
1533 {
1534     CInic *self_ = (CInic *)self;
1535     Inic_StdResult_t res_data;
1536
1537     if (msg_ptr->tel.tel_len > 0U)
1538     {
1539         res_data.data_info = NULL;
1540         res_data.result = Inic_TranslateError(self_,
1541                                               &msg_ptr->tel.tel_data_ptr[0], 
1542                                               (msg_ptr->tel.tel_len));
1543         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], &res_data, true);
1544     }
1545 }
1546
1547 /*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosis.Result
1548  * \param  self     reference to INIC object
1549  * \param  msg_ptr  received message
1550  */
1551 void Inic_NwSysDiagnosis_Result(void *self, Msg_MostTel_t *msg_ptr)
1552 {
1553     CInic *self_ = (CInic *)self;
1554     Inic_StdResult_t res_data;
1555
1556     MISC_UNUSED(msg_ptr);
1557
1558     res_data.data_info       = NULL;
1559     res_data.result.code     = UCS_RES_SUCCESS;
1560     res_data.result.info_ptr = NULL;
1561     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], &res_data, true);
1562 }
1563
1564 /*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosisEnd.Error
1565  * \param  self     reference to INIC object
1566  * \param  msg_ptr  received message
1567  */
1568 void Inic_NwSysDiagEnd_Error(void *self, Msg_MostTel_t *msg_ptr)
1569 {
1570     CInic *self_ = (CInic *)self;
1571     Inic_StdResult_t res_data;
1572
1573     if (msg_ptr->tel.tel_len > 0U)
1574     {
1575         res_data.data_info = NULL;
1576         res_data.result = Inic_TranslateError(self_,
1577                                               &msg_ptr->tel.tel_data_ptr[0], 
1578                                               (msg_ptr->tel.tel_len));
1579         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGEND], &res_data, true);
1580     }
1581 }
1582
1583 /*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosisEnd.Result
1584  * \param  self     reference to INIC object
1585  * \param  msg_ptr  received message
1586  */
1587 void Inic_NwSysDiagEnd_Result(void *self, Msg_MostTel_t *msg_ptr)
1588 {
1589     CInic *self_ = (CInic *)self;
1590     Inic_StdResult_t res_data;
1591
1592     MISC_UNUSED(msg_ptr);
1593
1594     res_data.data_info       = NULL;
1595     res_data.result.code     = UCS_RES_SUCCESS;
1596     res_data.result.info_ptr = NULL;
1597     Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGEND], &res_data, true);
1598 }
1599
1600
1601
1602 /*! \brief Handler function for INIC.BCDiag.Error
1603  * \param  self     reference to INIC object
1604  * \param  msg_ptr  received message
1605  */
1606 void Inic_BCDiagnosis_Error(void *self, Msg_MostTel_t *msg_ptr)
1607 {
1608     CInic *self_ = (CInic *)self;
1609     Inic_StdResult_t res_data;
1610
1611     res_data.data_info = NULL;
1612     res_data.result = Inic_TranslateError(self_,
1613                                           &msg_ptr->tel.tel_data_ptr[0], 
1614                                           (msg_ptr->tel.tel_len));
1615     Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAGNOSIS], &res_data, true);
1616 }
1617
1618 /*! \brief Handler function for INIC.BCDiag.ResultAck
1619  * \param  self     reference to INIC object
1620  * \param  msg_ptr  received message
1621  */
1622 void Inic_BCDiagnosis_Result(void *self, Msg_MostTel_t *msg_ptr)
1623 {
1624     CInic *self_ = (CInic *)self;
1625     Inic_StdResult_t res_data;
1626
1627     MISC_UNUSED(msg_ptr);
1628
1629     res_data.data_info       = NULL;
1630     res_data.result.code     = UCS_RES_SUCCESS;
1631     res_data.result.info_ptr = NULL;
1632     Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAGNOSIS], &res_data, true);
1633 }
1634
1635 /*! \brief Handler function for INIC.BCDiagEnd.Error
1636  * \param  self     reference to INIC object
1637  * \param  msg_ptr  received message
1638  */
1639 void Inic_BCDiagEnd_Error(void *self, Msg_MostTel_t *msg_ptr)
1640 {
1641     CInic *self_ = (CInic *)self;
1642     Inic_StdResult_t res_data;
1643
1644     res_data.data_info = NULL;
1645     res_data.result = Inic_TranslateError(self_,
1646                                           &msg_ptr->tel.tel_data_ptr[0], 
1647                                           (msg_ptr->tel.tel_len));
1648     Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAG_END], &res_data, true);
1649 }
1650
1651 /*! \brief Handler function for INIC.BCDiagEnd.Result
1652  * \param  self     reference to INIC object
1653  * \param  msg_ptr  received message
1654  */
1655 void Inic_BCDiagEnd_Result(void *self, Msg_MostTel_t *msg_ptr)
1656 {
1657     CInic *self_ = (CInic *)self;
1658     Inic_StdResult_t res_data;
1659
1660     MISC_UNUSED(msg_ptr);
1661
1662     res_data.data_info       = NULL;
1663     res_data.result.code     = UCS_RES_SUCCESS;
1664     res_data.result.info_ptr = NULL;
1665     Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAG_END], &res_data, true);
1666 }
1667
1668
1669
1670
1671
1672 /*! \brief Handler function for INIC.MOSTNetworkRBDResult.Status
1673  *  \param  self        Reference to INIC object
1674  *  \param  msg_ptr     Received message
1675  */
1676 void Inic_NwRbdResult_Status(void *self, Msg_MostTel_t *msg_ptr)
1677 {
1678     CInic *self_ = (CInic *)self;
1679     Inic_RbdResult_t rbd_result_data;
1680     Inic_StdResult_t res_data;
1681
1682     if (msg_ptr->tel.tel_len > 0U)
1683     {
1684         rbd_result_data.result   = (Ucs_Diag_RbdResult_t)msg_ptr->tel.tel_data_ptr[0];
1685         rbd_result_data.position = msg_ptr->tel.tel_data_ptr[1];
1686         rbd_result_data.status   = msg_ptr->tel.tel_data_ptr[2];
1687         MISC_DECODE_WORD(&(rbd_result_data.diag_id), &(msg_ptr->tel.tel_data_ptr[3]));
1688         res_data.data_info       = &rbd_result_data;
1689         res_data.result.code     = UCS_RES_SUCCESS;
1690         res_data.result.info_ptr = NULL;
1691
1692         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
1693     }
1694     Al_Release(&self_->lock.api, INIC_API_NW_RBD_RESULT);
1695 }
1696
1697 /*! \brief Handler function for INIC.MOSTNetworkRBDResult.Error
1698  * \param  self     reference to INIC object
1699  * \param  msg_ptr  received message
1700  */
1701 void Inic_NwRbdResult_Error(void *self, Msg_MostTel_t *msg_ptr)
1702 {
1703     CInic *self_ = (CInic *)self;
1704     Inic_StdResult_t res_data;
1705
1706     if (msg_ptr->tel.tel_len > 0U)
1707     {
1708         res_data.data_info  = NULL;
1709         res_data.result = Inic_TranslateError(self_,
1710                                               &msg_ptr->tel.tel_data_ptr[0], 
1711                                               msg_ptr->tel.tel_len);
1712
1713         Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
1714     }
1715     Al_Release(&self_->lock.api, INIC_API_NW_RBD_RESULT);
1716 }
1717
1718
1719
1720
1721 /*------------------------------------------------------------------------------------------------*/
1722 /* Helper functions                                                                               */
1723 /*------------------------------------------------------------------------------------------------*/
1724 /*! \brief Translates INIC error codes into UNICENS error codes and wraps the raw INIC
1725  *         error data to a byte stream.
1726  *  \param self         Instance of CInic
1727  *  \param error_data[] INIC error data
1728  *  \param error_size   Size of INIC error data in bytes
1729  *  \return             The formatted error
1730  */
1731 Ucs_StdResult_t Inic_TranslateError(CInic *self, uint8_t error_data[], uint8_t error_size)
1732 {
1733     Ucs_StdResult_t ret_val;
1734     MISC_UNUSED(self);
1735
1736     if(error_data[0] != 0x20U)
1737     {
1738         ret_val.code = UCS_RES_ERR_MOST_STANDARD;
1739     }
1740     else
1741     {
1742         ret_val.code = (Ucs_Result_t)(error_data[1] + 1U);
1743     }
1744
1745     ret_val.info_ptr  = &error_data[0];
1746     ret_val.info_size = error_size;
1747
1748     return ret_val;
1749 }
1750
1751
1752 /*------------------------------------------------------------------------------------------------*/
1753 /* Synchronous Getters                                                                            */
1754 /*------------------------------------------------------------------------------------------------*/
1755 uint16_t Inic_GetGroupAddress(CInic *self)
1756 {
1757     return self->network_config.group_address;
1758 }
1759
1760 uint16_t Inic_GetPacketDataBandwidth(CInic *self)
1761 {
1762     return self->network_status.packet_bw;
1763 }
1764
1765 uint16_t Inic_GetNodeAddress(CInic *self)
1766 {
1767     return self->network_status.node_address;
1768 }
1769
1770 uint8_t Inic_GetNodePosition(CInic *self)
1771 {
1772     return self->network_status.node_position;
1773 }
1774
1775 uint8_t Inic_GetNumberOfNodes(CInic *self)
1776 {
1777     return self->network_status.max_position;
1778 }
1779
1780 uint8_t Inic_GetInicLlrbc(CInic *self)
1781 {
1782     return self->network_config.llrbc;
1783 }
1784
1785 Ucs_Inic_Version_t Inic_GetDeviceVersion(CInic *self)
1786 {
1787     return self->device_version;
1788 }
1789
1790 Ucs_Inic_LastResetReason_t Inic_GetLastResetReason(CInic *self)
1791 {
1792     return self->device_status.last_reset_reason;
1793 }
1794
1795 Ucs_Inic_PowerState_t Inic_GetDevicePowerState(CInic *self)
1796 {
1797     return self->device_status.power_state;
1798 }
1799
1800 Ucs_Network_Availability_t Inic_GetAvailability(CInic *self)
1801 {
1802     return self->network_status.availability;
1803 }
1804
1805 uint16_t Inic_GetTargetAddress (CInic *self)
1806 {
1807     return self->target_address;
1808 }
1809
1810 /*!
1811  * @}
1812  * \endcond
1813  */
1814 /*------------------------------------------------------------------------------------------------*/
1815 /* End of file                                                                                    */
1816 /*------------------------------------------------------------------------------------------------*/
1817