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_NativeService
19 /// \brief This file contains the implementation for the synchronization
22 ///////////////////////////////////////////////////////////////////////////////
24 #include <native_service/frameworkunified_multithreading.h>
25 #include <native_service/frameworkunified_framework_sync.h>
26 #include <native_service/frameworkunified_framework_if.h>
27 #include <native_service/ns_logger_if.h>
31 #include "frameworkunified_framework_core.h"
33 /// initialization of static members of class
34 CFrameworkunifiedSyncData *CFrameworkunifiedSyncData::m_psSyncData = NULL;
36 pthread_spinlock_t CFrameworkunifiedSyncData::m_pSyncLock;
37 static pthread_mutex_t g_instance_lock = PTHREAD_MUTEX_INITIALIZER;
39 // Template function to invoke callback function of CFrameworkunifiedSyncData class
40 template <typename C, eFrameworkunifiedStatus(C::*M)(HANDLE)> EFrameworkunifiedStatus SyncDataCallback(HANDLE hThread) {
41 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
43 C *l_pClass = C::FrameworkunifiedGetSyncDataInstance();
45 if (NULL != l_pClass) {
46 l_eStatus = (l_pClass->*M)(hThread);
52 ////////////////////////////////////////////////////////////////////////////////////////////////////
53 /// CFrameworkunifiedSyncData
54 /// Constructor of CFrameworkunifiedSyncData class
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
56 CFrameworkunifiedSyncData::CFrameworkunifiedSyncData(): m_bSyncThreadStarted(FALSE),
58 m_hSyncThreadAppHandle(NULL),
60 m_hSyncThreadMsgQHandle(NULL) {
61 pthread_spin_init(&m_pSyncLock, 1);
64 ////////////////////////////////////////////////////////////////////////////////////////////////////
65 /// CFrameworkunifiedSyncData
66 /// Destructor of CFrameworkunifiedSyncData class
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 CFrameworkunifiedSyncData::~CFrameworkunifiedSyncData() {
69 pthread_spin_destroy(&m_pSyncLock);
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
73 /// FrameworkunifiedStartNotificationSync
74 /// This method is used to start the synchronization notification thread.
75 ////////////////////////////////////////////////////////////////////////////////////////////////////
76 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedStartNotificationSync(HANDLE hApp) {
77 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
78 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
80 pthread_spin_lock(&m_pSyncLock);
81 if (frameworkunifiedCheckValidAppHandle(hApp)) {
83 std::string l_cThreadName = FrameworkunifiedGetAppName(hApp);
84 // l_cThreadName.append("SyncThread");
85 std::reverse(l_cThreadName.begin(), l_cThreadName.end());
87 if (NULL == m_hSyncThreadMsgQHandle) {
89 m_hSyncThreadMsgQHandle = FrameworkunifiedCreateChildThread(hApp,
90 l_cThreadName.c_str(),
91 SyncDataCallback<CFrameworkunifiedSyncData,
92 &CFrameworkunifiedSyncData::FrameworkunifiedSyncDataThreadStart>,
93 SyncDataCallback<CFrameworkunifiedSyncData,
94 &CFrameworkunifiedSyncData::FrameworkunifiedSyncDataThreadStop>);
95 if (NULL != m_hSyncThreadMsgQHandle) {
96 if (FALSE == m_bSyncThreadStarted) {
97 if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedStartChildThread(hApp,
98 m_hSyncThreadMsgQHandle,
101 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, " Failed to start Thread.");
103 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, " Sync Data Thread Started");
104 m_bSyncThreadStarted = TRUE;
107 l_eStatus = eFrameworkunifiedStatusThreadAlreadyRunning;
111 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, " Sync Data Thread Message Queue Null");
112 l_eStatus = eFrameworkunifiedStatusNullPointer;
115 l_eStatus = eFrameworkunifiedStatusThreadAlreadyRunning;
118 l_eStatus = eFrameworkunifiedStatusNullPointer;
121 pthread_spin_unlock(&m_pSyncLock);
123 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
127 ////////////////////////////////////////////////////////////////////////////////////////////////////
128 /// FrameworkunifiedStartNotificationSync
129 /// This method is used to stop the synchronization notification thread.
130 ////////////////////////////////////////////////////////////////////////////////////////////////////
131 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedStopNotificationSync(HANDLE hApp) {
132 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
133 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
135 if (frameworkunifiedCheckValidAppHandle(hApp)) {
136 if (NULL != m_hSyncThreadMsgQHandle) {
137 pthread_spin_lock(&m_pSyncLock);
138 if (eFrameworkunifiedStatusOK != (l_eStatus = (FrameworkunifiedStopChildThread(hApp,
139 m_hSyncThreadMsgQHandle,
142 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "FrameworkunifiedStopChildThread Sync Thread Failed.");
144 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "FrameworkunifiedStopChildThread Sync Thread Success.");
145 m_bSyncThreadStarted = FALSE;
147 pthread_spin_unlock(&m_pSyncLock);
149 l_eStatus = eFrameworkunifiedStatusThreadNotExist;
152 l_eStatus = eFrameworkunifiedStatusNullPointer;
155 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
159 ////////////////////////////////////////////////////////////////////////////////////////////////////
160 /// FrameworkunifiedGetSyncDataInstance
161 /// This function is used to get the singleton instance of class.
162 ////////////////////////////////////////////////////////////////////////////////////////////////////
163 CFrameworkunifiedSyncData *CFrameworkunifiedSyncData::FrameworkunifiedGetSyncDataInstance() {
164 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
166 if (NULL == m_psSyncData) {
167 pthread_mutex_lock(&g_instance_lock);
168 if (NULL == m_psSyncData) {
169 CFrameworkunifiedSyncData *l_pFrameworkunifiedSyncData = new(std::nothrow)CFrameworkunifiedSyncData();
170 m_psSyncData = l_pFrameworkunifiedSyncData;
172 pthread_mutex_unlock(&g_instance_lock);
175 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
180 ////////////////////////////////////////////////////////////////////////////////////////////////////
181 /// FrameworkunifiedReleaseSyncDataInstance
182 /// This function is used to release the instance of class.
183 ////////////////////////////////////////////////////////////////////////////////////////////////////
184 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedReleaseSyncDataInstance() {
185 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
186 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
188 if (NULL != m_psSyncData) {
189 pthread_mutex_lock(&g_instance_lock);
190 if (NULL != m_psSyncData) {
194 pthread_mutex_unlock(&g_instance_lock);
197 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
201 ////////////////////////////////////////////////////////////////////////////////////////////////////
202 /// FrameworkunifiedSyncDataThreadStart
203 /// This function is callback function on the start of the sync thread.
204 ////////////////////////////////////////////////////////////////////////////////////////////////////
205 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedSyncDataThreadStart(HANDLE hThread) {
206 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
207 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
209 if (NULL != hThread) {
210 // Set Sync Thread Handle
211 m_hSyncThreadAppHandle = hThread;
213 if (NULL == m_mSyncDataMap) {
214 m_mSyncDataMap = new(std::nothrow)TSyncDataPacketList();
216 l_eStatus = eFrameworkunifiedStatusNullPointer;
219 l_eStatus = eFrameworkunifiedStatusNullPointer;
221 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
225 ////////////////////////////////////////////////////////////////////////////////////////////////////
226 /// FrameworkunifiedSyncDataThreadStop
227 /// This function is callback function on the stop of the sync thread.
228 ////////////////////////////////////////////////////////////////////////////////////////////////////
229 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedSyncDataThreadStop(HANDLE hThread) {
230 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
232 if (NULL != m_mSyncDataMap) {
233 for (TSyncDataPacketItr l_itSyncDataPacketItr = m_mSyncDataMap->begin() ;
234 l_itSyncDataPacketItr != m_mSyncDataMap->end();) {
235 SFrameworkunifiedSyncDataPacket *l_ptDataPacket = l_itSyncDataPacketItr->second;
237 if (NULL != l_ptDataPacket) {
238 if (NULL != l_ptDataPacket->m_pNotificationData) {
239 delete[](static_cast<PCHAR>(l_ptDataPacket->m_pNotificationData));
240 l_ptDataPacket->m_pNotificationData = NULL;
242 delete l_ptDataPacket;
243 l_ptDataPacket = NULL;
244 m_mSyncDataMap->erase(l_itSyncDataPacketItr++);
246 l_itSyncDataPacketItr++;
250 delete m_mSyncDataMap;
251 m_mSyncDataMap = NULL;
253 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
254 return eFrameworkunifiedStatusExit;
257 ////////////////////////////////////////////////////////////////////////////////////////////////////
258 /// FrameworkunifiedSubscribeNotificationWithDataSync
259 /// This function is used to subscribe to notifications.
260 ////////////////////////////////////////////////////////////////////////////////////////////////////
261 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedSubscribeNotificationWithDataSync(const std::string &f_cNotification) {
262 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
263 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
265 pthread_spin_lock(&m_pSyncLock);
266 if (TRUE != f_cNotification.empty() && NULL != m_hSyncThreadAppHandle) {
267 if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedSubscribeNotificationWithCallback(
268 m_hSyncThreadAppHandle, // Thread Application handle
269 f_cNotification.c_str(), // Notification
270 SyncDataCallback<CFrameworkunifiedSyncData,
271 &CFrameworkunifiedSyncData::FrameworkunifiedSyncDataNotifCallback>))) { // Callback Function
272 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "FrameworkunifiedSubscribeNotificationWithCallback Sync Notification Data failed.");
273 l_eStatus = eFrameworkunifiedStatusFail;
275 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "FrameworkunifiedSubscribeNotificationWithCallback Sync Notification Data success.");
278 l_eStatus = eFrameworkunifiedStatusFail;
280 pthread_spin_unlock(&m_pSyncLock);
282 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
286 ////////////////////////////////////////////////////////////////////////////////////////////////////
287 /// FrameworkunifiedUnSubscribeNotificationWithDataSync
288 /// This function is used to unsubscribe to notifications.
289 ////////////////////////////////////////////////////////////////////////////////////////////////////
290 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedUnSubscribeNotificationWithDataSync(const std::string &f_cNotification) {
291 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
292 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
294 pthread_spin_lock(&m_pSyncLock);
295 if (TRUE != f_cNotification.empty() && NULL != m_hSyncThreadAppHandle) {
296 if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedUnsubscribeNotificationWithCallback
297 (m_hSyncThreadAppHandle, // Thread Application Handle
298 f_cNotification.c_str()))) { // Notification
299 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "FrameworkunifiedUnsubscribeNotificationWithCallback failed.");
300 l_eStatus = eFrameworkunifiedStatusFail;
302 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "FrameworkunifiedUnsubscribeNotificationWithCallback success.");
304 TSyncDataPacketItr l_itSycDataPacketItr = m_mSyncDataMap->find(f_cNotification);
305 // Delete the notification data
306 if (m_mSyncDataMap->end() != l_itSycDataPacketItr) {
307 SFrameworkunifiedSyncDataPacket *l_ptDataPacket = l_itSycDataPacketItr->second;
308 if (NULL != l_ptDataPacket && NULL != l_ptDataPacket->m_pNotificationData) {
309 delete[](static_cast<PCHAR>(l_ptDataPacket->m_pNotificationData));
310 l_ptDataPacket->m_pNotificationData = NULL;
311 delete l_ptDataPacket;
312 l_ptDataPacket = NULL;
313 m_mSyncDataMap->erase(l_itSycDataPacketItr);
318 l_eStatus = eFrameworkunifiedStatusFail;
320 pthread_spin_unlock(&m_pSyncLock);
322 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
326 ////////////////////////////////////////////////////////////////////////////////////////////////////
327 /// FrameworkunifiedSyncDataNotifCallback
328 /// This function is callback to notifications on publication of notifications.
329 ////////////////////////////////////////////////////////////////////////////////////////////////////
330 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedSyncDataNotifCallback(HANDLE hThread) {
331 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
332 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
334 if (NULL == hThread) {
335 return eFrameworkunifiedStatusInvldHandle;
338 PCSTR l_pcLastNotification = FrameworkunifiedGetLastNotification(hThread);
340 if (NULL == l_pcLastNotification || 0 == std::strlen(l_pcLastNotification)) {
341 return eFrameworkunifiedStatusInvldNotification;
344 UI_32 l_uiBufferSize = FrameworkunifiedGetMsgLength(hThread);
345 PVOID l_pDataBuffer = new(std::nothrow)CHAR[l_uiBufferSize];
347 if ((NULL != l_pDataBuffer) &&
348 (eFrameworkunifiedStatusOK == FrameworkunifiedGetMsgDataOfSize(hThread, l_pDataBuffer, l_uiBufferSize, eSMRRelease))) {
349 SFrameworkunifiedSyncDataPacket *l_ptDataPacket = NULL;
351 pthread_spin_lock(&m_pSyncLock);
353 TSyncDataPacketItr l_itSycDataPacketItr = m_mSyncDataMap->find(l_pcLastNotification);
354 // Delete the last notification data
355 if (m_mSyncDataMap->end() == l_itSycDataPacketItr) {
356 l_ptDataPacket = new(std::nothrow)SFrameworkunifiedSyncDataPacket();
358 l_ptDataPacket = l_itSycDataPacketItr->second;
359 if (NULL != l_ptDataPacket && NULL != l_ptDataPacket->m_pNotificationData) {
360 delete[](static_cast<PCHAR>(l_ptDataPacket->m_pNotificationData));
361 l_ptDataPacket->m_pNotificationData = NULL;
365 if (NULL != l_ptDataPacket) {
366 l_ptDataPacket->m_pNotificationData = l_pDataBuffer;
367 l_ptDataPacket->m_uiDataSize = l_uiBufferSize;
368 l_ptDataPacket->m_tTimeStamp = time(NULL);
369 m_mSyncDataMap->insert(std::make_pair(l_pcLastNotification, l_ptDataPacket));
371 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "NULL pointer: l_ptDataPacket");
374 pthread_spin_unlock(&m_pSyncLock);
376 l_eStatus = eFrameworkunifiedStatusFail;
378 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
382 ////////////////////////////////////////////////////////////////////////////////////////////////////
383 /// FrameworkunifiedGetSyncDataSize
384 /// This function is used to get the size of the synchronization data.
385 ////////////////////////////////////////////////////////////////////////////////////////////////////
386 UI_32 CFrameworkunifiedSyncData::FrameworkunifiedGetSyncDataSize(const std::string &f_cNotification) {
387 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
388 UI_32 l_uiSyncDataSize = 0;
390 if (TRUE != f_cNotification.empty()) {
391 pthread_spin_lock(&m_pSyncLock);
393 TSyncDataPacketItr l_itSyncDataPacketItr = m_mSyncDataMap->find(f_cNotification);
394 SFrameworkunifiedSyncDataPacket *l_ptDataPacket = NULL;
396 if (m_mSyncDataMap->end() != l_itSyncDataPacketItr) {
397 l_ptDataPacket = l_itSyncDataPacketItr->second;
398 l_uiSyncDataSize = l_ptDataPacket->m_uiDataSize;
400 pthread_spin_unlock(&m_pSyncLock);
403 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");
404 return l_uiSyncDataSize;
407 ////////////////////////////////////////////////////////////////////////////////////////////////////
408 /// FrameworkunifiedGetSyncNotificationData
409 /// This function is used to get the synchronization notification data for a particular notification .
410 ////////////////////////////////////////////////////////////////////////////////////////////////////
411 EFrameworkunifiedStatus CFrameworkunifiedSyncData::FrameworkunifiedGetSyncNotificationData(const std::string &f_cNotification, PVOID f_pBuffer,
412 UI_16 f_nBufferSize) {
413 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "+");
414 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
416 if (TRUE != f_cNotification.empty() && NULL != f_pBuffer && 0 != f_nBufferSize) {
417 pthread_spin_lock(&m_pSyncLock);
418 TSyncDataPacketItr l_itSyncDataPacketItr = m_mSyncDataMap->find(f_cNotification);
419 if (m_mSyncDataMap->end() != l_itSyncDataPacketItr) {
420 if (NULL != l_itSyncDataPacketItr->second) {
421 if (NULL != std::memcpy(f_pBuffer, l_itSyncDataPacketItr->second->m_pNotificationData,
422 l_itSyncDataPacketItr->second->m_uiDataSize)) {
423 l_eStatus = eFrameworkunifiedStatusOK;
425 l_eStatus = eFrameworkunifiedStatusFail;
428 l_eStatus = eFrameworkunifiedStatusFail;
431 l_eStatus = eFrameworkunifiedStatusNullPointer;
433 pthread_spin_unlock(&m_pSyncLock);
435 l_eStatus = eFrameworkunifiedStatusFail;
437 FRAMEWORKUNIFIEDLOG(ZONE_NS_INFO, __FUNCTION__, "-");