2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_SystemManager
19 /// \brief This file provides support for the application heartbeat system.
21 ///////////////////////////////////////////////////////////////////////////////
23 #include <native_service/frameworkunified_framework_if.h>
24 #include <native_service/frameworkunified_service_protocol.h>
25 #include <system_service/ss_heartbeat_service_protocol.h>
26 #include <system_service/ss_services.h>
27 #include <system_service/ss_sm_thread_names.h>
28 #include <system_service/ss_templates.h>
35 #include "ss_sm_systemmanagerlog.h"
36 #include "ss_hb_thread.h"
37 #include "ss_hb_session.h"
38 #include "ss_system_manager.h"
40 using namespace std; // NOLINT
42 CHeartBeatSessionHandler::CHeartBeatSessionHandler() {
45 CHeartBeatSessionHandler::~CHeartBeatSessionHandler() { // LCOV_EXCL_START 14: Resident process, not called by NSFW
46 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
50 /*****************************************************************************
51 @ingroup: SS_SystemManager
53 @note: HbSessionInfo constructor
56 *****************************************************************************/
57 CHeartBeatSessionHandler::HbSessionInfo::HbSessionInfo(SubscriberName f_Subscriber) {
59 fHeartBeatRequestSent = FALSE;
60 fHeartBeatResponseReceived = FALSE;
61 HeartBeatRetryCount = 0;
62 fHeartBeatTimedOut = FALSE;
64 szName = f_Subscriber;
65 fisAvailability = FALSE;
68 /*****************************************************************************
69 @ingroup: SS_SystemManager
70 @brief: HBEntrySubscriber
74 *****************************************************************************/
75 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBEntrySubscriber(SubscriberName &f_Subscriber) {
76 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
77 // check if the subscriber is already in map
78 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(f_Subscriber);
80 // the l_SessionInfoIterator is set to the end then the subscriber is not in the map
81 if (m_mapHbSessions.end() == l_SessionInfoIterator) {
82 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Entry Subscriber : %s", f_Subscriber.c_str());
83 HbSessionInfo l_NewHBClientSessionInfo(f_Subscriber.c_str()); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
85 pair<HbSessionIter, bool> ret;
86 // insert new subscriber entry into the session map
87 ret = m_mapHbSessions.insert(std::make_pair(f_Subscriber, l_NewHBClientSessionInfo));
88 if (!ret.second) { // LCOV_EXCL_BR_LINE 6:l_NewHBClientSessionInfo must not be NULL.
89 // LCOV_EXCL_START 6:l_NewHBClientSessionInfo must not be NULL.
90 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
91 l_eStatus = eFrameworkunifiedStatusFail;
92 SS_ASERT(0); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length)
96 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__, "Subscriber '%s' is already in the map", f_Subscriber.c_str());
101 /*****************************************************************************
102 @ingroup: SS_SystemManager
103 @brief: ProcessHBClientResponse
104 @note: Process the response received from client, update relevant structure data
106 @return EFrameworkunifiedStatus
107 *****************************************************************************/
108 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBProcessClientResponse(HANDLE f_hThread) {
109 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
110 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "+");
111 BOOL l_availability = FALSE;
113 if (eFrameworkunifiedStatusOK != (l_eStatus = ReadMsg<BOOL>(f_hThread, l_availability))) {
114 LOG_ERROR("ReadMsg()"); // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h // NOLINT(whitespace/line_length)
117 // find the subscriber...
118 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(FrameworkunifiedGetMsgSrc(f_hThread));
120 // the l_SessionInfoIterator is set to the end then the subscriber is not in the map
121 if (m_mapHbSessions.end() != l_SessionInfoIterator) {
122 l_SessionInfoIterator->second.HeartBeatRetryCount = 0;
123 l_SessionInfoIterator->second.fHeartBeatResponseReceived = TRUE;
124 l_SessionInfoIterator->second.fHeartBeatRequestSent = FALSE;
125 l_SessionInfoIterator->second.fisAvailability = l_availability;
126 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__,
127 "HeartBeat received from module: %s ", l_SessionInfoIterator->first.c_str());
129 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__,
130 "Ignoring Heart Beat Response, Client: %s not found in the map!", FrameworkunifiedGetMsgSrc(f_hThread));
132 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "-");
136 /*****************************************************************************
137 @ingroup: SS_SystemManager
138 @brief: HBPrintConnection
139 @note: .Print registered client information
142 *****************************************************************************/
143 VOID CHeartBeatSessionHandler::HBPrintConnection() {
144 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
146 // find the subscriber...
147 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin();
148 for (; l_SessionInfoIterator != m_mapHbSessions.end(); l_SessionInfoIterator++) {
149 FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__,
150 "HeartBeat Service is Connected to: %s via a Session: Running: %s ",
151 l_SessionInfoIterator->second.szName.data(),
152 (l_SessionInfoIterator->second.fRunning ? "YES" : "NO"));
154 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
157 /*****************************************************************************
158 @ingroup: SS_SystemManager
160 @note: .Print registered client information
163 *****************************************************************************/
164 VOID CHeartBeatSessionHandler::HBPrintStack(UI_32 f_MaxHeartBeatRetryCount) {
165 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
167 // find the subscriber...
168 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin();
169 for (; l_SessionInfoIterator != m_mapHbSessions.end(); l_SessionInfoIterator++) {
170 if (FALSE == l_SessionInfoIterator->second.fHeartBeatResponseReceived) {
171 FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__,
172 "HeartBeat Service is Connected to: %s via a Session: Running: %s ",
173 l_SessionInfoIterator->second.szName.data(),
174 (l_SessionInfoIterator->second.fRunning ? "YES" : "NO"));
175 FRAMEWORKUNIFIEDLOG(ZONE_DEBUG_DUMP, __FUNCTION__,
176 "Retry count (%d) within limit (%d), HeartBeatTimedout = %s",
177 l_SessionInfoIterator->second.HeartBeatRetryCount,
178 f_MaxHeartBeatRetryCount,
179 (l_SessionInfoIterator->second.fHeartBeatTimedOut == TRUE ?
183 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
186 /*****************************************************************************
187 @ingroup: SS_SystemManager
188 @brief: HBCheckResponses
189 @note: Check if all clients have replied to heartbeat query and generate report
190 @param THbReportData Report structure to be filled
191 @param UI_32 Heartbeat max retry count
192 @return eFrameworkunifiedStatusFail if one or more modules have timed out, eFrameworkunifiedStatusOK otherwise.
193 *****************************************************************************/
194 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBCheckResponses(
195 THbReportData &f_tReportData, UI_32 f_MaxHeartBeatRetryCount,
196 SI_32 f_HeartBeatIntervalRepeat, SI_32 f_ChkIndex) {
197 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
198 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+");
200 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin();
201 memset(&f_tReportData, 0, sizeof(THbReportData));
205 while (l_SessionInfoIterator != m_mapHbSessions.end()) {
206 if (f_ChkIndex == (index % f_HeartBeatIntervalRepeat)) {
207 // check if report queue is full
208 // LCOV_EXCL_BR_START 6: f_tReportData.nNumOfModules can't more than SS_MAX_NUM_MODULES
209 if (SS_MAX_NUM_MODULES <= f_tReportData.nNumOfModules) {
211 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
212 " Error: SS_MAX_NUM_MODULES '%d' <= f_tReportData.nNumOfModules '%d'. See ss_system_manager_if.h.",
213 SS_MAX_NUM_MODULES, f_tReportData.nNumOfModules);
215 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-");
216 return eFrameworkunifiedStatusInvldBuf;
220 strncpy(f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcQueueName,
221 l_SessionInfoIterator->first.c_str(),
222 sizeof(f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcQueueName) - 1);
223 f_tReportData.tModuleList[f_tReportData.nNumOfModules].HeartBeatRetryCount =
224 l_SessionInfoIterator->second.HeartBeatRetryCount;
225 f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_GOOD;
227 if (TRUE == l_SessionInfoIterator->second.fHeartBeatResponseReceived) {
228 l_SessionInfoIterator->second.fHeartBeatResponseReceived = FALSE;
229 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__,
230 "[%s] Heart Beat Response Received !",
231 l_SessionInfoIterator->second.szName.c_str());
232 } else if (TRUE == l_SessionInfoIterator->second.fHeartBeatTimedOut) {
233 f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_TIMEOUT;
234 } else if ((TRUE == l_SessionInfoIterator->second.fHeartBeatRequestSent)
235 && (FALSE == l_SessionInfoIterator->second.fHeartBeatTimedOut)) {
236 l_SessionInfoIterator->second.HeartBeatRetryCount++;
238 if (l_SessionInfoIterator->second.HeartBeatRetryCount > f_MaxHeartBeatRetryCount) {
239 l_eStatus = eFrameworkunifiedStatusFail;
240 l_SessionInfoIterator->second.fHeartBeatTimedOut = TRUE;
241 l_SessionInfoIterator->second.HeartBeatRetryCount = 0;
243 f_tReportData.tModuleList[f_tReportData.nNumOfModules].ProcHBState = HB_STATUS_TIMEOUT;
245 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
246 " Error: Heart Beat Retry count of [%s] has crossed max limit (%d)."
247 "Disabling sending HeartBeat query to it",
248 l_SessionInfoIterator->second.szName.c_str(),
249 f_MaxHeartBeatRetryCount);
251 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
252 " Error: [%s] has missed a Heart Beat. Retry count (%d) is within max retry limit (%d)",
253 l_SessionInfoIterator->second.szName.c_str(),
254 l_SessionInfoIterator->second.HeartBeatRetryCount,
255 f_MaxHeartBeatRetryCount);
260 f_tReportData.nNumOfModules++;
261 ++l_SessionInfoIterator;
265 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-");
269 /*****************************************************************************
270 @ingroup: SS_SystemManager
271 @brief: HBSendRequest
272 @note: .Sent heart beat query to the registered clients
274 @return EFrameworkunifiedStatus
275 ******************************************************************************/
276 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBSendRequest(HANDLE f_hThread,
277 SI_32 f_HeartBeatIntervalRepeat, SI_32 f_ChkIndex) {
278 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
279 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+");
281 // Get session iterator
282 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.begin();
284 if (l_SessionInfoIterator == m_mapHbSessions.end()) {
285 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__, "No Client has opened session with HeartBeat");
286 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-");
292 while (l_SessionInfoIterator != m_mapHbSessions.end()) {
293 if (f_ChkIndex == (index % f_HeartBeatIntervalRepeat)) {
294 if (l_SessionInfoIterator->second.hSession == NULL) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL
295 l_SessionInfoIterator->second.hSession = FrameworkunifiedMcOpenSender(f_hThread, l_SessionInfoIterator->first.c_str());
296 if (NULL == l_SessionInfoIterator->second.hSession) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL
297 // LCOV_EXCL_START 200: hSession must not be NULL
298 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
299 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
300 " Error: FrameworkunifiedMcOpenSender(%s) returned NULL",
301 l_SessionInfoIterator->first.c_str());
304 l_SessionInfoIterator->second.fRunning = TRUE;
308 if ((NULL != l_SessionInfoIterator->second.hSession)
309 && (FALSE == l_SessionInfoIterator->second.fHeartBeatTimedOut)) {
310 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)
311 /// TODO review if we are required to return failure if sending message to one process failed.
312 l_SessionInfoIterator->second.fHeartBeatResponseReceived = FALSE;
313 l_SessionInfoIterator->second.fHeartBeatRequestSent = TRUE;
314 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__,
315 "HeartBeat Request sent to : %s", l_SessionInfoIterator->first.c_str());
317 // LCOV_EXCL_START 5:NSFW's error
318 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
319 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
320 " Error: FrameworkunifiedSendMsg(%s, SS_HEARTBEAT_REQUEST) errored: %d/'%s'",
321 l_SessionInfoIterator->first.c_str(), l_eStatus,
322 GetStr(l_eStatus).c_str());
326 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_INFO, __FUNCTION__,
327 " HeartBeat Request was not sent to '%s', timeout is '%s'",
328 l_SessionInfoIterator->first.c_str(),
329 (l_SessionInfoIterator->second.fHeartBeatTimedOut == TRUE ? "TRUE" : "FALSE"));
332 ++l_SessionInfoIterator;
336 FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "-");
340 /*****************************************************************************
341 @ingroup: SS_SystemManager
342 @brief: HBDeleteRegisteredClientEntry
345 @return EFrameworkunifiedStatus
346 ******************************************************************************/
347 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBDeleteRegisteredClientEntry(HANDLE f_hThread, PSTR pQueueName) {
348 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
349 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
351 SubscriberName tQueuename(pQueueName);
353 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Looking for %s.", tQueuename.c_str());
355 HbSessionIter l_SessionInfoIterator = m_mapHbSessions.find(tQueuename);
357 if (m_mapHbSessions.end() != l_SessionInfoIterator) {
358 // Close the session handle
359 if (NULL != l_SessionInfoIterator->second.hSession) { // LCOV_EXCL_BR_LINE 200:hSession must not be NULL when tQueuename exists. // NOLINT(whitespace/line_length)
360 // LCOV_EXCL_BR_START 4: NSFW error case.
361 if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedMcClose(l_SessionInfoIterator->second.hSession))) {
363 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
364 LOG_ERROR("FrameworkunifiedMcClose()"); // LCOV_EXCL_LINE 4: NSFW error case.
366 l_SessionInfoIterator->second.hSession = NULL;
368 m_mapHbSessions.erase(tQueuename);
369 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Deleting '%s' Successful ", tQueuename.c_str());
371 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
372 "%s not found in Heart beat client list", tQueuename.c_str());
374 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
378 /*****************************************************************************
379 @ingroup: SS_SystemManager
380 @brief: HBAvailableCheck
383 @return EFrameworkunifiedStatus
384 ******************************************************************************/
385 EFrameworkunifiedStatus CHeartBeatSessionHandler::HBAvailableCheck(THbAvailCheck &check) {
386 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
389 std::list<std::string> ngList;
390 for (HbSessionIter ite = m_mapHbSessions.begin(); ite != m_mapHbSessions.end(); ite++) {
391 if (ite->second.fisAvailability == FALSE) {
392 ngList.push_back(ite->first);
393 // Notify Last Service as Representative
394 snprintf(check.serviceName, SS_SM_HB_MAX_PROC_NAME_SIZE, "%s", ite->first.c_str());
400 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "********* AVAILABILITY CHECK ERROR **********");
401 fprintf(stderr, "HBOnAvailCheckRequest/********* AVAILABILITY CHECK ERROR **********\n"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
403 FRAMEWORKUNIFIEDLOG(ZONE_STATE, __FUNCTION__, "********* AVAILABILITY CHECK OK **********");
404 fprintf(stderr, "HBOnAvailCheckRequest/********* AVAILABILITY CHECK OK **********\n"); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)
407 for (std::list<std::string>::iterator ite = ngList.begin(); ite != ngList.end(); ite++) {
408 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " %s", ite->c_str());
409 fprintf(stderr, " %s\n", ite->c_str()); // LCOV_EXCL_BR_LINE 11:unexpected branch // NOLINT(whitespace/line_length)