From 30e19fdfbd361e5cf7abc042481e5ee2097f135e Mon Sep 17 00:00:00 2001 From: Valentina Gaggero Date: Wed, 5 Apr 2023 14:08:12 +0000 Subject: [PATCH 01/10] Add diagnostic formatter and parsers for each diagnostic messages class. --- .../icubmod/embObjLib/CMakeLists.txt | 5 +- .../icubmod/embObjLib/FeatureInterface.cpp | 17 + .../icubmod/embObjLib/FeatureInterface.h | 2 + .../icubmod/embObjLib/IethResource.cpp | 6 + .../icubmod/embObjLib/IethResource.h | 8 + .../icubmod/embObjLib/diagnosticInfo.cpp | 76 + .../icubmod/embObjLib/diagnosticInfo.h | 52 + .../embObjLib/diagnosticInfoFormatter.cpp | 155 ++ .../embObjLib/diagnosticInfoParsers.cpp | 1330 +++++++++++++++++ .../embObjLib/diagnosticLowLevelFormatter.h | 54 + .../diagnosticLowLevelFormatter_hid.h | 199 +++ .../icubmod/embObjLib/ethManager.cpp | 7 + src/libraries/icubmod/embObjLib/ethManager.h | 2 + .../EoProtocolMN_fun_userdef.c | 8 +- .../embObjMotionControl.cpp | 16 +- .../embObjMotionControl/embObjMotionControl.h | 1 + 16 files changed, 1930 insertions(+), 8 deletions(-) create mode 100644 src/libraries/icubmod/embObjLib/diagnosticInfo.cpp create mode 100644 src/libraries/icubmod/embObjLib/diagnosticInfo.h create mode 100644 src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp create mode 100644 src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp create mode 100644 src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter.h create mode 100644 src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter_hid.h diff --git a/src/libraries/icubmod/embObjLib/CMakeLists.txt b/src/libraries/icubmod/embObjLib/CMakeLists.txt index d57cbbd78d..80e3ccf33e 100644 --- a/src/libraries/icubmod/embObjLib/CMakeLists.txt +++ b/src/libraries/icubmod/embObjLib/CMakeLists.txt @@ -44,7 +44,10 @@ set(EXTRA_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/hostTransceiver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/batteryInfo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/theNVmanager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/embObjGeneralDevPrivData.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/mcEventDownsampler.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/mcEventDownsampler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticInfoFormatter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticInfoParsers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/diagnosticInfo.cpp) set(NVS_CBK_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/protocolCallbacks/EoProtocolMN_fun_userdef.c ${CMAKE_CURRENT_SOURCE_DIR}/protocolCallbacks/EoProtocolMC_fun_userdef.c diff --git a/src/libraries/icubmod/embObjLib/FeatureInterface.cpp b/src/libraries/icubmod/embObjLib/FeatureInterface.cpp index ccccdc0c17..886cb42736 100755 --- a/src/libraries/icubmod/embObjLib/FeatureInterface.cpp +++ b/src/libraries/icubmod/embObjLib/FeatureInterface.cpp @@ -27,6 +27,8 @@ #include "EOYtheSystem.h" #include "EOYmutex.h" +#include "diagnosticLowLevelFormatter.h" + using namespace eth; @@ -339,6 +341,21 @@ void feat_PrintFatal(char *string) } +void feat_manage_diagnostic(eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd) +{ + if(NULL == _interface2ethManager) + { + yError("the diagnostic service can not start. The interface to the eth manager is not working."); + return; + } + Diagnostic::LowLevel::InfoFormatter dngFormatter(_interface2ethManager, infobasic, extra, nv, rd); + + Diagnostic::EmbeddedInfo info; + dngFormatter.getDiagnosticInfo(info); + info.printMessage(); +} + + // returns a void pointer to the allocated ACE_Recursive_Thread_Mutex void* ace_mutex_new(void) { diff --git a/src/libraries/icubmod/embObjLib/FeatureInterface.h b/src/libraries/icubmod/embObjLib/FeatureInterface.h index 647961e74f..009bc84e4f 100755 --- a/src/libraries/icubmod/embObjLib/FeatureInterface.h +++ b/src/libraries/icubmod/embObjLib/FeatureInterface.h @@ -75,6 +75,8 @@ void feat_PrintError(char *string); void feat_PrintFatal(char *string); +void feat_manage_diagnostic(eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd); + void* ace_mutex_new(void); diff --git a/src/libraries/icubmod/embObjLib/IethResource.cpp b/src/libraries/icubmod/embObjLib/IethResource.cpp index f305ccf3d7..b3d4d48d10 100644 --- a/src/libraries/icubmod/embObjLib/IethResource.cpp +++ b/src/libraries/icubmod/embObjLib/IethResource.cpp @@ -69,6 +69,12 @@ const char * IethResource::stringOfType() return names[t]; } +bool IethResource::getEntityName(uint32_t entityId, std::string &entityName) +{ + entityName.clear(); + return true; +} + // - end-of-file (leave a blank line after)---------------------------------------------------------------------------- diff --git a/src/libraries/icubmod/embObjLib/IethResource.h b/src/libraries/icubmod/embObjLib/IethResource.h index 565532669a..f4f33cdb5b 100644 --- a/src/libraries/icubmod/embObjLib/IethResource.h +++ b/src/libraries/icubmod/embObjLib/IethResource.h @@ -27,6 +27,7 @@ #include "EoProtocol.h" +#include // marco.accame on 20 oct 2014. @@ -91,6 +92,13 @@ namespace eth { public: const char * stringOfType(); + /* the entityName there will be the name of the entity, or it can be an empty string if the enity han't name + The entity could be: + - axis in case the ethResource type is iethres_motioncontrol + - sensor id in case of, skin, mais and strain + The defiult value is an empty string + return false in case of error, like entityId is not present. Aniway the entity name is initialize to empty string.*/ + virtual bool getEntityName(uint32_t entityId, std::string &entityName); private: static const char * names[iethresType_numberof+1]; diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfo.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfo.cpp new file mode 100644 index 0000000000..3e14736172 --- /dev/null +++ b/src/libraries/icubmod/embObjLib/diagnosticInfo.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + +#include +#include "diagnosticInfo.h" +#include + + +using namespace Diagnostic; + + +/**************************************************************************************************************************/ +/****************************************** TimeOfInfo ***************************************************/ +/**************************************************************************************************************************/ + +void TimeOfInfo::toString(std::string &str_toi) +{ + char str[50]; + snprintf(str, sizeof(str), "%ds %dm %du", sec, msec, usec); + str_toi.clear(); + str_toi.append(str); +} + + + +/**************************************************************************************************************************/ +/****************************************** Info ***************************************************/ +/**************************************************************************************************************************/ + +void EmbeddedInfo::printMessage() +{ + std::string str_toi; + timeOfInfo.toString(str_toi); + + std::string final_str = "from BOARD " + sourceBoardIpAddrStr + " (" + sourceBoardName +") time=" + str_toi + " : " + finalMessage; + switch(severity) + { + case SeverityOfError::info: + { + yInfo() << final_str; + } break; + + case SeverityOfError::debug: + { + yDebug() << final_str; + } break; + + case SeverityOfError::warning: + { + yWarning() << final_str; + } break; + + case SeverityOfError::error: + { + yError() << final_str; + } break; + + case SeverityOfError::fatal: + { + yError() << "EMS received the following FATAL error: " < + + +namespace Diagnostic { + enum class SeverityOfError {info=0, debug =1, warning =2, error=3, fatal=4}; //TBD + class EmbeddedInfo; + class TimeOfInfo; +} + +class Diagnostic::TimeOfInfo +{ +public: + uint32_t sec; + uint32_t msec; + uint32_t usec; + + void toString(std::string &str_toi); + +}; + + +class Diagnostic::EmbeddedInfo +{ +public: + std::string sourceBoardIpAddrStr; // is the ipv4 address, in string, of the board that sends the diagnostic information + std::string sourceBoardName; // is the name of the board that sends the diagnostic information + std::string sourceCANPortStr; // if the diagnostic info si sent by a board on CAN, this field contains the CAN port expressed in string + uint8_t sourceCANBoardAddr; // if the diagnostic info si sent by a board on CAN, this field contains the CAN address of the board + std::string finalMessage; // contains the final diagostic message after the parsering + Diagnostic::SeverityOfError severity; // is the severity of the message + Diagnostic::TimeOfInfo timeOfInfo; //it is the time of the board when it sent the message + std::string axisName; //if the error contains the joint number, then axisName contain its name. + +public: + void printMessage(); +}; + + + +#endif //__diagnosticInfo_h__ diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp new file mode 100644 index 0000000000..8033667e08 --- /dev/null +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + +#include +#include "diagnosticLowLevelFormatter.h" +#include "diagnosticLowLevelFormatter_hid.h" + + + +using namespace Diagnostic::LowLevel; +using namespace Diagnostic; + + +InfoFormatter::InfoFormatter(eth::TheEthManager* ethManager, eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd) : + m_ethManager(ethManager),m_infobasic(infobasic), m_extra(extra), m_nv(nv), m_rd(rd) +{;} + + +bool InfoFormatter::getDiagnosticInfo(EmbeddedInfo &info) +{ + //==> firts of all fill all the common info to all messages and then parser the parameter depending on the specific message + + AuxEmbeddedInfo dnginfo; + + //1. fill all the common info to all messages + dnginfo.sourceBoardIpAddr = eo_nv_GetIP(m_nv); + dnginfo.baseInfo.sourceBoardName = m_ethManager->getName(eo_nv_GetIP(m_nv)); + getTimeOfInfo(dnginfo.baseInfo.timeOfInfo); + getSourceOfMessage(dnginfo.baseInfo); + getSeverityOfError(dnginfo.baseInfo); + + dnginfo.baseMessage = std::string(eoerror_code2string(m_infobasic->properties.code)); + + eOmn_info_extraformat_t extraf = static_castEOMN_INFO_PROPERTIES_FLAGS_get_extraformat(m_infobasic->properties.flags); + dnginfo.extraMessage.clear(); + + if(eomn_info_extraformat_verbal == extraf) + { + dnginfo.extraMessage.append((NULL == m_extra) ? ("no extra info despite we are in verbal mode") : ((const char *)m_extra)); + } + else + { + dnginfo.extraMessage.append("."); + } + + + ipv4ToString(dnginfo.baseInfo); + dnginfo.param64 = m_infobasic->properties.par64; + dnginfo.param16 = m_infobasic->properties.par16; + dnginfo.errorCode = m_infobasic->properties.code; + + EntityNameProvider entityNameProvider{dnginfo.sourceBoardIpAddr, m_ethManager}; + + //2. create the parser related to the error cod family + std::unique_ptr parser_ptr; + + eOerror_category_t category = eoerror_code2category(m_infobasic->properties.code); + switch(category) + { + case eoerror_category_Config: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_MotionControl: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_HardWare: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_System: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_ETHmonitor: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + default: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + }; + + parser_ptr->parseInfo(); + + //3. return the parsered info + info = dnginfo.baseInfo; + + return true; + +} + +void InfoFormatter::getSourceOfMessage(EmbeddedInfo &info) +{ + const char * const sourcenames[] = + { + "LOCAL", + "CAN1", + "CAN2", + "UNKNOWN" + }; + + eOmn_info_source_t source = static_castEOMN_INFO_PROPERTIES_FLAGS_get_source(m_infobasic->properties.flags); + + info.sourceCANBoardAddr = EOMN_INFO_PROPERTIES_FLAGS_get_address(m_infobasic->properties.flags); + + info.sourceCANPortStr = std::string(((source > eomn_info_source_can2) ? (sourcenames[3]) : (sourcenames[source]))); + +} + + + +void InfoFormatter::getTimeOfInfo(TimeOfInfo &timeOfInfo) +{ + timeOfInfo.sec = m_infobasic->timestamp / 1000000; + timeOfInfo.msec = (m_infobasic->timestamp % 1000000) / 1000; + timeOfInfo.usec = m_infobasic->timestamp % 1000; +} + + +void InfoFormatter::ipv4ToString(EmbeddedInfo &info) +{ + char ipinfo[20] = {0}; + eo_common_ipv4addr_to_string(eo_nv_GetIP(m_nv), ipinfo, sizeof(ipinfo)); + info.sourceBoardIpAddrStr.clear(); + info.sourceBoardIpAddrStr.append(ipinfo); +} + +void InfoFormatter::getSeverityOfError(EmbeddedInfo &info) +{ + eOmn_info_type_t type = static_castEOMN_INFO_PROPERTIES_FLAGS_get_type(m_infobasic->properties.flags); + switch(type) + { + case eomn_info_type_info: {info.severity = SeverityOfError::info;return;} + case eomn_info_type_debug: {info.severity = SeverityOfError::debug;return;} + case eomn_info_type_warning: {info.severity = SeverityOfError::warning;return;} + case eomn_info_type_error: {info.severity = SeverityOfError::error;return;} + case eomn_info_type_fatal: {info.severity = SeverityOfError::fatal;return;} + + + }; +} + +/**************************************************************************************************************************/ +/****************************************** EntityNameProvider ***************************************************/ +/**************************************************************************************************************************/ +EntityNameProvider::EntityNameProvider(eOipv4addr_t boardAddr, eth::TheEthManager* ethManager):m_ethManager(ethManager) +{ + m_MC_ethRes = m_ethManager->getInterface(boardAddr, eth::iethresType_t::iethres_motioncontrol); +} + +bool EntityNameProvider::getAxisName(uint32_t entityId, std::string &axisName) +{ + if(m_MC_ethRes == nullptr) + { + axisName = "N/A"; + return false; + } + + return (m_MC_ethRes->getEntityName(entityId, axisName)); +} \ No newline at end of file diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp new file mode 100644 index 0000000000..b5ed322114 --- /dev/null +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -0,0 +1,1330 @@ +/* + * Copyright (C) Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + +#include +#include "diagnosticLowLevelFormatter_hid.h" +#include "diagnosticLowLevelFormatter.h" +#include "EoBoards.h" + + +using namespace Diagnostic::LowLevel; + + + + +/**************************************************************************************************************************/ +/****************************************** DefaultParser ***************************************************/ +/**************************************************************************************************************************/ +DefaultParser::DefaultParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):m_dnginfo(dnginfo), m_entityNameProvider(entityNameProvider){;} + +void DefaultParser::parseInfo() +{ + char str[512] = {0}; + uint8_t *p64 = (uint8_t*)&(m_dnginfo.param64); + snprintf(str, sizeof(str), " src %s, adr %d,(code 0x%.8x, par16 0x%.4x par64 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x) -> %s %s", + m_dnginfo.baseInfo.sourceCANPortStr.c_str(), + m_dnginfo.baseInfo.sourceCANBoardAddr, + m_dnginfo.errorCode, + m_dnginfo.param16, + p64[7], p64[6], p64[5], p64[4], p64[3], p64[2], p64[1], p64[0], + eoerror_code2string(m_dnginfo.errorCode), + m_dnginfo.extraMessage.c_str() + ); + m_dnginfo.baseInfo.finalMessage.clear(); + m_dnginfo.baseInfo.finalMessage.append(str); + +} + + + +/**************************************************************************************************************************/ +/****************************************** ConfigParser ***************************************************/ +/**************************************************************************************************************************/ + +ConfigParser::ConfigParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void ConfigParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_CFG_candiscovery_started: + { + uint16_t maskcan2 = m_dnginfo.param16; + eObrd_type_t brdnum = static_cast((m_dnginfo.param64 & 0x0000ff0000000000) >> 40); + const char *canboardname = eoboards_type2string(brdnum); + uint16_t maskcan1 = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x000000ffff000000) >> 24; + uint64_t reqfw = (m_dnginfo.param64 & 0x0000000000ffffff); + uint8_t num =0; + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 16) & 0xff; + appl.minor = (reqfw >> 8) & 0xff; + appl.build = reqfw & 0xff; + num = eo_common_hlfword_bitsetcount(maskcan1)+eo_common_hlfword_bitsetcount(maskcan2); + + snprintf(str, sizeof(str), " %s %d %s boards on (can1map, can2map) = (0x%.4x, 0x%.4x) with target can protocol ver %d.%d and application ver %d.%d.%d.", + m_dnginfo.baseMessage.c_str(), + num, canboardname, + maskcan1, maskcan2, + prot.major, prot.minor, + appl.major, appl.minor, appl.build + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_candiscovery_ok: + { + uint8_t num = m_dnginfo.param16 & 0x00ff; + eObool_t fakesearch = (0x0000 == (m_dnginfo.param16 & 0xf000)) ? (eobool_false) : (eobool_true); + uint64_t brdnum = (m_dnginfo.param64 & 0x0000ff0000000000) >> 40; + const char *canboardname = eoboards_type2string(static_cast(brdnum)); + uint64_t searchtime = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x000000ffff000000) >> 24; + uint64_t reqfw = (m_dnginfo.param64 & 0x0000000000ffffff); + char strOK[80] = "OK"; + + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 16) & 0xff; + appl.minor = (reqfw >> 8) & 0xff; + appl.build = reqfw & 0xff; + + + if(eobool_true == fakesearch) + { + snprintf(strOK, sizeof(strOK), "OK but FAKE (without any control on CAN w/ get-fw-version<> message)"); + } + + snprintf(str, sizeof(str), "%s is %s for %d %s boards with target can protocol ver %d.%d and application ver %d.%d.%d. Search time was %d ms", + m_dnginfo.baseMessage.c_str(), + strOK, + num, canboardname, + prot.major, prot.minor, + appl.major, appl.minor, appl.build, + (int)searchtime + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_candiscovery_detectedboard: + { + uint64_t brdnum = (m_dnginfo.param64 & 0x0000ff0000000000) >> 40; + const char *canboardname = eoboards_type2string(static_cast(brdnum)); + uint64_t searchtime = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x000000ffff000000) >> 24; + uint64_t reqfw = (m_dnginfo.param64 & 0x0000000000ffffff); + uint8_t address; + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 16) & 0xff; + appl.minor = (reqfw >> 8) & 0xff; + appl.build = reqfw & 0xff; + address = m_dnginfo.param16 & 0x000f; + + + snprintf(str, sizeof(str), "%s %s board in %s addr %d with can protocol ver %d.%d and application ver %d.%d.%d Search time was %d ms", + m_dnginfo.baseMessage.c_str(), + canboardname, + m_dnginfo.baseInfo.sourceCANPortStr.c_str(), address, + prot.major, prot.minor, + appl.major, appl.minor, appl.build, + (int)searchtime + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_candiscovery_boardsmissing: + { + uint8_t numofmissing = m_dnginfo.param16 & 0x00ff; + const char *canboardname = eoboards_type2string(static_cast((m_dnginfo.param16 >> 8))); + uint64_t searchtime = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + uint16_t maskofmissing = m_dnginfo.param64 & 0x000000000000ffff; + + uint8_t n = 1; + uint8_t i = 0; + + snprintf(str, sizeof(str), "%s %d missing %s boards for %d ms in %s:", + m_dnginfo.baseMessage.c_str(), + numofmissing, + canboardname, + (int)searchtime, + m_dnginfo.baseInfo.sourceCANPortStr.c_str() + ); + m_dnginfo.baseInfo.finalMessage.append(str); + for(i=1; i<15; i++) + { + if(eobool_true == eo_common_hlfword_bitcheck(maskofmissing, i)) + { + snprintf(str, sizeof(str), "%d of %d: missing %s BOARD %s:%s:%d", + n, numofmissing, canboardname, + m_dnginfo.baseInfo.sourceBoardIpAddrStr.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), i + ); + m_dnginfo.baseInfo.finalMessage.append(str); + n++; + + } + } + + } break; + + case eoerror_value_CFG_candiscovery_boardsinvalid: + { + uint8_t numofinvalid = m_dnginfo.param16 & 0x00ff; + const char *canboardname = eoboards_type2string(static_cast(m_dnginfo.param16 >> 8)); + uint64_t invalidmask = m_dnginfo.param64; + uint8_t n = 1; + uint8_t i = 0; + const char *empty = ""; + const char *wrongtype = "WRONG BOARD TYPE"; + const char *wrongprot = "WRONG PROTOCOL VERSION"; + const char *wrongappl = "WRONG APPLICATION VERSION"; + + snprintf(str, sizeof(str), "%s %d invalid %s boards in %s:", + m_dnginfo.baseMessage.c_str(), + numofinvalid, + canboardname, + m_dnginfo.baseInfo.sourceCANPortStr.c_str() + ); + m_dnginfo.baseInfo.finalMessage.append(str); + + + + for(i=1; i<15; i++) + { + uint64_t val = (invalidmask >> (4*i)) & 0x0f; + if(0 != val) + { + snprintf(str, sizeof(str), "%d of %d: wrong %s BOARD %s:%s:%d because it has: %s %s %s", + n, numofinvalid, canboardname, + m_dnginfo.baseInfo.sourceBoardIpAddrStr.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), i, + ((val & 0x1) == 0x1) ? (wrongtype) : (empty), + ((val & 0x2) == 0x2) ? (wrongappl) : (empty), + ((val & 0x4) == 0x4) ? (wrongprot) : (empty) + ); + m_dnginfo.baseInfo.finalMessage.append(str); + n++; + + } + } + + } break; + + case eoerror_value_CFG_skin_ok: + { + uint16_t maskcan1 = (m_dnginfo.param64 & 0x0000ffff00000000) >> 32; + uint16_t maskcan2 = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint64_t reqfw = (m_dnginfo.param64 & 0x000000000000ffff); + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 8) & 0xff; + appl.minor = reqfw & 0xff; + uint16_t numOfpatches = m_dnginfo.param16; + + snprintf(str, sizeof(str), "%s on %d skin patches for boards on (can1map, can2map) = (0x%.4x, 0x%.4x) with target can protocol ver %d.%d and application ver %d.%d", + m_dnginfo.baseMessage.c_str(), + numOfpatches, + maskcan1, maskcan2, + prot.major, prot.minor, + appl.major, appl.minor + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_skin_failed_toomanyboards: + case eoerror_value_CFG_inertials_failed_toomanyboards: + case eoerror_value_CFG_inertials3_failed_toomanyboards: + case eoerror_value_CFG_temperatures_failed_toomanyboards: + { + uint8_t numOfReqBoards = (m_dnginfo.param16 & 0xff00) >> 8; + uint8_t numOfMaxBoards = m_dnginfo.param16 & 0x00ff; + + uint16_t maskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + uint16_t maskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + + snprintf(str, sizeof(str), " %s for %d boards. Limit of max number of boards is %d. Boards are on (can1map, can2map) = (0x%.4x, 0x%.4x)", + m_dnginfo.baseMessage.c_str(), + numOfReqBoards, numOfMaxBoards, + maskcan1, maskcan2 + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_skin_failed_candiscovery: + case eoerror_value_CFG_inertials_failed_candiscovery: + case eoerror_value_CFG_inertials3_failed_candiscovery: + case eoerror_value_CFG_temperatures_failed_candiscovery: + { + uint16_t incompMaskcan2 = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + uint16_t incompMaskcan1 = (m_dnginfo.param64 & 0x0000ffff00000000) >> 32; + uint16_t missMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t missMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + uint16_t numOfPatches = m_dnginfo.param16; + + if (eoerror_value_CFG_skin_failed_candiscovery == value) + { + snprintf(str, sizeof(str), "%s for %d skin patches. ", m_dnginfo.baseMessage.c_str(), numOfPatches); + m_dnginfo.baseInfo.finalMessage.append(str); + } + else + { + snprintf(str, sizeof(str), "%s. ", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } + + snprintf(str, sizeof(str), "Missing can boards on (can1map, can2map) = (0x%.4x, 0x%.4x) and found but incompatible can boards on (can1map, can2map) = (0x%.4x, 0x%.4x)"); + + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_strain_ok: + case eoerror_value_CFG_strain_failed_candiscovery: + { + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint64_t reqfw = (m_dnginfo.param64 & 0x000000000000ffff); + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 8) & 0xff; + appl.minor = reqfw & 0xff; + uint8_t strain = (m_dnginfo.param64 & 0x0000000f00000000) >> 20; + uint8_t address = m_dnginfo.param16 & 0x00ff; + uint8_t port = m_dnginfo.param16 >> 8; + + snprintf(str, sizeof(str), "%s for board at addr:%d and port:%d with can protocol ver %d.%d and application ver %d.%d. Strain number is:%d", + m_dnginfo.baseMessage.c_str(), + address, port, + prot.major, prot.minor, + appl.major, appl.minor, + strain + ); + } break; + + case eoerror_value_CFG_mais_ok: + case eoerror_value_CFG_mais_failed_candiscovery: + case eoerror_value_CFG_psc_ok: + case eoerror_value_CFG_psc_failed_candiscovery: + case eoerror_value_CFG_pos_ok: + case eoerror_value_CFG_pos_failed_candiscovery: + { + eObrd_protocolversion_t prot = {0}; + eObrd_firmwareversion_t appl = {0}; + uint64_t reqpr = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint64_t reqfw = (m_dnginfo.param64 & 0x000000000000ffff); + prot.major = reqpr >> 8; + prot.minor = reqpr & 0xff; + appl.major = (reqfw >> 8) & 0xff; + appl.minor = reqfw & 0xff; + uint8_t address = m_dnginfo.param16 & 0x00ff; + uint8_t port = m_dnginfo.param16 >> 8; + + snprintf(str, sizeof(str), "%s on board at addr: %d and port:%d with can protocol ver %d.%d and application ver %d.%d.", + m_dnginfo.baseMessage.c_str(), + address, + port, + prot.major, prot.minor, + appl.major, appl.minor + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_mais_failed_verify_because_active: + case eoerror_value_CFG_mc_foc_ok: + case eoerror_value_CFG_mc_foc_failed_candiscovery_of_foc: + case eoerror_value_CFG_mc_foc_failed_encoders_verify: + case eoerror_value_CFG_mc_mc4_ok: + case eoerror_value_CFG_mc_mc4_failed_candiscovery_of_mc4: + case eoerror_value_CFG_mc_mc4_failed_mais_verify: + case eoerror_value_CFG_mc_mc4plus_ok: + case eoerror_value_CFG_mc_mc4plus_failed_encoders_verify: + case eoerror_value_CFG_inertials_ok: + case eoerror_value_CFG_comm_cannotloadaregularrop: + case eoerror_value_CFG_mc_mc4plusmais_ok: + case eoerror_value_CFG_mc_mc4plusmais_failed_encoders_verify: + case eoerror_value_CFG_mc_mc4plusmais_failed_candiscovery_of_mais: + case eoerror_value_CFG_services_not_verified_yet: + case eoerror_value_CFG_mc_not_verified_yet: + case eoerror_value_CFG_strain_not_verified_yet: + case eoerror_value_CFG_mais_not_verified_yet: + case eoerror_value_CFG_skin_not_verified_yet: + case eoerror_value_CFG_inertials_not_verified_yet: + case eoerror_value_CFG_inertials3_not_verified_yet: + case eoerror_value_CFG_encoders_not_verified_yet: + case eoerror_value_CFG_mc_using_onboard_config: + case eoerror_value_CFG_strain_using_onboard_config: + case eoerror_value_CFG_mais_using_onboard_config: + case eoerror_value_CFG_inertials_using_onboard_config: + case eoerror_value_CFG_inertials3_using_onboard_config: + case eoerror_value_CFG_skin_using_onboard_config: + case eoerror_value_CFG_inertials3_ok: + case eoerror_value_CFG_temperatures_not_verified_yet: + case eoerror_value_CFG_temperatures_ok: + case eoerror_value_CFG_temperatures_using_onboard_config: + case eoerror_value_CFG_psc_failed_verify_because_active: + case eoerror_value_CFG_psc_not_verified_yet: + case eoerror_value_CFG_psc_using_onboard_config: + case eoerror_value_CFG_mc_mc2pluspsc_ok: + case eoerror_value_CFG_mc_mc2pluspsc_failed_encoders_verify: + case eoerror_value_CFG_mc_mc2pluspsc_failed_candiscovery_of_pscs: + case eoerror_value_CFG_inertials_failed_notsupported: + case eoerror_value_CFG_inertials3_failed_notsupported: + case eoerror_value_CFG_temperatures_failed_notsupported: + case eoerror_value_CFG_mais_failed_notsupported: + case eoerror_value_CFG_strain_failed_notsupported: + case eoerror_value_CFG_skin_failed_notsupported: + case eoerror_value_CFG_psc_failed_notsupported: + case eoerror_value_CFG_mc_failed_notsupported: + case eoerror_value_CFG_encoders_failed_notsupported: + case eoerror_value_CFG_pos_not_verified_yet: + case eoerror_value_CFG_pos_using_onboard_config: + case eoerror_value_CFG_pos_failed_notsupported: + case eoerror_value_CFG_mc_mc4plusfaps_ok: + case eoerror_value_CFG_mc_mc4plusfaps_failed_encoders_verify: + case eoerror_value_CFG_mc_mc4plusfaps_failed_candiscovery: + case eoerror_value_CFG_mc_mc4pluspmc_ok: + case eoerror_value_CFG_mc_mc4pluspmc_failed_encoders_verify: + case eoerror_value_CFG_mc_mc4pluspmc_failed_candiscovery_of_pmc: + case eoerror_value_CFG_ft_ok: + case eoerror_value_CFG_ft_failed_candiscovery: + case eoerror_value_CFG_ft_not_verified_yet: + case eoerror_value_CFG_ft_using_onboard_config: + case eoerror_value_CFG_ft_failed_notsupported: + case eoerror_value_CFG_ft_failed_fullscales: + case eoerror_value_CFG_bat_ok: + case eoerror_value_CFG_bat_failed_candiscovery: + case eoerror_value_CFG_bat_not_verified_yet: + case eoerror_value_CFG_bat_using_onboard_config: + case eoerror_value_CFG_bat_failed_notsupported: + //case eoerror_value_CFG_encoders_ok: + { + snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + // p16&0xf000: number of joint; primary encs: failure mask in p16&0x000f and errorcodes in p64&0x0000ffff; secondary encs: failure mask in p16&0x00f0 and errorcodes in p64&0xffff0000"}, + case eoerror_value_CFG_encoders_ok: + case eoerror_value_CFG_encoders_failed_verify: + { + uint8_t numOfJoints = (m_dnginfo.param16 & 0xf000) >> 12; + uint8_t failmaskenc1 = m_dnginfo.param16 & 0x000f; + int16_t errorenc1 = m_dnginfo.param64 & 0x0000ffff; + uint8_t failmaskenc2 = (m_dnginfo.param16 & 0x00f0) >> 4; + int16_t errorenc2 = (m_dnginfo.param64 & 0xffff0000) >> 16; + + int16_t rawerror1 = errorenc1 & failmaskenc1; + int16_t rawerror2 = errorenc2 & failmaskenc2; + snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + + for(auto i=0; i < numOfJoints; i++) + { + // 1. check if joint ith has encoder with errors + auto primary_enc_with_error = (failmaskenc1 & (1<> 4*i); + m_entityNameProvider.getAxisName(i, m_dnginfo.baseInfo.axisName); + snprintf(str, sizeof(str), " joint %d (%s) has error on primary encoder (code=%d). ", + i, m_dnginfo.baseInfo.axisName.c_str(), primary_error_code); //TODO: get a string instead of a code + m_dnginfo.baseInfo.finalMessage.append(str); + } + + if(secondary_enc_with_error) + { + primary_error_code = ( (errorenc2 & (0xf <> 4*i); + m_entityNameProvider.getAxisName(i, m_dnginfo.baseInfo.axisName); + snprintf(str, sizeof(str), " joint %d (%s) has error on secodary encoder (code=%d)", + i, m_dnginfo.baseInfo.axisName.c_str(), secondary_error_code); //TODO: get a string instead of a code + m_dnginfo.baseInfo.finalMessage.append(str); + } + + + } + + } break; + + case eoerror_value_CFG_inertials_failed_unsupportedsensor: + case eoerror_value_CFG_inertials3_failed_unsupportedsensor: + { + int16_t unsuppsens = m_dnginfo.param16; + + snprintf(str, sizeof(str), "%s. Number of unsupported sens is %d", + m_dnginfo.baseMessage.c_str(), + unsuppsens + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_inertials_changed_requestedrate: + case eoerror_value_CFG_inertials3_changed_requestedrate: + case eoerror_value_CFG_temperatures_changed_requestedrate: + case eoerror_value_CFG_psc_changed_requestedrate: + case eoerror_value_CFG_pos_changed_requestedrate: + { + uint8_t reqrate = (m_dnginfo.param16 & 0xff00) >> 8; + uint8_t assrate = m_dnginfo.param16 & 0x00ff; + + snprintf(str, sizeof(str), "%s. Requested rate %u and Assigned rate %u", + m_dnginfo.baseMessage.c_str(), + reqrate, + assrate + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_CFG_inertials3_failed_generic: + case eoerror_value_CFG_temperatures_failed_generic: + { + uint8_t numOfSens = m_dnginfo.param64; + + snprintf(str, sizeof(str), "%s for %d sensors", + m_dnginfo.baseMessage.c_str(), + numOfSens + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_Config error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch + + + +} + + + + +/**************************************************************************************************************************/ +/****************************************** MotionControlParser ***************************************************/ +/**************************************************************************************************************************/ + +MotionControlParser::MotionControlParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void MotionControlParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_MC_motor_external_fault: + case eoerror_value_MC_motor_qencoder_phase_disappeared: + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_MC_motor_overcurrent: + case eoerror_value_MC_motor_i2t_limit: + case eoerror_value_MC_motor_hallsensors: + case eoerror_value_MC_motor_can_invalid_prot: + case eoerror_value_MC_motor_can_generic: + case eoerror_value_MC_motor_can_no_answer: + case eoerror_value_MC_axis_torque_sens: + case eoerror_value_MC_joint_hard_limit: + { + uint8_t joint_num = m_dnginfo.param16 & 0x00ff; + m_entityNameProvider.getAxisName(joint_num, m_dnginfo.baseInfo.axisName); + + snprintf(str, sizeof(str), " %s (Joint=%s (NIB=%d))", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.axisName.c_str(), joint_num); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_MC_aea_abs_enc_invalid: + case eoerror_value_MC_aea_abs_enc_spikes: + case eoerror_value_MC_aea_abs_enc_timeout: + { + uint8_t joint_num = m_dnginfo.param16 & 0x00ff; + uint8_t enc_port = (m_dnginfo.param16 & 0xff00)>>8; + m_entityNameProvider.getAxisName(joint_num, m_dnginfo.baseInfo.axisName); + + snprintf(str, sizeof(str), " %s (Joint=%s (NIB=%d), encoderPort=%d)", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.axisName.c_str(), joint_num, enc_port + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case eoerror_value_MC_motor_qencoder_dirty: + case eoerror_value_MC_motor_qencoder_phase: //TBD: check encoder raw value + { + uint16_t joint_num = m_dnginfo.param16; + uint16_t enc_raw_value = m_dnginfo.param64 & 0xffff; + m_entityNameProvider.getAxisName(joint_num, m_dnginfo.baseInfo.axisName); + + snprintf(str, sizeof(str), " %s (Joint=%s (NIB=%d), Raw_quad_encoder_value=%d)", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.axisName.c_str(), joint_num, enc_raw_value + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_MC_generic_error: //TBD Check print + { + snprintf(str, sizeof(str), " %s (Error is %lx)", m_dnginfo.baseMessage.c_str(), m_dnginfo.param64); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_MC_motor_wrong_state: //TBD: check states + { + uint16_t joint_num = m_dnginfo.param16; + uint16_t req_state = (m_dnginfo.param64 & 0xf0)>>4; + uint16_t cur_state = m_dnginfo.param64 & 0x0f; + + m_entityNameProvider.getAxisName(joint_num, m_dnginfo.baseInfo.axisName); + + + snprintf(str, sizeof(str), " %s Joint=%s (NIB=%d). The requested state is %d, but the current is %d)", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.axisName.c_str(), joint_num, req_state, cur_state + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_MotionControl error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch + + + +} + + + + +/**************************************************************************************************************************/ +/****************************************** SkinParser ***************************************************/ +/**************************************************************************************************************************/ + + + +SkinParser::SkinParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void SkinParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch (value) + { + case eoerror_value_SYS_unspecified: + case eoerror_value_SK_obsoletecommand: + { + snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SK_arrayofcandataoverflow: + { + uint8_t frame_id = m_dnginfo.param16 & 0x00ff; + uint8_t frame_size = (m_dnginfo.param16 & 0xf000) >> 12; + uint64_t frame_data = m_dnginfo.param64; + + snprintf(str, sizeof(str), " %s. Frame.ID=%d, Frame.Size=%d Frame.Data=0x%lx", + m_dnginfo.baseMessage.c_str(), frame_id, frame_size, frame_data + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SK_onoroff: + { + std::string emsboardstate = "unknown"; + switch (m_dnginfo.param16) + { + case 0: emsboardstate = "OFF"; break; + case 1: emsboardstate = "ON"; break; + }; + + snprintf(str, sizeof(str), " %s %s", m_dnginfo.baseMessage.c_str(), emsboardstate.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SK_unexpecteddata: + { + std::string emsboardstate = "unknown"; + switch (m_dnginfo.param16) + { + case 0: emsboardstate = "CFG"; break; + case 1: emsboardstate = "RUN"; break; + } + + snprintf(str, sizeof(str), " %s %s", m_dnginfo.baseMessage.c_str(), emsboardstate.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognized eoerror_category_Skin error value"); + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } break; + } +} + +/**************************************************************************************************************************/ +/****************************************** HwErrorParser ***************************************************/ +/**************************************************************************************************************************/ + + + +HwErrorParser::HwErrorParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void HwErrorParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_HW_strain_saturation: + { + uint16_t channel = m_dnginfo.param16; + uint32_t lower_saturation_counts = m_dnginfo.param64 & 0xffffffff; + uint32_t upper_saturation_counts = (m_dnginfo.param64 & 0xffffffff00000000)>>32; + snprintf(str, sizeof(str), " %s %d is the channel involved. In the last second, the lower saturation counts is %d and the upper one is %d", + m_dnginfo.baseMessage.c_str(), + channel, + lower_saturation_counts, + upper_saturation_counts); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_HW_encoder_invalid_value: + case eoerror_value_HW_encoder_close_to_limits: + case eoerror_value_HW_encoder_crc: + case eoerror_value_HW_encoder_not_connected: + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_HardWare error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch + + + +} + + + +/**************************************************************************************************************************/ +/****************************************** SysErrorParser ***************************************************/ +/**************************************************************************************************************************/ + + + +SysParser::SysParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void SysParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_SYS_runninghappily: + { + std::string appstate = "unknown"; + switch(m_dnginfo.param16&0x000f) + { + case 0: appstate="just restarted"; break; + case 1: appstate="idle"; break; + case 2: appstate="running"; break; + }; + snprintf(str, sizeof(str), " %s Application state is %s.", m_dnginfo.baseMessage.c_str(), appstate.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_ctrloop_execoverflowRX: + { + snprintf(str, sizeof(str), " %s RX execution time %d[usec]. Latest previous execution times of TX, RX, DO, TX %ld[usec]", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, m_dnginfo.param64); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_ctrloop_execoverflowDO: + { + snprintf(str, sizeof(str), " %s DO execution time %d[usec]. Latest previous execution times of RX, DO, TX, RX %ld[usec]", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, m_dnginfo.param64); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_ctrloop_execoverflowTX: + { + snprintf(str, sizeof(str), " %s TX execution time %d[usec]. Latest previous execution times of TX, RX, DO %ld[usec]. Num of frames in tx queue: CAN1 is %d, CAN2 is %d ", + m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, + (m_dnginfo.param64&0x0000ffffffffffff), + (int16_t)((m_dnginfo.param64&0x00ff000000000000)>>48), + (int16_t)((m_dnginfo.param64&0xff00000000000000)>>56) ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_ropparsingerror: + { + snprintf(str, sizeof(str), " %s Error code is %d (eOparserResult_t).", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_halerror: + { + snprintf(str, sizeof(str), " %s HAL error code is %d.", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_osalerror: + { + snprintf(str, sizeof(str), " %s OSAL error code is %d.", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_ipalerror: + { + snprintf(str, sizeof(str), " %s IPAL error code is %d.", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_dispatcherfifooverflow: + { + snprintf(str, sizeof(str), " %s Number of lost items is %d.", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_txfifooverflow: + { + snprintf(str, sizeof(str), " %s CanPort=%s Frame.ID=%d, Frame.Size=%d Frame.Data=0x.%lx", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), (m_dnginfo.param16&& 0x0fff), ((m_dnginfo.param16&& 0xf000)>>12), m_dnginfo.param64 ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_txbusfailure: + { + snprintf(str, sizeof(str), " %s CanPort=%s. Size of fifo is %d", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), ((m_dnginfo.param16&& 0xff00) >>8)); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_formingfailure: + { + snprintf(str, sizeof(str), " %s CanPort=%s. Message class is %d. Message cmd is %d", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), ((m_dnginfo.param16&& 0xff00) >>8), (m_dnginfo.param16&& 0x00ff)); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_parsingfailure: + { + snprintf(str, sizeof(str), " %s CanPort=%s. Frame.size=%d. Frame.Id=%d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), ((m_dnginfo.param16&& 0xf000) >>12), (m_dnginfo.param16&& 0x0fff)); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_genericerror: + { + snprintf(str, sizeof(str), " %s error code is %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_rxphaseaverage: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_dophaseaverage: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_txphaseaverage: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_rxphasemax: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_dophasemax: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + case eoerror_value_SYS_ctrloop_txphasemax: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_rxphasemin: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_dophasemin: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_ctrloop_txphasemin: + { + snprintf(str, sizeof(str), " %s %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_proxy_forward_fails: + { + snprintf(str, sizeof(str), " %s. ROP.sign=%d, ROP.id=%d. Proxy list capacity is %d, size is %d ", + m_dnginfo.baseMessage.c_str(), + (int32_t)((m_dnginfo.param64&0xffffffff00000000)>>32), + (int32_t)(m_dnginfo.param64&0x00000000ffffffff), + ((m_dnginfo.param16&0xff00)>>8), (m_dnginfo.param16&0x00ff)); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_proxy_ropdes_notfound: + { + snprintf(str, sizeof(str), " %s ROP.id=%d ", m_dnginfo.baseMessage.c_str(), (int32_t)(m_dnginfo.param64&0x00000000ffffffff)); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + case eoerror_value_SYS_canservices_canprint: + { + snprintf(str, sizeof(str), " %s CanPort=%s Frame.Size=%d Frame.Data=0x.%lx", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.param16, m_dnginfo.param64 ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_rxmaisbug: + { + snprintf(str, sizeof(str), " %s CanPort=%s Frame.Size=%d Frame.Data=0x.%lx", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.param16, m_dnginfo.param64 ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_rxfromwrongboard: + { + snprintf(str, sizeof(str), " %s CanPort=%s Frame.Size=%d Frame.Data=0x.%lx", m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.param16, m_dnginfo.param64 ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_transceiver_rxseqnumber_error: + { + int16_t receivedNum = m_dnginfo.param64+ m_dnginfo.param16; + snprintf(str, sizeof(str), " %s Expected number is %ld, received number is %d ", m_dnginfo.baseMessage.c_str(), m_dnginfo.param64, receivedNum); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_transceiver_rxseqnumber_restarted: + { + snprintf(str, sizeof(str), " %s Expected number is %ld", m_dnginfo.baseMessage.c_str(), m_dnginfo.param64); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_board_detected: + { + //in param64 the fw copies the struct eObrd_typeandversions_t defined in EoBoards.h in icub=firmware repo + /** + typedef struct { + eOenum08_t boardtype; + uint8_t firmwarebuildnumber; + eObrd_version_t firmwareversion; + eObrd_version_t protocolversion; + } eObrd_typeandversions_t; EO_VERIFYsizeof(eObrd_typeandversions_t, 6); + + + typedef struct // size is: 1+1+0 = 2 + { + uint8_t major; + uint8_t minor; + } eObrd_version_t; + + */ + //TODO: + //checking the fw it seems this error code is no longer used. + //So I cannot retrieve the board type. + //For now I leave the code. When I'm sure that it is old, I'll remove it + int fw_build = (m_dnginfo.param64 & 0x00000000000000ff); + int fw_major = (m_dnginfo.param64 & 0x000000000000ff00) >> 8; + int fw_minor = (m_dnginfo.param64 & 0x0000000000ff0000) >> 16; + int proto_major = (m_dnginfo.param64 & 0x00000000ff000000) >> 24; + int proto_minor = (m_dnginfo.param64 & 0x000000ff00000000) >> 32; + + //used in comm-v1 protocol + // eObrd_typeandversions_t *brd_info_ptr = (eObrd_typeandversions_t *)&m_dnginfo.param64; + // int fw_build = brd_info_ptr->firmwarebuildnumber; + // int fw_major = brd_info_ptr->firmwareversion.major; + // int fw_minor = brd_info_ptr->firmwareversion.minor; + // int proto_major =brd_info_ptr->protocolversion.major; + // int proto_minor =brd_info_ptr->protocolversion.minor; + + // eObrd_type_t general_brd_type = eoboards_cantype2type((eObrd_cantype_t )brd_info_ptr->boardtype); + + // std::string board_type_str = eoboards_type2string(general_brd_type); + + snprintf(str, sizeof(str), " %s on CAN port=%s with address %d. Fw ver is %d.%d.%d. Proto ver is %d.%d", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.baseInfo.sourceCANBoardAddr, + fw_build, fw_major, fw_minor, proto_major, proto_minor ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_board_wrongprotversion: + { + //in param64 the fw copies the struct eObrd_typeandversions_t defined in EoBoards.h in icub=firmware repo + /** + typedef struct { + eOenum08_t boardtype; + uint8_t firmwarebuildnumber; + eObrd_version_t firmwareversion; + eObrd_version_t protocolversion; + } eObrd_typeandversions_t; EO_VERIFYsizeof(eObrd_typeandversions_t, 6); + + + typedef struct // size is: 1+1+0 = 2 + { + uint8_t major; + uint8_t minor; + } eObrd_version_t; + + */ + //as above + int fw_build = (m_dnginfo.param64 & 0x00000000000000ff); + int fw_major = (m_dnginfo.param64 & 0x000000000000ff00) >> 8; + int fw_minor = (m_dnginfo.param64 & 0x0000000000ff0000) >> 16; + int proto_major = (m_dnginfo.param64 & 0x00000000ff000000) >> 24; + int proto_minor = (m_dnginfo.param64 & 0x000000ff00000000) >> 32; + int req_proto_major = (m_dnginfo.param16 & 0xff00) >>8; + int req_proto_minor = (m_dnginfo.param16 & 0x00ff); + + + snprintf(str, sizeof(str), " %s on CAN port=%s with address %d. Fw ver is %d.%d.%d. Proto ver is %d.%d. Required Version is %d.%d", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.baseInfo.sourceCANBoardAddr, + fw_build, fw_major, fw_minor, proto_major, proto_minor, req_proto_major, req_proto_minor ); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_SYS_canservices_board_notfound: + { + eObrd_type_t general_brd_type = eoboards_cantype2type((eObrd_cantype_t)m_dnginfo.param16); + snprintf(str, sizeof(str), " %s The board is on CAN port=%s with address %d. Board type is %s.", + m_dnginfo.baseMessage.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), + m_dnginfo.baseInfo.sourceCANBoardAddr, eoboards_type2string(general_brd_type)); + m_dnginfo.baseInfo.finalMessage.append(str); + + }break; + + + case eoerror_value_SYS_unspecified: + case eoerror_value_SYS_tobedecided: + case eoerror_value_SYS_memory_zerorequested: + case eoerror_value_SYS_memory_notinitialised: + case eoerror_value_SYS_memory_missing: + case eoerror_value_SYS_mutex_timeout: + case eoerror_value_SYS_wrongparam: + case eoerror_value_SYS_wrongusage: + case eoerror_value_SYS_runtimeerror: + case eoerror_value_SYS_runninginfatalerrorstate: + case eoerror_value_SYS_udptxfailure: + case eoerror_value_SYS_configurator_udptxfailure: + case eoerror_value_SYS_runner_udptxfailure: + case eoerror_value_SYS_runner_transceivererror: + case eoerror_value_SYS_canservices_rxfifooverflow: + case eoerror_value_SYS_proxy_forward_ok: + case eoerror_value_SYS_proxy_forward_callback_fails: + case eoerror_value_SYS_proxy_reply_ok: + case eoerror_value_SYS_proxy_reply_fails: + case eoerror_value_SYS_canservices_boards_missing: + case eoerror_value_SYS_canservices_boards_searched: + case eoerror_value_SYS_canservices_boards_found: + case eoerror_value_SYS_transceiver_rxinvalidframe_error: + case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_monitor_regularcontact: //TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_monitor_lostcontact: //TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_monitor_stillnocontact://TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_monitor_retrievedcontact: //TODO: make a specific message.need some translation from enum to string + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_HardWare error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch + + + +} + + + + + + +/**************************************************************************************************************************/ +/****************************************** EthMonitorParser *****************************************/ +/**************************************************************************************************************************/ + + + +EthMonitorParser::EthMonitorParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void EthMonitorParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_ETHMON_link_goes_up: + case eoerror_value_ETHMON_link_goes_down: + case eoerror_value_ETHMON_error_rxcrc: + { + std::string appstate = "unknown"; + switch(m_dnginfo.param64&0xff00000000000000) + { + case 0: appstate="N/A"; break; + case 1: appstate="idle"; break; + case 3: appstate="running"; break; + }; + + std::string ethport = "unknown"; + switch(m_dnginfo.param16) + { + case 0: ethport="ETH input (P2/P13/J4)"; break; + case 1: ethport="ETH output (P3/P12/J5)"; break; + case 2: ethport="internal"; break; + }; + if(eoerror_value_ETHMON_error_rxcrc == value) + snprintf(str, sizeof(str), " %s in port %s. Application state is %s. Number of erros is %ld", + m_dnginfo.baseMessage.c_str(), ethport.c_str(), appstate.c_str(), (m_dnginfo.param64&0xffffffff)); + else + snprintf(str, sizeof(str), " %s in port %s. Application state is %s.", m_dnginfo.baseMessage.c_str(), ethport.c_str(), appstate.c_str()); + + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + case eoerror_value_ETHMON_txseqnumbermissing: + { + snprintf(str, sizeof(str), " %s w/ expected sequence %ld and number of detected %d", m_dnginfo.baseMessage.c_str(), m_dnginfo.param64, m_dnginfo.param16); + m_dnginfo.baseInfo.finalMessage.append(str); + }break; + + + case eoerror_value_ETHMON_juststarted: + case eoerror_value_ETHMON_justverified: + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_HardWare error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch +} + + +/**************************************************************************************************************************/ +/****************************************** InertialSensorParser ********************************************/ +/**************************************************************************************************************************/ + +InertialSensorParser::InertialSensorParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} + +void InertialSensorParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_IS_arrayofinertialdataoverflow: + { + + uint8_t frame_id = m_dnginfo.param16 & 0x00ff; + uint8_t frame_size = (m_dnginfo.param16 & 0xf000) >> 12; + uint64_t frame_data = m_dnginfo.param64; + + snprintf(str, sizeof(str), " %s. Frame.ID=%d, Frame.Size=%d Frame.Data=0x%lx", + m_dnginfo.baseMessage.c_str(), frame_id, frame_size, frame_data + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_IS_unknownsensor: + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_HardWare error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch +} + +/**************************************************************************************************************************/ +/****************************************** AnalogSensorParser **********************************************/ +/**************************************************************************************************************************/ + +AnalogSensorParser::AnalogSensorParser(AuxEmbeddedInfo &dnginfo, EntityNameProvider &entityNameProvider):DefaultParser(dnginfo, entityNameProvider){;} +void AnalogSensorParser::parseInfo() +{ + char str[512] = {0}; + eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); + + switch(value) + { + + case eoerror_value_AS_arrayoftemperaturedataoverflow: + { + + uint8_t frame_id = m_dnginfo.param16 & 0x00ff; + uint8_t frame_size = (m_dnginfo.param16 & 0xf000) >> 12; + uint64_t frame_data = m_dnginfo.param64; + + snprintf(str, sizeof(str), " %s. Frame.ID=%d, Frame.Size=%d Frame.Data=0x%lx", + m_dnginfo.baseMessage.c_str(), frame_id, frame_size, frame_data + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_AS_unknownsensor: + { + snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + + case EOERROR_VALUE_DUMMY: + { + m_dnginfo.baseInfo.finalMessage.append(": unrecognised eoerror_category_HardWare error value."); + + + } break; + + default: + { + Diagnostic::LowLevel::DefaultParser::parseInfo(); + + } + + }//end switch +} + diff --git a/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter.h b/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter.h new file mode 100644 index 0000000000..cf69814585 --- /dev/null +++ b/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + + +#ifndef __diagnosticLowLevelFormatter_h__ +#define __diagnosticLowLevelFormatter_h__ + +#include + + +#include "EoManagement.h" +#include "ethManager.h" +#include "diagnosticInfo.h" + + + +namespace Diagnostic { + namespace LowLevel { + class InfoFormatter; + } +} + +//The info formatter is used to read the diagnostic embedded info on reception of a nv diagnostic realated. +class Diagnostic::LowLevel::InfoFormatter +{ +public: + InfoFormatter(eth::TheEthManager* ethManager, eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd); + InfoFormatter() = delete; + InfoFormatter(const Diagnostic::LowLevel::InfoFormatter &InfoFormatter){}; + ~InfoFormatter(){;}; + InfoFormatter(const Diagnostic::LowLevel::InfoFormatter &&InfoFormatter){}; + + virtual bool getDiagnosticInfo(Diagnostic::EmbeddedInfo &info); + + +private: + eOmn_info_basic_t* m_infobasic; + uint8_t * m_extra; + const EOnv* m_nv; + const eOropdescriptor_t* m_rd; + eth::TheEthManager* m_ethManager; + + void getTimeOfInfo(Diagnostic::TimeOfInfo &timeOfInfo); + void getSourceOfMessage(Diagnostic::EmbeddedInfo &info); + void ipv4ToString(Diagnostic::EmbeddedInfo &info); + void getSeverityOfError(Diagnostic::EmbeddedInfo &info); +}; + +#endif //__diagnosticLowLevelFormatter_h__ \ No newline at end of file diff --git a/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter_hid.h b/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter_hid.h new file mode 100644 index 0000000000..18e36a906b --- /dev/null +++ b/src/libraries/icubmod/embObjLib/diagnosticLowLevelFormatter_hid.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) + * All rights reserved. + * + * This software may be modified and distributed under the terms of the + * BSD-3-Clause license. See the accompanying LICENSE file for details. + */ + + +#ifndef __diagnosticLowLevelFormatter_hid_h__ +#define __diagnosticLowLevelFormatter_hid_h__ + +#include +#include +#include +#include "diagnosticLowLevelFormatter.h" +#include "EoError.h" + +#include "IethResource.h" + + +namespace Diagnostic { + namespace LowLevel { + class DefaultParser; + class ConfigParser; + class MotionControlParser; + class SkinParser; + class HwErrorParser; + class SysParser; + class EthMonitorParser; + class InertialSensorParser; + class AnalogSensorParser; + class AuxEmbeddedInfo; + class EntityNameProvider; + + } +} + + + +//In this class the Info formatter and the parsers collect the embedded diagnostic Info. +//Only the info contained in Diagnostic::EmbeddedInfo baseInfo are usefull for the user level. +class Diagnostic::LowLevel::AuxEmbeddedInfo +{ +public: + Diagnostic::EmbeddedInfo baseInfo; + eOipv4addr_t sourceBoardIpAddr; // is the ipv4 address, in eOipv4addr_t, of the board that sends the diagnostic information + eOerror_code_t errorCode; // this is the error code sent by the board; + std::string baseMessage; //this is the base message string without any parameter + std::string extraMessage;// in some case, the board can send an extra string + uint64_t param64; // the 64 bits paramter sent by the board + uint16_t param16; //the 16 bits parameter sent by the board + +public: + void printMessage(); +}; + + +//This class has the goal to provide the name of an entity (axis, sensors, etc) to the parsers. +class Diagnostic::LowLevel::EntityNameProvider +{ +public: + EntityNameProvider(eOipv4addr_t boardAddr, eth::TheEthManager* ethManager); + EntityNameProvider() = delete; + EntityNameProvider(const Diagnostic::LowLevel::EntityNameProvider &EntityNameProvider){}; + ~EntityNameProvider(){;}; + EntityNameProvider(const Diagnostic::LowLevel::EntityNameProvider &&EntityNameProvider){}; +private: + eth::TheEthManager* m_ethManager; + eth::IethResource* m_MC_ethRes; +public: + bool getAxisName(uint32_t entityId, std::string &axisName); +}; + + + +class Diagnostic::LowLevel::DefaultParser +{ + +public: + DefaultParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + DefaultParser() = delete; + DefaultParser(const Diagnostic::LowLevel::DefaultParser &parser)= delete; + ~DefaultParser(){}; + DefaultParser(Diagnostic::LowLevel::DefaultParser &&parser)= delete; + virtual void parseInfo(); + +protected: + Diagnostic::LowLevel::AuxEmbeddedInfo &m_dnginfo; + Diagnostic::LowLevel::EntityNameProvider &m_entityNameProvider; +}; + +class Diagnostic::LowLevel::ConfigParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + ConfigParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + ConfigParser() = delete; + ConfigParser(const Diagnostic::LowLevel::ConfigParser &parser)= delete; + ~ConfigParser(){}; + ConfigParser(Diagnostic::LowLevel::ConfigParser &&parser)=delete; + + void parseInfo(); +}; + + +class Diagnostic::LowLevel::MotionControlParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + MotionControlParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + MotionControlParser() = delete; + MotionControlParser(const Diagnostic::LowLevel::MotionControlParser &parser)= delete; + ~MotionControlParser(){}; + MotionControlParser(Diagnostic::LowLevel::MotionControlParser &&parser)=delete; + + void parseInfo(); + + +}; + +class Diagnostic::LowLevel::SkinParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + SkinParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + SkinParser() = delete; + SkinParser(const Diagnostic::LowLevel::SkinParser &parser) = delete; + ~SkinParser(){}; + SkinParser(Diagnostic::LowLevel::SkinParser &&parser) = delete; + + void parseInfo(); +}; + +class Diagnostic::LowLevel::HwErrorParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + HwErrorParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + HwErrorParser() = delete; + HwErrorParser(const Diagnostic::LowLevel::HwErrorParser &parser)= delete; + ~HwErrorParser(){}; + HwErrorParser(Diagnostic::LowLevel::HwErrorParser &&parser)=delete; + + void parseInfo(); + + +}; + +class Diagnostic::LowLevel::SysParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + SysParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + SysParser() = delete; + SysParser(const Diagnostic::LowLevel::SysParser &parser)= delete; + ~SysParser(){}; + SysParser(Diagnostic::LowLevel::SysParser &&parser)=delete; + + void parseInfo(); + +}; + + +class Diagnostic::LowLevel::EthMonitorParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + EthMonitorParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + EthMonitorParser() = delete; + EthMonitorParser(const Diagnostic::LowLevel::EthMonitorParser &parser)= delete; + ~EthMonitorParser(){}; + EthMonitorParser(Diagnostic::LowLevel::EthMonitorParser &&parser)=delete; + + void parseInfo(); + +}; + +class Diagnostic::LowLevel::InertialSensorParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + InertialSensorParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + InertialSensorParser() = delete; + InertialSensorParser(const Diagnostic::LowLevel::InertialSensorParser &parser) = delete; + ~InertialSensorParser(){}; + InertialSensorParser(Diagnostic::LowLevel::InertialSensorParser &&parser) = delete; + + void parseInfo(); +}; + +class Diagnostic::LowLevel::AnalogSensorParser : public Diagnostic::LowLevel::DefaultParser +{ +public: + AnalogSensorParser(Diagnostic::LowLevel::AuxEmbeddedInfo &dnginfo, Diagnostic::LowLevel::EntityNameProvider &entityNameProvider); + AnalogSensorParser() = delete; + AnalogSensorParser(const Diagnostic::LowLevel::AnalogSensorParser &parser) = delete; + ~AnalogSensorParser(){}; + AnalogSensorParser(Diagnostic::LowLevel::AnalogSensorParser &&parser) = delete; + + void parseInfo(); +}; + + + +#endif //__diagnosticLowLevelFormatter_hid_h__ diff --git a/src/libraries/icubmod/embObjLib/ethManager.cpp b/src/libraries/icubmod/embObjLib/ethManager.cpp index 18dbad89fa..75b2af226f 100755 --- a/src/libraries/icubmod/embObjLib/ethManager.cpp +++ b/src/libraries/icubmod/embObjLib/ethManager.cpp @@ -524,6 +524,13 @@ IethResource* TheEthManager::getInterface(eOipv4addr_t ipv4, eOprotID32_t id32) } +IethResource* TheEthManager::getInterface(eOipv4addr_t ipv4, iethresType_t type) +{ + IethResource *interfacePointer = ethBoards->get_interface(ipv4, type); + + return interfacePointer; +} + double TheEthManager::getLifeTime(void) { return(yarp::os::Time::now() - startUpTime); diff --git a/src/libraries/icubmod/embObjLib/ethManager.h b/src/libraries/icubmod/embObjLib/ethManager.h index cd26fdee1d..560bd57b01 100755 --- a/src/libraries/icubmod/embObjLib/ethManager.h +++ b/src/libraries/icubmod/embObjLib/ethManager.h @@ -129,6 +129,8 @@ namespace eth { IethResource* getInterface(eOipv4addr_t ipv4, eOprotID32_t id32); + IethResource* getInterface(eOipv4addr_t ipv4, iethresType_t type); + int getNumberOfResources(void); const string & getName(eOipv4addr_t ipv4); diff --git a/src/libraries/icubmod/embObjLib/protocolCallbacks/EoProtocolMN_fun_userdef.c b/src/libraries/icubmod/embObjLib/protocolCallbacks/EoProtocolMN_fun_userdef.c index c54f809e60..8edc9b9626 100644 --- a/src/libraries/icubmod/embObjLib/protocolCallbacks/EoProtocolMN_fun_userdef.c +++ b/src/libraries/icubmod/embObjLib/protocolCallbacks/EoProtocolMN_fun_userdef.c @@ -225,15 +225,11 @@ static void s_eoprot_print_mninfo_status(eOmn_info_basic_t* infobasic, uint8_t * { s_process_CANPRINT(infobasic, extra, nv, rd); } - else if(eoerror_category_Config == category) - { - s_process_category_Config(infobasic, extra, nv, rd); - } else { - s_process_category_Default(infobasic, extra, nv, rd); + feat_manage_diagnostic(infobasic, extra, nv, rd); } - + } diff --git a/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.cpp b/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.cpp index fae9d10774..10245ff8fd 100644 --- a/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.cpp +++ b/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.cpp @@ -1503,7 +1503,7 @@ void embObjMotionControl::cleanup(void) } - + //////////////// IethResource INTERFACE eth::iethresType_t embObjMotionControl::type() { return eth::iethres_motioncontrol; @@ -1568,6 +1568,20 @@ bool embObjMotionControl::update(eOprotID32_t id32, double timestamp, void *rxda } +bool embObjMotionControl::getEntityName(uint32_t entityId, std::string &entityName) +{ + bool ret = getAxisNameRaw(entityId, entityName); + + //since getAxisNameRaw set "ERROR" in entityName when an error occurred, + //while this function has to return an empty string, I reset the entityName string + if(!ret) + { + entityName.clear(); + } + return ret; + +} + ///////////// PID INTERFACE bool embObjMotionControl::setPidRaw(const PidControlTypeEnum& pidtype, int j, const Pid &pid) { diff --git a/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.h b/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.h index 336b09dc62..edac70c9d4 100644 --- a/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.h +++ b/src/libraries/icubmod/embObjMotionControl/embObjMotionControl.h @@ -358,6 +358,7 @@ class yarp::dev::embObjMotionControl: public DeviceDriver, virtual bool initialised(); virtual eth::iethresType_t type(); virtual bool update(eOprotID32_t id32, double timestamp, void *rxdata); + virtual bool getEntityName(uint32_t entityId, std::string &entityName); ///////// PID INTERFACE ///////// virtual bool setPidRaw(const PidControlTypeEnum& pidtype, int j, const Pid &pid) override; From 7310d51fddcbce6a039fe40e7a69b09fd60a60fa Mon Sep 17 00:00:00 2001 From: Jacopo Date: Thu, 15 Jun 2023 17:53:12 +0200 Subject: [PATCH 02/10] Add parser rule string to Default Parser --- src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index b5ed322114..5a41e29563 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -26,13 +26,14 @@ void DefaultParser::parseInfo() { char str[512] = {0}; uint8_t *p64 = (uint8_t*)&(m_dnginfo.param64); - snprintf(str, sizeof(str), " src %s, adr %d,(code 0x%.8x, par16 0x%.4x par64 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x) -> %s %s", + snprintf(str, sizeof(str), " src %s, adr %d,(code 0x%.8x, par16 0x%.4x par64 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x) -> %s %s %s", m_dnginfo.baseInfo.sourceCANPortStr.c_str(), m_dnginfo.baseInfo.sourceCANBoardAddr, m_dnginfo.errorCode, m_dnginfo.param16, p64[7], p64[6], p64[5], p64[4], p64[3], p64[2], p64[1], p64[0], eoerror_code2string(m_dnginfo.errorCode), + eoerror_code2rulesstring(m_dnginfo.errorCode), m_dnginfo.extraMessage.c_str() ); m_dnginfo.baseInfo.finalMessage.clear(); @@ -52,6 +53,7 @@ void ConfigParser::parseInfo() { char str[512] = {0}; eOerror_value_t value = eoerror_code2value(m_dnginfo.errorCode); + m_dnginfo.baseInfo.finalMessage.clear(); switch(value) From 6a5edbfed83a0fa650499a0457726533fb024dc3 Mon Sep 17 00:00:00 2001 From: Jacopo Date: Fri, 16 Jun 2023 10:03:09 +0200 Subject: [PATCH 03/10] Add missing error class to switch case for error class unique pointer --- src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp index 8033667e08..79c4455555 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp @@ -72,6 +72,12 @@ bool InfoFormatter::getDiagnosticInfo(EmbeddedInfo &info) case eoerror_category_ETHmonitor: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + case eoerror_category_Skin: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_InertialSensor: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + + case eoerror_category_AnalogSensor: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; + default: parser_ptr = std::make_unique(dnginfo, entityNameProvider); break; }; From b8be7820d7d3d7dd3785f85ec5940c5b6848748a Mon Sep 17 00:00:00 2001 From: Jacopo Date: Fri, 16 Jun 2023 12:21:05 +0200 Subject: [PATCH 04/10] Define specific parser for errors eoerror_value_SYS_canservices_boards_lostcontact and eoerror_value_SYS_canservices_boards_retrievedcontact --- .../embObjLib/diagnosticInfoParsers.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index 5a41e29563..e9fbcc4d2d 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -293,7 +293,10 @@ void ConfigParser::parseInfo() m_dnginfo.baseInfo.finalMessage.append(str); } - snprintf(str, sizeof(str), "Missing can boards on (can1map, can2map) = (0x%.4x, 0x%.4x) and found but incompatible can boards on (can1map, can2map) = (0x%.4x, 0x%.4x)"); + snprintf(str, sizeof(str), "Missing can boards on (can1map, can2map) = (0x%.4x, 0x%.4x) and found but incompatible can boards on (can1map, can2map) = (0x%.4x, 0x%.4x)", + missMaskcan1, missMaskcan2, + incompMaskcan1, incompMaskcan2 + ); m_dnginfo.baseInfo.finalMessage.append(str); } break; @@ -320,6 +323,7 @@ void ConfigParser::parseInfo() appl.major, appl.minor, strain ); + m_dnginfo.baseInfo.finalMessage.append(str); } break; case eoerror_value_CFG_mais_ok: @@ -1092,6 +1096,22 @@ void SysParser::parseInfo() }break; + case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: make a specific message.need some translation from enum to string + { + eOmn_serv_category_t serv_category = m_dnginfo.param16; + uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + + snprintf(str, sizeof(str), "%s Type of service category is %u. Lost can boards on (can1map, can2map) = (0x%.4x, 0x%.4x)", + m_dnginfo.baseMessage.c_str(), + eomn_servicecategory2string(serv_category), + lostMaskcan1, lostMaskcan2 + ); + + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + case eoerror_value_SYS_unspecified: case eoerror_value_SYS_tobedecided: @@ -1116,8 +1136,6 @@ void SysParser::parseInfo() case eoerror_value_SYS_canservices_boards_searched: case eoerror_value_SYS_canservices_boards_found: case eoerror_value_SYS_transceiver_rxinvalidframe_error: - case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: make a specific message.need some translation from enum to string - case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: make a specific message.need some translation from enum to string case eoerror_value_SYS_canservices_monitor_regularcontact: //TODO: make a specific message.need some translation from enum to string case eoerror_value_SYS_canservices_monitor_lostcontact: //TODO: make a specific message.need some translation from enum to string case eoerror_value_SYS_canservices_monitor_stillnocontact://TODO: make a specific message.need some translation from enum to string From 65c3d9249a5fa63a8a72c7d4c5f0281b9bd6bdd4 Mon Sep 17 00:00:00 2001 From: Jacopo Date: Fri, 16 Jun 2023 14:05:29 +0200 Subject: [PATCH 05/10] Update all missing messages --- .../icubmod/embObjLib/diagnosticInfo.h | 4 +- .../embObjLib/diagnosticInfoParsers.cpp | 73 +++++++++++++++++-- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfo.h b/src/libraries/icubmod/embObjLib/diagnosticInfo.h index 592d7468f3..30a8319248 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfo.h +++ b/src/libraries/icubmod/embObjLib/diagnosticInfo.h @@ -35,9 +35,9 @@ class Diagnostic::EmbeddedInfo { public: std::string sourceBoardIpAddrStr; // is the ipv4 address, in string, of the board that sends the diagnostic information - std::string sourceBoardName; // is the name of the board that sends the diagnostic information + std::string sourceBoardName; // is the name of the board that sends the diagnostic information std::string sourceCANPortStr; // if the diagnostic info si sent by a board on CAN, this field contains the CAN port expressed in string - uint8_t sourceCANBoardAddr; // if the diagnostic info si sent by a board on CAN, this field contains the CAN address of the board + uint8_t sourceCANBoardAddr; // if the diagnostic info is sent by a board on CAN, this field contains the CAN address of the board std::string finalMessage; // contains the final diagostic message after the parsering Diagnostic::SeverityOfError severity; // is the severity of the message Diagnostic::TimeOfInfo timeOfInfo; //it is the time of the board when it sent the message diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index e9fbcc4d2d..7c4bff2dd7 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -1096,8 +1096,8 @@ void SysParser::parseInfo() }break; - case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: make a specific message.need some translation from enum to string - case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: DONE (see eomn_servicecategory2string) make a specific message.need some translation from enum to string + case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: DONE (see eomn_servicecategory2string) make a specific message.need some translation from enum to string { eOmn_serv_category_t serv_category = m_dnginfo.param16; uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; @@ -1112,6 +1112,71 @@ void SysParser::parseInfo() m_dnginfo.baseInfo.finalMessage.append(str); } break; +/** + * {eoerror_value_SYS_canservices_monitor_regularcontact, "SYS: a service has verified that the TX of its CAN boards is regular. In sourceaddress the eOmn_serv_category_t, in par64 LS 32 bits the bit mask of boards (CAN1 in MS 16 bits and CAN2 in LS 16 bits)"}, + {eoerror_value_SYS_canservices_monitor_lostcontact, "SYS: a service has detected that some CAN boards have stopped transmission. In sourceaddress the eOmn_serv_category_t, in par64 LS 32 bits the bit mask of lost board (CAN1 in MS 16 bits and CAN2 in LS 16 bits), in in par64 MS 32 bits the time in ms since last contact"}, + {eoerror_value_SYS_canservices_monitor_stillnocontact, "SYS: a service has detected that some CAN boards are still not transmitting. In sourceaddress the eOmn_serv_category_t, in par64 LS 32 bits the bit mask of lost board (CAN1 in MS 16 bits and CAN2 in LS 16 bits), in in par64 MS 32 bits the total disappearence time in ms"}, + {eoerror_value_SYS_canservices_monitor_retrievedcontact, "SYS: a service has recovered all CAN boards that were not transmitting. In sourceaddress the eOmn_serv_category_t)"} + +*/ + case eoerror_value_SYS_canservices_monitor_retrievedcontact: //TODO: make a specific message.need some translation from enum to string + { + eOmn_serv_category_t serv_category = m_dnginfo.baseInfo.sourceCANBoardAddr; + snprintf(str, sizeof(str), "%s Type of service category is %u.", + m_dnginfo.baseMessage.c_str(), + eomn_servicecategory2string(serv_category) + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SYS_canservices_monitor_regularcontact: //TODO: make a specific message.need some translation from enum to string + { + eOmn_serv_category_t serv_category = m_dnginfo.baseInfo.sourceCANBoardAddr; + uint16_t maskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t maskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + snprintf(str, sizeof(str), "%s Type of service category is %u. CAN boards are on (can1map, can2map) = (0x%.4x, 0x%.4x)", + m_dnginfo.baseMessage.c_str(), + eomn_servicecategory2string(serv_category), + maskcan1, + maskcan2 + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SYS_canservices_monitor_lostcontact: //TODO: make a specific message.need some translation from enum to string + { + eOmn_serv_category_t serv_category = m_dnginfo.baseInfo.sourceCANBoardAddr; + uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + uint64_t timeLastContact = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + + snprintf(str, sizeof(str), "%s Type of service category is %u. Lost CAN boards are on (can1map, can2map) = (0x%.4x, 0x%.4x). Time since last contact: %d", + m_dnginfo.baseMessage.c_str(), + eomn_servicecategory2string(serv_category), + lostMaskcan1, + lostMaskcan2, + timeLastContact + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + + case eoerror_value_SYS_canservices_monitor_stillnocontact://TODO: make a specific message.need some translation from enum to string + { + eOmn_serv_category_t serv_category = m_dnginfo.baseInfo.sourceCANBoardAddr; + uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + uint64_t totDisappTime = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + + snprintf(str, sizeof(str), "%s Type of service category is %u. Lost CAN boards are on (can1map, can2map) = (0x%.4x, 0x%.4x). Total disappearance time: %d", + m_dnginfo.baseMessage.c_str(), + eomn_servicecategory2string(serv_category), + lostMaskcan1, + lostMaskcan2, + totDisappTime + ); + m_dnginfo.baseInfo.finalMessage.append(str); + } break; + case eoerror_value_SYS_unspecified: case eoerror_value_SYS_tobedecided: @@ -1136,10 +1201,6 @@ void SysParser::parseInfo() case eoerror_value_SYS_canservices_boards_searched: case eoerror_value_SYS_canservices_boards_found: case eoerror_value_SYS_transceiver_rxinvalidframe_error: - case eoerror_value_SYS_canservices_monitor_regularcontact: //TODO: make a specific message.need some translation from enum to string - case eoerror_value_SYS_canservices_monitor_lostcontact: //TODO: make a specific message.need some translation from enum to string - case eoerror_value_SYS_canservices_monitor_stillnocontact://TODO: make a specific message.need some translation from enum to string - case eoerror_value_SYS_canservices_monitor_retrievedcontact: //TODO: make a specific message.need some translation from enum to string { snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); m_dnginfo.baseInfo.finalMessage.append(str); From 40d1c490db9df69e64fc58d96b16a6d5f75357b9 Mon Sep 17 00:00:00 2001 From: Jacopo Date: Fri, 16 Jun 2023 15:49:41 +0200 Subject: [PATCH 06/10] Add for loops for getting board can address from number of erroneous boards. todo: bring that to method --- .../embObjLib/diagnosticInfoParsers.cpp | 102 ++++++++++++++---- 1 file changed, 84 insertions(+), 18 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index 7c4bff2dd7..734f90e603 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -206,8 +206,6 @@ void ConfigParser::parseInfo() ); m_dnginfo.baseInfo.finalMessage.append(str); - - for(i=1; i<15; i++) { uint64_t val = (invalidmask >> (4*i)) & 0x0f; @@ -219,7 +217,8 @@ void ConfigParser::parseInfo() ((val & 0x1) == 0x1) ? (wrongtype) : (empty), ((val & 0x2) == 0x2) ? (wrongappl) : (empty), ((val & 0x4) == 0x4) ? (wrongprot) : (empty) - ); + ); + m_dnginfo.baseInfo.finalMessage.append(str); n++; @@ -460,7 +459,7 @@ void ConfigParser::parseInfo() if(secondary_enc_with_error) { - primary_error_code = ( (errorenc2 & (0xf <> 4*i); + secondary_error_code = ( (errorenc2 & (0xf <> 4*i); m_entityNameProvider.getAxisName(i, m_dnginfo.baseInfo.axisName); snprintf(str, sizeof(str), " joint %d (%s) has error on secodary encoder (code=%d)", i, m_dnginfo.baseInfo.axisName.c_str(), secondary_error_code); //TODO: get a string instead of a code @@ -1102,14 +1101,31 @@ void SysParser::parseInfo() eOmn_serv_category_t serv_category = m_dnginfo.param16; uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + char lostCanBoards1[64] = {0}; + char lostCanBoards2[64] = {0}; + + for(i=1; i<15; i++) + { + if ( (lostMaskcan1 & (1<> 16; - uint16_t maskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); - snprintf(str, sizeof(str), "%s Type of service category is %u. CAN boards are on (can1map, can2map) = (0x%.4x, 0x%.4x)", + uint16_t foundMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; + uint16_t foundMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); + char foundCanBoards1[64] = {0}; + char foundCanBoards2[64] = {0}; + + for(i=1; i<15; i++) + { + if ( (foundMaskcan1 & (1<> 16; uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); uint64_t timeLastContact = (m_dnginfo.param64 & 0xffff000000000000) >> 48; + char lostCanBoards1[64] = {0}; + char lostCanBoards2[64] = {0}; + + for(i=1; i<15; i++) + { + if ( (lostMaskcan1 & (1<> 48; - snprintf(str, sizeof(str), "%s Type of service category is %u. Lost CAN boards are on (can1map, can2map) = (0x%.4x, 0x%.4x). Total disappearance time: %d", + char lostCanBoards1[64] = {0}; + char lostCanBoards2[64] = {0}; + + for(i=1; i<15; i++) + { + if ( (lostMaskcan1 & (1< Date: Fri, 16 Jun 2023 17:59:37 +0200 Subject: [PATCH 07/10] Fix errors and version - check todos left --- conf/iCubFindDependencies.cmake | 4 ++-- .../icubmod/embObjLib/diagnosticInfoParsers.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/conf/iCubFindDependencies.cmake b/conf/iCubFindDependencies.cmake index a74f740741..d2db400ec6 100644 --- a/conf/iCubFindDependencies.cmake +++ b/conf/iCubFindDependencies.cmake @@ -65,8 +65,8 @@ checkandset_dependency(OpenCV) checkandset_dependency(Qt5) if(icub_firmware_shared_FOUND AND ICUB_USE_icub_firmware_shared) - if(icub_firmware_shared_VERSION VERSION_LESS 1.35.0) - message(FATAL_ERROR "An old version of icub-firmware-shared has been detected: at least 1.35.0 is required") + if(icub_firmware_shared_VERSION VERSION_LESS 1.35.1) + message(FATAL_ERROR "An old version of icub-firmware-shared has been detected: at least 1.35.1 is required") endif() endif() diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index 734f90e603..a0ef2e9fc3 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -810,6 +810,7 @@ void SysParser::parseInfo() case eoerror_value_SYS_ctrloop_execoverflowRX: { + // TODO: check if time to show is TX. Shouldn't be RX in this case? snprintf(str, sizeof(str), " %s RX execution time %d[usec]. Latest previous execution times of TX, RX, DO, TX %ld[usec]", m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, m_dnginfo.param64); m_dnginfo.baseInfo.finalMessage.append(str); }break; @@ -822,11 +823,10 @@ void SysParser::parseInfo() case eoerror_value_SYS_ctrloop_execoverflowTX: { - snprintf(str, sizeof(str), " %s TX execution time %d[usec]. Latest previous execution times of TX, RX, DO %ld[usec]. Num of frames in tx queue: CAN1 is %d, CAN2 is %d ", - m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, - (m_dnginfo.param64&0x0000ffffffffffff), - (int16_t)((m_dnginfo.param64&0x00ff000000000000)>>48), - (int16_t)((m_dnginfo.param64&0xff00000000000000)>>56) ); + // TODO: ask suggested the usec time (last parsed value is just one value, not 4) --> do I need to mask it or printing just par64 as int does the job? + snprintf(str, sizeof(str), " %s TX execution time %d[usec]. Latest previous execution times of TX, RX, DO %ld[usec]", + m_dnginfo.baseMessage.c_str(), m_dnginfo.param16, m_dnginfo.param64 + ); m_dnginfo.baseInfo.finalMessage.append(str); }break; @@ -1125,7 +1125,7 @@ void SysParser::parseInfo() ); m_dnginfo.baseInfo.finalMessage.append(str); - + } break; /** @@ -1197,7 +1197,7 @@ void SysParser::parseInfo() } } - snprintf(str, sizeof(str), "%s Type of service category is %s. Lost CAN boards are on (can1map, can2map) = ([ %s ], [ %s ]). Time since last contact: %d", + snprintf(str, sizeof(str), "%s Type of service category is %s. Lost CAN boards are on (can1map, can2map) = ([ %s ], [ %s ]). Time since last contact: %d [ms]", m_dnginfo.baseMessage.c_str(), eomn_servicecategory2string(serv_category), lostCanBoards1, @@ -1233,7 +1233,7 @@ void SysParser::parseInfo() } } - snprintf(str, sizeof(str), "%s Type of service category is %s. Lost CAN boards are on (can1map, can2map) = ([ %s ] , [ %s ]). Total disappearance time: %d", + snprintf(str, sizeof(str), "%s Type of service category is %s. Lost CAN boards are on (can1map, can2map) = ([ %s ] , [ %s ]). Total disappearance time: %d [ms]", m_dnginfo.baseMessage.c_str(), eomn_servicecategory2string(serv_category), lostCanBoards1, From 5e1c3baae7aa2738950900771e9886a6026dff7c Mon Sep 17 00:00:00 2001 From: Jacopo Date: Mon, 19 Jun 2023 13:40:37 +0200 Subject: [PATCH 08/10] Fix strcat in for loops --- .../embObjLib/diagnosticInfoParsers.cpp | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index a0ef2e9fc3..06aa8de805 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -1108,12 +1108,14 @@ void SysParser::parseInfo() { if ( (lostMaskcan1 & (1< Date: Tue, 4 Jul 2023 15:49:30 +0200 Subject: [PATCH 09/10] Fix string initialization when printing base info --- .../embObjLib/diagnosticInfoParsers.cpp | 74 +++++++++---------- .../diagnosticLowLevelFormatter_hid.h | 2 + 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index 06aa8de805..3e5920d469 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -41,6 +41,12 @@ void DefaultParser::parseInfo() } +void DefaultParser::printBaseInfo() +{ + char str[512] = {0}; + snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); + m_dnginfo.baseInfo.finalMessage.append(str); +} /**************************************************************************************************************************/ @@ -206,7 +212,7 @@ void ConfigParser::parseInfo() ); m_dnginfo.baseInfo.finalMessage.append(str); - for(i=1; i<15; i++) + for(int i=1; i<15; i++) { uint64_t val = (invalidmask >> (4*i)) & 0x0f; if(0 != val) @@ -420,10 +426,8 @@ void ConfigParser::parseInfo() case eoerror_value_CFG_bat_not_verified_yet: case eoerror_value_CFG_bat_using_onboard_config: case eoerror_value_CFG_bat_failed_notsupported: - //case eoerror_value_CFG_encoders_ok: { - snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); - m_dnginfo.baseInfo.finalMessage.append(str); + printBaseInfo(); } break; // p16&0xf000: number of joint; primary encs: failure mask in p16&0x000f and errorcodes in p64&0x0000ffff; secondary encs: failure mask in p16&0x00f0 and errorcodes in p64&0xffff0000"}, @@ -659,11 +663,10 @@ void SkinParser::parseInfo() switch (value) { - case eoerror_value_SYS_unspecified: + case eoerror_value_SK_unspecified: case eoerror_value_SK_obsoletecommand: { - snprintf(str, sizeof(str), "%s", m_dnginfo.baseMessage.c_str()); - m_dnginfo.baseInfo.finalMessage.append(str); + printBaseInfo(); } break; case eoerror_value_SK_arrayofcandataoverflow: @@ -752,8 +755,7 @@ void HwErrorParser::parseInfo() case eoerror_value_HW_encoder_crc: case eoerror_value_HW_encoder_not_connected: { - snprintf(str, sizeof(str), " %s", m_dnginfo.baseMessage.c_str()); - m_dnginfo.baseInfo.finalMessage.append(str); + printBaseInfo(); } break; @@ -1098,23 +1100,23 @@ void SysParser::parseInfo() case eoerror_value_SYS_canservices_boards_lostcontact: //TODO: DONE (see eomn_servicecategory2string) make a specific message.need some translation from enum to string case eoerror_value_SYS_canservices_boards_retrievedcontact://TODO: DONE (see eomn_servicecategory2string) make a specific message.need some translation from enum to string { - eOmn_serv_category_t serv_category = m_dnginfo.param16; + eOmn_serv_category_t serv_category = (eOmn_serv_category_t)m_dnginfo.param16; uint16_t lostMaskcan2 = (m_dnginfo.param64 & 0x00000000ffff0000) >> 16; uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); char lostCanBoards1[64] = {0}; char lostCanBoards2[64] = {0}; - for(i=1; i<15; i++) + for(int i=1; i<15; i++) { if ( (lostMaskcan1 & (1<> 16; uint16_t foundMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); char foundCanBoards1[64] = {0}; char foundCanBoards2[64] = {0}; - for(i=1; i<15; i++) + for(int i=1; i<15; i++) { if ( (foundMaskcan1 & (1<> 16; uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); uint64_t timeLastContact = (m_dnginfo.param64 & 0xffff000000000000) >> 48; char lostCanBoards1[64] = {0}; char lostCanBoards2[64] = {0}; - for(i=1; i<15; i++) + for(int i=1; i<15; i++) { if ( (lostMaskcan1 & (1<> 16; uint16_t lostMaskcan1 = (m_dnginfo.param64 & 0x000000000000ffff); uint64_t totDisappTime = (m_dnginfo.param64 & 0xffff000000000000) >> 48; @@ -1223,22 +1225,22 @@ void SysParser::parseInfo() char lostCanBoards1[64] = {0}; char lostCanBoards2[64] = {0}; - for(i=1; i<15; i++) + for(int i=1; i<15; i++) { if ( (lostMaskcan1 & (1< Date: Thu, 27 Jul 2023 13:30:54 +0000 Subject: [PATCH 10/10] Improve diagnostic parser for eoerror_value_CFG_candiscovery_boardsinvalid --- src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp index 3e5920d469..72f5f4c78c 100644 --- a/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp +++ b/src/libraries/icubmod/embObjLib/diagnosticInfoParsers.cpp @@ -204,7 +204,7 @@ void ConfigParser::parseInfo() const char *wrongprot = "WRONG PROTOCOL VERSION"; const char *wrongappl = "WRONG APPLICATION VERSION"; - snprintf(str, sizeof(str), "%s %d invalid %s boards in %s:", + snprintf(str, sizeof(str), "%s %d invalid %s boards in %s:\n", m_dnginfo.baseMessage.c_str(), numofinvalid, canboardname, @@ -217,9 +217,8 @@ void ConfigParser::parseInfo() uint64_t val = (invalidmask >> (4*i)) & 0x0f; if(0 != val) { - snprintf(str, sizeof(str), "%d of %d: wrong %s BOARD %s:%s:%d because it has: %s %s %s", + snprintf(str, sizeof(str), "\t %d of %d: wrong %s because it has: %s%s%s \n", n, numofinvalid, canboardname, - m_dnginfo.baseInfo.sourceBoardIpAddrStr.c_str(), m_dnginfo.baseInfo.sourceCANPortStr.c_str(), i, ((val & 0x1) == 0x1) ? (wrongtype) : (empty), ((val & 0x2) == 0x2) ? (wrongappl) : (empty), ((val & 0x4) == 0x4) ? (wrongprot) : (empty)