diff options
Diffstat (limited to 'systemservice/system_manager/server/src/heartbeat')
4 files changed, 1155 insertions, 0 deletions
diff --git a/systemservice/system_manager/server/src/heartbeat/ss_hb_if.cpp b/systemservice/system_manager/server/src/heartbeat/ss_hb_if.cpp new file mode 100644 index 00000000..a3c27776 --- /dev/null +++ b/systemservice/system_manager/server/src/heartbeat/ss_hb_if.cpp @@ -0,0 +1,201 @@ +/* + * @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 <native_service/frameworkunified_application.h> +#include <native_service/frameworkunified_framework_if.h> +#include <native_service/frameworkunified_service_protocol.h> +#include <ss_hb_thread.h> +#include <system_service/ss_sm_client_if.h> +#include <system_service/ss_heartbeat_notifications.h> +#include <system_service/ss_heartbeat_service_protocol.h> +#include <system_service/ss_templates.h> +#include <new> +#include "ss_sm_systemmanagerlog.h" + +template<typename C, eFrameworkunifiedStatus (C::*M)(HANDLE)> EFrameworkunifiedStatus HBThreadCallback(HANDLE hThread) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusNullPointer; + C * pObj = static_cast<C *>(FrameworkunifiedGetThreadSpecificData(hThread)); + if (pObj) { // LCOV_EXCL_BR_LINE 4:pObj must not be NULL + eStatus = (pObj->*M)(hThread); + } + return eStatus; +} + +static VOID DeletePObj(CHeartBeatThread * pObj) { // LCOV_EXCL_START 8: dead code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + delete pObj; +} +// LCOV_EXCL_STOP + +static VOID DeleteHBTimer(CHeartBeatThread * pObj) { // LCOV_EXCL_START 8: dead code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + EFrameworkunifiedStatus l_eStatus = pObj->HeartBeatTimersDelete(); + LOG_STATUS_IF_ERRORED(l_eStatus, "pObj->HeartBeatTimersDelete()"); +} +// LCOV_EXCL_STOP + +#define DetachParentCbThreadProtocols(hThread, handler) \ +{ \ + EFrameworkunifiedStatus l_eStatus = DetachParentCallbacksFromInterfaceunifiedDispatcher( \ + hThread, \ + handler, \ + static_cast<UI_32>(_countof(handler))); \ + LOG_STATUS_IF_ERRORED(l_eStatus, "DetachParentCallbacksFromInterfaceunifiedDispatcher()") \ +} + +#define DetachCbProtocols(hThread, f_pStr, f_protocolHandlers, hSession) \ +{ \ + EFrameworkunifiedStatus l_eStatus = \ + DetachCallbacksFromInterfaceunifiedDispatcher( \ + hThread, \ + f_pStr, \ + f_protocolHandlers, \ + static_cast<UI_32>(_countof(f_protocolHandlers)), \ + hSession); \ + LOG_STATUS_IF_ERRORED(l_eStatus, "DetachCallbacksFromInterfaceunifiedDispatcher()") \ +} + +/*****************************************************************************/ +/** + @ingroup: SS_SystemManager + @brief: HBThreadStart: function would be called at the time of starting of the thread + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus + */ +/*****************************************************************************/ +EFrameworkunifiedStatus HBThreadStart(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG0(ZONE_FUNC, __FUNCTION__, "+"); + + FrameworkunifiedProtocolCallbackHandler HBThreadCommonHandlers[] = { + // Command ID, Call back functions + { SS_HEARTBEAT_RESPONSE, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnClientResponse> }, + { SS_HEARTBEAT_PRINT_CONNECTIONS, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnPrintConnections> }, + { SS_HEARTBEAT_PRINT_STACK, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnPrintStack> } }; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + FrameworkunifiedProtocolCallbackHandler HBThreadProtocolHandlers[] = { + // Command ID, Call back functions + { SS_HEARTBEAT_START, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnStartThread> }, + { SS_HEARTBEAT_STOP, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnStopThread> }, + { SS_HEARTBEAT_DELETE_MODULE_ENTRY, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnRemoveModule> }, + { SS_HEARTBEAT_APPEND_MODULE_ENTRY, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnAppendModule> }, + { SS_HEARTBEAT_PERIODIC_STATUS_REQ, HBThreadCallback<CHeartBeatThread, + &CHeartBeatThread::HBOnPeriodicStatusRequest> }, + { SS_HEARTBEAT_AVAIL_CHECK_REQ, HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnAvailCheckRequest> } + }; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + CHeartBeatThread * pObj = new (std::nothrow) CHeartBeatThread(hThread); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + if (NULL == pObj) { // LCOV_EXCL_BR_LINE 5: Standard lib + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + l_eStatus = eFrameworkunifiedStatusNullPointer; // LCOV_EXCL_LINE 5: Standard lib + LOG_ERROR("new(std::nothrow) CHeartBeatThread(hThread)"); // LCOV_EXCL_LINE 5: Standard lib + // LCOV_EXCL_BR_START 6:always return eFrameworkunifiedStatusOK + } else if (eFrameworkunifiedStatusOK != (l_eStatus = pObj->HeartBeatTimerInit(hThread))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("pObj->HeartBeatTimerInit(hThread)"); // LCOV_EXCL_LINE 6:always return eFrameworkunifiedStatusOK + DeletePObj(pObj); // LCOV_EXCL_LINE 6:always return eFrameworkunifiedStatusOK + // LCOV_EXCL_BR_START 4: NSFW error case. + } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedAttachParentCallbacksToDispatcher(hThread, + HBThreadProtocolHandlers, static_cast<UI_32>(_countof(HBThreadProtocolHandlers))))) { + // LCOV_EXCL_BR_STOP + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedAttachParentCallbacksToDispatcher(HBThreadProtocolHandlers)"); + DeleteHBTimer(pObj); + DeletePObj(pObj); + // LCOV_EXCL_STOP + // LCOV_EXCL_BR_START 4: NSFW error case. + } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedAttachParentCallbacksToDispatcher(hThread, + HBThreadCommonHandlers, static_cast<UI_32>(_countof(HBThreadCommonHandlers))))) { + // LCOV_EXCL_BR_STOP + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedAttachParentCallbacksToDispatcher(HBThreadCommonHandlers)"); + DetachParentCbThreadProtocols(hThread, HBThreadProtocolHandlers); + DeleteHBTimer(pObj); + DeletePObj(pObj); + // LCOV_EXCL_STOP + } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedAttachCallbacksToDispatcher(hThread, FRAMEWORKUNIFIED_ANY_SOURCE, HBThreadCommonHandlers, static_cast<UI_32>(_countof(HBThreadCommonHandlers)), NULL))) { // LCOV_EXCL_BR_LINE 4: NSFW error case. // NOLINT(whitespace/line_length) + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedAttachCallbacksToDispatcher(" + "FRAMEWORKUNIFIED_ANY_SOURCE, HBThreadCommonHandlers)"); + DetachParentCbThreadProtocols(hThread, HBThreadCommonHandlers); + DetachParentCbThreadProtocols(hThread, HBThreadProtocolHandlers); + DeleteHBTimer(pObj); + DeletePObj(pObj); + // LCOV_EXCL_STOP + } else { + l_eStatus = FrameworkunifiedSetThreadSpecificData(hThread, pObj); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedSetThreadSpecificData(hThread, pObj)"); + DetachCbProtocols(hThread, FRAMEWORKUNIFIED_ANY_SOURCE, HBThreadCommonHandlers, + NULL); + DetachParentCbThreadProtocols(hThread, HBThreadCommonHandlers); + DetachParentCbThreadProtocols(hThread, HBThreadProtocolHandlers); + DeleteHBTimer(pObj); + DeletePObj(pObj); + // LCOV_EXCL_STOP + } else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Successful"); + } + } + FRAMEWORKUNIFIEDLOG0(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/*****************************************************************************/ +/** + @ingroup: SS_SystemManager + @brief: HBThreadStop: function would be called at the time of stopping of the thread + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus + */ +/*****************************************************************************/ +EFrameworkunifiedStatus HBThreadStop(HANDLE hThread) { // LCOV_EXCL_START 14: Resident process, not called by NSFW + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + EFrameworkunifiedStatus l_eStatus; + + FRAMEWORKUNIFIEDLOG0(ZONE_FUNC, __FUNCTION__, "+"); + + CHeartBeatThread * pObj = static_cast<CHeartBeatThread *>(FrameworkunifiedGetThreadSpecificData(hThread)); + if (NULL == pObj) { + l_eStatus = eFrameworkunifiedStatusNullPointer; + LOG_ERROR("FrameworkunifiedGetThreadSpecificData(hThread)"); + } else { + // delete timers + CALL_AND_LOG_STATUS_IF_ERRORED(pObj->HeartBeatTimersDelete()); + CALL_AND_LOG_STATUS_IF_ERRORED(pObj->HBPublishAvailabilityStatus(hThread, FALSE)); + DeletePObj(pObj); + } + + FrameworkunifiedSetThreadSpecificData(hThread, NULL); + CALL_AND_LOG_STATUS_IF_ERRORED(FrameworkunifiedDetachServiceFromDispatcher(hThread, FrameworkunifiedGetAppName(hThread))); + + FRAMEWORKUNIFIEDLOG0(ZONE_FUNC, __FUNCTION__, "-"); + + return l_eStatus; +}// LCOV_EXCL_STOP diff --git a/systemservice/system_manager/server/src/heartbeat/ss_hb_service_protocol.cpp b/systemservice/system_manager/server/src/heartbeat/ss_hb_service_protocol.cpp new file mode 100644 index 00000000..5fb4e001 --- /dev/null +++ b/systemservice/system_manager/server/src/heartbeat/ss_hb_service_protocol.cpp @@ -0,0 +1,184 @@ +/* + * @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 <system_service/ss_heartbeat_service_protocol.h> +#include <system_service/ss_system_manager_if.h> +#include <system_service/ss_system_manager_if_local.h> +#include <stdlib.h> +#include <string.h> +#include <native_service/frameworkunified_framework_if.h> +#include <system_service/ss_services.h> +#include <system_service/ss_templates.h> + +#include "ss_hb_thread.h" +#include "ss_sm_systemmanagerlog.h" + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnTimerExpiry + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnTimerExpiry(HANDLE f_hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + EFrameworkunifiedStatus l_eStatus; + + // check heart beat replies received from clients. + l_eStatus = HBCheckHeartBeatResponses(f_hThread); + LOG_STATUS_IF_ERRORED(l_eStatus, "HBCheckHeartBeatResponses()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + // send heart beat requests to clients + l_eStatus = HBSendRequest(f_hThread); + LOG_STATUS_IF_ERRORED(l_eStatus, "HBSendRequest()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return (l_eStatus); +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnClientResponse + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus OK or Fail + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnClientResponse(HANDLE f_hThread) { + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + l_eStatus = m_oSessionHandler.HBProcessClientResponse(f_hThread); + LOG_STATUS_IF_ERRORED(l_eStatus, "m_oSessionHandler.HBProcessClientResponse(f_hThread)"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnPeriodicStatusRequest + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus OK or Fail + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnPeriodicStatusRequest(HANDLE f_hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedSendParent(f_hThread, SS_HEARTBEAT_PERIODIC_RESP, 0, NULL))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedSendParent(SS_HEARTBEAT_PERIODIC_RESP)"); // LCOV_EXCL_LINE 4: NSFW error case. + } else { + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "Successful"); + } + + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnPeriodicStatusRequest + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus OK or Fail + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnAvailCheckRequest(HANDLE f_hThread) { + FRAMEWORKUNIFIEDLOG(ZONE_STATE, __FUNCTION__, "+"); + + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + THbAvailCheck check; + l_eStatus = m_oSessionHandler.HBAvailableCheck(check); + SS_ASERT(l_eStatus == eFrameworkunifiedStatusOK); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedSendParent(f_hThread, SS_HEARTBEAT_AVAIL_CHECK_RESP, sizeof(check), &check))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedSendParent(SS_HEARTBEAT_AVAIL_CHECK_RESP)"); // LCOV_EXCL_LINE 4: NSFW error case. + } + + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnRemoveModule + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus OK or Fail + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnRemoveModule(HANDLE f_hThread) { + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + TSMRequestMessage tReqMsgData; + // ReadMsg(): * + // Check hApp ptr, msg size, msg reception, read msg if all ok. * + // Report any errors found. * + // * + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != (l_eStatus = ReadMsg <TSMRequestMessage> (f_hThread, tReqMsgData))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("ReadMsg()"); // LCOV_EXCL_LINE 4: NSFW error case. + } else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, + " %s is required to be Deleted from HeartBeat Monitor List", tReqMsgData.pstModuleName); + + // delete module entry from map + l_eStatus = m_oSessionHandler.HBDeleteRegisteredClientEntry(f_hThread, tReqMsgData.pstModuleName); + LOG_STATUS_IF_ERRORED(l_eStatus, "m_oSessionHandler.HBDeleteRegisteredProcessEntry()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnAppendModule + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus OK or Fail + *****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnAppendModule(HANDLE f_hThread) { + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + TSMRequestMessage tReqMsgData; + // ReadMsg(): * + // Check hApp ptr, msg size, msg reception, read msg if all ok. * + // Report any errors found. * + // * + if (eFrameworkunifiedStatusOK != (l_eStatus = ReadMsg < TSMRequestMessage > (f_hThread, tReqMsgData))) { + LOG_ERROR("ReadMsg()"); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, + " %s is required to be Appended from HeartBeat Monitor List", tReqMsgData.pstModuleName); + + // append module entry from map + SubscriberName l_Subscriber = tReqMsgData.pstModuleName; + l_eStatus = m_oSessionHandler.HBEntrySubscriber(l_Subscriber); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + LOG_STATUS_IF_ERRORED(l_eStatus, "m_oSessionHandler.HBEntrySubscriber()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} +// EOF 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 <native_service/frameworkunified_framework_if.h> +#include <native_service/frameworkunified_service_protocol.h> +#include <system_service/ss_heartbeat_service_protocol.h> +#include <system_service/ss_services.h> +#include <system_service/ss_sm_thread_names.h> +#include <system_service/ss_templates.h> +#include <iostream> +#include <iomanip> +#include <utility> +#include <list> +#include <string> + +#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<HbSessionIter, bool> 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<BOOL>(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<std::string> 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<std::string>::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; +} diff --git a/systemservice/system_manager/server/src/heartbeat/ss_hb_thread.cpp b/systemservice/system_manager/server/src/heartbeat/ss_hb_thread.cpp new file mode 100644 index 00000000..19d124ae --- /dev/null +++ b/systemservice/system_manager/server/src/heartbeat/ss_hb_thread.cpp @@ -0,0 +1,355 @@ +/* + * @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 <native_service/frameworkunified_application.h> +#include <native_service/frameworkunified_framework_if.h> +#include <native_service/frameworkunified_service_protocol.h> +#include <system_service/ss_heartbeat_notifications.h> +#include <system_service/ss_heartbeat_service_protocol.h> +#include <system_service/ss_power_service_notifications.h> +#include <system_service/ss_services.h> +#include <system_service/ss_templates.h> + +#include "ss_hb_thread.h" +#include "ss_sm_systemmanagerlog.h" +#include "ss_system_manager.h" + +/// Total Timers used by Heart Beat Thread +/// This value is used for creating timers +#define HBMaxTimers 1 +#define HBTimerInterval 1 + +template<typename C, eFrameworkunifiedStatus (C::*M)(HANDLE)> EFrameworkunifiedStatus HBThreadCallback(HANDLE hThread) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + C * pObj = static_cast<C *>(FrameworkunifiedGetThreadSpecificData(hThread)); + if (pObj) { // LCOV_EXCL_BR_LINE 4:pObj must not be NULL + eStatus = (pObj->*M)(hThread); + } + return eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: CHeartBeatThread + @note: Constructor +*****************************************************************************/ +CHeartBeatThread::CHeartBeatThread(HANDLE f_hThread) : + m_oTimerCtrl(HBMaxTimers) + , m_HBTimerID(0) + , m_NextChkIndex(0) + , m_hThread(f_hThread) { // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + std::memset(&m_HBConfigParams, 0, sizeof(m_HBConfigParams)); +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: ~CHeartBeatThread + @note: Destructor +*****************************************************************************/ +CHeartBeatThread::~CHeartBeatThread() { // 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: HBPublishAvailabilityStatus + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @param BOOL - The Availability Status to be published + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBPublishAvailabilityStatus(HANDLE hThread, BOOL f_bAvailabiltyStatus) {// LCOV_EXCL_START 14: Resident process, not called by NSFW + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + // Send availability notification to users + l_eStatus = FrameworkunifiedPublishServiceAvailability(hThread, f_bAvailabiltyStatus); + char l_cBuf[100] = { 0 }; + snprintf(l_cBuf, + sizeof(l_cBuf), + "FrameworkunifiedPublishServiceAvailability(%s)", + GetStr(f_bAvailabiltyStatus).c_str()); + LOG_STATUS(l_eStatus, l_cBuf); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +}// LCOV_EXCL_STOP + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnStartThread + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnStartThread(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + UI_32 l_DataLen = FrameworkunifiedGetMsgLength(hThread); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + + if ((sizeof(UI_32) + (SS_MAX_NUM_MODULES * SS_SM_HB_MAX_PROC_NAME_SIZE) + sizeof(m_HBConfigParams)) < l_DataLen) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: message buffer sizes invalid:received %d", l_DataLen); + return eFrameworkunifiedStatusInvldParam; + } + + CHAR l_Data[l_DataLen]; // NOLINT + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != + (l_eStatus = FrameworkunifiedGetMsgDataOfSize(hThread, (PVOID) & l_Data, static_cast<UI_32>(sizeof(l_Data)), eSMRRelease))) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + " Error: FrameworkunifiedGetMsgDataOfSize() errored: 0x%x", l_eStatus); + return l_eStatus; + } + + CHAR* p_Data = &l_Data[0]; + UI_32 list_num; + memcpy(&m_HBConfigParams, p_Data, sizeof(m_HBConfigParams)); + p_Data = p_Data + sizeof(m_HBConfigParams); + memcpy(&list_num, p_Data, sizeof(list_num)); + p_Data = p_Data + sizeof((list_num)); + + for (UI_32 i = 0; i < list_num; i++) { + SubscriberName l_Subscriber = p_Data; // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != m_oSessionHandler.HBEntrySubscriber(l_Subscriber)) { + // LCOV_EXCL_BR_STOP + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: HBEntrySubscriber"); + } + p_Data = p_Data + SS_SM_HB_MAX_PROC_NAME_SIZE; + } + + if (0 == m_HBConfigParams.ApplicationHeartBeatIntervalInitial) { + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, + " Warning: Heart beat disabled via configuration file interval " + "parameter set to 0."); + } else if (0 != m_HBTimerID) { + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, + " Warning: Heart Beat Timer ID '%d' already created, ignoring " + "repeated Heart Beat Start command.", m_HBTimerID); + } else { + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != + (l_eStatus = FrameworkunifiedRegisterServiceAvailabilityNotification(hThread, NTFY_HeartBeatAvailability))) { + // LCOV_EXCL_BR_STOP + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("FrameworkunifiedRegisterServiceAvailabilityNotification(" NTFY_HeartBeatAvailability ")"); + // LCOV_EXCL_STOP + } + else { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, + "Service availability %s Registered SOURCE : %s", + NTFY_HeartBeatAvailability, + FrameworkunifiedGetAppName(hThread)); + + // Publish Heart Beat Availability + // LCOV_EXCL_BR_START 4: NSFW error case. + if (eFrameworkunifiedStatusOK != (l_eStatus = HBPublishAvailabilityStatus(hThread, TRUE))) { + // LCOV_EXCL_BR_STOP + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + LOG_ERROR("HBPublishAvailabilityStatus(TRUE)"); + // LCOV_EXCL_STOP + } + } + // Create Heart Beat app monitor + m_HBTimerID = m_oTimerCtrl.CreateTimer(HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnTimerExpiry>); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + if (0 == m_HBTimerID) { // LCOV_EXCL_BR_LINE 8: m_HBTimerID can't be 0 + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: Heart Beat Timer ID creation failed."); + // return eFrameworkunifiedStatusFail; + } else { + // Start Heart Beat app monitor + m_oTimerCtrl.StartTimer(m_HBTimerID, + m_HBConfigParams.ApplicationHeartBeatIntervalInitial, + 0, + HBTimerInterval, + 0); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length) + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Initial Heart Beat Timer created for %d seconds interval", + m_HBConfigParams.ApplicationHeartBeatIntervalInitial); + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Repetitive Heart Beat Timer created for %d seconds interval", + m_HBConfigParams.ApplicationHeartBeatIntervalRepeat); + } + } + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnStopThread + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnStopThread(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + if (0 != m_HBTimerID) { + // Stop HeartBeat timer + m_oTimerCtrl.StopTimer(m_HBTimerID); + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Timer '%d' stopped", m_HBTimerID); + } + else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: 'm_HBTimerID' is '0'; unable to stop timer"); + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HeartBeatTimerInit + @note: + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HeartBeatTimerInit(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + m_oTimerCtrl.Initialize(hThread); + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HeartBeatTimersDelete + @note: + @param void + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HeartBeatTimersDelete() {// LCOV_EXCL_START 14: Resident process, not called by NSFW + EFrameworkunifiedStatus l_eStatus; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + if (0 == m_HBTimerID) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: 'm_HBTimerID' is '0'; unable to delete timer"); + l_eStatus = eFrameworkunifiedStatusInvldParam; + } else { + // Delete Heart Beat timer + UI_32 l_TimerID = m_oTimerCtrl.DeleteTimer(m_HBTimerID); + if (0 == l_TimerID) { + l_eStatus = eFrameworkunifiedStatusDbRecNotFound; + LOG_ERROR("m_oTimerCtrl.DeleteTimer(m_HBTimerID)"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } else { + l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Successful"); + } + m_HBTimerID = 0; + } + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +}// LCOV_EXCL_STOP + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBCheckHeartBeatResponses + @note: This function checks heartbeat responses and generates a summary + report for System Manager if one or more modules have failed to + reply within the configured maximum number of heartbeat retries. + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBCheckHeartBeatResponses(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus; + THbReportData f_tReportData; + FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+"); + + l_eStatus = m_oSessionHandler.HBCheckResponses(f_tReportData, + m_HBConfigParams.MaxHeartBeatRetryCount, + m_HBConfigParams.ApplicationHeartBeatIntervalRepeat, + m_NextChkIndex); + if (l_eStatus == eFrameworkunifiedStatusFail) { // Send a heartbeat report ONLY if a heartbeat failure is detected. + // send report to system manager + l_eStatus = FrameworkunifiedSendParent(hThread, + SS_HEARTBEAT_ERROR_DETECTED, + sizeof(f_tReportData), + &f_tReportData); + LOG_STATUS_IF_ERRORED(l_eStatus, "FrameworkunifiedSendParent(SS_HEARTBEAT_ERROR_DETECTED)"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + } + FRAMEWORKUNIFIEDLOG0(ZONE_PERIODIC_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBSendRequest + @note: . + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBSendRequest(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus; + + CALL_AND_LOG_STATUS_IF_ERRORED( // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + m_oSessionHandler.HBSendRequest(hThread, m_HBConfigParams.ApplicationHeartBeatIntervalRepeat, m_NextChkIndex)); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length) + + m_NextChkIndex++; + if (m_HBConfigParams.ApplicationHeartBeatIntervalRepeat <= m_NextChkIndex) { + m_NextChkIndex = 0; + } + + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnPrintConnections + @note: .Prints all active sessions connected to HeartBeat + @param HANDLE hThread + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnPrintConnections(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + m_oSessionHandler.HBPrintConnection(); + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} + +/***************************************************************************** + @ingroup: SS_SystemManager + @brief: HBOnPrintStack + @note: . Prints all sessions connected to HeartBeat + @param HANDLE - Handle to message queue of HeartBeat Service. + @return EFrameworkunifiedStatus +*****************************************************************************/ +EFrameworkunifiedStatus CHeartBeatThread::HBOnPrintStack(HANDLE hThread) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+"); + + m_oSessionHandler.HBPrintStack(m_HBConfigParams.MaxHeartBeatRetryCount); + + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-"); + return l_eStatus; +} |