/*------------------------------------------------------------------------------------------------*/
/* UNICENS V2.1.0-3491 */
/* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG. */
/* */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see . */
/* */
/* You may also obtain this software under a propriety license from Microchip. */
/* Please contact Microchip for further information. */
/*------------------------------------------------------------------------------------------------*/
/*!
* \file
* \brief Implementation of FBlock INIC
* \details Contains the general, device an network management parts of INIC management
*
* \cond UCS_INTERNAL_DOC
* \addtogroup G_INIC
* @{
*/
/*------------------------------------------------------------------------------------------------*/
/* Includes */
/*------------------------------------------------------------------------------------------------*/
#include "ucs_misc.h"
#include "ucs_ret_pb.h"
#include "ucs_inic.h"
/*------------------------------------------------------------------------------------------------*/
/* Internal constants */
/*------------------------------------------------------------------------------------------------*/
/*! \brief List of all INIC messages */
static const Dec_FktOpIcm_t inic_handler[] = /* parasoft-suppress MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
{
{ DEC_FKTOP(INIC_FID_NOTIFICATION, UCS_OP_STATUS), Inic_Notification_Status },
{ DEC_FKTOP(INIC_FID_NOTIFICATION, UCS_OP_ERROR), Inic_Notification_Error },
{ DEC_FKTOP(INIC_FID_DEVICE_STATUS, UCS_OP_STATUS), Inic_DeviceStatus_Status },
{ DEC_FKTOP(INIC_FID_DEVICE_STATUS, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_DEVICE_VERSION, UCS_OP_STATUS), Inic_DeviceVersion_Status },
{ DEC_FKTOP(INIC_FID_DEVICE_VERSION, UCS_OP_ERROR), Inic_DeviceVersion_Error },
{ DEC_FKTOP(INIC_FID_DEVICE_POWER_OFF, UCS_OP_STATUS), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_DEVICE_POWER_OFF, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_DEVICE_ATTACH, UCS_OP_RESULT), Inic_DeviceAttach_Result },
{ DEC_FKTOP(INIC_FID_DEVICE_ATTACH, UCS_OP_ERROR), Inic_DeviceAttach_Error },
{ DEC_FKTOP(INIC_FID_DEVICE_SYNC, UCS_OP_RESULT), Inic_DeviceSync_Result },
{ DEC_FKTOP(INIC_FID_DEVICE_SYNC, UCS_OP_ERROR), Inic_DeviceSync_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_STATUS, UCS_OP_STATUS), Inic_NwStatus_Status },
{ DEC_FKTOP(INIC_FID_MOST_NW_STATUS, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_MOST_NW_CFG, UCS_OP_STATUS), Inic_NwConfig_Status },
{ DEC_FKTOP(INIC_FID_MOST_NW_CFG, UCS_OP_ERROR), Inic_NwConfig_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_FRAME_COUNTER, UCS_OP_STATUS), Inic_NwFrameCounter_Status },
{ DEC_FKTOP(INIC_FID_MOST_NW_FRAME_COUNTER, UCS_OP_ERROR), Inic_NwFrameCounter_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_STARTUP, UCS_OP_RESULT), Inic_NwStartup_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_STARTUP, UCS_OP_ERROR), Inic_NwStartup_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_SHUTDOWN, UCS_OP_RESULT), Inic_NwShutdown_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_SHUTDOWN, UCS_OP_ERROR), Inic_NwShutdown_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_TRIGGER_RBD, UCS_OP_RESULT), Inic_NwTriggerRbd_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_TRIGGER_RBD, UCS_OP_ERROR), Inic_NwTriggerRbd_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_RBD_RESULT, UCS_OP_STATUS), Inic_NwRbdResult_Status },
{ DEC_FKTOP(INIC_FID_MOST_NW_RBD_RESULT, UCS_OP_ERROR), Inic_NwRbdResult_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_ATTACH, UCS_OP_RESULT), Inic_NwAttach_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_ATTACH, UCS_OP_ERROR), Inic_NwAttach_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_FORCE_NO_AVAIL, UCS_OP_STATUS), Inic_NwForceNotAvailable_Status },
{ DEC_FKTOP(INIC_FID_MOST_NW_FORCE_NO_AVAIL, UCS_OP_ERROR), Inic_NwForceNotAvailable_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAGNOSIS, UCS_OP_RESULT), Inic_NwSysDiagnosis_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAGNOSIS, UCS_OP_ERROR), Inic_NwSysDiagnosis_Error },
{ DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAG_END, UCS_OP_RESULT), Inic_NwSysDiagEnd_Result },
{ DEC_FKTOP(INIC_FID_MOST_NW_SYS_DIAG_END, UCS_OP_ERROR), Inic_NwSysDiagEnd_Error },
{ DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAGNOSIS, UCS_OP_RESULT), Inic_BCDiagnosis_Result },
{ DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAGNOSIS, UCS_OP_ERROR), Inic_BCDiagnosis_Error },
{ DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAG_END, UCS_OP_RESULT), Inic_BCDiagEnd_Result },
{ DEC_FKTOP(INIC_FID_BACK_CHANNEL_DIAG_END, UCS_OP_ERROR), Inic_BCDiagEnd_Error },
{ DEC_FKTOP(INIC_FID_MOST_PORT_STATUS, UCS_OP_STATUS), Inic_MostPortStatus_Status },
{ DEC_FKTOP(INIC_FID_MOST_PORT_STATUS, UCS_OP_ERROR), Inic_MostPortStatus_Error },
{ DEC_FKTOP(INIC_FID_MOST_SOCKET_CREATE, UCS_OP_RESULT), Inic_MostSocketCreate_Result },
{ DEC_FKTOP(INIC_FID_MOST_SOCKET_CREATE, UCS_OP_ERROR), Inic_MostSocketCreate_Error },
{ DEC_FKTOP(INIC_FID_MOST_SOCKET_STATUS, UCS_OP_STATUS), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_MOST_SOCKET_STATUS, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_MLB_PORT_CREATE, UCS_OP_RESULT), Inic_MlbPortCreate_Result },
{ DEC_FKTOP(INIC_FID_MLB_PORT_CREATE, UCS_OP_ERROR), Inic_MlbPortCreate_Error },
/* { DEC_FKTOP(INIC_FID_MLB_PORT_ALLOCATE_ONLY, UCS_OP_RESULT), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_MLB_PORT_ALLOCATE_ONLY, UCS_OP_ERROR), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_MLB_PORT_DEALLOC_ONLY, UCS_OP_RESULT), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_MLB_PORT_DEALLOC_ONLY, UCS_OP_ERROR), Inic_DummyHandler }, */
{ DEC_FKTOP(INIC_FID_MLB_SOCKET_CREATE, UCS_OP_RESULT), Inic_MlbSocketCreate_Result },
{ DEC_FKTOP(INIC_FID_MLB_SOCKET_CREATE, UCS_OP_ERROR), Inic_MlbSocketCreate_Error },
{ DEC_FKTOP(INIC_FID_SPI_PORT_CREATE, UCS_OP_RESULT), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_SPI_PORT_CREATE, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_SPI_SOCKET_CREATE, UCS_OP_RESULT), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_SPI_SOCKET_CREATE, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_USB_PORT_CREATE, UCS_OP_RESULT), Inic_UsbPortCreate_Result },
{ DEC_FKTOP(INIC_FID_USB_PORT_CREATE, UCS_OP_ERROR), Inic_UsbPortCreate_Error },
{ DEC_FKTOP(INIC_FID_USB_SOCKET_CREATE, UCS_OP_RESULT), Inic_UsbSocketCreate_Result },
{ DEC_FKTOP(INIC_FID_USB_SOCKET_CREATE, UCS_OP_ERROR), Inic_UsbSocketCreate_Error },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_CONFIG, UCS_OP_STATUS), Inic_StreamPortConfig_Status },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_CONFIG, UCS_OP_ERROR), Inic_StreamPortConfig_Error },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_CREATE, UCS_OP_RESULT), Inic_StreamPortCreate_Result },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_CREATE, UCS_OP_ERROR), Inic_StreamPortCreate_Error },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_LOOPBACK, UCS_OP_STATUS), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_STREAM_PORT_LOOPBACK, UCS_OP_ERROR), Inic_DummyHandler },
{ DEC_FKTOP(INIC_FID_STREAM_SOCKET_CREATE, UCS_OP_RESULT), Inic_StreamSocketCreate_Result },
{ DEC_FKTOP(INIC_FID_STREAM_SOCKET_CREATE, UCS_OP_ERROR), Inic_StreamSocketCreate_Error },
{ DEC_FKTOP(INIC_FID_RMCK_PORT_CREATE, UCS_OP_RESULT), Inic_RmckPortCreate_Result },
{ DEC_FKTOP(INIC_FID_RMCK_PORT_CREATE, UCS_OP_ERROR), Inic_RmckPortCreate_Error },
{ DEC_FKTOP(INIC_FID_I2C_PORT_CREATE, UCS_OP_RESULT), Inic_I2cPortCreate_Result },
{ DEC_FKTOP(INIC_FID_I2C_PORT_CREATE, UCS_OP_ERROR), Inic_I2cPortCreate_Error },
{ DEC_FKTOP(INIC_FID_I2C_PORT_READ, UCS_OP_RESULT), Inic_I2cPortRead_Result },
{ DEC_FKTOP(INIC_FID_I2C_PORT_READ, UCS_OP_ERROR), Inic_I2cPortRead_Error },
{ DEC_FKTOP(INIC_FID_I2C_PORT_WRITE, UCS_OP_RESULT), Inic_I2cPortWrite_Result },
{ DEC_FKTOP(INIC_FID_I2C_PORT_WRITE, UCS_OP_ERROR), Inic_I2cPortWrite_Error },
{ DEC_FKTOP(INIC_FID_PCI_PORT_CREATE, UCS_OP_RESULT), Inic_PciPortCreate_Result },
{ DEC_FKTOP(INIC_FID_PCI_PORT_CREATE, UCS_OP_ERROR), Inic_PciPortCreate_Error },
{ DEC_FKTOP(INIC_FID_PCI_SOCKET_CREATE, UCS_OP_RESULT), Inic_PciSocketCreate_Result },
{ DEC_FKTOP(INIC_FID_PCI_SOCKET_CREATE, UCS_OP_ERROR), Inic_PciSocketCreate_Error },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_CREATE, UCS_OP_RESULT), Inic_GpioPortCreate_Result },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_CREATE, UCS_OP_ERROR), Inic_GpioPortCreate_Error },
{ DEC_FKTOP(INIC_FID_MOST_PORT_ENABLE, UCS_OP_RESULT), Inic_MostPortEnable_Result },
{ DEC_FKTOP(INIC_FID_MOST_PORT_ENABLE, UCS_OP_ERROR), Inic_MostPortEnable_Error },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_MODE, UCS_OP_STATUS), Inic_GpioPortPinMode_Status },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_MODE, UCS_OP_ERROR), Inic_GpioPortPinMode_Error },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_STATE, UCS_OP_STATUS), Inic_GpioPortPinState_Status },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_PIN_STATE, UCS_OP_ERROR), Inic_GpioPortPinState_Error },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_TRIGGER_EVENT, UCS_OP_STATUS), Inic_GpioPortTrigger_Status },
{ DEC_FKTOP(INIC_FID_GPIO_PORT_TRIGGER_EVENT, UCS_OP_ERROR), Inic_GpioPortTrigger_Error },
{ DEC_FKTOP(INIC_FID_RESOURCE_DESTROY, UCS_OP_RESULT), Inic_ResourceDestroy_Result },
{ DEC_FKTOP(INIC_FID_RESOURCE_DESTROY, UCS_OP_ERROR), Inic_ResourceDestroy_Error },
{ DEC_FKTOP(INIC_FID_RESOURCE_INVALID_LIST, UCS_OP_STATUS), Inic_ResourceInvalidList_Status },
{ DEC_FKTOP(INIC_FID_RESOURCE_INVALID_LIST, UCS_OP_ERROR), Inic_ResourceInvalidList_Error },
{ DEC_FKTOP(INIC_FID_RESOURCE_MONITOR, UCS_OP_STATUS), Inic_ResourceMonitor_Status },
{ DEC_FKTOP(INIC_FID_RESOURCE_MONITOR, UCS_OP_ERROR), Inic_ResourceMonitor_Error },
/* { DEC_FKTOP(INIC_FID_PACKET_ATTACH_SOCKETS, UCS_OP_RESULT), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_PACKET_ATTACH_SOCKETS, UCS_OP_ERROR), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_PACKET_DETACH_SOCKETS, UCS_OP_RESULT), Inic_DummyHandler }, */
/* { DEC_FKTOP(INIC_FID_PACKET_DETACH_SOCKETS, UCS_OP_ERROR), Inic_DummyHandler }, */
{ DEC_FKTOP(INIC_FID_QOS_CREATE, UCS_OP_RESULT), Inic_QoSCreate_Result },
{ DEC_FKTOP(INIC_FID_QOS_CREATE, UCS_OP_ERROR), Inic_QoSCreate_Error },
{ DEC_FKTOP(INIC_FID_AVP_CREATE, UCS_OP_RESULT), Inic_AvpCreate_Result },
{ DEC_FKTOP(INIC_FID_AVP_CREATE, UCS_OP_ERROR), Inic_AvpCreate_Error },
{ DEC_FKTOP(INIC_FID_SYNC_CREATE, UCS_OP_RESULT), Inic_SyncCreate_Result },
{ DEC_FKTOP(INIC_FID_SYNC_CREATE, UCS_OP_ERROR), Inic_SyncCreate_Error },
{ DEC_FKTOP(INIC_FID_SYNC_MUTE, UCS_OP_RESULT), Inic_SyncMute_Result },
{ DEC_FKTOP(INIC_FID_SYNC_MUTE, UCS_OP_ERROR), Inic_SyncMute_Error },
{ DEC_FKTOP(INIC_FID_SYNC_DEMUTE, UCS_OP_RESULT), Inic_SyncDemute_Result },
{ DEC_FKTOP(INIC_FID_SYNC_DEMUTE, UCS_OP_ERROR), Inic_SyncDemute_Error },
{ DEC_FKTOP(INIC_FID_DFIPHASE_CREATE, UCS_OP_RESULT), Inic_DfiPhaseCreate_Result },
{ DEC_FKTOP(INIC_FID_DFIPHASE_CREATE, UCS_OP_ERROR), Inic_DfiPhaseCreate_Error },
{ DEC_FKTOP(INIC_FID_IPC_CREATE, UCS_OP_RESULT), Inic_IpcCreate_Result },
{ DEC_FKTOP(INIC_FID_IPC_CREATE, UCS_OP_ERROR), Inic_IpcCreate_Error },
{ DEC_FKTOP(INIC_FID_COMBINER_CREATE, UCS_OP_RESULT), Inic_CombinerCreate_Result },
{ DEC_FKTOP(INIC_FID_COMBINER_CREATE, UCS_OP_ERROR), Inic_CombinerCreate_Error },
{ DEC_FKTOP(INIC_FID_SPLITTER_CREATE, UCS_OP_RESULT), Inic_SplitterCreate_Result },
{ DEC_FKTOP(INIC_FID_SPLITTER_CREATE, UCS_OP_ERROR), Inic_SplitterCreate_Error },
{ DEC_FKTOP_TERMINATION, NULL }
};
/*------------------------------------------------------------------------------------------------*/
/* Internal definitions */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Bitmask for API method Inic_NwForceNotAvailable() used by API locking manager */
#define INIC_API_NW_FORCE_NA 0x01U
/*! \brief Bitmask for API method Inic_NwShutdown() used by API locking manager */
#define INIC_API_NW_SHUTDOWN 0x02U
/*! \brief Bitmask for API method Inic_NwFrameCounter_Get() used by API locking manager */
#define INIC_API_NW_FRAME_COUNTER 0x04U
/*! \brief Bitmask for API method Inic_NwTriggerRbd() used by API locking manager */
#define INIC_API_NW_TRIGGER_RBD 0x08U
/*! \brief Bitmask for API method Inic_NwRbdResult_Get() used by API locking manager */
#define INIC_API_NW_RBD_RESULT 0x10U
/*! \brief Bitmask for API method Inic_DeviceVersion_Get() used by API locking manager */
#define INIC_API_DEVICE_VERSION_GET 0x20U
/*------------------------------------------------------------------------------------------------*/
/* Internal prototypes */
/*------------------------------------------------------------------------------------------------*/
static void Inic_HandleInternalErrors(void *self, void *error_code_ptr);
static void Inic_HandleApiTimeout(void *self, void *method_mask_ptr);
static void Inic_DecodeIcm(CInic *self, Msg_MostTel_t *msg_ptr);
static void Inic_MsgTxStatusCb(void *self, Msg_MostTel_t *tel_ptr, Ucs_MsgTxStatus_t status);
/*------------------------------------------------------------------------------------------------*/
/* Implementation */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Constructor of class CInic.
* \param self Reference to CInic instance
* \param init_ptr Reference to initialization data
*/
void Inic_Ctor(CInic *self, Inic_InitData_t *init_ptr)
{
uint8_t i;
MISC_MEM_SET((void *)self, 0, sizeof(*self));
self->base_ptr = init_ptr->base_ptr;
self->xcvr_ptr = init_ptr->xcvr_ptr;
self->fkt_op_list_ptr = &inic_handler[0];
self->target_address = init_ptr->tgt_addr;
/* create instances of single-observers */
for(i=0U; issubs[i], self->base_ptr->ucs_user_ptr);
}
/* create instances of "normal" observers */
for(i=0U; isubs[i], self->base_ptr->ucs_user_ptr);
}
/* Observe internal errors and events */
Mobs_Ctor(&self->internal_error_obs, self, EH_M_TERMINATION_EVENTS, &Inic_HandleInternalErrors);
Eh_AddObsrvInternalEvent(&self->base_ptr->eh, &self->internal_error_obs);
/* Initialize API locking mechanism */
Sobs_Ctor(&self->lock.observer, self, &Inic_HandleApiTimeout);
Al_Ctor(&self->lock.api, &self->lock.observer, self->base_ptr->ucs_user_ptr);
Alm_RegisterApi(&self->base_ptr->alm, &self->lock.api);
/* Initialize Resource Management part */
Inic_InitResourceManagement(self);
}
/*! \brief Handles internal errors and events
* \param self Instance pointer
* \param error_code_ptr Reference to reported error code
*/
static void Inic_HandleInternalErrors(void *self, void *error_code_ptr)
{
uint8_t i;
Inic_StdResult_t res_data;
CInic *self_ = (CInic *)self;
MISC_UNUSED(error_code_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_ERR_SYSTEM;
res_data.result.info_ptr = NULL;
res_data.result.info_size = 0U;
/* Internal error has been occurred => Cancel running jobs */
for(i=0U; issubs[i], &res_data, true);
}
}
/*! \brief Handles an API timeout
* \param self Instance pointer
* \param method_mask_ptr Bitmask to signal which API method has caused the timeout
*/
static void Inic_HandleApiTimeout(void *self, void *method_mask_ptr)
{
CInic *self_ = (CInic *)self;
Alm_ModuleMask_t method_mask = *((Alm_ModuleMask_t *)method_mask_ptr);
Inic_StdResult_t res_data;
res_data.data_info = NULL;
res_data.result.code = UCS_RES_ERR_TIMEOUT;
res_data.result.info_ptr = NULL;
switch(method_mask)
{
case INIC_API_NW_SHUTDOWN:
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwShutdown().", 0U));
break;
case INIC_API_NW_FRAME_COUNTER:
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true);
TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwFrameCounter_Get().", 0U));
break;
case INIC_API_NW_TRIGGER_RBD:
self_->lock.rbd_trigger_timeout_counter++;
if(self_->lock.rbd_trigger_timeout_counter < 5U)
{
(void)Al_Lock(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
}
else
{
Inic_StdResult_t rbd_result_data;
Ucs_StdResult_t result = {UCS_RES_ERR_TIMEOUT, NULL, 0U};
rbd_result_data.data_info = NULL;
rbd_result_data.result = result;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &rbd_result_data, true);
TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwTriggerRbd().", 0U));
}
break;
case INIC_API_NW_RBD_RESULT:
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "API locking timeout occurred for method Inic_NwRbdResult_Get().", 0U));
break;
default:
TR_ERROR((self_->base_ptr->ucs_user_ptr, "[INIC]", "Unknown API locking bitmask detected. Mask: 0x%02X", 1U, method_mask));
break;
}
}
/*! \brief Decode an ICM message
* \param self Instance pointer to FBlock INIC
* \param msg_ptr pointer to the ICM message to decode
*/
static void Inic_DecodeIcm(CInic *self, Msg_MostTel_t *msg_ptr)
{
Dec_Return_t result;
uint16_t index;
result = Dec_SearchFktOpIcm(self->fkt_op_list_ptr, &index, msg_ptr->id.function_id, msg_ptr->id.op_type);
if (result == DEC_RET_SUCCESS)
{
self->fkt_op_list_ptr[index].handler_function_ptr(self, msg_ptr);
}
else
{
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));
}
}
/*! \brief Receives ICMs
* \param self reference to INIC object
* \param tel_ptr received message
*/
void Inic_OnIcmRx(void *self, Msg_MostTel_t *tel_ptr)
{
CInic *self_ = (CInic *)self;
if ((tel_ptr->source_addr == MSG_ADDR_INIC) && (tel_ptr->destination_addr == MSG_ADDR_EHC_CFG))
{
Inic_DecodeIcm(self_, tel_ptr);
}
Trcv_RxReleaseMsg(self_->xcvr_ptr, tel_ptr); /* free Rx telegram */
}
/*! \brief Filters RCM Rx messages
* \details The filter function shall not release the message object
* \param self Reference to INIC object
* \param tel_ptr Reference to the RCM Rx message object
*/
void Inic_OnRcmRxFilter(void *self, Msg_MostTel_t *tel_ptr)
{
uint16_t index;
CInic *self_ = (CInic *)self;
if (Dec_SearchFktOpIcm(self_->fkt_op_list_ptr, &index, tel_ptr->id.function_id, tel_ptr->id.op_type) == DEC_RET_SUCCESS)
{
self_->fkt_op_list_ptr[index].handler_function_ptr(self, tel_ptr);
}
}
/*! \brief Handle message Tx status and free message objects
* \param self The instance
* \param tel_ptr Reference to transmitted message
* \param status Status of the transmitted message
*/
static void Inic_MsgTxStatusCb(void *self, Msg_MostTel_t *tel_ptr, Ucs_MsgTxStatus_t status)
{
CInic *self_ = (CInic *)self;
if ((status != UCS_MSG_STAT_OK) && (tel_ptr->info_ptr != NULL))
{
Inic_StdResult_t res_data;
CSingleSubject *ssub_ptr = (CSingleSubject *)tel_ptr->info_ptr;
res_data.data_info = &status;
res_data.result.code = UCS_RES_ERR_TRANSMISSION;
res_data.result.info_ptr = NULL;
res_data.result.info_size = 0U;
Ssub_Notify(ssub_ptr, &res_data, true);
}
Trcv_TxReleaseMsg(tel_ptr);
/* ICM messages pending? */
if (Sub_GetNumObservers(&self_->subs[INIC_SUB_TX_MSG_OBJ_AVAIL]) > 0U)
{
Sub_Notify(&self_->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], NULL);
}
}
/*! \brief Add an observer to be notified when a tx message object is available
* \param self instance of CInic
* \param obs_ptr pointer to observer to be informed
*/
void Inic_AddObsrvOnTxMsgObjAvail(CInic *self, CObserver *obs_ptr)
{
(void)Sub_AddObserver(&self->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], obs_ptr);
}
/*! \brief Delete an observer set by Inic_AddObsrvOnTxMsgObjAvail()
* \param self instance of CInic
* \param obs_ptr pointer to observer to be removed
*/
void Inic_DelObsrvOnTxMsgObjAvail(CInic *self, CObserver *obs_ptr)
{
(void)Sub_RemoveObserver(&self->subs[INIC_SUB_TX_MSG_OBJ_AVAIL], obs_ptr);
}
/*! \brief Add an observer to the NetworkStatus subject
* \param self instance of CInic
* \param obs_ptr pointer to observer to be informed
*/
void Inic_AddObsrvNwStatus(CInic *self, CObserver *obs_ptr)
{
(void)Sub_AddObserver(&self->subs[INIC_SUB_NW_STATUS], obs_ptr);
}
/*! \brief Delete an observer to the NetworkStatus subject
* \param self instance of CInic
* \param obs_ptr pointer to observer to be removed
*/
void Inic_DelObsrvNwStatus(CInic *self, CObserver *obs_ptr)
{
(void)Sub_RemoveObserver(&self->subs[INIC_SUB_NW_STATUS], obs_ptr);
}
/*! \brief Add an observer to the NetworkConfiguration subject
* \param self instance of CInic
* \param obs_ptr pointer to observer to be informed
*/
void Inic_AddObsvrNwConfig(CInic *self, CObserver *obs_ptr)
{
(void)Sub_AddObserver(&self->subs[INIC_SUB_NW_CONFIG], obs_ptr);
}
/*! \brief Delete an observer to the NetworkConfiguration subject
* \param self instance of CInic
* \param obs_ptr pointer to observer to be removed
*/
void Inic_DelObsvrNwConfig(CInic *self, CObserver *obs_ptr)
{
(void)Sub_RemoveObserver(&self->subs[INIC_SUB_NW_CONFIG], obs_ptr);
}
/*! \brief Add an observer to the DeviceStatus subject
* \details The provided data points to a \ref Inic_DeviceStatus_t structure
* \param self instance of CInic
* \param obs_ptr pointer to observer to be informed
*/
void Inic_AddObsvrDeviceStatus(CInic *self, CObserver *obs_ptr)
{
(void)Sub_AddObserver(&self->subs[INIC_SUB_DEVICE_STATUS], obs_ptr);
}
/*! \brief Delete an observer to the DeviceStatus subject
* \param self instance of CInic
* \param obs_ptr pointer to observer to be removed
*/
void Inic_DelObsvrDeviceStatus(CInic *self, CObserver *obs_ptr)
{
(void)Sub_RemoveObserver(&self->subs[INIC_SUB_DEVICE_STATUS], obs_ptr);
}
/*------------------------------------------------------------------------------------------------*/
/* Internal API */
/*------------------------------------------------------------------------------------------------*/
/*! \brief This method requests the INIC version info
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_DeviceVersion_Get(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if(Al_Lock(&self->lock.api, INIC_API_DEVICE_VERSION_GET) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_DEVICE_VERSION;
msg_ptr->id.op_type = UCS_OP_GET;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_DEVICE_VERSION];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_DEVICE_VERSION], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_DEVICE_VERSION_GET);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief Attach EHC to the INIC
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_DeviceAttach(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_DEVICE_ATTACH;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_DEVICE_ATTACH];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_DEVICE_ATTACH], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Attaches the given PMS channel to the network
* \param self Reference to CInic instance
* \param pmp_channel_handle Port message channel resource handle
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_NwAttach(CInic *self,
uint16_t pmp_channel_handle,
CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 2U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_ATTACH;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->tel.tel_data_ptr[0] = MISC_HB(pmp_channel_handle);
msg_ptr->tel.tel_data_ptr[1] = MISC_LB(pmp_channel_handle);
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_ATTACH];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_ATTACH], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Starts the System diagnosis
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_NwSysDiagnosis(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_SYS_DIAGNOSIS;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Stops the System diagnosis
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_NwSysDiagEnd(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_SYS_DIAG_END;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SYS_DIAGEND];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SYS_DIAGEND], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Starts the Backchannel Diagnosis Mode
*
* \param *self Reference to CInic instance
* \param *obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_BCDiagnosis(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = MSG_ADDR_INIC;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_BACK_CHANNEL_DIAGNOSIS;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_BC_DIAGNOSIS];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_BC_DIAGNOSIS], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Stops the Backchannel Diagnosis Mode
*
* \param *self Reference to CInic instance
* \param *obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_BCDiagEnd(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = MSG_ADDR_INIC;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_BACK_CHANNEL_DIAG_END;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_BC_DIAG_END];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_BC_DIAG_END], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Requests the INIC.MOSTNetworRBDResult.Status message
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwRbdResult_Get(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if(Al_Lock(&self->lock.api, INIC_API_NW_RBD_RESULT) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_RBD_RESULT;
msg_ptr->id.op_type = UCS_OP_GET;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_RBD_RESULT];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_RBD_RESULT], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_NW_RBD_RESULT);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief This functions starts up the MOST network.
* \param self Reference to CInic instance
* \param auto_forced_na The delay time to shutdown the network after INIC has entered the
* protected mode.
* \param packet_bandwidth The desired packed bandwidth
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwStartup(CInic *self, uint16_t auto_forced_na,
uint16_t packet_bandwidth, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if (self->startup_locked == false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 4U);
if (msg_ptr != NULL)
{
self->startup_locked = true;
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_STARTUP;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->tel.tel_data_ptr[0] = MISC_HB(auto_forced_na);
msg_ptr->tel.tel_data_ptr[1] = MISC_LB(auto_forced_na);
msg_ptr->tel.tel_data_ptr[2] = MISC_HB(packet_bandwidth);
msg_ptr->tel.tel_data_ptr[3] = MISC_LB(packet_bandwidth);
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_STARTUP];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_STARTUP], obs_ptr);
}
else
{
self->startup_locked = false;
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief This function shuts down the entire MOST network.
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwShutdown(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if(Al_Lock(&self->lock.api, INIC_API_NW_SHUTDOWN) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_SHUTDOWN;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_SHUTDOWN];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_SHUTDOWN], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_NW_SHUTDOWN);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief This function triggers the Ring Break Diagnosis.
* \param self Reference to CInic instance
* \param type Specifies if the INIC starts the RBD as a TimingMaster or TimingSlave.
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwTriggerRbd(CInic *self, Ucs_Diag_RbdType_t type, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if(Al_Lock(&self->lock.api, INIC_API_NW_TRIGGER_RBD) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
if (msg_ptr != NULL)
{
self->lock.rbd_trigger_timeout_counter = 0U;
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_TRIGGER_RBD;
msg_ptr->id.op_type = UCS_OP_STARTRESULT;
msg_ptr->tel.tel_data_ptr[0] = (uint8_t)type;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_TRIGGER_RBD];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_TRIGGER_RBD], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_NW_TRIGGER_RBD);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief This function triggers the INIC to force the NotAvailable state
* \param self Reference to CInic instance
* \param force Is \c true if the INIC shall force the network in NotAvailable state.
* If \c false the INIC shall no no longer force the network to NotAvailable state.
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwForceNotAvailable(CInic *self, bool force, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if (Al_Lock(&self->lock.api, INIC_API_NW_FORCE_NA) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_FORCE_NO_AVAIL;
msg_ptr->id.op_type = UCS_OP_SETGET;
if (force == false)
{
msg_ptr->tel.tel_data_ptr[0] = 0U;
}
else
{
msg_ptr->tel.tel_data_ptr[0] = 1U;
}
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_FORCE_NA];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_FORCE_NA], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_NW_FORCE_NA);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*! \brief This function modifies the INIC network configuration.
* \param self Reference to CInic instance
* \param mask Allows to change a single, multiple, or all parameters
* \param config Holds the parameter values
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_NwConfig_SetGet(CInic *self, uint16_t mask, Inic_NetworkConfig_t config,
CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 24U);
if (msg_ptr != NULL)
{
mask = mask & 7U; /* allow only bit 0..2 */
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_CFG;
msg_ptr->id.op_type = UCS_OP_SETGET;
msg_ptr->tel.tel_data_ptr[0] = MISC_HB(mask);
msg_ptr->tel.tel_data_ptr[1] = MISC_LB(mask);
msg_ptr->tel.tel_data_ptr[2] = MISC_HB(config.node_address);
msg_ptr->tel.tel_data_ptr[3] = MISC_LB(config.node_address);
msg_ptr->tel.tel_data_ptr[4] = MISC_HB(config.group_address);
msg_ptr->tel.tel_data_ptr[5] = MISC_LB(config.group_address);
msg_ptr->tel.tel_data_ptr[6] = config.llrbc;
MISC_MEM_SET(&msg_ptr->tel.tel_data_ptr[7], 0, 17U);
Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_CONFIG], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Requests the INIC.NetworkConfiguration.Status message
* \param self Reference to CInic instance
* \param obs_ptr Reference to an optional observer. The result must be casted into type
* Inic_StdResult_t.
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
*/
Ucs_Return_t Inic_NwConfig_Get(CInic *self, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_CFG;
msg_ptr->id.op_type = UCS_OP_GET;
Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_CONFIG], obs_ptr);
}
else
{
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
return result;
}
/*! \brief Requests the INIC.MOSTNetworkFrameCounter.Status message
* \param self Reference to CInic instance
* \param reference Reference counter value
* \param obs_ptr Reference to an optional observer
* \return UCS_RET_SUCCESS message was created
* \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
* \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
*/
Ucs_Return_t Inic_NwFrameCounter_Get(CInic *self, uint32_t reference, CSingleObserver *obs_ptr)
{
Ucs_Return_t result = UCS_RET_SUCCESS;
if(Al_Lock(&self->lock.api, INIC_API_NW_FRAME_COUNTER) != false)
{
Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 4U);
if (msg_ptr != NULL)
{
msg_ptr->destination_addr = self->target_address;
msg_ptr->id.fblock_id = FB_INIC;
msg_ptr->id.instance_id = 0U;
msg_ptr->id.function_id = INIC_FID_MOST_NW_FRAME_COUNTER;
msg_ptr->id.op_type = UCS_OP_GET;
msg_ptr->tel.tel_data_ptr[0] = (uint8_t)(reference >> 24);
msg_ptr->tel.tel_data_ptr[1] = (uint8_t)(reference >> 16);
msg_ptr->tel.tel_data_ptr[2] = (uint8_t)(reference >> 8);
msg_ptr->tel.tel_data_ptr[3] = (uint8_t)reference;
msg_ptr->info_ptr = &self->ssubs[INIC_SSUB_NW_FRAME_COUNTER];
Trcv_TxSendMsgExt(self->xcvr_ptr, msg_ptr, &Inic_MsgTxStatusCb, self);
(void)Ssub_AddObserver(&self->ssubs[INIC_SSUB_NW_FRAME_COUNTER], obs_ptr);
}
else
{
Al_Release(&self->lock.api, INIC_API_NW_FRAME_COUNTER);
result = UCS_RET_ERR_BUFFER_OVERFLOW;
}
}
else
{
result = UCS_RET_ERR_API_LOCKED;
}
return result;
}
/*------------------------------------------------------------------------------------------------*/
/* Handler functions */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Dummy handler function for unused INIC functions
*
* \param self instance of CInic
* \param msg_ptr Pointer to received message
*/
void Inic_DummyHandler(void *self, Msg_MostTel_t *msg_ptr)
{
MISC_UNUSED(self);
MISC_UNUSED(msg_ptr);
}
/*! \brief Handler function for INIC.DeviceStatus.Status
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_DeviceStatus_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
if (msg_ptr->tel.tel_len > 0U)
{
TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_len == 5U));
self_->device_status.config_iface_state= (Inic_AttachState_t)msg_ptr->tel.tel_data_ptr[0];
self_->device_status.app_iface_state = (Inic_AttachState_t)msg_ptr->tel.tel_data_ptr[1];
self_->device_status.power_state = (Ucs_Inic_PowerState_t)msg_ptr->tel.tel_data_ptr[2];
self_->device_status.bist = (Inic_Bist_t)msg_ptr->tel.tel_data_ptr[3];
self_->device_status.last_reset_reason = (Ucs_Inic_LastResetReason_t)msg_ptr->tel.tel_data_ptr[4];
/* INIC BIST error detected */
if (self_->device_status.bist == INIC_BIST_ERROR)
{
Eh_ReportEvent(&self_->base_ptr->eh, EH_E_BIST_FAILED);
}
Sub_Notify(&self_->subs[INIC_SUB_DEVICE_STATUS], &self_->device_status);
}
}
/*! \brief Handler function for INIC.DeviceVersion.Status
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_DeviceVersion_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
MISC_DECODE_DWORD(&(self_->device_version.product_identifier), &(msg_ptr->tel.tel_data_ptr[0]));
self_->device_version.major_version = msg_ptr->tel.tel_data_ptr[4];
self_->device_version.minor_version = msg_ptr->tel.tel_data_ptr[5];
self_->device_version.release_version = msg_ptr->tel.tel_data_ptr[6];
MISC_DECODE_DWORD(&(self_->device_version.build_version), &(msg_ptr->tel.tel_data_ptr[7]));
self_->device_version.hw_revision = msg_ptr->tel.tel_data_ptr[11];
MISC_DECODE_WORD(&(self_->device_version.diagnosis_id), &(msg_ptr->tel.tel_data_ptr[12]));
TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_data_ptr[14] == 0x01U)); /* ExtIdentifier == CFGS ? */
self_->device_version.cs_major_version = msg_ptr->tel.tel_data_ptr[15];
self_->device_version.cs_minor_version = msg_ptr->tel.tel_data_ptr[16];
self_->device_version.cs_release_version = msg_ptr->tel.tel_data_ptr[17];
res_data.data_info = &self_->device_version;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_VERSION], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_DEVICE_VERSION_GET);
}
/*! \brief Handler function for INIC.DeviceVersion.Error
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_DeviceVersion_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
msg_ptr->tel.tel_len);
Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_VERSION], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_DEVICE_VERSION_GET);
}
/*! \brief Handler function for INIC.NetworkStatus.Status
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwStatus_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = &self_->network_status;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
TR_ASSERT(self_->base_ptr->ucs_user_ptr, "[INIC]", (msg_ptr->tel.tel_len == 11U));
MISC_DECODE_WORD(&(self_->network_status.events), &(msg_ptr->tel.tel_data_ptr[0]));
self_->network_status.availability = (Ucs_Network_Availability_t)msg_ptr->tel.tel_data_ptr[2];
self_->network_status.avail_info = (Ucs_Network_AvailInfo_t)msg_ptr->tel.tel_data_ptr[3];
self_->network_status.avail_trans_cause = (Ucs_Network_AvailTransCause_t)msg_ptr->tel.tel_data_ptr[4];
MISC_DECODE_WORD(&(self_->network_status.node_address), &(msg_ptr->tel.tel_data_ptr[5]));
self_->network_status.node_position = msg_ptr->tel.tel_data_ptr[7];
self_->network_status.max_position = msg_ptr->tel.tel_data_ptr[8];
MISC_DECODE_WORD(&(self_->network_status.packet_bw), &(msg_ptr->tel.tel_data_ptr[9]));
Sub_Notify(&self_->subs[INIC_SUB_NW_STATUS], &res_data);
}
}
/*! \brief Handler function for INIC.NetworkConfiguration.Status
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwConfig_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 4U)
{
res_data.data_info = &self_->network_config;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
MISC_DECODE_WORD(&(self_->network_config.node_address), &(msg_ptr->tel.tel_data_ptr[0]));
MISC_DECODE_WORD(&(self_->network_config.group_address), &(msg_ptr->tel.tel_data_ptr[2]));
self_->network_config.llrbc = msg_ptr->tel.tel_data_ptr[4];
Sub_Notify(&self_->subs[INIC_SUB_NW_CONFIG], &res_data);
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_CONFIG], &res_data, true);
}
}
/*! \brief Handler function for INIC.NetworkConfiguration.Error
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwConfig_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
msg_ptr->tel.tel_len);
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_CONFIG], &res_data, true);
}
}
/*! \brief Handler function for INIC.MOSTNetworkFrameCounter.Status
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwFrameCounter_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
Inic_FrameCounterStatus_t frame_counter_status;
if (msg_ptr->tel.tel_len > 0U)
{
MISC_DECODE_DWORD(&frame_counter_status.reference, &(msg_ptr->tel.tel_data_ptr[0]));
MISC_DECODE_DWORD(&frame_counter_status.frame_counter, &(msg_ptr->tel.tel_data_ptr[4]));
frame_counter_status.lock = msg_ptr->tel.tel_data_ptr[8];
res_data.data_info = &frame_counter_status;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true); /* provides pointer to Inic_StdResult_t structure */
}
Al_Release(&self_->lock.api, INIC_SSUB_NW_FRAME_COUNTER);
}
/*! \brief Handler function for INIC.MOSTNetworkFrameCounter.Error
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwFrameCounter_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
msg_ptr->tel.tel_len);
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FRAME_COUNTER], &res_data, true); /* provides pointer to Inic_StdResult_t structure */
}
Al_Release(&self_->lock.api, INIC_SSUB_NW_FRAME_COUNTER);
}
/*! \brief Handler function for INIC.MOSTNetworkStartup.ErrorAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwStartup_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
self_->startup_locked = false;
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_STARTUP], &res_data, true);
}
/*! \brief Handler function for INIC.MOSTNetworkStartup.ResultAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwStartup_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
self_->startup_locked = false;
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_STARTUP], &res_data, true);
}
/*! \brief Handler function for INIC.MOSTNetworkShutdown.ErrorAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwShutdown_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_NW_SHUTDOWN);
}
/*! \brief Handler function for INIC.MOSTNetworkShutdown.ResultAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwShutdown_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SHUTDOWN], &res_data, true);
Al_Release(&self_->lock.api, INIC_API_NW_SHUTDOWN);
}
/*! \brief Handler function for INIC.MOSTNetworkTriggerRBD.ErrorAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwTriggerRbd_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
}
/*! \brief Handler function for INIC.MOSTNetworkTriggerRBD.ResultAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwTriggerRbd_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_TRIGGER_RBD], &res_data, true);
Al_Release(&self_->lock.api, INIC_API_NW_TRIGGER_RBD);
}
/*! \brief Handler function for INIC.MOSTNetworkForceNotAvailable.ErrorAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwForceNotAvailable_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FORCE_NA], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_NW_FORCE_NA);
}
/*! \brief Handler function for INIC.MOSTNetworkForceNotAvailable.ResultAck
* \param self Reference to CInic instance
* \param msg_ptr Pointer to received message
*/
void Inic_NwForceNotAvailable_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_FORCE_NA], &res_data, true);
Al_Release(&self_->lock.api, INIC_API_NW_FORCE_NA);
}
/*! \brief Handler function for INIC.DeviceAttach.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_DeviceAttach_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_ATTACH], &res_data, true);
}
}
/*! \brief Handler function for INIC.DeviceAttach.Result
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_DeviceAttach_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_DEVICE_ATTACH], &res_data, true);
}
/*! \brief Handler function for INIC.NetworkAttach.ErrorAck
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwAttach_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_ATTACH], &res_data, true);
}
}
/*! \brief Handler function for INIC.NetworkAttach.ResultAck
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwAttach_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_ATTACH], &res_data, true);
}
/*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosis.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwSysDiagnosis_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], &res_data, true);
}
}
/*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosis.Result
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwSysDiagnosis_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGNOSIS], &res_data, true);
}
/*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosisEnd.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwSysDiagEnd_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGEND], &res_data, true);
}
}
/*! \brief Handler function for INIC.MOSTNetworkSystemDiagnosisEnd.Result
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwSysDiagEnd_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_SYS_DIAGEND], &res_data, true);
}
/*! \brief Handler function for INIC.BCDiag.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_BCDiagnosis_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAGNOSIS], &res_data, true);
}
/*! \brief Handler function for INIC.BCDiag.ResultAck
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_BCDiagnosis_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAGNOSIS], &res_data, true);
}
/*! \brief Handler function for INIC.BCDiagEnd.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_BCDiagEnd_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
(msg_ptr->tel.tel_len));
Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAG_END], &res_data, true);
}
/*! \brief Handler function for INIC.BCDiagEnd.Result
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_BCDiagEnd_Result(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
MISC_UNUSED(msg_ptr);
res_data.data_info = NULL;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_BC_DIAG_END], &res_data, true);
}
/*! \brief Handler function for INIC.MOSTNetworkRBDResult.Status
* \param self Reference to INIC object
* \param msg_ptr Received message
*/
void Inic_NwRbdResult_Status(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_RbdResult_t rbd_result_data;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
rbd_result_data.result = (Ucs_Diag_RbdResult_t)msg_ptr->tel.tel_data_ptr[0];
rbd_result_data.position = msg_ptr->tel.tel_data_ptr[1];
rbd_result_data.status = msg_ptr->tel.tel_data_ptr[2];
MISC_DECODE_WORD(&(rbd_result_data.diag_id), &(msg_ptr->tel.tel_data_ptr[3]));
res_data.data_info = &rbd_result_data;
res_data.result.code = UCS_RES_SUCCESS;
res_data.result.info_ptr = NULL;
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_NW_RBD_RESULT);
}
/*! \brief Handler function for INIC.MOSTNetworkRBDResult.Error
* \param self reference to INIC object
* \param msg_ptr received message
*/
void Inic_NwRbdResult_Error(void *self, Msg_MostTel_t *msg_ptr)
{
CInic *self_ = (CInic *)self;
Inic_StdResult_t res_data;
if (msg_ptr->tel.tel_len > 0U)
{
res_data.data_info = NULL;
res_data.result = Inic_TranslateError(self_,
&msg_ptr->tel.tel_data_ptr[0],
msg_ptr->tel.tel_len);
Ssub_Notify(&self_->ssubs[INIC_SSUB_NW_RBD_RESULT], &res_data, true);
}
Al_Release(&self_->lock.api, INIC_API_NW_RBD_RESULT);
}
/*------------------------------------------------------------------------------------------------*/
/* Helper functions */
/*------------------------------------------------------------------------------------------------*/
/*! \brief Translates INIC error codes into UNICENS error codes and wraps the raw INIC
* error data to a byte stream.
* \param self Instance of CInic
* \param error_data[] INIC error data
* \param error_size Size of INIC error data in bytes
* \return The formatted error
*/
Ucs_StdResult_t Inic_TranslateError(CInic *self, uint8_t error_data[], uint8_t error_size)
{
Ucs_StdResult_t ret_val;
MISC_UNUSED(self);
if(error_data[0] != 0x20U)
{
ret_val.code = UCS_RES_ERR_MOST_STANDARD;
}
else
{
ret_val.code = (Ucs_Result_t)(error_data[1] + 1U);
}
ret_val.info_ptr = &error_data[0];
ret_val.info_size = error_size;
return ret_val;
}
/*------------------------------------------------------------------------------------------------*/
/* Synchronous Getters */
/*------------------------------------------------------------------------------------------------*/
uint16_t Inic_GetGroupAddress(CInic *self)
{
return self->network_config.group_address;
}
uint16_t Inic_GetPacketDataBandwidth(CInic *self)
{
return self->network_status.packet_bw;
}
uint16_t Inic_GetNodeAddress(CInic *self)
{
return self->network_status.node_address;
}
uint8_t Inic_GetNodePosition(CInic *self)
{
return self->network_status.node_position;
}
uint8_t Inic_GetNumberOfNodes(CInic *self)
{
return self->network_status.max_position;
}
uint8_t Inic_GetInicLlrbc(CInic *self)
{
return self->network_config.llrbc;
}
Ucs_Inic_Version_t Inic_GetDeviceVersion(CInic *self)
{
return self->device_version;
}
Ucs_Inic_LastResetReason_t Inic_GetLastResetReason(CInic *self)
{
return self->device_status.last_reset_reason;
}
Ucs_Inic_PowerState_t Inic_GetDevicePowerState(CInic *self)
{
return self->device_status.power_state;
}
Ucs_Network_Availability_t Inic_GetAvailability(CInic *self)
{
return self->network_status.availability;
}
uint16_t Inic_GetTargetAddress (CInic *self)
{
return self->target_address;
}
/*!
* @}
* \endcond
*/
/*------------------------------------------------------------------------------------------------*/
/* End of file */
/*------------------------------------------------------------------------------------------------*/