From 947c78887e791596d4a5ec2d1079f8b1a049628b Mon Sep 17 00:00:00 2001 From: takeshi_hoshina Date: Tue, 27 Oct 2020 11:16:21 +0900 Subject: basesystem 0.1 --- .../server/src/heartbeat/ss_hb_session.cpp | 415 +++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 systemservice/system_manager/server/src/heartbeat/ss_hb_session.cpp (limited to 'systemservice/system_manager/server/src/heartbeat/ss_hb_session.cpp') diff --git a/systemservice/system_manager/server/src/heartbeat/ss_hb_session.cpp b/systemservice/system_manager/server/src/heartbeat/ss_hb_session.cpp new file mode 100644 index 00000000..8178e46d --- /dev/null +++ b/systemservice/system_manager/server/src/heartbeat/ss_hb_session.cpp @@ -0,0 +1,415 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_SystemManager +/// \brief This file provides support for the application heartbeat system. +/// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ss_sm_systemmanagerlog.h" +#include "ss_hb_thread.h" +#include "ss_hb_session.h" +#include "ss_system_manager.h" + +using namespace std; // NOLINT + +CHeartBeatSessionHandler::CHeartBeatSessionHandler() { +} + +CHeartBeatSessionHandler::~CHeartBeatSessionHandler() { // LCOV_EXCL_START 14: Resident process, not called by NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert +} +// LCOV_EXCL_STOP + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HbSessionInfo + @note: HbSessionInfo constructor + @param + @return + *****************************************************************************/ +CHeartBeatSessionHandler::HbSessionInfo::HbSessionInfo(SubscriberName f_Subscriber) { + fRunning = FALSE; + fHeartBeatRequestSent = FALSE; + fHeartBeatResponseReceived = FALSE; + HeartBeatRetryCount = 0; + fHeartBeatTimedOut = FALSE; + hSession = NULL; + szName = f_Subscriber; + fisAvailability = FALSE; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBEntrySubscriber + @note: + @param + @return + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBEntrySubscriber(SubscriberName &f_Subscriber) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + // check if the subscriber is already in map + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(f_Subscriber); + + // the l_SessionInfoIterator is set to the end then the subscriber is not in the map + if (m_mapHbSessions.end() == l_SessionInfoIterator) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Entry Subscriber : %s", f_Subscriber.c_str()); + HbSessionInfo l_NewHBClientSessionInfo(f_Subscriber.c_str()); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + pair ret; + // insert new subscriber entry into the session map + ret = m_mapHbSessions.insert(std::make_pair(f_Subscriber, l_NewHBClientSessionInfo)); + if (!ret.second) { // LCOV_EXCL_BR_LINE 6:l_NewHBClientSessionInfo must not be NULL. + // LCOV_EXCL_START 6:l_NewHBClientSessionInfo must not be NULL. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusFail; + SS_ASERT(0); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + // LCOV_EXCL_STOP + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, "Subscriber '%s' is already in the map", f_Subscriber.c_str()); + } + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: ProcessHBClientResponse + @note: Process the response received from client, update relevant structure data + @param HANDLE + @return EFrameworkunifiedStatus + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBProcessClientResponse(HANDLE f_hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "+"); + BOOL l_availability = FALSE; + + if (eFrameworkunifiedStatusOK != (l_eStatus = ReadMsg(f_hThread, l_availability))) { + LOG_ERROR("ReadMsg()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + + // find the subscriber... + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(FrameworkunifiedGetMsgSrc(f_hThread)); + + // the l_SessionInfoIterator is set to the end then the subscriber is not in the map + if (m_mapHbSessions.end() != l_SessionInfoIterator) { + l_SessionInfoIterator->second.HeartBeatRetryCount = 0; + l_SessionInfoIterator->second.fHeartBeatResponseReceived = TRUE; + l_SessionInfoIterator->second.fHeartBeatRequestSent = FALSE; + l_SessionInfoIterator->second.fisAvailability = l_availability; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, + "HeartBeat received from module: %s ", l_SessionInfoIterator->first.c_str()); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, + "Ignoring Heart Beat Response, Client: %s not found in the map!", FrameworkunifiedGetMsgSrc(f_hThread)); + } + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBPrintConnection + @note: .Print registered client information + @param VOID + @return VOID + *****************************************************************************/ +VOID CHeartBeatSessionHandler::HBPrintConnection() { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + // find the subscriber... + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin(); + for (; l_SessionInfoIterator != m_mapHbSessions.end(); l_SessionInfoIterator++) { + FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__, + "HeartBeat Service is Connected to: %s via a Session: Running: %s ", + l_SessionInfoIterator->second.szName.data(), + (l_SessionInfoIterator->second.fRunning ? "YES" : "NO")); + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBPrintStack + @note: .Print registered client information + @param VOID + @return VOID + *****************************************************************************/ +VOID CHeartBeatSessionHandler::HBPrintStack(UI_32 f_MaxHeartBeatRetryCount) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + // find the subscriber... + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin(); + for (; l_SessionInfoIterator != m_mapHbSessions.end(); l_SessionInfoIterator++) { + if (FALSE == l_SessionInfoIterator->second.fHeartBeatResponseReceived) { + FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__, + "HeartBeat Service is Connected to: %s via a Session: Running: %s ", + l_SessionInfoIterator->second.szName.data(), + (l_SessionInfoIterator->second.fRunning ? "YES" : "NO")); + FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__, + "Retry count (%d) within limit (%d), HeartBeatTimedout = %s", + l_SessionInfoIterator->second.HeartBeatRetryCount, + f_MaxHeartBeatRetryCount, + (l_SessionInfoIterator->second.fHeartBeatTimedOut == TRUE ? + "TRUE" : "FALSE")); + } + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBCheckResponses + @note: Check if all clients have replied to heartbeat query and generate report + @param THbReportData Report structure to be filled + @param UI_32 Heartbeat max retry count + @return eFrameworkunifiedStatusFail if one or more modules have timed out, eFrameworkunifiedStatusOK otherwise. + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBCheckResponses( + THbReportData &f_tReportData, UI_32 f_MaxHeartBeatRetryCount, + SI_32 f_HeartBeatIntervalRepeat, SI_32 f_ChkIndex) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin(); + memset(&f_tReportData, 0, sizeof(THbReportData)); + + int index = 0; + + while (l_SessionInfoIterator != m_mapHbSessions.end()) { + if (f_ChkIndex == (index % f_HeartBeatIntervalRepeat)) { + // check if report queue is full + // LCOV_EXCL_BR_START 6: f_tReportData.nNumOfModules can't more than SS_MAX_NUM_MODULES + if (SS_MAX_NUM_MODULES <= f_tReportData.nNumOfModules) { + // LCOV_EXCL_BR_STOP + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: SS_MAX_NUM_MODULES '%d' <= f_tReportData.nNumOfModules '%d'. See ss_system_manager_if.h.", + SS_MAX_NUM_MODULES, f_tReportData.nNumOfModules); + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return eFrameworkunifiedStatusInvldBuf; + } + + + strncpy(f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcQueueName, + l_SessionInfoIterator->first.c_str(), + sizeof(f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcQueueName) - 1); + f_tReportData.tModuleList[f_tReportData.nNumOfModules].HeartBeatRetryCount = + l_SessionInfoIterator->second.HeartBeatRetryCount; + f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_GOOD; + + if (TRUE == l_SessionInfoIterator->second.fHeartBeatResponseReceived) { + l_SessionInfoIterator->second.fHeartBeatResponseReceived = FALSE; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, + "[%s] Heart Beat Response Received !", + l_SessionInfoIterator->second.szName.c_str()); + } else if (TRUE == l_SessionInfoIterator->second.fHeartBeatTimedOut) { + f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_TIMEOUT; + } else if ((TRUE == l_SessionInfoIterator->second.fHeartBeatRequestSent) + && (FALSE == l_SessionInfoIterator->second.fHeartBeatTimedOut)) { + l_SessionInfoIterator->second.HeartBeatRetryCount++; + + if (l_SessionInfoIterator->second.HeartBeatRetryCount > f_MaxHeartBeatRetryCount) { + l_eStatus = eFrameworkunifiedStatusFail; + l_SessionInfoIterator->second.fHeartBeatTimedOut = TRUE; + l_SessionInfoIterator->second.HeartBeatRetryCount = 0; + + f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_TIMEOUT; + + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: Heart Beat Retry count of [%s] has crossed max limit (%d)." + "Disabling sending HeartBeat query to it", + l_SessionInfoIterator->second.szName.c_str(), + f_MaxHeartBeatRetryCount); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: [%s] has missed a Heart Beat. Retry count (%d) is within max retry limit (%d)", + l_SessionInfoIterator->second.szName.c_str(), + l_SessionInfoIterator->second.HeartBeatRetryCount, + f_MaxHeartBeatRetryCount); + } + } + } + + f_tReportData.nNumOfModules++; + ++l_SessionInfoIterator; + index++; + } + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBSendRequest + @note: .Sent heart beat query to the registered clients + @param void + @return EFrameworkunifiedStatus +******************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBSendRequest(HANDLE f_hThread, + SI_32 f_HeartBeatIntervalRepeat, SI_32 f_ChkIndex) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + + // Get session iterator + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin(); + + if (l_SessionInfoIterator == m_mapHbSessions.end()) { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "No Client has opened session with HeartBeat"); + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; + } + + int index = 0; + + while (l_SessionInfoIterator != m_mapHbSessions.end()) { + if (f_ChkIndex == (index % f_HeartBeatIntervalRepeat)) { + if (l_SessionInfoIterator->second.hSession == NULL) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL + l_SessionInfoIterator->second.hSession = FrameworkunifiedMcOpenSender(f_hThread, l_SessionInfoIterator->first.c_str()); + if (NULL == l_SessionInfoIterator->second.hSession) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL + // LCOV_EXCL_START 200: hSession must not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: FrameworkunifiedMcOpenSender(%s) returned NULL", + l_SessionInfoIterator->first.c_str()); + // LCOV_EXCL_STOP + } else { + l_SessionInfoIterator->second.fRunning = TRUE; + } + } + + if ((NULL != l_SessionInfoIterator->second.hSession) + && (FALSE == l_SessionInfoIterator->second.fHeartBeatTimedOut)) { + if (eFrameworkunifiedStatusOK == (l_eStatus = FrameworkunifiedSendMsg(l_SessionInfoIterator->second.hSession, SS_HEARTBEAT_REQUEST, 0, NULL))) { // LCOV_EXCL_BR_LINE 5:NSFW's error // NOLINT(whitespace/line_length) + /// TODO review if we are required to return failure if sending message to one process failed. + l_SessionInfoIterator->second.fHeartBeatResponseReceived = FALSE; + l_SessionInfoIterator->second.fHeartBeatRequestSent = TRUE; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, + "HeartBeat Request sent to : %s", l_SessionInfoIterator->first.c_str()); + } else { + // LCOV_EXCL_START 5:NSFW's error + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: FrameworkunifiedSendMsg(%s, SS_HEARTBEAT_REQUEST) errored: %d/'%s'", + l_SessionInfoIterator->first.c_str(), l_eStatus, + GetStr(l_eStatus).c_str()); + // LCOV_EXCL_STOP + } + } else { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, + " HeartBeat Request was not sent to '%s', timeout is '%s'", + l_SessionInfoIterator->first.c_str(), + (l_SessionInfoIterator->second.fHeartBeatTimedOut == TRUE ? "TRUE" : "FALSE")); + } + } + ++l_SessionInfoIterator; + index++; + } + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBDeleteRegisteredClientEntry + @note: . + @param + @return EFrameworkunifiedStatus +******************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBDeleteRegisteredClientEntry(HANDLE f_hThread, PSTR pQueueName) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + SubscriberName tQueuename(pQueueName); + + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Looking for %s.", tQueuename.c_str()); + + HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(tQueuename); + + if (m_mapHbSessions.end() != l_SessionInfoIterator) { + // Close the session handle + if (NULL != l_SessionInfoIterator->second.hSession) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL when tQueuename exists. // NOLINT(whitespace/line_length) + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedMcClose(l_SessionInfoIterator->second.hSession))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedMcClose()"); // LCOV_EXCL_LINE 4: NSFW error case. + } + l_SessionInfoIterator->second.hSession = NULL; + } + m_mapHbSessions.erase(tQueuename); + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Deleting '%s' Successful ", tQueuename.c_str()); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, + "%s not found in Heart beat client list", tQueuename.c_str()); + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBAvailableCheck + @note: . + @param + @return EFrameworkunifiedStatus +******************************************************************************/ +EFrameworkunifiedStatus CHeartBeatSessionHandler::HBAvailableCheck(THbAvailCheck &check) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + BOOL isOk = TRUE; + + std::list ngList; + for (HbSessionIter ite = m_mapHbSessions.begin(); ite != m_mapHbSessions.end(); ite++) { + if (ite->second.fisAvailability == FALSE) { + ngList.push_back(ite->first); + // Notify Last Service as Representative + snprintf(check.serviceName, SS_SM_HB_MAX_PROC_NAME_SIZE, "%s", ite->first.c_str()); + isOk = FALSE; + } + } + + if (isOk == FALSE) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "********* AVAILABILITY CHECK ERROR **********"); + fprintf(stderr, "HBOnAvailCheckRequest/********* AVAILABILITY CHECK ERROR **********\n"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + } else { + FRAMEWORKUNIFIEDLOG(ZONE_STATE, __FUNCTION__, "********* AVAILABILITY CHECK OK **********"); + fprintf(stderr, "HBOnAvailCheckRequest/********* AVAILABILITY CHECK OK **********\n"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + } + + for (std::list::iterator ite = ngList.begin(); ite != ngList.end(); ite++) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " %s", ite->c_str()); + fprintf(stderr, " %s\n", ite->c_str()); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + } + + check.isOk = isOk; + + return l_eStatus; +} -- cgit 1.2.3-korg