1 /*------------------------------------------------------------------------------------------------*/
2 /* UNICENS V2.1.0-3491 */
3 /* Copyright (c) 2017 Microchip Technology Germany II GmbH & Co. KG. */
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. */
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. */
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/>. */
18 /* You may also obtain this software under a propriety license from Microchip. */
19 /* Please contact Microchip for further information. */
20 /*------------------------------------------------------------------------------------------------*/
24 * \brief Implementation of FBlock ExtendedNetworkControl
25 * \details Contains the housekeeping functions of INIC management
27 * \cond UCS_INTERNAL_DOC
32 /*------------------------------------------------------------------------------------------------*/
34 /*------------------------------------------------------------------------------------------------*/
36 #include "ucs_ret_pb.h"
41 /*------------------------------------------------------------------------------------------------*/
42 /* Internal definitions */
43 /*------------------------------------------------------------------------------------------------*/
44 /*! \brief Bitmask for API method Exc_PhyTestResult_Get() used by API locking manager */
45 #define EXC_API_PHY_LAY_TEST_RESULT 0x01U
46 /*! \brief Bitmask for API method Exc_MemSessionOpen_Sr() used by API locking manager */
47 #define EXC_API_MEM_SESSION_OPEN 0x02U
48 /*! \brief Bitmask for API method Exc_MemSessionClose_Sr() used by API locking manager */
49 #define EXC_API_MEM_SESSION_CLOSE 0x04U
50 /*! \brief Bitmask for API method Exc_MemoryRead_Sr() used by API locking manager */
51 #define EXC_API_MEM_READ 0x08U
52 /*! \brief Bitmask for API method Exc_MemoryWrite_Sr() used by API locking manager */
53 #define EXC_API_MEM_WRITE 0x10U
55 /*! \brief max. number of elements used in MemoryWrite and MemoryWrite messages */
56 #define MAX_UNIT_LEN 18U
58 /*! \brief length of signature (V1) */
59 #define EXC_SIGNATURE_LEN_V1 26U
62 /*------------------------------------------------------------------------------------------------*/
63 /* Internal prototypes */
64 /*------------------------------------------------------------------------------------------------*/
65 static void Exc_DecodeMsg(CExc *self, Msg_MostTel_t *msg_rx_ptr);
66 static void Exc_EnablePort_Error(void *self, Msg_MostTel_t *msg_ptr);
67 static void Exc_EnablePort_Result(void *self, Msg_MostTel_t *msg_ptr);
68 static void Exc_Hello_Status(void *self, Msg_MostTel_t *msg_ptr);
69 static void Exc_Hello_Error(void *self, Msg_MostTel_t *msg_ptr);
70 static void Exc_Welcome_Error(void *self, Msg_MostTel_t *msg_ptr);
71 static void Exc_Welcome_Result(void *self, Msg_MostTel_t *msg_ptr);
72 static void Exc_Signature_Status(void *self, Msg_MostTel_t *msg_ptr);
73 static void Exc_Signature_Error(void *self, Msg_MostTel_t *msg_ptr);
74 static void Exc_DeviceInit_Error(void *self, Msg_MostTel_t *msg_ptr);
75 static void Exc_CableLinkDiag_Error(void *self, Msg_MostTel_t *msg_ptr);
76 static void Exc_CableLinkDiag_Result(void *self, Msg_MostTel_t *msg_ptr);
77 static void Exc_NwPhyTest_Error(void *self, Msg_MostTel_t *msg_ptr);
78 static void Exc_NwPhyTestResult_Status(void *self, Msg_MostTel_t *msg_ptr);
79 static void Exc_NwPhyTestResult_Error(void *self, Msg_MostTel_t *msg_ptr);
80 static void Exc_BC_Diag_Result(void *self, Msg_MostTel_t *msg_ptr);
81 static void Exc_BC_Diag_Error(void *self, Msg_MostTel_t *msg_ptr);
82 static void Exc_BC_EnableTx_Result(void *self, Msg_MostTel_t *msg_ptr);
83 static void Exc_BC_EnableTx_Error(void *self, Msg_MostTel_t *msg_ptr);
84 static void Exc_MemoryRead_Result(void *self, Msg_MostTel_t *msg_ptr);
85 static void Exc_MemoryRead_Error(void *self, Msg_MostTel_t *msg_ptr);
86 static void Exc_MemoryWrite_Result(void *self, Msg_MostTel_t *msg_ptr);
87 static void Exc_MemoryWrite_Error(void *self, Msg_MostTel_t *msg_ptr);
88 static void Exc_MemSessionOpen_Result(void *self, Msg_MostTel_t *msg_ptr);
89 static void Exc_MemSessionOpen_Error(void *self, Msg_MostTel_t *msg_ptr);
90 static void Exc_MemSessionClose_Result(void *self, Msg_MostTel_t *msg_ptr);
91 static void Exc_MemSessionClose_Error(void *self, Msg_MostTel_t *msg_ptr);
93 static void Exc_HandleApiTimeout(void *self, void *method_mask_ptr);
95 static Ucs_StdResult_t Exc_TranslateError(CExc *self, uint8_t error_data[], uint8_t error_size);
96 static void Exc_Read_Signature(Ucs_Signature_t *dest, uint8_t source[]);
99 /*------------------------------------------------------------------------------------------------*/
100 /* Internal constants */
101 /*------------------------------------------------------------------------------------------------*/
102 /*! \brief List of all EXC messages */
103 static const Dec_FktOpIsh_t exc_handler[] = /* parasoft-suppress MISRA2004-8_7 "Value shall be part of the module, not part of a function." */
105 { DEC_FKTOP(EXC_FID_HELLO, UCS_OP_STATUS), Exc_Hello_Status },
106 { DEC_FKTOP(EXC_FID_HELLO, UCS_OP_ERROR), Exc_Hello_Error },
107 { DEC_FKTOP(EXC_FID_WELCOME, UCS_OP_RESULT), Exc_Welcome_Result },
108 { DEC_FKTOP(EXC_FID_WELCOME, UCS_OP_ERROR), Exc_Welcome_Error },
109 { DEC_FKTOP(EXC_FID_SIGNATURE, UCS_OP_STATUS), Exc_Signature_Status },
110 { DEC_FKTOP(EXC_FID_SIGNATURE, UCS_OP_ERROR), Exc_Signature_Error },
111 { DEC_FKTOP(EXC_FID_DEVICE_INIT, UCS_OP_ERROR), Exc_DeviceInit_Error },
112 { DEC_FKTOP(EXC_FID_ENABLEPORT, UCS_OP_RESULT), Exc_EnablePort_Result },
113 { DEC_FKTOP(EXC_FID_ENABLEPORT, UCS_OP_ERROR), Exc_EnablePort_Error },
114 { DEC_FKTOP(EXC_FID_CABLE_LINK_DIAG, UCS_OP_RESULT), Exc_CableLinkDiag_Result },
115 { DEC_FKTOP(EXC_FID_CABLE_LINK_DIAG, UCS_OP_ERROR), Exc_CableLinkDiag_Error },
116 { DEC_FKTOP(EXC_FID_PHY_LAY_TEST, UCS_OP_ERROR), Exc_NwPhyTest_Error },
117 { DEC_FKTOP(EXC_FID_PHY_LAY_TEST_RES, UCS_OP_STATUS), Exc_NwPhyTestResult_Status },
118 { DEC_FKTOP(EXC_FID_PHY_LAY_TEST_RES, UCS_OP_ERROR), Exc_NwPhyTestResult_Error },
119 { DEC_FKTOP(EXC_FID_BC_DIAG, UCS_OP_RESULT), Exc_BC_Diag_Result },
120 { DEC_FKTOP(EXC_FID_BC_DIAG, UCS_OP_ERROR), Exc_BC_Diag_Error },
121 { DEC_FKTOP(EXC_FID_BC_ENABLE_TX, UCS_OP_RESULT), Exc_BC_EnableTx_Result },
122 { DEC_FKTOP(EXC_FID_BC_ENABLE_TX, UCS_OP_ERROR), Exc_BC_EnableTx_Error },
123 { DEC_FKTOP(EXC_FID_MEM_SESSION_OPEN, UCS_OP_RESULT), Exc_MemSessionOpen_Result },
124 { DEC_FKTOP(EXC_FID_MEM_SESSION_OPEN, UCS_OP_ERROR), Exc_MemSessionOpen_Error },
125 { DEC_FKTOP(EXC_FID_MEM_SESSION_CLOSE, UCS_OP_RESULT), Exc_MemSessionClose_Result },
126 { DEC_FKTOP(EXC_FID_MEM_SESSION_CLOSE, UCS_OP_ERROR), Exc_MemSessionClose_Error },
127 { DEC_FKTOP(EXC_FID_MEMORY_READ, UCS_OP_RESULT), Exc_MemoryRead_Result },
128 { DEC_FKTOP(EXC_FID_MEMORY_READ, UCS_OP_ERROR), Exc_MemoryRead_Error },
129 { DEC_FKTOP(EXC_FID_MEMORY_WRITE, UCS_OP_RESULT), Exc_MemoryWrite_Result },
130 { DEC_FKTOP(EXC_FID_MEMORY_WRITE, UCS_OP_ERROR), Exc_MemoryWrite_Error },
131 { DEC_FKTOP_TERMINATION, NULL }
135 /*------------------------------------------------------------------------------------------------*/
137 /*------------------------------------------------------------------------------------------------*/
139 /*! \brief Constructor of class CExc.
140 * \param self Reference to CExc instance
141 * \param base_ptr Reference to a Base instance
142 * \param rcm_ptr Reference to Transceiver instance
144 void Exc_Ctor(CExc *self, CBase *base_ptr, CTransceiver *rcm_ptr)
147 MISC_MEM_SET((void *)self, 0, sizeof(*self));
149 self->base_ptr = base_ptr;
150 self->xcvr_ptr = rcm_ptr;
152 self->fkt_op_list_ptr = &exc_handler[0];
155 /* Initialize API locking mechanism */
156 Sobs_Ctor(&self->lock.observer, self, &Exc_HandleApiTimeout);
157 Al_Ctor(&self->lock.api, &self->lock.observer, self->base_ptr->ucs_user_ptr);
158 Alm_RegisterApi(&self->base_ptr->alm, &self->lock.api);
163 /*! \brief Callback function to filter RCM Rx messages
164 * \details Do not release the message object here
165 * \param self reference to INIC object
166 * \param tel_ptr received message
168 void Exc_OnRcmRxFilter(void *self, Msg_MostTel_t *tel_ptr)
170 CExc *self_ = (CExc *)self;
171 Exc_DecodeMsg(self_, tel_ptr);
176 /*! \brief Decode a message for FBlock EXC
177 * \param self Instance pointer to FBlock EXC
178 * \param msg_rx_ptr pointer to the MCM message to decode
180 static void Exc_DecodeMsg(CExc *self, Msg_MostTel_t *msg_rx_ptr)
185 result = Dec_SearchFktOpIsh(self->fkt_op_list_ptr, &index, msg_rx_ptr->id.function_id, msg_rx_ptr->id.op_type);
187 if (result == DEC_RET_SUCCESS)
189 self->fkt_op_list_ptr[index].handler_function_ptr(self, msg_rx_ptr);
193 /* no handling of decoding error for shadow OpTypes */
199 /*! \brief Handles an API timeout
200 * \param self Instance pointer
201 * \param method_mask_ptr Bitmask to signal which API method has caused the timeout
203 static void Exc_HandleApiTimeout(void *self, void *method_mask_ptr)
205 CExc *self_ = (CExc *)self;
206 Alm_ModuleMask_t method_mask = *((Alm_ModuleMask_t *)method_mask_ptr);
207 Exc_StdResult_t res_data;
209 res_data.result.code = UCS_RES_ERR_TIMEOUT;
210 res_data.result.info_ptr = NULL;
211 res_data.result.info_size = 0U;
212 res_data.data_info = NULL;
216 #if 0 /* System Diagnosis supervises timeouts for these functions */
217 case EXC_API_ENABLE_PORT:
218 Ssub_Notify(&self_->ssubs.enableport, &res_data, false);
219 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_EnablePort_Sr().", 0U));
222 Ssub_Notify(&self_->ssubs.hello, &res_data, false);
223 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_Hello_Get().", 0U));
225 case EXC_API_WELCOME:
226 Ssub_Notify(&self_->ssubs.welcome, &res_data, false);
227 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_Welcome_Sr().", 0U));
229 case EXC_API_CABLE_LINK_DIAG:
230 Ssub_Notify(&self_->ssubs.cablelinkdiag, &res_data, false);
231 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_CableLinkDiagnosis_Start().", 0U));
234 case EXC_API_PHY_LAY_TEST_RESULT:
235 Ssub_Notify(&self_->ssubs.phylaytestresult, &res_data, false);
236 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_PhyTestResult_Get().", 0U));
238 case EXC_API_MEM_SESSION_OPEN:
239 Ssub_Notify(&self_->ssubs.memsessionopen, &res_data, false);
240 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_MemSessionOpen_Sr().", 0U));
242 case EXC_API_MEM_SESSION_CLOSE:
243 Ssub_Notify(&self_->ssubs.memsessionclose, &res_data, false);
244 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_MemSessionClose_Sr().", 0U));
246 case EXC_API_MEM_READ:
247 Ssub_Notify(&self_->ssubs.memoryread, &res_data, false);
248 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_MemoryRead_Sr().", 0U));
250 case EXC_API_MEM_WRITE:
251 Ssub_Notify(&self_->ssubs.memorywrite, &res_data, false);
252 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "API locking timeout occurred for method Exc_MemoryWrite_Sr().", 0U));
256 TR_ERROR((self_->base_ptr->ucs_user_ptr, "[EXC]", "Unknown API locking bitmask detected. Mask: 0x%02X", 1U, method_mask));
264 /*------------------------------------------------------------------------------------------------*/
266 /*------------------------------------------------------------------------------------------------*/
267 /*! \brief This method sends the Hello.Get message
268 * \param self Reference to CExc instance
269 * \param target_address Target address
270 * \param version_limit Signature version limit
271 * \param obs_ptr Reference to an optional observer
272 * \return UCS_RET_SUCCESS message was created
273 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
275 Ucs_Return_t Exc_Hello_Get(CExc *self,
276 uint16_t target_address,
277 uint8_t version_limit,
278 CSingleObserver *obs_ptr)
280 Ucs_Return_t result = UCS_RET_SUCCESS;
282 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
286 if (version_limit > UCS_EXC_SIGNATURE_VERSION_LIMIT)
288 version_limit = UCS_EXC_SIGNATURE_VERSION_LIMIT;
291 msg_ptr->destination_addr = target_address;
293 msg_ptr->id.fblock_id = FB_EXC;
294 msg_ptr->id.instance_id = 0U;
295 msg_ptr->id.function_id = EXC_FID_HELLO;
296 msg_ptr->id.op_type = UCS_OP_GET;
297 msg_ptr->tel.tel_data_ptr[0] = version_limit;
299 msg_ptr->info_ptr = &self->ssubs.hello;
300 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
302 (void)Ssub_AddObserver(&self->ssubs.hello, obs_ptr);
306 result = UCS_RET_ERR_BUFFER_OVERFLOW;
313 /*! \brief This method send the Welcome.StartResult message
314 * \param self Reference to CExc instance
315 * \param target_address Target address
316 * \param admin_node_address The node address used during system diagnosis
317 * \param version Signature version
318 * \param signature Signature of the device
319 * \param obs_ptr Reference to an optional observer
320 * \return UCS_RET_SUCCESS message was created
321 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
323 Ucs_Return_t Exc_Welcome_Sr(CExc *self,
324 uint16_t target_address,
325 uint16_t admin_node_address,
327 Ucs_Signature_t signature,
328 CSingleObserver *obs_ptr)
330 Ucs_Return_t result = UCS_RET_SUCCESS;
332 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, EXC_SIGNATURE_LEN_V1 + 3U); /* Signature v1 */
336 msg_ptr->destination_addr = target_address;
337 msg_ptr->id.fblock_id = FB_EXC;
338 msg_ptr->id.instance_id = 0U;
339 msg_ptr->id.function_id = EXC_FID_WELCOME;
340 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
341 msg_ptr->tel.tel_data_ptr[0] = MISC_HB(admin_node_address);
342 msg_ptr->tel.tel_data_ptr[1] = MISC_LB(admin_node_address);
343 msg_ptr->tel.tel_data_ptr[2] = version;
344 msg_ptr->tel.tel_data_ptr[3] = MISC_HB(signature.node_address);
345 msg_ptr->tel.tel_data_ptr[4] = MISC_LB(signature.node_address);
346 msg_ptr->tel.tel_data_ptr[5] = MISC_HB(signature.group_address);
347 msg_ptr->tel.tel_data_ptr[6] = MISC_LB(signature.group_address);
348 msg_ptr->tel.tel_data_ptr[7] = MISC_HB(signature.mac_47_32);
349 msg_ptr->tel.tel_data_ptr[8] = MISC_LB(signature.mac_47_32);
350 msg_ptr->tel.tel_data_ptr[9] = MISC_HB(signature.mac_31_16);
351 msg_ptr->tel.tel_data_ptr[10] = MISC_LB(signature.mac_31_16);
352 msg_ptr->tel.tel_data_ptr[11] = MISC_HB(signature.mac_15_0);
353 msg_ptr->tel.tel_data_ptr[12] = MISC_LB(signature.mac_15_0);
354 msg_ptr->tel.tel_data_ptr[13] = MISC_HB(signature.node_pos_addr);
355 msg_ptr->tel.tel_data_ptr[14] = MISC_LB(signature.node_pos_addr);
356 msg_ptr->tel.tel_data_ptr[15] = MISC_HB(signature.diagnosis_id);
357 msg_ptr->tel.tel_data_ptr[16] = MISC_LB(signature.diagnosis_id);
358 msg_ptr->tel.tel_data_ptr[17] = signature.num_ports;
359 msg_ptr->tel.tel_data_ptr[18] = signature.chip_id;
360 msg_ptr->tel.tel_data_ptr[19] = signature.fw_major;
361 msg_ptr->tel.tel_data_ptr[20] = signature.fw_minor;
362 msg_ptr->tel.tel_data_ptr[21] = signature.fw_release;
363 msg_ptr->tel.tel_data_ptr[22] = MISC_HB((signature.fw_build) >>16U);
364 msg_ptr->tel.tel_data_ptr[23] = MISC_LB((signature.fw_build) >>16U);
365 msg_ptr->tel.tel_data_ptr[24] = MISC_HB(signature.fw_build);
366 msg_ptr->tel.tel_data_ptr[25] = MISC_LB(signature.fw_build);
367 msg_ptr->tel.tel_data_ptr[26] = signature.cs_major;
368 msg_ptr->tel.tel_data_ptr[27] = signature.cs_minor;
369 msg_ptr->tel.tel_data_ptr[28] = signature.cs_release;
370 /* msg_ptr->tel.tel_data_ptr[29] = signature.uid_persistency;
371 msg_ptr->tel.tel_data_ptr[30] = MISC_HB((signature.uid) >>16U);
372 msg_ptr->tel.tel_data_ptr[31] = MISC_LB((signature.uid) >>16U);
373 msg_ptr->tel.tel_data_ptr[32] = MISC_HB(signature.uid);
374 msg_ptr->tel.tel_data_ptr[33] = MISC_LB(signature.uid);
377 msg_ptr->info_ptr = &self->ssubs.welcome;
378 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
380 (void)Ssub_AddObserver(&self->ssubs.welcome, obs_ptr);
384 result = UCS_RET_ERR_BUFFER_OVERFLOW;
391 /*! \brief This method sends the Signature.Get message
392 * \param self Reference to CExc instance
393 * \param target_address Target address
394 * \param version_limit Signature version limit
395 * \param obs_ptr Reference to an optional observer
396 * \return UCS_RET_SUCCESS message was created
397 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
399 Ucs_Return_t Exc_Signature_Get(CExc *self,
400 uint16_t target_address,
401 uint8_t version_limit,
402 CSingleObserver *obs_ptr)
404 Ucs_Return_t result = UCS_RET_SUCCESS;
406 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
410 if (version_limit > UCS_EXC_SIGNATURE_VERSION_LIMIT)
412 version_limit = UCS_EXC_SIGNATURE_VERSION_LIMIT;
415 msg_ptr->destination_addr = target_address;
417 msg_ptr->id.fblock_id = FB_EXC;
418 msg_ptr->id.instance_id = 0U;
419 msg_ptr->id.function_id = EXC_FID_SIGNATURE;
420 msg_ptr->id.op_type = UCS_OP_GET;
421 msg_ptr->tel.tel_data_ptr[0] = version_limit;
423 msg_ptr->info_ptr = &self->ssubs.signature;
424 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
426 (void)Ssub_AddObserver(&self->ssubs.signature, obs_ptr);
430 result = UCS_RET_ERR_BUFFER_OVERFLOW;
437 /*! \brief This method sends the DeviceInit.Start message
438 * \param self Reference to CExc instance
439 * \param target_address Target address
440 * \param obs_ptr Reference to an optional observer
441 * \return UCS_RET_SUCCESS message was created
442 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
444 Ucs_Return_t Exc_DeviceInit_Start(CExc *self,
445 uint16_t target_address,
446 CSingleObserver *obs_ptr)
448 Ucs_Return_t result = UCS_RET_SUCCESS;
450 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
454 msg_ptr->destination_addr = target_address;
456 msg_ptr->id.fblock_id = FB_EXC;
457 msg_ptr->id.instance_id = 0U;
458 msg_ptr->id.function_id = EXC_FID_DEVICE_INIT;
459 msg_ptr->id.op_type = UCS_OP_START;
461 msg_ptr->info_ptr = &self->ssubs.deviceinit;
462 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
464 (void)Ssub_AddObserver(&self->ssubs.deviceinit, obs_ptr);
468 result = UCS_RET_ERR_BUFFER_OVERFLOW;
475 /*! \brief This method enables a port
476 * \param self Reference to CExc instance
477 * \param target_address Target address
478 * \param port_number PortNumber
479 * \param enabled Enabled
480 * \param obs_ptr Reference to an optional observer
481 * \return UCS_RET_SUCCESS message was created
482 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
484 Ucs_Return_t Exc_EnablePort_Sr(CExc *self,
485 uint16_t target_address,
488 CSingleObserver *obs_ptr)
490 Ucs_Return_t result = UCS_RET_SUCCESS;
492 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 2U);
496 msg_ptr->destination_addr = target_address;
498 msg_ptr->id.fblock_id = FB_EXC;
499 msg_ptr->id.instance_id = 0U;
500 msg_ptr->id.function_id = EXC_FID_ENABLEPORT;
501 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
502 msg_ptr->tel.tel_data_ptr[0] = port_number;
503 msg_ptr->tel.tel_data_ptr[1] = (uint8_t)enabled;
505 msg_ptr->info_ptr = &self->ssubs.enableport;
506 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
508 (void)Ssub_AddObserver(&self->ssubs.enableport, obs_ptr);
512 result = UCS_RET_ERR_BUFFER_OVERFLOW;
518 /*! \brief This method starts the Cable Link Diagnosis
519 * \param self Reference to CExc instance
520 * \param target_address Target address
521 * \param port_number PortNumber
522 * \param obs_ptr Reference to an optional observer
523 * \return UCS_RET_SUCCESS message was created
524 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
526 Ucs_Return_t Exc_CableLinkDiagnosis_Start(CExc *self,
527 uint16_t target_address,
529 CSingleObserver *obs_ptr)
531 Ucs_Return_t result = UCS_RET_SUCCESS;
533 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
537 msg_ptr->destination_addr = target_address;
539 msg_ptr->id.fblock_id = FB_EXC;
540 msg_ptr->id.instance_id = 0U;
541 msg_ptr->id.function_id = EXC_FID_CABLE_LINK_DIAG;
542 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
543 msg_ptr->tel.tel_data_ptr[0] = port_number;
545 msg_ptr->info_ptr = &self->ssubs.cablelinkdiag;
546 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
548 (void)Ssub_AddObserver(&self->ssubs.cablelinkdiag, obs_ptr);
552 result = UCS_RET_ERR_BUFFER_OVERFLOW;
558 /*! \brief This method starts the Physical Layer Test
559 * \param self Reference to CExc instance
560 * \param port_number PortNumber
562 * \param lead_in Lead-in
563 * \param duration Duration
564 * \param lead_out Lead-out
565 * \param obs_ptr Reference to an optional observer
566 * \return UCS_RET_SUCCESS message was created
567 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
569 Ucs_Return_t Exc_PhyTest_Start(CExc *self,
571 Ucs_Diag_PhyTest_Type_t type,
575 CSingleObserver *obs_ptr)
577 Ucs_Return_t result = UCS_RET_SUCCESS;
579 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 10U);
583 msg_ptr->destination_addr = MSG_ADDR_INIC;
585 msg_ptr->id.fblock_id = FB_EXC;
586 msg_ptr->id.instance_id = 0U;
587 msg_ptr->id.function_id = EXC_FID_PHY_LAY_TEST;
588 msg_ptr->id.op_type = UCS_OP_START;
589 msg_ptr->tel.tel_data_ptr[0] = port_number;
590 msg_ptr->tel.tel_data_ptr[1] = (uint8_t)type;
591 msg_ptr->tel.tel_data_ptr[2] = MISC_HB(lead_in);
592 msg_ptr->tel.tel_data_ptr[3] = MISC_LB(lead_in);
593 msg_ptr->tel.tel_data_ptr[4] = (uint8_t)((duration) >> 24);
594 msg_ptr->tel.tel_data_ptr[5] = (uint8_t)((duration) >> 16);
595 msg_ptr->tel.tel_data_ptr[6] = (uint8_t)((duration) >> 8);
596 msg_ptr->tel.tel_data_ptr[7] = (uint8_t)(duration & (uint32_t)0xFF);
597 msg_ptr->tel.tel_data_ptr[8] = MISC_HB(lead_out);
598 msg_ptr->tel.tel_data_ptr[9] = MISC_LB(lead_out);
601 msg_ptr->info_ptr = &self->ssubs.phylaytest;
602 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
604 (void)Ssub_AddObserver(&self->ssubs.phylaytest, obs_ptr);
608 result = UCS_RET_ERR_BUFFER_OVERFLOW;
615 /*! \brief Requests the EXC.PhysicalLayerTestResult.Status message
616 * \param self Reference to CExc instance
617 * \param obs_ptr Reference to an optional observer
618 * \return UCS_RET_SUCCESS message was created
619 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
620 * \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
622 Ucs_Return_t Exc_PhyTestResult_Get(CExc *self,
623 CSingleObserver *obs_ptr)
625 Ucs_Return_t result = UCS_RET_SUCCESS;
627 if(Al_Lock(&self->lock.api, EXC_API_PHY_LAY_TEST_RESULT) != false)
629 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 0U);
633 msg_ptr->destination_addr = MSG_ADDR_INIC;
635 msg_ptr->id.fblock_id = FB_EXC;
636 msg_ptr->id.instance_id = 0U;
637 msg_ptr->id.function_id = EXC_FID_PHY_LAY_TEST_RES;
638 msg_ptr->id.op_type = UCS_OP_GET;
640 msg_ptr->info_ptr = &self->ssubs.phylaytestresult;
641 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
643 (void)Ssub_AddObserver(&self->ssubs.phylaytestresult, obs_ptr);
647 Al_Release(&self->lock.api, EXC_API_PHY_LAY_TEST_RESULT);
648 result = UCS_RET_ERR_BUFFER_OVERFLOW;
653 result = UCS_RET_ERR_API_LOCKED;
661 /*! Sends the BCDiag.Startresult command
663 * \param *self Reference to CExc instance
664 * \param position Position of the segment to be checked.
665 * \param admin_na Admin Node Address
666 * \param t_send Timing parameter t_Send
667 * \param t_wait4dut Timing parameter t_WaitForDUT
668 * \param t_switch Timing parameter t_Switch
669 * \param t_back Timing parameter t_Back
670 * \param autoback TBD
671 * \param *obs_ptr Reference to an optional observer
672 * \return UCS_RET_SUCCESS message was created
673 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
675 Ucs_Return_t Exc_BCDiag_Start(CExc *self,
683 CSingleObserver *obs_ptr)
685 Ucs_Return_t result = UCS_RET_SUCCESS;
687 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 12U);
691 msg_ptr->destination_addr = UCS_ADDR_BROADCAST_BLOCKING;
692 msg_ptr->id.fblock_id = FB_EXC;
693 msg_ptr->id.instance_id = 0U;
694 msg_ptr->id.function_id = EXC_FID_BC_DIAG;
695 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
696 msg_ptr->tel.tel_data_ptr[0] = position;
697 msg_ptr->tel.tel_data_ptr[1] = MISC_HB(admin_na);
698 msg_ptr->tel.tel_data_ptr[2] = MISC_LB(admin_na);
699 msg_ptr->tel.tel_data_ptr[3] = MISC_HB(t_send);
700 msg_ptr->tel.tel_data_ptr[4] = MISC_LB(t_send);
701 msg_ptr->tel.tel_data_ptr[5] = MISC_HB(t_wait4dut);
702 msg_ptr->tel.tel_data_ptr[6] = MISC_LB(t_wait4dut);
703 msg_ptr->tel.tel_data_ptr[7] = MISC_HB(t_switch);
704 msg_ptr->tel.tel_data_ptr[8] = MISC_LB(t_switch);
705 msg_ptr->tel.tel_data_ptr[9] = MISC_HB(t_back);
706 msg_ptr->tel.tel_data_ptr[10] = MISC_LB(t_back);
707 msg_ptr->tel.tel_data_ptr[11] = (uint8_t)autoback;
710 msg_ptr->info_ptr = &self->ssubs.bcdiag;
711 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
713 (void)Ssub_AddObserver(&self->ssubs.bcdiag, obs_ptr);
717 result = UCS_RET_ERR_BUFFER_OVERFLOW;
724 /*! Enables the signal during backChannel Diagnosis
726 * \param *self Reference to CExc instance
727 * \param port Number of port which has to be enabled.
728 * \param *obs_ptr Reference to an optional observer
729 * \return UCS_RET_SUCCESS message was created
730 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
732 Ucs_Return_t Exc_BCEnableTx_StartResult(CExc *self,
734 CSingleObserver *obs_ptr)
736 Ucs_Return_t result = UCS_RET_SUCCESS;
738 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
742 msg_ptr->destination_addr = UCS_ADDR_BROADCAST_BLOCKING;
743 msg_ptr->id.fblock_id = FB_EXC;
744 msg_ptr->id.instance_id = 0U;
745 msg_ptr->id.function_id = EXC_FID_BC_ENABLE_TX;
746 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
747 msg_ptr->tel.tel_data_ptr[0] = port;
749 msg_ptr->info_ptr = &self->ssubs.enabletx;
750 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
752 (void)Ssub_AddObserver(&self->ssubs.enabletx, obs_ptr);
756 result = UCS_RET_ERR_BUFFER_OVERFLOW;
763 /*! \brief This function is used to open a memory session.
765 * A memory session is used to control access to the memory resources. Before a memory could
766 * be read or written, a session of the appropriate type has to be opened.
767 * Only a single memory session is supported. Once opened, the session must be first
768 * closed before a new session of a different type could be used. Some session types
769 * (0x01, 0x02 and 0x04) require a hardware reset after they were closed.
770 * Function Exc_MemSessionOpen_Sr() also performs some preprocessing,
771 * depending on the session_type. This includes clearing of the configuration
772 * and identification strings before the error memory is programmed or erased.
774 * \param *self Reference to CExc instance
775 * \param target_address Target address
776 * \param session_type Defines the set of MemIDs and the memory access type(s) (read and/or write)
777 * \param *obs_ptr Reference to an optional observer
779 * \return UCS_RET_SUCCESS message was created and sent to INIC
780 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
781 * \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
783 Ucs_Return_t Exc_MemSessionOpen_Sr(CExc *self,
784 uint16_t target_address,
785 uint8_t session_type,
786 CSingleObserver *obs_ptr)
788 Ucs_Return_t result = UCS_RET_SUCCESS;
790 if(Al_Lock(&self->lock.api, EXC_API_MEM_SESSION_OPEN) != false)
792 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 1U);
796 msg_ptr->destination_addr = target_address;
798 msg_ptr->id.fblock_id = FB_EXC;
799 msg_ptr->id.instance_id = 0U;
800 msg_ptr->id.function_id = EXC_FID_MEM_SESSION_OPEN;
801 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
802 msg_ptr->tel.tel_data_ptr[0] = session_type;
804 msg_ptr->info_ptr = &self->ssubs.memsessionopen;
805 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
807 (void)Ssub_AddObserver(&self->ssubs.memsessionopen, obs_ptr);
811 Al_Release(&self->lock.api, EXC_API_MEM_SESSION_OPEN);
812 result = UCS_RET_ERR_BUFFER_OVERFLOW;
817 result = UCS_RET_ERR_API_LOCKED;
824 /*! \brief This function is used to close an active memory session that was previously opened by
825 * function Exc_MemSessionOpen_Sr().
827 * In addition, the function performs some post-processing on given session types. This includes
828 * validation of the newly programmed configuration and identification strings as well as
829 * the deactivation of the current configuration and identification strings. In these cases,
830 * the new configuration becomes active after a hardware reset.
832 * \param *self Reference to CExc instance
833 * \param target_address Target address
834 * \param session_handle Unique number assigned to the active memory session
835 * \param *obs_ptr Reference to an optional observer
837 * \return UCS_RET_SUCCESS message was created and sent to INIC
838 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
839 * \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
841 Ucs_Return_t Exc_MemSessionClose_Sr(CExc *self,
842 uint16_t target_address,
843 uint16_t session_handle,
844 CSingleObserver *obs_ptr)
846 Ucs_Return_t result = UCS_RET_SUCCESS;
848 if(Al_Lock(&self->lock.api, EXC_API_MEM_SESSION_CLOSE) != false)
850 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 2U);
854 msg_ptr->destination_addr = target_address;
856 msg_ptr->id.fblock_id = FB_EXC;
857 msg_ptr->id.instance_id = 0U;
858 msg_ptr->id.function_id = EXC_FID_MEM_SESSION_CLOSE;
859 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
860 msg_ptr->tel.tel_data_ptr[0] = MISC_HB(session_handle);
861 msg_ptr->tel.tel_data_ptr[1] = MISC_LB(session_handle);
863 msg_ptr->info_ptr = &self->ssubs.memsessionclose;
864 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
866 (void)Ssub_AddObserver(&self->ssubs.memsessionclose, obs_ptr);
870 Al_Release(&self->lock.api, EXC_API_MEM_SESSION_CLOSE);
871 result = UCS_RET_ERR_BUFFER_OVERFLOW;
876 result = UCS_RET_ERR_API_LOCKED;
883 /*! \brief This function provides read access to the memories described by parameter MemID.
885 * In addition, the function can be used to retrieve the active Configuration String and
886 * Identification String.
887 * Reading the memory can only be done within an active memory session. Parameter
888 * session_handle authorizes the access to the memory resource defined by parameter
889 * MemID. The session_handle is provided by function Exc_MemSessionOpen_Sr(),
890 * which must be called in advance to memory access.
892 * \param *self Reference to CExc instance
893 * \param target_address Target address
894 * \param session_handle Unique number assigned to the active memory session
895 * \param mem_id Represents the memory resource to be read
896 * \param address Defines the memory location at which the reading operation starts
897 * \param unit_len Sets the number of memory units to be read. Memory units can be
898 * unsigned bytes, unsigned words or unsigned masked data depending
899 * on the memory type.
900 * \param *obs_ptr Reference to an optional observer
902 * \return UCS_RET_SUCCESS message was created and sent to INIC
903 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
904 * \return UCS_RET_ERR_PARAM parameter ubit_len ist too big
905 * \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
907 Ucs_Return_t Exc_MemoryRead_Sr(CExc *self,
908 uint16_t target_address,
909 uint16_t session_handle,
913 CSingleObserver *obs_ptr)
915 Ucs_Return_t result = UCS_RET_SUCCESS;
917 if(Al_Lock(&self->lock.api, EXC_API_MEM_READ) != false)
919 if (unit_len > MAX_UNIT_LEN)
921 result = UCS_RET_ERR_PARAM;
924 if (result == UCS_RET_SUCCESS)
926 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 8U);
930 msg_ptr->destination_addr = target_address;
931 msg_ptr->id.fblock_id = FB_EXC;
932 msg_ptr->id.instance_id = 0U;
933 msg_ptr->id.function_id = EXC_FID_MEMORY_READ;
934 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
935 msg_ptr->tel.tel_data_ptr[0] = MISC_HB(session_handle);
936 msg_ptr->tel.tel_data_ptr[1] = MISC_LB(session_handle);
937 msg_ptr->tel.tel_data_ptr[2] = mem_id;
938 msg_ptr->tel.tel_data_ptr[3] = (uint8_t)((address) >> 24);
939 msg_ptr->tel.tel_data_ptr[4] = (uint8_t)((address) >> 16);
940 msg_ptr->tel.tel_data_ptr[5] = (uint8_t)((address) >> 8);
941 msg_ptr->tel.tel_data_ptr[6] = (uint8_t)(address & (uint32_t)0xFF);
942 msg_ptr->tel.tel_data_ptr[7] = unit_len;
944 msg_ptr->info_ptr = &self->ssubs.memoryread;
945 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
947 (void)Ssub_AddObserver(&self->ssubs.memoryread, obs_ptr);
951 Al_Release(&self->lock.api, EXC_API_MEM_READ);
952 result = UCS_RET_ERR_BUFFER_OVERFLOW;
958 result = UCS_RET_ERR_API_LOCKED;
965 /*! \brief This function provides write access to the memories described by parameter MemID.
967 * In addition, the function can be used to program a new Configuration String and Identification
969 * Writing the memory can only be done within an active memory session. Parameter
970 * SessionHandle authorizes the access to the memory resource defined by parameter
971 * MemID. The SessionHandle is provided by function ExtendedNetworkControl.MemorySessionOpen(),
972 * which must be called in advance to memory access.
974 * \param *self Reference to CExc instance
975 * \param target_address Target address
976 * \param session_handle Unique number assigned to the active memory session
977 * \param mem_id Represents the memory resource to be read
978 * \param address Defines the memory location at which the reading operation starts
979 * \param unit_len Sets the number of memory units to be read. Memory units can be
980 * unsigned bytes, unsigned words or unsigned masked data depending
981 * on the memory type.
982 * \param *unit_data Contains the actual data written to the memory resource and formatted
984 * \param *obs_ptr Reference to an optional observer
986 * \return UCS_RET_SUCCESS message was created and sent to INIC
987 * \return UCS_RET_ERR_BUFFER_OVERFLOW no message buffer available
988 * \return UCS_RET_ERR_PARAM parameter ubit_len ist too big
989 * \return UCS_RET_ERR_API_LOCKED Resource API is already used by another command
991 Ucs_Return_t Exc_MemoryWrite_Sr(CExc *self,
992 uint16_t target_address,
993 uint16_t session_handle,
998 CSingleObserver *obs_ptr)
1000 Ucs_Return_t result = UCS_RET_SUCCESS;
1002 if(Al_Lock(&self->lock.api, EXC_API_MEM_WRITE) != false)
1004 if (unit_len > MAX_UNIT_LEN)
1006 result = UCS_RET_ERR_PARAM;
1009 if (result == UCS_RET_SUCCESS)
1011 Msg_MostTel_t *msg_ptr = Trcv_TxAllocateMsg(self->xcvr_ptr, 8U + unit_len);
1013 if (msg_ptr != NULL)
1017 msg_ptr->destination_addr = target_address;
1018 msg_ptr->id.fblock_id = FB_EXC;
1019 msg_ptr->id.instance_id = 0U;
1020 msg_ptr->id.function_id = EXC_FID_MEMORY_WRITE;
1021 msg_ptr->id.op_type = UCS_OP_STARTRESULT;
1022 msg_ptr->tel.tel_data_ptr[0] = MISC_HB(session_handle);
1023 msg_ptr->tel.tel_data_ptr[1] = MISC_LB(session_handle);
1024 msg_ptr->tel.tel_data_ptr[2] = mem_id;
1025 msg_ptr->tel.tel_data_ptr[3] = (uint8_t)((address) >> 24);
1026 msg_ptr->tel.tel_data_ptr[4] = (uint8_t)((address) >> 16);
1027 msg_ptr->tel.tel_data_ptr[5] = (uint8_t)((address) >> 8);
1028 msg_ptr->tel.tel_data_ptr[6] = (uint8_t)(address & (uint32_t)0xFF);
1029 msg_ptr->tel.tel_data_ptr[7] = unit_len;
1030 for (i=0U; i<unit_len; ++i)
1032 msg_ptr->tel.tel_data_ptr[8U+i] = *(unit_data + i);
1035 msg_ptr->info_ptr = &self->ssubs.memorywrite;
1036 Trcv_TxSendMsg(self->xcvr_ptr, msg_ptr);
1038 (void)Ssub_AddObserver(&self->ssubs.memorywrite, obs_ptr);
1042 Al_Release(&self->lock.api, EXC_API_MEM_WRITE);
1043 result = UCS_RET_ERR_BUFFER_OVERFLOW;
1049 result = UCS_RET_ERR_API_LOCKED;
1057 /*------------------------------------------------------------------------------------------------*/
1058 /* Handler functions */
1059 /*------------------------------------------------------------------------------------------------*/
1060 /*! \brief Handler function for EXC.Hello.Status
1061 * \param self Reference to EXC object
1062 * \param msg_ptr Received message
1064 static void Exc_Hello_Status(void *self, Msg_MostTel_t *msg_ptr)
1066 CExc *self_ = (CExc *)self;
1067 Exc_HelloStatus_t hello_data;
1068 Exc_StdResult_t res_data;
1070 if (msg_ptr->tel.tel_len >= (EXC_SIGNATURE_LEN_V1 + 1U))
1072 hello_data.version = msg_ptr->tel.tel_data_ptr[0];
1073 Exc_Read_Signature(&(hello_data.signature), &(msg_ptr->tel.tel_data_ptr[1]));
1075 res_data.data_info = &hello_data;
1076 res_data.result.code = UCS_RES_SUCCESS;
1077 res_data.result.info_ptr = NULL;
1078 res_data.result.info_size = 0U;
1080 /* Node Discovery sends the Hello.Get as broadcast message. So we will need the observer
1082 Ssub_Notify(&self_->ssubs.hello, &res_data, false);
1087 /*! \brief Handler function for EXC.Hello.Error
1088 * \param self reference to EXC object
1089 * \param msg_ptr received message
1091 static void Exc_Hello_Error(void *self, Msg_MostTel_t *msg_ptr)
1093 CExc *self_ = (CExc *)self;
1094 Exc_StdResult_t res_data;
1096 if (msg_ptr->tel.tel_len > 0U)
1098 res_data.data_info = NULL;
1099 res_data.result = Exc_TranslateError(self_,
1100 &msg_ptr->tel.tel_data_ptr[0],
1101 (uint8_t)(msg_ptr->tel.tel_len));
1103 /* Node Discovery sends the Hello.Get as broadcast message. So we will need the observer
1105 Ssub_Notify(&self_->ssubs.hello, &res_data, false);
1110 /*! \brief Handler function for EXC.Welcome.Error
1111 * \param self reference to EXC object
1112 * \param msg_ptr received message
1114 static void Exc_Welcome_Error(void *self, Msg_MostTel_t *msg_ptr)
1116 CExc *self_ = (CExc *)self;
1117 Exc_StdResult_t res_data;
1119 if (msg_ptr->tel.tel_len > 0U)
1121 res_data.data_info = NULL;
1122 res_data.result = Exc_TranslateError(self_,
1123 &msg_ptr->tel.tel_data_ptr[0],
1124 (uint8_t)(msg_ptr->tel.tel_len));
1126 Ssub_Notify(&self_->ssubs.welcome, &res_data, true);
1130 /*! \brief Handler function for the EXC.Welcome.Result message
1131 * \param self reference to EXC object
1132 * \param msg_ptr received message
1134 static void Exc_Welcome_Result(void *self, Msg_MostTel_t *msg_ptr)
1136 CExc *self_ = (CExc *)self;
1137 Exc_WelcomeResult_t welcome_data;
1138 Exc_StdResult_t res_data;
1140 if (msg_ptr->tel.tel_len >= (EXC_SIGNATURE_LEN_V1 + 2U))
1142 welcome_data.res = msg_ptr->tel.tel_data_ptr[0];
1143 welcome_data.version = msg_ptr->tel.tel_data_ptr[1];
1144 Exc_Read_Signature(&(welcome_data.signature), &(msg_ptr->tel.tel_data_ptr[2]));
1145 res_data.data_info = &welcome_data;
1146 res_data.result.code = UCS_RES_SUCCESS;
1147 res_data.result.info_ptr = NULL;
1149 Ssub_Notify(&self_->ssubs.welcome, &res_data, true);
1154 /*! Handler function for the EXC.Signature.Status message
1155 * \param self reference to EXC object
1156 * \param msg_ptr received message
1158 static void Exc_Signature_Status(void *self, Msg_MostTel_t *msg_ptr)
1160 CExc *self_ = (CExc *)self;
1161 Exc_SignatureStatus_t signature_data;
1162 Exc_StdResult_t res_data;
1164 if (msg_ptr->tel.tel_len >= (EXC_SIGNATURE_LEN_V1 + 1U))
1166 signature_data.version = msg_ptr->tel.tel_data_ptr[0];
1167 Exc_Read_Signature(&(signature_data.signature), &(msg_ptr->tel.tel_data_ptr[1]));
1169 res_data.data_info = &signature_data;
1170 res_data.result.code = UCS_RES_SUCCESS;
1171 res_data.result.info_ptr = NULL;
1172 res_data.result.info_size = 0U;
1174 Ssub_Notify(&self_->ssubs.signature, &res_data, true);
1179 /*! Handler function for the EXC.Signature.Error message
1180 * \param self reference to EXC object
1181 * \param msg_ptr received message
1183 static void Exc_Signature_Error(void *self, Msg_MostTel_t *msg_ptr)
1185 CExc *self_ = (CExc *)self;
1186 Exc_StdResult_t res_data;
1188 if (msg_ptr->tel.tel_len > 0U)
1190 res_data.data_info = NULL;
1191 res_data.result = Exc_TranslateError(self_,
1192 &msg_ptr->tel.tel_data_ptr[0],
1193 (uint8_t)(msg_ptr->tel.tel_len));
1195 Ssub_Notify(&self_->ssubs.signature, &res_data, true);
1200 /*! Handler function for the EXC.DeviceInit.Error message
1201 * \param self reference to EXC object
1202 * \param msg_ptr received message
1204 static void Exc_DeviceInit_Error(void *self, Msg_MostTel_t *msg_ptr)
1206 CExc *self_ = (CExc *)self;
1207 Exc_StdResult_t res_data;
1209 if (msg_ptr->tel.tel_len >0U)
1211 res_data.data_info = NULL;
1212 res_data.result = Exc_TranslateError(self_,
1213 &msg_ptr->tel.tel_data_ptr[0],
1214 (uint8_t)(msg_ptr->tel.tel_len));
1216 Ssub_Notify(&self_->ssubs.deviceinit, &res_data, true);
1221 /*! \brief Handler function for EXC.EnablePort.Error
1222 * \param self reference to EXC object
1223 * \param msg_ptr received message
1225 static void Exc_EnablePort_Error(void *self, Msg_MostTel_t *msg_ptr)
1227 CExc *self_ = (CExc *)self;
1228 Exc_StdResult_t res_data;
1230 if (msg_ptr->tel.tel_len > 0U)
1232 res_data.result = Exc_TranslateError(self_,
1233 &msg_ptr->tel.tel_data_ptr[0],
1234 (uint8_t)(msg_ptr->tel.tel_len));
1236 Ssub_Notify(&self_->ssubs.enableport, &res_data, true);
1240 /*! \brief Handler function for EXC.EnablePort.Result
1241 * \param self reference to EXC object
1242 * \param msg_ptr received message
1244 static void Exc_EnablePort_Result(void *self, Msg_MostTel_t *msg_ptr)
1246 CExc *self_ = (CExc *)self;
1247 Exc_StdResult_t res_data;
1249 MISC_UNUSED(msg_ptr);
1251 res_data.result.code = UCS_RES_SUCCESS;
1252 res_data.result.info_ptr = NULL;
1253 Ssub_Notify(&self_->ssubs.enableport, &res_data, true);
1257 /*! \brief Handler function for EXC.CableLinkDiag.Error
1258 * \param self reference to EXC object
1259 * \param msg_ptr received message
1261 static void Exc_CableLinkDiag_Error(void *self, Msg_MostTel_t *msg_ptr)
1263 CExc *self_ = (CExc *)self;
1264 Exc_StdResult_t res_data;
1266 if (msg_ptr->tel.tel_len > 0U)
1268 res_data.data_info = NULL;
1269 res_data.result = Exc_TranslateError(self_,
1270 &msg_ptr->tel.tel_data_ptr[0],
1271 (uint8_t)(msg_ptr->tel.tel_len));
1273 Ssub_Notify(&self_->ssubs.cablelinkdiag, &res_data, true);
1277 /*! \brief Handler function for EXC.CableLinkDiag.Result
1278 * \param self reference to EXC object
1279 * \param msg_ptr received message
1281 static void Exc_CableLinkDiag_Result(void *self, Msg_MostTel_t *msg_ptr)
1283 CExc *self_ = (CExc *)self;
1284 Exc_CableLinkDiagResult_t cable_link_diag_result_data;
1285 Exc_StdResult_t res_data;
1287 if (msg_ptr->tel.tel_len > 0U)
1289 cable_link_diag_result_data.port_number = msg_ptr->tel.tel_data_ptr[0];
1290 cable_link_diag_result_data.result = msg_ptr->tel.tel_data_ptr[1];
1291 res_data.data_info = &cable_link_diag_result_data;
1292 res_data.result.code = UCS_RES_SUCCESS;
1293 res_data.result.info_ptr = NULL;
1295 Ssub_Notify(&self_->ssubs.cablelinkdiag, &res_data, true);
1300 /*! \brief Handler function for EXC.PhysicalLayerTest.Error
1301 * \param self reference to EXC object
1302 * \param msg_ptr received message
1303 */static void Exc_NwPhyTest_Error(void *self, Msg_MostTel_t *msg_ptr)
1305 CExc *self_ = (CExc *)self;
1306 Exc_StdResult_t res_data;
1308 if (msg_ptr->tel.tel_len > 0U)
1310 res_data.data_info = NULL;
1311 res_data.result = Exc_TranslateError(self_,
1312 &msg_ptr->tel.tel_data_ptr[0],
1313 (uint8_t)(msg_ptr->tel.tel_len));
1315 Ssub_Notify(&self_->ssubs.phylaytest, &res_data, true);
1320 /*! \brief Handler function for EXC.MOSTNetworkPhysicalLayerTestResult.Status
1321 * \param self Reference to EXC object
1322 * \param msg_ptr Received message
1324 static void Exc_NwPhyTestResult_Status(void *self, Msg_MostTel_t *msg_ptr)
1326 CExc *self_ = (CExc *)self;
1327 Exc_PhyTestResult_t phy_test_result;
1328 Exc_StdResult_t res_data;
1330 if (msg_ptr->tel.tel_len > 0U)
1332 phy_test_result.port_number = msg_ptr->tel.tel_data_ptr[0];
1333 phy_test_result.lock_status = (msg_ptr->tel.tel_data_ptr[1] != 0U) ? true : false;
1334 MISC_DECODE_WORD(&(phy_test_result.err_count), &(msg_ptr->tel.tel_data_ptr[2]));
1335 res_data.data_info = &phy_test_result;
1336 res_data.result.code = UCS_RES_SUCCESS;
1337 res_data.result.info_ptr = NULL;
1339 Ssub_Notify(&self_->ssubs.phylaytestresult, &res_data, true);
1341 Al_Release(&self_->lock.api, EXC_API_PHY_LAY_TEST_RESULT);
1345 /*! \brief Handler function for EXC.MOSTNetworkPhysicalLayerTestResult.Error
1346 * \param self reference to EXC object
1347 * \param msg_ptr received message
1349 static void Exc_NwPhyTestResult_Error(void *self, Msg_MostTel_t *msg_ptr)
1351 CExc *self_ = (CExc *)self;
1352 Exc_StdResult_t res_data;
1354 if (msg_ptr->tel.tel_len > 0U)
1356 res_data.data_info = NULL;
1357 res_data.result = Exc_TranslateError(self_,
1358 &msg_ptr->tel.tel_data_ptr[0],
1359 (uint8_t)(msg_ptr->tel.tel_len));
1361 Ssub_Notify(&self_->ssubs.phylaytestresult, &res_data, true);
1363 Al_Release(&self_->lock.api, EXC_API_PHY_LAY_TEST_RESULT);
1368 /*! \brief Handler function for EXC.BCDiag.Status
1369 * \param self Reference to EXC object
1370 * \param msg_ptr Received message
1372 static void Exc_BC_Diag_Result(void *self, Msg_MostTel_t *msg_ptr)
1374 CExc *self_ = (CExc *)self;
1375 Exc_BCDiagResult bcd_result;
1376 Exc_StdResult_t res_data;
1378 if (msg_ptr->tel.tel_len > 1U)
1380 bcd_result.diag_result = (Exc_BCDiagResValue)(msg_ptr->tel.tel_data_ptr[0] >> 4U);
1381 MISC_DECODE_WORD(&(bcd_result.admin_addr), &(msg_ptr->tel.tel_data_ptr[0]));
1382 bcd_result.admin_addr &= 0x0FFFU;
1383 res_data.data_info = &bcd_result;
1384 res_data.result.code = UCS_RES_SUCCESS;
1385 res_data.result.info_ptr = NULL;
1387 Ssub_Notify(&self_->ssubs.bcdiag, &res_data, true);
1392 /*! \brief Handler function for EXC.BCDiag.Error
1393 * \param self reference to EXC object
1394 * \param msg_ptr received message
1396 static void Exc_BC_Diag_Error(void *self, Msg_MostTel_t *msg_ptr)
1398 CExc *self_ = (CExc *)self;
1399 Exc_StdResult_t res_data;
1401 if (msg_ptr->tel.tel_len > 0U)
1403 res_data.data_info = NULL;
1404 res_data.result = Exc_TranslateError(self_,
1405 &msg_ptr->tel.tel_data_ptr[0],
1406 (uint8_t)(msg_ptr->tel.tel_len));
1408 Ssub_Notify(&self_->ssubs.bcdiag, &res_data, true);
1415 /*! \brief Handler function for EXC.BCEnableTx.Result
1416 * \param self Reference to EXC object
1417 * \param msg_ptr Received message
1419 static void Exc_BC_EnableTx_Result(void *self, Msg_MostTel_t *msg_ptr)
1421 CExc *self_ = (CExc *)self;
1422 Exc_StdResult_t res_data;
1424 res_data.data_info = NULL;
1425 res_data.result.code = UCS_RES_SUCCESS;
1426 res_data.result.info_ptr = NULL;
1428 Ssub_Notify(&self_->ssubs.enabletx, &res_data, true);
1430 MISC_UNUSED(msg_ptr);
1434 /*! \brief Handler function for EXC.BCEnableTx.Error
1435 * \param self reference to EXC object
1436 * \param msg_ptr received message
1438 static void Exc_BC_EnableTx_Error(void *self, Msg_MostTel_t *msg_ptr)
1440 CExc *self_ = (CExc *)self;
1441 Exc_StdResult_t res_data;
1443 if (msg_ptr->tel.tel_len > 0U)
1445 res_data.data_info = NULL;
1446 res_data.result = Exc_TranslateError(self_,
1447 &msg_ptr->tel.tel_data_ptr[0],
1448 (uint8_t)(msg_ptr->tel.tel_len));
1450 Ssub_Notify(&self_->ssubs.enabletx, &res_data, true);
1455 /*! \brief Handler function for EXC.MemorySessionOpen.Result
1456 * \param self reference to EXC object
1457 * \param msg_ptr received message
1459 static void Exc_MemSessionOpen_Result(void *self, Msg_MostTel_t *msg_ptr)
1461 CExc *self_ = (CExc *)self;
1462 uint16_t session_handle;
1463 Exc_StdResult_t res_data;
1465 if (msg_ptr->tel.tel_len > 0U)
1467 MISC_DECODE_WORD(&(session_handle), &(msg_ptr->tel.tel_data_ptr[0]));
1468 res_data.data_info = &session_handle;
1469 res_data.result.code = UCS_RES_SUCCESS;
1470 res_data.result.info_ptr = NULL;
1472 Ssub_Notify(&self_->ssubs.memsessionopen, &res_data, true);
1474 Al_Release(&self_->lock.api, EXC_API_MEM_SESSION_OPEN);
1478 /*! \brief Handler function for EXC.MemorySessionOpen.Error
1479 * \param self reference to EXC object
1480 * \param msg_ptr received message
1482 static void Exc_MemSessionOpen_Error(void *self, Msg_MostTel_t *msg_ptr)
1484 CExc *self_ = (CExc *)self;
1485 Exc_StdResult_t res_data;
1487 if (msg_ptr->tel.tel_len > 0U)
1489 res_data.data_info = NULL;
1490 res_data.result = Exc_TranslateError(self_,
1491 &msg_ptr->tel.tel_data_ptr[0],
1492 (uint8_t)(msg_ptr->tel.tel_len));
1494 Ssub_Notify(&self_->ssubs.memsessionopen, &res_data, true);
1496 Al_Release(&self_->lock.api, EXC_API_MEM_SESSION_OPEN);
1500 /*! \brief Handler function for EXC.MemorySessionClose.Result
1501 * \param self reference to EXC object
1502 * \param msg_ptr received message
1504 static void Exc_MemSessionClose_Result(void *self, Msg_MostTel_t *msg_ptr)
1506 CExc *self_ = (CExc *)self;
1507 uint8_t session_result;
1508 Exc_StdResult_t res_data;
1510 if (msg_ptr->tel.tel_len > 0U)
1512 session_result = msg_ptr->tel.tel_data_ptr[0];
1513 res_data.data_info = &session_result;
1514 res_data.result.code = UCS_RES_SUCCESS;
1515 res_data.result.info_ptr = NULL;
1517 Ssub_Notify(&self_->ssubs.memsessionclose, &res_data, true);
1519 Al_Release(&self_->lock.api, EXC_API_MEM_SESSION_CLOSE);
1522 /*! \brief Handler function for EXC.MemorySessionClose.Error
1523 * \param self reference to EXC object
1524 * \param msg_ptr received message
1526 static void Exc_MemSessionClose_Error(void *self, Msg_MostTel_t *msg_ptr)
1528 CExc *self_ = (CExc *)self;
1529 Exc_StdResult_t res_data;
1531 if (msg_ptr->tel.tel_len > 0U)
1533 res_data.data_info = NULL;
1534 res_data.result = Exc_TranslateError(self_,
1535 &msg_ptr->tel.tel_data_ptr[0],
1536 (uint8_t)(msg_ptr->tel.tel_len));
1538 Ssub_Notify(&self_->ssubs.memsessionclose, &res_data, true);
1540 Al_Release(&self_->lock.api, EXC_API_MEM_SESSION_CLOSE);
1543 /*! \brief Handler function for EXC.MemoryRead.Result
1544 * \param self reference to EXC object
1545 * \param msg_ptr received message
1547 static void Exc_MemoryRead_Result(void *self, Msg_MostTel_t *msg_ptr)
1549 CExc *self_ = (CExc *)self;
1550 Exc_MemReadResult_t mem_read_result;
1551 Exc_StdResult_t res_data;
1554 if (msg_ptr->tel.tel_len > 0U)
1556 MISC_DECODE_WORD(&(mem_read_result.session_handle), &(msg_ptr->tel.tel_data_ptr[0]));
1557 mem_read_result.mem_id = msg_ptr->tel.tel_data_ptr[2];
1558 MISC_DECODE_DWORD(&(mem_read_result.address), &(msg_ptr->tel.tel_data_ptr[3]));
1559 mem_read_result.unit_len = msg_ptr->tel.tel_data_ptr[7];
1560 for (i=0U; (i<mem_read_result.unit_len) && (i<MAX_UNIT_LEN); ++i)
1562 mem_read_result.unit_data[i] = msg_ptr->tel.tel_data_ptr[8U+i];
1565 res_data.data_info = &mem_read_result;
1566 res_data.result.code = UCS_RES_SUCCESS;
1567 res_data.result.info_ptr = NULL;
1569 Ssub_Notify(&self_->ssubs.memoryread, &res_data, true);
1571 Al_Release(&self_->lock.api, EXC_API_MEM_READ);
1575 /*! \brief Handler function for EXC.MemoryRead.Error
1576 * \param self reference to EXC object
1577 * \param msg_ptr received message
1579 static void Exc_MemoryRead_Error(void *self, Msg_MostTel_t *msg_ptr)
1581 CExc *self_ = (CExc *)self;
1582 Exc_StdResult_t res_data;
1584 if (msg_ptr->tel.tel_len > 0U)
1586 res_data.data_info = NULL;
1587 res_data.result = Exc_TranslateError(self_,
1588 &msg_ptr->tel.tel_data_ptr[0],
1589 (uint8_t)(msg_ptr->tel.tel_len));
1591 Ssub_Notify(&self_->ssubs.memoryread, &res_data, true);
1593 Al_Release(&self_->lock.api, EXC_API_MEM_READ);
1597 /*! \brief Handler function for EXC.MemoryWrite.Result
1598 * \param self reference to EXC object
1599 * \param msg_ptr received message
1601 static void Exc_MemoryWrite_Result(void *self, Msg_MostTel_t *msg_ptr)
1603 CExc *self_ = (CExc *)self;
1604 Exc_MemWriteResult_t mem_write_result;
1605 Exc_StdResult_t res_data;
1607 if (msg_ptr->tel.tel_len > 0U)
1609 MISC_DECODE_WORD(&(mem_write_result.session_handle), &(msg_ptr->tel.tel_data_ptr[0]));
1610 mem_write_result.mem_id = msg_ptr->tel.tel_data_ptr[2];
1612 res_data.data_info = &mem_write_result;
1613 res_data.result.code = UCS_RES_SUCCESS;
1614 res_data.result.info_ptr = NULL;
1616 Ssub_Notify(&self_->ssubs.memorywrite, &res_data, true);
1618 Al_Release(&self_->lock.api, EXC_API_MEM_WRITE);
1622 /*! \brief Handler function for EXC.MemoryWrite.Error
1623 * \param self reference to EXC object
1624 * \param msg_ptr received message
1626 static void Exc_MemoryWrite_Error(void *self, Msg_MostTel_t *msg_ptr)
1628 CExc *self_ = (CExc *)self;
1629 Exc_StdResult_t res_data;
1631 if (msg_ptr->tel.tel_len > 0U)
1633 res_data.data_info = NULL;
1634 res_data.result = Exc_TranslateError(self_,
1635 &msg_ptr->tel.tel_data_ptr[0],
1636 (uint8_t)(msg_ptr->tel.tel_len));
1638 Ssub_Notify(&self_->ssubs.memorywrite, &res_data, true);
1640 Al_Release(&self_->lock.api, EXC_API_MEM_WRITE);
1645 /*------------------------------------------------------------------------------------------------*/
1646 /* Helper functions */
1647 /*------------------------------------------------------------------------------------------------*/
1648 /*! \brief Translates EXC error codes into UNICENS error codes and wraps the raw INIC
1649 * error data to a byte stream.
1650 * \param self Instance of CExc
1651 * \param error_data[] EXC error data
1652 * \param error_size Size of EXC error data in bytes
1653 * \return The formatted error
1655 static Ucs_StdResult_t Exc_TranslateError(CExc *self, uint8_t error_data[], uint8_t error_size)
1657 Ucs_StdResult_t ret_val;
1660 if(error_data[0] != 0x20U)
1662 ret_val.code = UCS_RES_ERR_MOST_STANDARD;
1666 ret_val.code = (Ucs_Result_t)(error_data[1] + 1U);
1669 ret_val.info_ptr = &error_data[0];
1670 ret_val.info_size = error_size;
1676 /*! \brief Reads a signature from a message's payload
1678 * \param dest Pointer to signature
1679 * \param source Pointer to start of signature inabyte array
1681 static void Exc_Read_Signature(Ucs_Signature_t *dest, uint8_t source[])
1683 MISC_DECODE_WORD(&(dest->node_address), source);
1684 MISC_DECODE_WORD(&(dest->group_address), &(source[2]));
1685 MISC_DECODE_WORD(&(dest->mac_47_32), &(source[4]));
1686 MISC_DECODE_WORD(&(dest->mac_31_16), &(source[6]));
1687 MISC_DECODE_WORD(&(dest->mac_15_0), &(source[8]));
1688 MISC_DECODE_WORD(&(dest->node_pos_addr), &(source[10]));
1689 MISC_DECODE_WORD(&(dest->diagnosis_id), &(source[12]));
1690 dest->num_ports = source[14];
1691 dest->chip_id = source[15];
1692 dest->fw_major = source[16];
1693 dest->fw_minor = source[17];
1694 dest->fw_release = source[18];
1695 MISC_DECODE_DWORD(&(dest->fw_build), &(source[19]));
1696 dest->cs_major = source[23];
1697 dest->cs_minor = source[24];
1698 dest->cs_release = source[25];
1699 /* dest->uid_persistency = source[26];*/ /* Signature v1 */
1700 /* MISC_DECODE_DWORD(&(dest->uid), &(source[27]));*/
1708 /*------------------------------------------------------------------------------------------------*/
1710 /*------------------------------------------------------------------------------------------------*/