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_NSSharedMemory
19 /// \brief SharedMemIf implementation
21 /// Implements interface functions to SharedMem service
22 //////////////////////////////////////////////////////////////////////////////////////////////////
23 #include <native_service/ns_shared_mem_if.h> ///< Shared mem source interface file
24 #include <native_service/ns_logger_if.h>
34 #define NS_SHM_HEADER_SIZE (48)
36 /////////////////////////////////////////////////////////////////////////////
37 /// Utility functions and classes
39 static TMemID getclock(void) {
41 if (clock_gettime(CLOCK_MONOTONIC_RAW, &tp) < 0) { // LCOV_EXCL_BR_LINE 5: clock_gettime's error case.
44 return (TMemID)(((uint64_t)tp.tv_sec * 1000 * 1000 * 1000 + tp.tv_nsec) >> 8);
47 static size_t uitoa(unsigned int value, char *buf) {
48 static const char c[] = "0123456789abcdef";
52 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "buf is NULL");
55 for (i = 0; i < 8; i++) {
56 buf[i] = c[(value >> ((7 - i) * 4)) & 0xf];
63 static inline void create_shmname(char *buf, TMemID id) {
65 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "buf is NULL");
68 strcpy(buf, "nsshm_"); // NOLINT (readability/nolint)
69 buf += sizeof("nsshm_") - 1;
73 //////////////////////////////////////////////////////////////////////////////////////////////////
74 // Public interface function definitions
76 TMemID SetDataToShared(const void *data, UI_32 dataBytes, const char *from, const char *to) {
80 void *addr = MAP_FAILED;
83 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "data is NULL");
87 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "from is NULL");
91 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "to is NULL");
96 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "DataSize is invalied(%d)", dataBytes);
102 create_shmname(shmname, id);
104 if ((fd = shm_open(shmname, O_CREAT | O_EXCL | O_RDWR, 0666)) < 0) {
105 if (errno == EEXIST) {
108 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "shm_open: %s", strerror(errno));
114 if (ftruncate(fd, dataBytes + NS_SHM_HEADER_SIZE) < 0) { // LCOV_EXCL_BR_LINE 5: ftruncate's error case.
115 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ftruncate: %s", strerror(errno));
120 if ((addr = mmap(NULL, dataBytes + NS_SHM_HEADER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
121 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "mmap: %s", strerror(errno));
126 strcpy(reinterpret_cast<char *>(addr), from); // NOLINT (readability/nolint)
127 strcpy(reinterpret_cast<char *>(addr) + (NS_SHM_HEADER_SIZE / 2), to); // NOLINT (readability/nolint)
130 * Specifying a large number (4097 or higher) for the Session Data Size for transmission results in a segmentation fault.
132 memcpy(reinterpret_cast<char *>(addr) + NS_SHM_HEADER_SIZE, data, dataBytes);
136 if (addr != MAP_FAILED) {
137 munmap(addr, dataBytes + NS_SHM_HEADER_SIZE);
139 if (id == BAD_MEM_ID) {
145 EFrameworkunifiedStatus GetDataFromShared(TMemID id, void *data, UI_32 dataMaxBytes) {
146 EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusFail;
149 void *addr = MAP_FAILED;
152 if (id == BAD_MEM_ID) {
153 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ShMemID is invalied(%u)", id);
154 return eFrameworkunifiedStatusInvldParam;
157 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "data is NULL");
158 return eFrameworkunifiedStatusInvldParam;
160 if (dataMaxBytes == 0) {
161 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "DataSize is invalied(%d)", dataMaxBytes);
162 return eFrameworkunifiedStatusInvldParam;
165 create_shmname(shmname, id);
167 if ((fd = shm_open(shmname, O_RDONLY, 0)) < 0) {
168 if (errno == ENOENT) {
169 eStatus = eFrameworkunifiedStatusInvldID;
171 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "shm_open: %s", strerror(errno));
175 if (fstat(fd, &sb) < 0) { // LCOV_EXCL_BR_LINE 5: fstat's error case
176 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "fstat: %s", strerror(errno));
179 if (sb.st_size - NS_SHM_HEADER_SIZE > static_cast<SI_64>(dataMaxBytes)) {
180 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "DataSize is invalied(%d-%d)", dataMaxBytes, (int)sb.st_size);
181 eStatus = eFrameworkunifiedStatusInvldParam;
185 if ((addr = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case.
186 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
187 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "mmap: %s", strerror(errno)); // LCOV_EXCL_LINE 5: mmap's error case.
191 memcpy(data, reinterpret_cast<char *>(addr) + NS_SHM_HEADER_SIZE, sb.st_size - NS_SHM_HEADER_SIZE);
192 eStatus = eFrameworkunifiedStatusOK;
196 if (addr != MAP_FAILED) {
197 munmap(addr, sb.st_size);
202 UI_32 GetLengthOfDataFromShared(TMemID id) {
208 if (id == BAD_MEM_ID) {
209 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ShMemID is invalied(%u)", id); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
213 create_shmname(shmname, id);
215 if ((fd = shm_open(shmname, O_RDWR, 0)) < 0) {
216 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "shm_open: %s", strerror(errno));
220 if (fstat(fd, &sb) < 0) { // LCOV_EXCL_BR_LINE 5: fstat's error case.
221 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
222 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "fstat: %s", strerror(errno)); // LCOV_EXCL_LINE 5: mmap's error case.
226 size = static_cast<UI_32>(sb.st_size - NS_SHM_HEADER_SIZE);
233 EFrameworkunifiedStatus DiscardDataFromShared(TMemID id) {
234 EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
237 if (id == BAD_MEM_ID) {
238 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ShMemID is invalied(%u)", id);
239 return eFrameworkunifiedStatusInvldParam;
242 create_shmname(shmname, id);
244 if (shm_unlink(shmname) < 0) {
245 if (errno == ENOENT) {
246 eStatus = eFrameworkunifiedStatusInvldID;
248 eStatus = eFrameworkunifiedStatusFail;
250 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "shm_unlink: %s", strerror(errno));