Re-organized sub-directory by category
[staging/basesystem.git] / service / native / notification_persistent_service / server / src / ns_npp_state_nor_persistence_notification.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 /// \defgroup <<Group Tag>> <<Group Name>>
19 /// \ingroup  tag_NS_NPPService
20 /// .
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
22
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
24 /// \ingroup  tag_NS_NPPService
25 /// \brief    This file contains implementation of class CStateNorPersistenceNotification.
26 ///
27 ////////////////////////////////////////////////////////////////////////////////////////////////////
28
29 ////////////////////////////////////////////////////////////////////////////////////////////////////
30 // Include Files
31 ////////////////////////////////////////////////////////////////////////////////////////////////////
32 #include <errno.h>
33 #include <native_service/ns_message_center_if.h>
34 #include <string>
35 #include <iostream>
36
37 #include "ns_npp_types.h"
38 #include "ns_npp_notificationpersistentservicelog.h"
39 #include "ns_npp_persistent_data.h"
40 #include "ns_npp_state_nor_persistence_notification.h"
41
42 HANDLE CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread = NULL;
43
44 ////////////////////////////////////////////////////////////////////////////////////////////////////
45 /// CStateNorPersistenceNotification
46 /// Constructor of CStateNorPersistenceNotification class
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
48 CStateNorPersistenceNotification::CStateNorPersistenceNotification(const std::string &f_cnotificationname,
49                                                                    const UI_32 f_uimaxmsgsize,
50                                                                    const UI_32 f_uidelay,
51                                                                    const EFrameworkunifiedPersistCategory f_epersistcategory):
52   CStateNotification(f_cnotificationname, f_uimaxmsgsize),
53   m_uiDelay(f_uidelay),
54   m_ePersistCategory(f_epersistcategory) {
55   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
56
57   m_ePersistentType = eFrameworkunifiedImmediatePersistedStateVar;
58
59   // also, register the notification with worker thread responsible for writing notification data
60   if (NULL != CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread) {  // LCOV_EXCL_BR_LINE 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null  // NOLINT[whitespace/line_length]
61     TImmediatePersistenceRegisterNotifInfo l_tRegisterNotifInfo = {};
62     std::strncpy(l_tRegisterNotifInfo.m_cnotificationname,
63                  f_cnotificationname.c_str(),
64                  sizeof(l_tRegisterNotifInfo.m_cnotificationname) - 1);
65     l_tRegisterNotifInfo.m_uidelay = f_uidelay;
66     l_tRegisterNotifInfo.m_epersistcategory = f_epersistcategory;
67
68     if (eFrameworkunifiedStatusOK != McSend(CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread, AppName, NOR_PERSISTENCE_REGISTER, sizeof(l_tRegisterNotifInfo), &l_tRegisterNotifInfo)) {  // LCOV_EXCL_BR_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
69       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
70       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "McSend for cmd 0x%X failed", NOR_PERSISTENCE_REGISTER);  // LCOV_EXCL_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
71     }
72   }
73
74   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
75 }
76
77
78 ////////////////////////////////////////////////////////////////////////////////////////////////////
79 /// ~CStateNorPersistenceNotification
80 /// Constructor of CStateNorPersistenceNotification class
81 ////////////////////////////////////////////////////////////////////////////////////////////////////
82 CStateNorPersistenceNotification::~CStateNorPersistenceNotification() {
83   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
84
85   // also, unregister the notification with worker thread responsible for writing notification data
86   if (NULL != CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread) {  // LCOV_EXCL_BR_LINE 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null  // NOLINT[whitespace/line_length]
87     TImmediatePersistenceUnregisterNotifInfo l_tUnregisterNotifInfo = {};
88     std::strncpy(l_tUnregisterNotifInfo.m_cnotificationname,
89                  GetNotificationName().c_str(),  // LCOV_EXCL_BR_LINE 11: except,C++ STL
90                  sizeof(l_tUnregisterNotifInfo.m_cnotificationname) - 1);
91
92     if (eFrameworkunifiedStatusOK != McSend(CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread, AppName, NOR_PERSISTENCE_UNREGISTER, sizeof(l_tUnregisterNotifInfo), &l_tUnregisterNotifInfo)) {  // LCOV_EXCL_BR_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
93       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
94       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "McSend for cmd 0x%X failed", NOR_PERSISTENCE_UNREGISTER);  // LCOV_EXCL_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
95     }
96   }
97
98   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////////////////////////
102 /// GetPersistenceDelay
103 /// Method to get the persistence time delay.
104 ////////////////////////////////////////////////////////////////////////////////////////////////////
105 UI_32 CStateNorPersistenceNotification::GetPersistenceDelay() {
106   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
107
108   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
109   return m_uiDelay;
110 }
111
112 ////////////////////////////////////////////////////////////////////////////////////////////////////
113 /// Publish
114 /// This function publishes the notification to subscribed clients and saves the data
115 /// immediately to persistent memory.
116 ////////////////////////////////////////////////////////////////////////////////////////////////////
117 EFrameworkunifiedStatus CStateNorPersistenceNotification::Publish(const std::string &f_cservicename,
118                                                      PVOID f_pmessage,
119                                                      const UI_32 f_uimsgsize) {
120   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
121   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
122
123   if (eFrameworkunifiedStatusOK == (l_estatus = PublishNotification(f_cservicename,
124                                                        f_pmessage,
125                                                        f_uimsgsize))) {
126     if (eFrameworkunifiedStatusOK != (l_estatus = SaveDataToNor(f_pmessage, f_uimsgsize))) {
127       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Error in saving persistent data on nor for %s published by %s, status: %d",
128              m_cNotificationName.c_str(), f_cservicename.c_str(), l_estatus);  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"  // NOLINT[whitespace/line_length]
129     }
130   }
131
132   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
133   return l_estatus;
134 }
135
136 ////////////////////////////////////////////////////////////////////////////////////////////////
137 /// PublishNotification
138 /// This function publishes the notification to subscribed clients.
139 ////////////////////////////////////////////////////////////////////////////////////////////////
140 EFrameworkunifiedStatus CStateNorPersistenceNotification::PublishNotification(const std::string &f_cservicename,
141                                                                  PVOID f_pmessage,
142                                                                  const UI_32 f_uimsgsize) {
143   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
144   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
145
146   l_estatus = CStateNotification::Publish(f_cservicename, f_pmessage, f_uimsgsize);
147
148   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
149   return l_estatus;
150 }
151
152 ////////////////////////////////////////////////////////////////////////////////////////////////////
153 /// SaveDataToNor
154 ////////////////////////////////////////////////////////////////////////////////////////////////////
155 EFrameworkunifiedStatus CStateNorPersistenceNotification::SaveDataToNor(PVOID f_pmessage, const UI_32 f_uimsgsize) {
156   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
157   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
158
159   if (NULL != f_pmessage && f_uimsgsize > 0) {
160     TNorPersistenceNotifInfoHeader l_tNorPersistentData = {};
161     UI_32 l_ui32SendDataTotalLength = static_cast<UI_32>(sizeof(TNorPersistenceNotifInfoHeader) + f_uimsgsize);
162     UI_8 *l_ui8SendData = new(std::nothrow) UI_8[l_ui32SendDataTotalLength];
163     UI_8 *l_ui8TmpOffset = l_ui8SendData;
164
165     if (NULL != l_ui8SendData) {  // LCOV_EXCL_BR_LINE 6: l_ui8SendData can't be NULL
166       std::strncpy(l_tNorPersistentData.m_cnotificationname,
167                    this->GetNotificationName().c_str(),
168                    sizeof(l_tNorPersistentData.m_cnotificationname) - 1);
169       std::strncpy(l_tNorPersistentData.m_cpublishername,
170                    this->GetPublisherName().c_str(),
171                    sizeof(l_tNorPersistentData.m_cpublishername) - 1);
172       l_tNorPersistentData.m_epersistenttype = this->GetNotificationType();
173       l_tNorPersistentData.m_uimaxmsglength = this->GetMaxMessageSize();
174       l_tNorPersistentData.m_uidelay = this->GetPersistenceDelay();
175       l_tNorPersistentData.m_uimsgsize = f_uimsgsize;
176       l_tNorPersistentData.m_epersistcategory = m_ePersistCategory;
177
178       std::memset(l_ui8SendData, 0, l_ui32SendDataTotalLength);
179       std::memcpy(l_ui8SendData, &l_tNorPersistentData, sizeof(l_tNorPersistentData));
180       l_ui8TmpOffset += sizeof(l_tNorPersistentData);
181       std::memcpy(l_ui8TmpOffset, f_pmessage, f_uimsgsize);
182
183       // issue a copy to the worker thread
184       if (NULL != CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread) {  // LCOV_EXCL_BR_LINE 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null  // NOLINT[whitespace/line_length]
185         if (eFrameworkunifiedStatusOK != (l_estatus = McSend(CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread, AppName, NOR_PERSISTENCE_TIMER_START, l_ui32SendDataTotalLength, l_ui8SendData))) {  // LCOV_EXCL_BR_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
186           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
187           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "McSend for nor worker thread failed %d ", l_estatus);  // LCOV_EXCL_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
188         }
189       } else {
190         // LCOV_EXCL_START 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null
191         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
192         l_estatus = eFrameworkunifiedStatusInvldHandle;
193         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Sender handle of nor worker thread is NULL. Can't send message.");
194         // LCOV_EXCL_STOP
195       }
196
197       delete[] l_ui8SendData;  // LCOV_EXCL_BR_LINE 11: unexpected branch
198       l_ui8SendData = NULL;
199     } else {
200       // LCOV_EXCL_START 6: l_ui8SendData can not be null
201       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
202       l_estatus = eFrameworkunifiedStatusNullPointer;
203       // LCOV_EXCL_STOP
204     }
205   } else {
206     l_estatus = eFrameworkunifiedStatusInvldParam;
207     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Notification data is NULL, size is %d", f_uimsgsize);  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"  // NOLINT[whitespace/line_length]
208   }
209
210   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
211   return l_estatus;
212 }
213
214 ////////////////////////////////////////////////////////////////////////////////////////////////////
215 /// GetPersistentCategory
216 /// Gets the persist type of notification.
217 ////////////////////////////////////////////////////////////////////////////////////////////////////
218 EFrameworkunifiedPersistCategory CStateNorPersistenceNotification::GetPersistentCategory() {   // LCOV_EXCL_START 100: never be used
219   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
220   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
221
222   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
223   return m_ePersistCategory;
224 }
225 // LCOV_EXCL_STOP
226
227 ////////////////////////////////////////////////////////////////////////////////////////////////////
228 /// SetPersistentCategory
229 /// Sets the persist type of notification.
230 ////////////////////////////////////////////////////////////////////////////////////////////////////
231 EFrameworkunifiedStatus CStateNorPersistenceNotification::SetPersistentCategory(const EFrameworkunifiedPersistCategory f_epersistcategory) {
232   EFrameworkunifiedStatus l_estatus = eFrameworkunifiedStatusOK;
233   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
234
235   if (f_epersistcategory != m_ePersistCategory) {
236     if (NULL != m_pData && NULL != m_pData->m_pMessage) {  // LCOV_EXCL_BR_LINE 6: if m_pData is not null, the m_pData->m_pMessage can not be null  // NOLINT[whitespace/line_length]
237       if (NULL != CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread) {  // LCOV_EXCL_BR_LINE 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null  // NOLINT[whitespace/line_length]
238         TImmediatePersistenceChangeCategory l_tChangeCategory = {};
239         UI_32 l_ui32SendDataTotalLength =
240           static_cast<UI_32>(sizeof(TImmediatePersistenceChangeCategory) + m_pData->m_uiMsgSize);
241         UI_8 *l_ui8SendData = new(std::nothrow) UI_8[l_ui32SendDataTotalLength];
242         UI_8 *l_ui8TmpOffset = l_ui8SendData;
243
244         if (NULL != l_ui8SendData) {  // LCOV_EXCL_BR_LINE 6: l_ui8SendData can't be NULL
245           std::strncpy(l_tChangeCategory.m_tnornotifInfoheader.m_cnotificationname, this->GetNotificationName().c_str(),
246                        sizeof(l_tChangeCategory.m_tnornotifInfoheader.m_cnotificationname) - 1);
247           std::strncpy(l_tChangeCategory.m_tnornotifInfoheader.m_cpublishername, this->GetPublisherName().c_str(),
248                        sizeof(l_tChangeCategory.m_tnornotifInfoheader.m_cpublishername) - 1);
249           l_tChangeCategory.m_tnornotifInfoheader.m_epersistenttype = this->GetNotificationType();
250           l_tChangeCategory.m_tnornotifInfoheader.m_uimaxmsglength = this->GetMaxMessageSize();
251           l_tChangeCategory.m_tnornotifInfoheader.m_uidelay = this->GetPersistenceDelay();
252           l_tChangeCategory.m_tnornotifInfoheader.m_uimsgsize = m_pData->m_uiMsgSize;
253           l_tChangeCategory.m_tnornotifInfoheader.m_epersistcategory = f_epersistcategory;
254
255           l_tChangeCategory.m_eoldpersistcategory = m_ePersistCategory;
256
257           std::memset(l_ui8SendData, 0, l_ui32SendDataTotalLength);
258           std::memcpy(l_ui8SendData, &l_tChangeCategory, sizeof(l_tChangeCategory));
259           l_ui8TmpOffset += sizeof(l_tChangeCategory);
260           std::memcpy(l_ui8TmpOffset, m_pData->m_pMessage, m_pData->m_uiMsgSize);
261
262           // issue a copy to the worker thread
263           if (eFrameworkunifiedStatusOK != (l_estatus = McSend(CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread,  // LCOV_EXCL_BR_LINE 4: NSFW error case  // NOLINT[whitespace/line_length]
264                                                   AppName,
265                                                   NOR_PERSISTENCE_CHANGE_CATEGORY,
266                                                   l_ui32SendDataTotalLength,
267                                                   l_ui8SendData))) {
268             // LCOV_EXCL_START 4: NSFW error case
269             AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
270             FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
271                    "McSend failed while changing category for notfn %s from %d to %d, status=%d",
272                    m_cNotificationName.c_str(), m_ePersistCategory, f_epersistcategory, l_estatus);
273             // LCOV_EXCL_STOP
274           } else {
275             FRAMEWORKUNIFIEDLOG(ZONE_NPP_INFO, __FUNCTION__,
276                    "Msg sent to immediate pers. thread to change persist category of %s from %d to %d",
277                    m_cNotificationName.c_str(), m_ePersistCategory, f_epersistcategory);
278           }
279
280           delete[] l_ui8SendData;
281           l_ui8SendData = NULL;
282         } else {
283           // LCOV_EXCL_START 6: l_ui8SendData can not be null
284           AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
285           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Memory alloc error for l_ui8SendData, errno=%d", errno);
286           l_estatus = eFrameworkunifiedStatusNullPointer;
287           // LCOV_EXCL_STOP
288         }
289       } else {
290         // LCOV_EXCL_START 6: CStateNorPersistenceNotification::m_hNSImmediatePersistenceThread can not be null
291         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
292         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Sender handle of nor worker thread is NULL. Can't send message.");
293         l_estatus = eFrameworkunifiedStatusInvldHandle;
294         // LCOV_EXCL_STOP
295       }
296     } else {  // no data is persisted in emmc for this notfn, so no need to send msg to worker thread
297       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Notfn %s has no data to persist", m_cNotificationName.c_str());
298     }
299
300     m_ePersistCategory = f_epersistcategory;
301   }
302
303   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
304   return l_estatus;
305 }