Re-organized sub-directory by category
[staging/basesystem.git] / service / native / framework_unified / client / NS_SharedMemIf / src / ns_sharedmem.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_NSSharedMemory
19 /// \brief    This file contains implementation of class CNSSharedMem.
20 ///           This class provides API to open, read, write and close shared memory
21 ///
22 ////////////////////////////////////////////////////////////////////////////////////////////////////
23
24 ////////////////////////////////////////////////////////////////////////////////////////////////////
25 // Include Files
26 ////////////////////////////////////////////////////////////////////////////////////////////////////
27 #include <unistd.h>
28 #include <sys/mman.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <limits.h>
35
36 #include <native_service/ns_sharedmem.h>
37 #include <native_service/ns_transmit_log.h>
38
39 #include <string>
40
41 static CNSSharedMem *g_pTransmitLogSharedBuf = NULL;
42
43 #define SHM_HEADER_EXT      "Hdr"
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49
50 ////////////////////////////////////////////////////////////////////////////////////////////
51 /// NSSharedMemTransmitLogOpen
52 /// Open the shared memory for transmit logging
53 ////////////////////////////////////////////////////////////////////////////////////////////
54 EFrameworkunifiedStatus NSSharedMemTransmitLogOpen() {
55   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
56
57   if (NULL == g_pTransmitLogSharedBuf) {
58     // Create the instance
59     g_pTransmitLogSharedBuf = new(std::nothrow) CNSSharedMem(TRANSMIT_LOG_SHAREDMEM_NAME, TRANSMIT_LOG_SHAREDMEM_SIZE);
60   }
61
62   if (NULL != g_pTransmitLogSharedBuf) {
63     if (!g_pTransmitLogSharedBuf->IsOpen()) {
64       // maps the shared memory buffer
65       l_eStatus = g_pTransmitLogSharedBuf->Open();
66     }
67   } else {
68     l_eStatus = eFrameworkunifiedStatusNullPointer;
69   }
70
71   return l_eStatus;
72 }
73
74 ////////////////////////////////////////////////////////////////////////////////////////////
75 /// NSSharedMemTransmitLogClose
76 /// Close the transmit logging shared memory
77 ////////////////////////////////////////////////////////////////////////////////////////////
78 EFrameworkunifiedStatus NSSharedMemTransmitLogClose() {
79   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
80
81   if (NULL != g_pTransmitLogSharedBuf) {
82     // un-map the shared memory object
83     l_eStatus = g_pTransmitLogSharedBuf->Close();
84
85     delete g_pTransmitLogSharedBuf;
86     g_pTransmitLogSharedBuf = NULL;
87   } else {
88     l_eStatus = eFrameworkunifiedStatusNullPointer;
89   }
90
91   return l_eStatus;
92 }
93
94 ////////////////////////////////////////////////////////////////////////////////////////////
95 /// NSSharedMemReadTransmitLog
96 /// Reads transmit log from the shared memory buffer.
97 ////////////////////////////////////////////////////////////////////////////////////////////
98 SI_32 NSSharedMemReadTransmitLog(PSTR f_pBuffer, const UI_32 f_uiLength, const BOOL f_bBlock) {
99   // no. of bytes read
100   SI_32 l_iReadSize = NS_SHM_ERROR;
101
102   if (NULL != g_pTransmitLogSharedBuf && NULL != f_pBuffer) {
103     // Writes log data into shared memory buffer
104     l_iReadSize = g_pTransmitLogSharedBuf->Read(f_pBuffer, f_uiLength, f_bBlock);
105   }
106
107   return l_iReadSize;
108 }
109
110 ////////////////////////////////////////////////////////////////////////////////////////////
111 /// NSSharedMemWriteTransmitLog
112 /// Write transmit log into the shared memory buffer.
113 ////////////////////////////////////////////////////////////////////////////////////////////
114 SI_32 NSSharedMemWriteTransmitLog(PCSTR f_pBuffer, const UI_32 f_uiLength) {
115   // no. of bytes read
116   SI_32 l_iWriteSize = NS_SHM_ERROR;
117
118   if (NULL != g_pTransmitLogSharedBuf && NULL != f_pBuffer) {
119     // Writes log data into shared memory buffer
120     l_iWriteSize = g_pTransmitLogSharedBuf->Write(f_pBuffer, f_uiLength);
121   }
122
123   return l_iWriteSize;
124 }
125
126 ////////////////////////////////////////////////////////////////////////////////////////////
127 /// NSSharedMemDumpTransmitLogToFile
128 /// Dump transmit log from the shared memory buffer into file.
129 ////////////////////////////////////////////////////////////////////////////////////////////
130 EFrameworkunifiedStatus NSSharedMemDumpTransmitLogToFile(PCSTR f_pPath, PUI_32 f_puiDumpSize) {
131   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
132
133   if (NULL != g_pTransmitLogSharedBuf && NULL != f_pPath) {
134     // Writes log data into shared memory buffer
135     l_eStatus = g_pTransmitLogSharedBuf->DumpToFile(f_pPath, f_puiDumpSize);
136   }
137
138   return l_eStatus;
139 }
140
141 // Used only in nstest_sharedmem.
142 #if defined(SHM_UNITTEST_ENABLE)
143 ////////////////////////////////////////////////////////////////////////////////////////////
144 /// NSSharedMemTransmitLogIsOpen
145 ////////////////////////////////////////////////////////////////////////////////////////////
146 BOOL NSSharedMemTransmitLogIsOpen() {
147   if (g_pTransmitLogSharedBuf != NULL) {
148     return g_pTransmitLogSharedBuf->IsOpen();
149   } else {
150     return FALSE;
151   }
152 }
153 #endif
154
155 #ifdef __cplusplus
156 }
157 #endif
158
159 ////////////////////////////////////////////////////////////////////////////////////////////////
160 /// CNSSharedMem
161 /// Parameterized Constructor of CNSSharedMem class
162 ////////////////////////////////////////////////////////////////////////////////////////////////
163 CNSSharedMem::CNSSharedMem(const std::string &f_cSharedMemName, const UI_32 f_uiSize):
164   m_cShmName(f_cSharedMemName), m_uiShmBuffSize(f_uiSize), m_pShmHdr(NULL), m_pShmBuff(NULL) {
165   m_cShmHdrName = f_cSharedMemName;
166   m_cShmHdrName.append(SHM_HEADER_EXT);
167 }
168
169 ////////////////////////////////////////////////////////////////////////////////////////////////
170 /// CNSSharedMem
171 /// Constructor of CNSSharedMem class
172 ////////////////////////////////////////////////////////////////////////////////////////////////
173 CNSSharedMem::CNSSharedMem():
174   m_cShmName(""), m_uiShmBuffSize(0), m_pShmHdr(NULL), m_pShmBuff(NULL) {
175   // do nothing
176 }
177
178 ////////////////////////////////////////////////////////////////////////////////////////////////
179 /// ~CNSSharedMem
180 /// Destructor of CNSSharedMem class
181 ////////////////////////////////////////////////////////////////////////////////////////////////
182 CNSSharedMem::~CNSSharedMem() {
183   if (NULL != m_pShmHdr) {
184     // un-map the shared memory object
185     Close();
186
187     m_pShmHdr = NULL;
188   }
189
190   // TODO(framework_unified): currently shared memory is not being unlinked,
191   // we need to find a method where we can unlink the sharedmem
192   // shm_unlink(m_cShmName.c_str());
193 }
194
195 ////////////////////////////////////////////////////////////////////////////////////////////////
196 /// Open
197 /// This function opens and maps the shared memory object.
198 /// It creates the shared memory if it does not exists.
199 ////////////////////////////////////////////////////////////////////////////////////////////////
200 EFrameworkunifiedStatus CNSSharedMem::Open() {
201   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusErrOther;
202
203 // Used only in nstest_sharedmem.
204 #if defined(SHM_UNITTEST_ENABLE)
205   if (getenv(NSTEST_FAIL_SHAREDMEM_OPEN) != NULL) {
206     return l_eStatus;
207   }
208 #endif
209
210   if (NULL == m_pShmHdr) {
211     // Open header shared memory
212     if (eFrameworkunifiedStatusOK != (l_eStatus = MapSM(reinterpret_cast<PVOID *>(&m_pShmHdr),
213       m_cShmHdrName, sizeof(NSSharedBufferHdr)))) {
214       if (ENOENT == errno) {  // Shared memory is not created yet
215         errno = EOK;
216
217         // Create shared memory
218         if (eFrameworkunifiedStatusOK == CreateSMHeader()) {
219           // Retry to open
220           l_eStatus = MapSM(reinterpret_cast<PVOID *>(&m_pShmHdr), m_cShmHdrName, sizeof(NSSharedBufferHdr));
221         }
222       }
223     } else {
224       pthread_mutex_lock(&m_pShmHdr->m_tBufMutex);
225
226       // if shared memory buffer is created with size 0, then set new size in header if any change
227       if (0 == m_pShmHdr->m_uiShMemSize && 0 < m_uiShmBuffSize) {
228         m_pShmHdr->m_uiShMemSize = m_uiShmBuffSize;
229       } else if (0 < m_pShmHdr->m_uiShMemSize && 0 == m_uiShmBuffSize) {
230         m_uiShmBuffSize = m_pShmHdr->m_uiShMemSize;
231       } else {
232         // do nothing
233       }
234
235       pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex);
236     }
237   }
238
239   if (eFrameworkunifiedStatusOK == l_eStatus && 0 != m_uiShmBuffSize) {
240     if (NULL == m_pShmBuff) {
241       // Open shared memory data buffer, create if not exists
242       if (eFrameworkunifiedStatusOK != (l_eStatus = MapSM(reinterpret_cast<PVOID *>(&m_pShmBuff), m_cShmName, m_uiShmBuffSize))) {
243         if (ENOENT == errno) {  // Shared memory is not created yet
244           // Create shared memory
245           if (eFrameworkunifiedStatusOK == CreateSMDataBuffer()) {
246             // Retry to open
247             l_eStatus = MapSM(reinterpret_cast<PVOID *>(&m_pShmBuff), m_cShmName, m_uiShmBuffSize);
248           }
249         }
250       }
251     } else {
252       l_eStatus = eFrameworkunifiedStatusErrOther;
253     }
254   }
255
256   return l_eStatus;
257 }
258
259 ////////////////////////////////////////////////////////////////////////////////////////////////
260 /// IsOpen
261 /// This function is used to check whether the shared memory buffer is opened or not.
262 ////////////////////////////////////////////////////////////////////////////////////////////////
263 BOOL CNSSharedMem::IsOpen() {
264   return NULL == m_pShmHdr ? FALSE : TRUE;
265 }
266
267 ////////////////////////////////////////////////////////////////////////////////////////////////
268 /// Close
269 /// This function closes the shared memory object.
270 ////////////////////////////////////////////////////////////////////////////////////////////////
271 EFrameworkunifiedStatus CNSSharedMem::Close() {
272   EFrameworkunifiedStatus l_eStatus1 = UnMapSM(m_pShmHdr, sizeof(NSSharedBufferHdr));
273   m_pShmHdr = NULL;
274
275   EFrameworkunifiedStatus l_eStatus2 = eFrameworkunifiedStatusOK;
276   if (0 != m_uiShmBuffSize) {
277     l_eStatus2 = UnMapSM(m_pShmBuff, m_uiShmBuffSize);
278     m_pShmBuff = NULL;
279   }
280   /*
281    * todo
282    * Even if an error occurs due to eFrameworkunifiedStatusNullPointer when UnMapSM fails,
283    * the error type cannot be determined by the caller because it is rounded to eFrameworkunifiedStatusFail
284    * if the API final determination is not OK.
285    */
286   return (eFrameworkunifiedStatusOK != l_eStatus1 || eFrameworkunifiedStatusOK != l_eStatus2) ? eFrameworkunifiedStatusFail : eFrameworkunifiedStatusOK;
287 }
288
289 ////////////////////////////////////////////////////////////////////////////////////////////////
290 /// Read
291 /// This function reads data from the shared memory.
292 ////////////////////////////////////////////////////////////////////////////////////////////////
293 SI_32 CNSSharedMem::Read(PSTR f_pBuffer, const UI_32 f_uilength, const BOOL f_bBlock) {
294   SI_32 l_iReadSize = NS_SHM_ERROR;
295
296   if ((NULL != f_pBuffer) && (NULL != m_pShmHdr) && (0 != f_uilength)) {
297     UI_32 l_uiDataSizeToRead = 0;
298
299     // Remaining buffer size from read pointer to end of the buffer
300     UI_32 l_uiRemainSize = 0;
301
302     if (0 == pthread_mutex_lock(&m_pShmHdr->m_tBufMutex)) {
303       if ((TRUE == f_bBlock) && (0 == m_pShmHdr->m_uiUnReadSize)) {
304         pthread_cond_wait(&m_pShmHdr->m_tCondVar, &m_pShmHdr->m_tBufMutex);
305       }
306
307       // if shared memory buffer size is changed by some other process, remap the updated buffer size in this process
308       // shared memory buffer size can only be changed if the initial size is 0.
309       if (m_uiShmBuffSize != m_pShmHdr->m_uiShMemSize) {
310         if (eFrameworkunifiedStatusOK == MapSM(reinterpret_cast<PVOID *>(&m_pShmBuff), m_cShmName, m_pShmHdr->m_uiShMemSize)) {
311           m_uiShmBuffSize = m_pShmHdr->m_uiShMemSize;
312         }
313       }
314
315       if (NULL != m_pShmBuff) {
316         l_uiRemainSize = m_uiShmBuffSize - m_pShmHdr->m_uiReadPtr;
317
318         // Round read data size depending on un-read data size in the buffer
319         l_uiDataSizeToRead = m_pShmHdr->m_uiUnReadSize < f_uilength ? m_pShmHdr->m_uiUnReadSize : f_uilength;
320
321         if (l_uiRemainSize < l_uiDataSizeToRead) {
322           // Wrapping read
323           memcpy(f_pBuffer, m_pShmBuff + m_pShmHdr->m_uiReadPtr, l_uiRemainSize);
324           memcpy(f_pBuffer + l_uiRemainSize, m_pShmBuff, l_uiDataSizeToRead - l_uiRemainSize);
325           m_pShmHdr->m_uiReadPtr = l_uiDataSizeToRead - l_uiRemainSize;
326         } else {
327           memcpy(f_pBuffer, m_pShmBuff + m_pShmHdr->m_uiReadPtr, l_uiDataSizeToRead);
328
329           m_pShmHdr->m_uiReadPtr += l_uiDataSizeToRead;
330
331           // Read pointer is the end of the buffer
332           if (m_pShmHdr->m_uiReadPtr == m_uiShmBuffSize) {
333             m_pShmHdr->m_uiReadPtr = 0;
334           }
335         }
336
337         m_pShmHdr->m_uiUnReadSize -= l_uiDataSizeToRead;  // Update un-read data size
338
339         l_iReadSize = l_uiDataSizeToRead;
340       }
341
342       pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex);
343     }
344   }
345
346   return l_iReadSize;
347 }
348
349 ////////////////////////////////////////////////////////////////////////////////////////////////
350 /// Write
351 /// This function writes the data into the shared memory.
352 ////////////////////////////////////////////////////////////////////////////////////////////////
353 SI_32 CNSSharedMem::Write(PCSTR f_pBuffer, const UI_32 f_uilength) {
354   SI_32 l_iWriteSize = NS_SHM_ERROR;
355
356   // size available in buffer
357   UI_32 l_uiRemainSize = 0;
358
359   if (NULL != m_pShmHdr && NULL != m_pShmBuff && NULL != f_pBuffer && f_uilength <= m_uiShmBuffSize) {
360     if (0 == pthread_mutex_lock(&m_pShmHdr->m_tBufMutex)) {
361       l_uiRemainSize = m_uiShmBuffSize - m_pShmHdr->m_uiWritePtr;
362
363       // Write data to the buffer
364       if (l_uiRemainSize < f_uilength) {
365         // Wrapping write
366         memcpy(m_pShmBuff + m_pShmHdr->m_uiWritePtr, f_pBuffer, l_uiRemainSize);
367         memcpy(m_pShmBuff, f_pBuffer + l_uiRemainSize, f_uilength - l_uiRemainSize);
368
369         // Update the write pointer
370         m_pShmHdr->m_uiWritePtr = f_uilength - l_uiRemainSize;
371
372         // The buffer is full of valid data
373         m_pShmHdr->m_bIsFull = TRUE;
374       } else {
375         memcpy(m_pShmBuff + m_pShmHdr->m_uiWritePtr, f_pBuffer, f_uilength);
376
377         // Update the write pointer
378         m_pShmHdr->m_uiWritePtr += f_uilength;
379
380         // Write pointer is the end of the buffer
381         if (m_pShmHdr->m_uiWritePtr == m_uiShmBuffSize) {
382           m_pShmHdr->m_uiWritePtr = 0;
383
384           // The buffer is full of valid data
385           m_pShmHdr->m_bIsFull = TRUE;
386         }
387       }
388
389       // Update un-read data size
390       m_pShmHdr->m_uiUnReadSize += f_uilength;
391
392       // Set read pointer to be same as write pointer if write pointer exceeds the read pointer
393       if (m_uiShmBuffSize < m_pShmHdr->m_uiUnReadSize) {
394         m_pShmHdr->m_uiReadPtr = m_pShmHdr->m_uiWritePtr;
395         m_pShmHdr->m_uiUnReadSize = m_uiShmBuffSize;
396       }
397
398       pthread_cond_signal(&m_pShmHdr->m_tCondVar);
399
400       pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex);
401
402       l_iWriteSize = f_uilength;
403     }
404   }
405
406   return l_iWriteSize;
407 }
408
409 ////////////////////////////////////////////////////////////////////////////////////////////////
410 /// DumpToFile
411 /// This function writes all the data in the buffer into provided file f_pPath.
412 ////////////////////////////////////////////////////////////////////////////////////////////////
413 EFrameworkunifiedStatus CNSSharedMem::DumpToFile(PCSTR f_pPath, PUI_32 f_uiDumpSize) {
414   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
415
416   ssize_t l_iSize = 0;
417
418   SI_32 fd = -1;
419
420   if (NULL == f_uiDumpSize) {
421     return eFrameworkunifiedStatusNullPointer;
422   }
423   *f_uiDumpSize = 0;
424
425   if (NULL != f_pPath) {
426     if (NULL != m_pShmHdr) {
427       // Open file
428       if (-1 != (fd = open(f_pPath, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRWXU | S_IRWXG | S_IRWXO))) {
429         if (NULL != m_pShmBuff && 0 != m_uiShmBuffSize) {
430           if (0 == pthread_mutex_lock(&m_pShmHdr->m_tBufMutex)) {
431             // Write buffer data to file
432             if (m_pShmHdr->m_bIsFull) {
433               // Buffer has full of data (read data from write pointer)
434               if (-1 != (l_iSize = write(fd, m_pShmBuff + m_pShmHdr->m_uiWritePtr,
435                 m_uiShmBuffSize - m_pShmHdr->m_uiWritePtr))) {
436                 *f_uiDumpSize += static_cast<UI_32>(l_iSize);
437               } else {
438                 l_eStatus = eFrameworkunifiedStatusErrOther;
439               }
440             }
441
442             if (-1 != (l_iSize = write(fd, m_pShmBuff, m_pShmHdr->m_uiWritePtr))) {
443               *f_uiDumpSize += static_cast<UI_32>(l_iSize);
444             }
445
446             if (0 != pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex)) {
447               l_eStatus = eFrameworkunifiedStatusSemUnlockFail;
448             }
449           } else {
450             l_eStatus = eFrameworkunifiedStatusSemLockFail;
451           }
452         } else if (NULL == m_pShmBuff && 0 != m_uiShmBuffSize) {
453           l_eStatus = eFrameworkunifiedStatusFail;
454         } else {
455           // do nothing
456         }
457
458         // Sync the file to force I/O operation completed
459         fsync(fd);
460
461         close(fd);
462       } else {
463         l_eStatus = eFrameworkunifiedStatusFileLoadError;
464       }
465     } else {
466       l_eStatus = eFrameworkunifiedStatusFail;
467     }
468   } else {
469     l_eStatus = eFrameworkunifiedStatusInvldParam;
470   }
471
472   return l_eStatus;
473 }
474
475 ////////////////////////////////////////////////////////////////////////////////////////////////
476 /// GetSize
477 /// This function returns the number of unread bytes which can be read by Read().
478 ////////////////////////////////////////////////////////////////////////////////////////////////
479 SI_32 CNSSharedMem::GetSize() {
480   SI_32 l_uiReadSize = NS_SHM_ERROR;
481
482   if (NULL != m_pShmHdr) {
483     l_uiReadSize = m_pShmHdr->m_uiUnReadSize;
484   }
485
486   return l_uiReadSize;
487 }
488
489 ////////////////////////////////////////////////////////////////////////////////////////////////
490 /// ClearBuf
491 /// This function clears the buffer.
492 ////////////////////////////////////////////////////////////////////////////////////////////////
493 EFrameworkunifiedStatus CNSSharedMem::ClearBuf() {
494   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
495
496   if (NULL != m_pShmHdr) {
497     if (0 == pthread_mutex_lock(&m_pShmHdr->m_tBufMutex)) {
498       // Initialize the r/w pointers
499       m_pShmHdr->m_uiReadPtr = 0;
500       m_pShmHdr->m_uiWritePtr = 0;
501       m_pShmHdr->m_uiUnReadSize = 0;
502       m_pShmHdr->m_bIsFull = FALSE;
503
504       if (0 != pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex)) {
505         l_eStatus = eFrameworkunifiedStatusSemUnlockFail;
506       }
507     } else {
508       l_eStatus = eFrameworkunifiedStatusSemLockFail;
509     }
510   } else {
511     l_eStatus = eFrameworkunifiedStatusFail;
512   }
513
514   return l_eStatus;
515 }
516
517 ////////////////////////////////////////////////////////////////////////////////////////////////
518 /// SetReadPtrToWritePtr
519 /// This function sets the position of read ptr to write ptr in buffer.
520 ////////////////////////////////////////////////////////////////////////////////////////////////
521 EFrameworkunifiedStatus CNSSharedMem::SetReadPtrToWritePtr() {
522   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
523
524   if (NULL != m_pShmHdr) {
525     if (0 == pthread_mutex_lock(&m_pShmHdr->m_tBufMutex)) {  // LCOV_EXCL_BR_LINE 5: pthread_mutex_lock's error case
526       // Initialize the r/w pointers
527       m_pShmHdr->m_uiReadPtr = m_pShmHdr->m_uiWritePtr;
528       m_pShmHdr->m_uiUnReadSize = 0;
529
530       if (0 != pthread_mutex_unlock(&m_pShmHdr->m_tBufMutex)) {  // LCOV_EXCL_BR_LINE 5: pthread_mutex_unlock's error
531         l_eStatus = eFrameworkunifiedStatusSemUnlockFail;
532       }
533     } else {
534       l_eStatus = eFrameworkunifiedStatusSemLockFail;
535     }
536   } else {
537     l_eStatus = eFrameworkunifiedStatusFail;
538   }
539
540   return l_eStatus;
541 }
542
543 ////////////////////////////////////////////////////////////////////////////////////////////////
544 /// CreateSMHeader
545 /// This function creates the shared memory object for header.
546 ////////////////////////////////////////////////////////////////////////////////////////////////
547 EFrameworkunifiedStatus CNSSharedMem::CreateSMHeader() {
548   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
549
550   // file descriptor of shared memory
551   SI_32 l_siId = -1;
552
553   // shared memory buffer headers
554   NSSharedBufferHdr *l_pShmHdr = NULL;
555
556   if ((!m_cShmHdrName.empty()) && (m_cShmHdrName.size() <= NAME_MAX)) {
557     // Try to create shared memory
558     l_siId = shm_open(m_cShmHdrName.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
559
560     if (-1 != l_siId) {
561       // Set the size of shared memory
562       if (-1 != ftruncate(l_siId, sizeof(NSSharedBufferHdr))) {
563         // Map the shared memory
564         l_pShmHdr = reinterpret_cast<NSSharedBufferHdr *>(mmap(NULL, sizeof(NSSharedBufferHdr),
565           (PROT_READ | PROT_WRITE), MAP_SHARED, l_siId, 0));
566
567         if (MAP_FAILED != l_pShmHdr) {
568           // mutex attribute
569           pthread_mutexattr_t l_tMtxAttr = {};
570           pthread_condattr_t l_tCondAttr = {};
571
572           // Initialize mutex
573           pthread_mutexattr_init(&l_tMtxAttr);
574           pthread_mutexattr_setpshared(&l_tMtxAttr, PTHREAD_PROCESS_SHARED);
575           pthread_mutex_init(&l_pShmHdr->m_tBufMutex, &l_tMtxAttr);
576           pthread_mutexattr_destroy(&l_tMtxAttr);
577
578           pthread_condattr_init(&l_tCondAttr);
579           pthread_condattr_setpshared(&l_tCondAttr, PTHREAD_PROCESS_SHARED);
580           pthread_cond_init(&l_pShmHdr->m_tCondVar, &l_tCondAttr);
581           pthread_condattr_destroy(&l_tCondAttr);
582
583           pthread_mutex_lock(&l_pShmHdr->m_tBufMutex);
584
585           // Initialize the r/w pointers
586           l_pShmHdr->m_uiReadPtr = 0;
587           l_pShmHdr->m_uiWritePtr = 0;
588           l_pShmHdr->m_uiUnReadSize = 0;
589           l_pShmHdr->m_bIsFull = FALSE;
590           l_pShmHdr->m_uiShMemSize = m_uiShmBuffSize;
591
592           pthread_mutex_unlock(&l_pShmHdr->m_tBufMutex);
593
594           // Once initialized un-map the shared memory
595           munmap(l_pShmHdr, sizeof(NSSharedBufferHdr));
596
597           l_eStatus = eFrameworkunifiedStatusOK;
598         }
599       }
600
601       close(l_siId);
602     } else if (EEXIST == errno) {
603       // Shared memory is already created
604       l_eStatus = eFrameworkunifiedStatusDuplicate;
605     } else {
606       // do nothing
607     }
608   } else {
609     l_eStatus = eFrameworkunifiedStatusInvldParam;
610   }
611
612   return l_eStatus;
613 }
614
615 ////////////////////////////////////////////////////////////////////////////////////////////////
616 /// CreateSMDataBuffer
617 /// This function creates the shared memory object for data buffer.
618 ////////////////////////////////////////////////////////////////////////////////////////////////
619 EFrameworkunifiedStatus CNSSharedMem::CreateSMDataBuffer() {
620   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
621
622   // file descriptor of shared memory
623   SI_32 l_siId = -1;
624
625   if ((!m_cShmName.empty()) && (m_cShmName.size() <= NAME_MAX)) {
626     // Try to create shared memory
627     l_siId = shm_open(m_cShmName.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
628
629     if (-1 != l_siId) {
630       // Set the size of shared memory
631       if (-1 != ftruncate(l_siId, m_uiShmBuffSize)) {
632         l_eStatus = eFrameworkunifiedStatusOK;
633       }
634
635       close(l_siId);
636     } else if (EEXIST == errno) {
637       // Shared memory is already created
638       l_eStatus = eFrameworkunifiedStatusDuplicate;
639     } else {
640       // do nothing
641     }
642   } else {
643     l_eStatus = eFrameworkunifiedStatusInvldParam;
644   }
645
646   return l_eStatus;
647 }
648
649 ////////////////////////////////////////////////////////////////////////////////////////////////
650 /// MapSMHeader
651 /// This function open and maps the shared memory header in process space.
652 ////////////////////////////////////////////////////////////////////////////////////////////////
653 EFrameworkunifiedStatus CNSSharedMem::MapSM(PVOID *f_pShMem, const std::string &f_cShmName, const UI_32 f_uiShmSize) {
654   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
655
656   // file descriptor of shared memory
657   SI_32 l_siId = -1;
658
659   // shared memory buffer headers
660   PVOID l_pShmBuf = NULL;
661
662   // Open shared memory
663   l_siId = shm_open(f_cShmName.c_str(), O_RDWR, 0);
664
665   if (-1 != l_siId) {
666     // Map the shared memory into its memory space
667     l_pShmBuf = mmap(NULL, f_uiShmSize, (PROT_READ | PROT_WRITE), MAP_SHARED, l_siId, 0);
668
669     if (MAP_FAILED != l_pShmBuf) {
670       *f_pShMem = l_pShmBuf;
671       l_eStatus = eFrameworkunifiedStatusOK;
672     }
673
674     close(l_siId);
675   }
676
677   return l_eStatus;
678 }
679
680 ////////////////////////////////////////////////////////////////////////////////////////////////
681 /// UnMapSM
682 /// This function unmaps the shared memory object.
683 ////////////////////////////////////////////////////////////////////////////////////////////////
684 EFrameworkunifiedStatus CNSSharedMem::UnMapSM(PVOID f_pShMem, const UI_32 f_uiShmSize) {
685   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
686
687   // Un-map the shared memory
688   if (NULL != f_pShMem) {
689     if (0 != munmap(f_pShMem, f_uiShmSize)) {
690       l_eStatus = eFrameworkunifiedStatusFail;
691     }
692   } else {
693     l_eStatus = eFrameworkunifiedStatusNullPointer;
694   }
695
696   return l_eStatus;
697 }