Init basesystem source codes.
[staging/basesystem.git] / systemservice / system_manager / server / src / heartbeat / ss_hb_thread.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup  tag_SystemManager
19 /// \brief    This file provides support for the application heartbeat system.
20 ///
21 ///////////////////////////////////////////////////////////////////////////////
22 #include <native_service/frameworkunified_application.h>
23 #include <native_service/frameworkunified_framework_if.h>
24 #include <native_service/frameworkunified_service_protocol.h>
25 #include <system_service/ss_heartbeat_notifications.h>
26 #include <system_service/ss_heartbeat_service_protocol.h>
27 #include <system_service/ss_power_service_notifications.h>
28 #include <system_service/ss_services.h>
29 #include <system_service/ss_templates.h>
30
31 #include "ss_hb_thread.h"
32 #include "ss_sm_systemmanagerlog.h"
33 #include "ss_system_manager.h"
34
35 /// Total Timers used by Heart Beat Thread
36 /// This value is used for creating timers
37 #define HBMaxTimers       1
38 #define HBTimerInterval   1
39
40 template<typename C, eFrameworkunifiedStatus (C::*M)(HANDLE)> EFrameworkunifiedStatus HBThreadCallback(HANDLE hThread) {
41   EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
42   C * pObj = static_cast<C *>(FrameworkunifiedGetThreadSpecificData(hThread));
43   if (pObj) {  // LCOV_EXCL_BR_LINE 4:pObj must not be NULL
44     eStatus = (pObj->*M)(hThread);
45   }
46   return eStatus;
47 }
48
49 /*****************************************************************************
50  @ingroup: SS_SystemManager
51  @brief: CHeartBeatThread
52  @note: Constructor
53 *****************************************************************************/
54 CHeartBeatThread::CHeartBeatThread(HANDLE f_hThread) :
55       m_oTimerCtrl(HBMaxTimers)
56     , m_HBTimerID(0)
57     , m_NextChkIndex(0)
58     , m_hThread(f_hThread) {  // LCOV_EXCL_BR_LINE 11:unexpected branch  // NOLINT(whitespace/line_length)
59   std::memset(&m_HBConfigParams, 0, sizeof(m_HBConfigParams));
60 }
61
62 /*****************************************************************************
63  @ingroup: SS_SystemManager
64  @brief: ~CHeartBeatThread
65  @note: Destructor
66 *****************************************************************************/
67 CHeartBeatThread::~CHeartBeatThread() {  // LCOV_EXCL_START 14: Resident process, not called by NSFW
68   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
69 }
70 // LCOV_EXCL_STOP
71
72 /*****************************************************************************
73  @ingroup: SS_SystemManager
74  @brief: HBPublishAvailabilityStatus
75  @note: .
76  @param HANDLE  - Handle to message queue of HeartBeat Service.
77  @param BOOL    - The Availability Status to be published
78  @return EFrameworkunifiedStatus
79 *****************************************************************************/
80 EFrameworkunifiedStatus CHeartBeatThread::HBPublishAvailabilityStatus(HANDLE hThread, BOOL f_bAvailabiltyStatus) {// LCOV_EXCL_START 14: Resident process, not called by NSFW
81   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
82   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
83
84   // Send availability notification to users
85   l_eStatus = FrameworkunifiedPublishServiceAvailability(hThread, f_bAvailabiltyStatus);
86   char l_cBuf[100] = { 0 };
87   snprintf(l_cBuf,
88            sizeof(l_cBuf),
89            "FrameworkunifiedPublishServiceAvailability(%s)",
90            GetStr(f_bAvailabiltyStatus).c_str());
91   LOG_STATUS(l_eStatus, l_cBuf);  // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h  // NOLINT(whitespace/line_length)
92
93   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
94   return l_eStatus;
95 }// LCOV_EXCL_STOP
96
97 /*****************************************************************************
98  @ingroup: SS_SystemManager
99  @brief: HBOnStartThread
100  @note: .
101  @param HANDLE  - Handle to message queue of HeartBeat Service.
102  @return EFrameworkunifiedStatus
103 *****************************************************************************/
104 EFrameworkunifiedStatus CHeartBeatThread::HBOnStartThread(HANDLE hThread) {
105   EFrameworkunifiedStatus l_eStatus;
106   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
107
108   UI_32 l_DataLen = FrameworkunifiedGetMsgLength(hThread);  // LCOV_EXCL_BR_LINE 11:unexpected branch  // NOLINT(whitespace/line_length)
109
110   if ((sizeof(UI_32) + (SS_MAX_NUM_MODULES * SS_SM_HB_MAX_PROC_NAME_SIZE) + sizeof(m_HBConfigParams)) < l_DataLen) {
111     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
112            " Error: message buffer sizes invalid:received %d", l_DataLen);
113     return eFrameworkunifiedStatusInvldParam;
114   }
115
116   CHAR l_Data[l_DataLen];  // NOLINT
117   // LCOV_EXCL_BR_START 4: NSFW error case.
118   if (eFrameworkunifiedStatusOK !=
119       (l_eStatus = FrameworkunifiedGetMsgDataOfSize(hThread, (PVOID) & l_Data, static_cast<UI_32>(sizeof(l_Data)), eSMRRelease))) {
120   // LCOV_EXCL_BR_STOP
121     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
122     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
123             " Error: FrameworkunifiedGetMsgDataOfSize() errored: 0x%x", l_eStatus);
124     return l_eStatus;
125   }
126
127   CHAR* p_Data = &l_Data[0];
128   UI_32 list_num;
129   memcpy(&m_HBConfigParams, p_Data, sizeof(m_HBConfigParams));
130   p_Data = p_Data + sizeof(m_HBConfigParams);
131   memcpy(&list_num, p_Data, sizeof(list_num));
132   p_Data = p_Data + sizeof((list_num));
133
134   for (UI_32 i = 0; i < list_num; i++) {
135     SubscriberName l_Subscriber = p_Data;  // LCOV_EXCL_BR_LINE 11:unexpected branch  // NOLINT(whitespace/line_length)
136     // LCOV_EXCL_BR_START 4: NSFW error case.
137     if (eFrameworkunifiedStatusOK != m_oSessionHandler.HBEntrySubscriber(l_Subscriber)) {
138     // LCOV_EXCL_BR_STOP
139       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
140       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: HBEntrySubscriber");
141     }
142     p_Data = p_Data + SS_SM_HB_MAX_PROC_NAME_SIZE;
143   }
144
145   if (0 == m_HBConfigParams.ApplicationHeartBeatIntervalInitial) {
146     FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__,
147          " Warning: Heart beat disabled via configuration file interval "
148          "parameter set to 0.");
149   } else if (0 != m_HBTimerID) {
150     FRAMEWORKUNIFIEDLOG(ZONE_WARN, __FUNCTION__,
151         " Warning: Heart Beat Timer ID '%d' already created, ignoring "
152         "repeated Heart Beat Start command.", m_HBTimerID);
153   } else {
154     // LCOV_EXCL_BR_START 4: NSFW error case.
155     if (eFrameworkunifiedStatusOK !=
156         (l_eStatus = FrameworkunifiedRegisterServiceAvailabilityNotification(hThread, NTFY_HeartBeatAvailability))) {
157     // LCOV_EXCL_BR_STOP
158       // LCOV_EXCL_START 4: NSFW error case.
159       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
160       LOG_ERROR("FrameworkunifiedRegisterServiceAvailabilityNotification(" NTFY_HeartBeatAvailability ")");
161       // LCOV_EXCL_STOP
162     }
163     else {
164       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
165           "Service availability %s Registered SOURCE : %s",
166           NTFY_HeartBeatAvailability,
167           FrameworkunifiedGetAppName(hThread));
168
169       // Publish Heart Beat Availability
170       // LCOV_EXCL_BR_START 4: NSFW error case.
171       if (eFrameworkunifiedStatusOK != (l_eStatus = HBPublishAvailabilityStatus(hThread, TRUE))) {
172       // LCOV_EXCL_BR_STOP
173         // LCOV_EXCL_START 4: NSFW error case.
174         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
175         LOG_ERROR("HBPublishAvailabilityStatus(TRUE)");
176         // LCOV_EXCL_STOP
177       }
178     }
179     // Create Heart Beat app monitor
180     m_HBTimerID = m_oTimerCtrl.CreateTimer(HBThreadCallback<CHeartBeatThread, &CHeartBeatThread::HBOnTimerExpiry>);  // LCOV_EXCL_BR_LINE 11:unexpected branch  // NOLINT(whitespace/line_length)
181     if (0 == m_HBTimerID) {  // LCOV_EXCL_BR_LINE 8: m_HBTimerID can't be 0
182       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
183       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: Heart Beat Timer ID creation failed.");
184       // return eFrameworkunifiedStatusFail;
185     } else {
186       // Start Heart Beat app monitor
187       m_oTimerCtrl.StartTimer(m_HBTimerID,
188                               m_HBConfigParams.ApplicationHeartBeatIntervalInitial,
189                               0,
190                               HBTimerInterval,
191                               0);  // LCOV_EXCL_BR_LINE 11:unexpected branch  // NOLINT(whitespace/line_length)
192       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Initial Heart Beat Timer created for %d seconds interval",
193                                       m_HBConfigParams.ApplicationHeartBeatIntervalInitial);
194       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Repetitive Heart Beat Timer created for %d seconds interval",
195               m_HBConfigParams.ApplicationHeartBeatIntervalRepeat);
196     }
197   }
198
199   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
200   return l_eStatus;
201 }
202
203 /*****************************************************************************
204  @ingroup: SS_SystemManager
205  @brief: HBOnStopThread
206  @note: .
207  @param HANDLE  - Handle to message queue of HeartBeat Service.
208  @return EFrameworkunifiedStatus
209 *****************************************************************************/
210 EFrameworkunifiedStatus CHeartBeatThread::HBOnStopThread(HANDLE hThread) {
211   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
212   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
213   if (0 != m_HBTimerID) {
214     // Stop HeartBeat timer
215     m_oTimerCtrl.StopTimer(m_HBTimerID);
216     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Timer '%d' stopped", m_HBTimerID);
217   }
218   else {
219     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: 'm_HBTimerID' is '0'; unable to stop timer");
220   }
221   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
222   return l_eStatus;
223 }
224
225 /*****************************************************************************
226  @ingroup: SS_SystemManager
227  @brief: HeartBeatTimerInit
228  @note:
229  @param HANDLE  - Handle to message queue of HeartBeat Service.
230  @return EFrameworkunifiedStatus
231 *****************************************************************************/
232 EFrameworkunifiedStatus CHeartBeatThread::HeartBeatTimerInit(HANDLE hThread) {
233   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
234   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
235
236   m_oTimerCtrl.Initialize(hThread);
237
238   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
239   return l_eStatus;
240 }
241
242 /*****************************************************************************
243  @ingroup: SS_SystemManager
244  @brief: HeartBeatTimersDelete
245  @note:
246  @param void
247  @return EFrameworkunifiedStatus
248 *****************************************************************************/
249 EFrameworkunifiedStatus CHeartBeatThread::HeartBeatTimersDelete() {// LCOV_EXCL_START 14: Resident process, not called by NSFW
250   EFrameworkunifiedStatus l_eStatus;
251   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
252
253   if (0 == m_HBTimerID) {
254     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error: 'm_HBTimerID' is '0'; unable to delete timer");
255     l_eStatus = eFrameworkunifiedStatusInvldParam;
256   } else {
257     // Delete Heart Beat timer
258     UI_32 l_TimerID = m_oTimerCtrl.DeleteTimer(m_HBTimerID);
259     if (0 == l_TimerID) {
260       l_eStatus = eFrameworkunifiedStatusDbRecNotFound;
261       LOG_ERROR("m_oTimerCtrl.DeleteTimer(m_HBTimerID)");  // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h  // NOLINT(whitespace/line_length)
262     } else {
263       l_eStatus = eFrameworkunifiedStatusOK;
264       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Successful");
265     }
266     m_HBTimerID = 0;
267   }
268   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
269   return l_eStatus;
270 }// LCOV_EXCL_STOP
271
272 /*****************************************************************************
273  @ingroup: SS_SystemManager
274  @brief: HBCheckHeartBeatResponses
275  @note:  This function checks heartbeat responses and generates a summary
276          report for System Manager if one or more modules have failed to
277          reply within the configured maximum number of heartbeat retries.
278  @param  HANDLE  - Handle to message queue of HeartBeat Service.
279  @return EFrameworkunifiedStatus
280 *****************************************************************************/
281 EFrameworkunifiedStatus CHeartBeatThread::HBCheckHeartBeatResponses(HANDLE hThread) {
282   EFrameworkunifiedStatus l_eStatus;
283   THbReportData f_tReportData;
284   FRAMEWORKUNIFIEDLOG(ZONE_PERIODIC_FUNC, __FUNCTION__, "+");
285
286   l_eStatus = m_oSessionHandler.HBCheckResponses(f_tReportData,
287                                                  m_HBConfigParams.MaxHeartBeatRetryCount,
288                                                  m_HBConfigParams.ApplicationHeartBeatIntervalRepeat,
289                                                  m_NextChkIndex);
290   if (l_eStatus == eFrameworkunifiedStatusFail) {  // Send a heartbeat report ONLY if a heartbeat failure is detected.
291     // send report to system manager
292     l_eStatus = FrameworkunifiedSendParent(hThread,
293                               SS_HEARTBEAT_ERROR_DETECTED,
294                               sizeof(f_tReportData),
295                               &f_tReportData);
296     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)
297   }
298   FRAMEWORKUNIFIEDLOG0(ZONE_PERIODIC_FUNC, __FUNCTION__, "-");
299   return l_eStatus;
300 }
301
302 /*****************************************************************************
303  @ingroup: SS_SystemManager
304  @brief: HBSendRequest
305  @note: .
306  @param  HANDLE  - Handle to message queue of HeartBeat Service.
307  @return EFrameworkunifiedStatus
308 *****************************************************************************/
309 EFrameworkunifiedStatus CHeartBeatThread::HBSendRequest(HANDLE hThread) {
310   EFrameworkunifiedStatus l_eStatus;
311
312   CALL_AND_LOG_STATUS_IF_ERRORED(  // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h  // NOLINT(whitespace/line_length)
313     m_oSessionHandler.HBSendRequest(hThread, m_HBConfigParams.ApplicationHeartBeatIntervalRepeat, m_NextChkIndex));  // LCOV_EXCL_BR_LINE 15: marco defined in ss_templates.h  // NOLINT(whitespace/line_length)
314
315   m_NextChkIndex++;
316   if (m_HBConfigParams.ApplicationHeartBeatIntervalRepeat <= m_NextChkIndex) {
317     m_NextChkIndex = 0;
318   }
319
320   return l_eStatus;
321 }
322
323 /*****************************************************************************
324  @ingroup: SS_SystemManager
325  @brief: HBOnPrintConnections
326  @note: .Prints all active sessions connected to HeartBeat
327  @param HANDLE hThread
328  @return EFrameworkunifiedStatus
329 *****************************************************************************/
330 EFrameworkunifiedStatus CHeartBeatThread::HBOnPrintConnections(HANDLE hThread) {
331   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
332   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
333
334   m_oSessionHandler.HBPrintConnection();
335
336   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
337   return l_eStatus;
338 }
339
340 /*****************************************************************************
341  @ingroup: SS_SystemManager
342  @brief: HBOnPrintStack
343  @note: . Prints all sessions connected to HeartBeat
344  @param HANDLE  - Handle to message queue of HeartBeat Service.
345  @return EFrameworkunifiedStatus
346 *****************************************************************************/
347 EFrameworkunifiedStatus CHeartBeatThread::HBOnPrintStack(HANDLE hThread) {
348   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
349   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
350
351   m_oSessionHandler.HBPrintStack(m_HBConfigParams.MaxHeartBeatRetryCount);
352
353   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
354   return l_eStatus;
355 }