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_NSMessageCenter
21 /// APIs to Open\Close and Send\Receive on message queues and shared memory.
23 ///////////////////////////////////////////////////////////////////////////////
25 #include <native_service/ns_message_center_if.h>
26 #include <ns_message_center_internal.h>
27 #include "ns_msg_queue.h"
28 #include <ns_mq_internal.h>
29 #include <ns_mc_internal.h>
30 #include <native_service/ns_msgs.h>
33 #include <native_service/ns_shared_mem_if.h>
38 #include <sys/timeb.h>
41 #include <sys/resource.h>
42 #include <sys/syscall.h>
43 #include <sys/socket.h>
46 #include <sys/epoll.h>
47 #include <native_service/ns_transmit_log.h>
48 #include <native_service/ns_logger_if.h>
49 #include <native_service/ns_resource_controler.h>
50 #include <native_service/nsfw_message.h>
53 #include <other_service/strlcpy.h>
55 #define assert_static(e) \
57 enum { assert_static__ = 1/(e) }; \
60 #define MC_INVOKE_SYNC_TIMEOUT (60 * 1000)
64 EFrameworkunifiedStatus ret_val;
68 static unsigned int mcSeed[4];
70 HANDLE McOpenReceiverNotBlocked(PCSTR name) {
71 return OpenReceiverNotBlocked(name);
74 HANDLE McOpenReceiver(PCSTR name) {
75 return OpenReceiver(name);
78 HANDLE McOpenSyncReceiver(PCSTR name) {
79 return openSyncReceiver(name);
83 HANDLE McOpenSender(PCSTR name) {
84 return OpenSender(name);
87 HANDLE McOpenSenderNotBlocked(PCSTR name) {
88 return OpenSender(name);
91 HANDLE McOpenSyncSender(PCSTR name) {
92 return openSyncSender(name);
95 static int mcSetMonitorName(char *str, PCSTR name) {
98 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "str is NULL");
102 len = sprintf(str + 1, "monitorS_%s", name != 0 ? name : NULL);
106 static int OpenMonitor(PCSTR name) {
107 int monitor_sock = -1;
109 struct sockaddr_un monitor_sa_un;
111 if ((monitor_sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)) < 0) {
112 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "socket:%s", strerror(errno));
116 memset(&monitor_sa_un, 0, sizeof(monitor_sa_un));
117 monitor_sa_un.sun_family = AF_UNIX;
118 monitor_sa_len = mcSetMonitorName(monitor_sa_un.sun_path, name);
119 monitor_sa_len += (int)offsetof(struct sockaddr_un, sun_path);
121 if (bind(monitor_sock, (struct sockaddr *)&monitor_sa_un, (socklen_t)monitor_sa_len) < 0) {
122 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "bind:%s:%s", name, strerror(errno)); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
126 if (listen(monitor_sock, SOMAXCONN) < 0) {
127 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "listen:%s", strerror(errno)); // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
133 if (monitor_sock >= 0) {
139 int mcOpenMonitor(PCSTR name) {
142 if (frameworkunifiedAcquireResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, name, &monitor_sock) < 0) {
143 if ((monitor_sock = OpenMonitor(name)) != -1) {
144 if (frameworkunifiedRegistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, name, monitor_sock, 1) < 0) {
151 return (int)monitor_sock;
154 int mcCloseMonitor(PCSTR name) {
157 if (frameworkunifiedGetResource(FRAMEWORKUNIFIED_RES_ABNMLMON, name, &monitor_sock) < 0) {
161 frameworkunifiedUnregistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, name);
162 close((int)monitor_sock);
167 static int mcSetClientName(char *str, PCSTR serverName, PCSTR clientName) {
170 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "str is NULL");
174 len = sprintf(str + 1, "monitorC_%s:%s", serverName != 0 ? serverName : NULL, clientName != 0 ? clientName : NULL);
178 static int ConnectMonitor(PCSTR serverName, PCSTR clientName) {
179 int client_sock = -1;
180 int client_sa_len, monitor_sa_len;
181 struct sockaddr_un client_sa_un, monitor_sa_un;
183 if ((client_sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) { // LCOV_EXCL_BR_LINE 5: socket's error case
184 // LCOV_EXCL_START 5:socket's error case
185 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
186 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "socket:%s", strerror(errno));
191 memset(&client_sa_un, 0, sizeof(client_sa_un));
192 client_sa_un.sun_family = AF_UNIX;
193 client_sa_len = mcSetClientName(client_sa_un.sun_path, serverName, clientName);
194 client_sa_len += (int)offsetof(struct sockaddr_un, sun_path);
196 if (bind(client_sock, (struct sockaddr *)&client_sa_un, (socklen_t)client_sa_len) < 0) {
197 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "bind:%s:%s", client_sa_un.sun_path + 1, strerror(errno));
201 memset(&monitor_sa_un, 0, sizeof(monitor_sa_un));
202 monitor_sa_un.sun_family = AF_UNIX;
203 monitor_sa_len = mcSetMonitorName(monitor_sa_un.sun_path, serverName);
204 monitor_sa_len += (int)offsetof(struct sockaddr_un, sun_path);
206 if (connect(client_sock, (struct sockaddr *)&monitor_sa_un, (socklen_t)monitor_sa_len) < 0) {
207 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "connect:%s", strerror(errno));
217 int mcSetConnectKey(char *buf, size_t size, PCSTR serverName, PCSTR clientName) {
218 int len = snprintf(buf, size, "%s:%s", serverName != 0 ? serverName : NULL, clientName != 0 ? clientName : NULL);
220 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "buf is NULL");
223 buf[size - 1] = '\0';
227 int mcConnectMonitor(PCSTR serverName, PCSTR clientName) {
229 char connect_key[32];
231 mcSetConnectKey(connect_key, sizeof(connect_key), serverName, clientName);
233 if (frameworkunifiedAcquireResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key, &client_sock) < 0) {
234 if ((client_sock = ConnectMonitor(serverName, clientName)) != -1) {
235 if (frameworkunifiedRegistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key, client_sock, 1) < 0) {
242 return (int)client_sock;
245 int mcCloseConnectMonitor(PCSTR serverName, PCSTR clientName) { // LCOV_EXCL_START 8: dead code
246 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
248 char connect_key[32];
250 mcSetConnectKey(connect_key, sizeof(connect_key), serverName, clientName);
252 if (frameworkunifiedGetResource(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key, &client_sock) == -1) {
256 if (frameworkunifiedReleaseResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key) == 0) {
257 frameworkunifiedUnregistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key);
258 close((int)client_sock);
264 static void mcGetClientName(const char *str, char *client_name, size_t size, int pathlen) {
265 size_t len = size - 1;
268 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "str is NULL");
271 char *p_div = strchr(str + 1, ':');
275 str_len = (size_t)(pathlen - (p_div - str + 1));
279 if (client_name == NULL) {
280 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "client_name is NULL");
283 strncpy(client_name, p_div + 1, len);
284 client_name[len] = '\0';
287 int mcAcceptMonitor(PCSTR serverName, int listenMonitorFd) {
288 int accept_sock = -1;
289 struct sockaddr_un client_sa_un;
290 socklen_t client_sa_len = sizeof(client_sa_un);
291 char client_name[16];
292 char connect_key[32];
294 if ((accept_sock = accept4(listenMonitorFd, (struct sockaddr *)&client_sa_un, &client_sa_len, SOCK_CLOEXEC)) < 0) {
295 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "accept:%s", strerror(errno));
299 mcGetClientName(client_sa_un.sun_path, client_name, sizeof(client_name), (int)(client_sa_len - offsetof(struct sockaddr_un,
301 mcSetConnectKey(connect_key, sizeof(connect_key), serverName, client_name);
303 frameworkunifiedRegistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key, accept_sock, 0);
307 int mcGetAcceptMonitor(PCSTR serverName, PCSTR clientName) {
309 char connect_key[32];
311 mcSetConnectKey(connect_key, sizeof(connect_key), serverName, clientName);
313 if (frameworkunifiedAcquireResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key, &accept_sock) < 0) {
317 return (int)accept_sock;
320 int mcGetClientNameFromConnectKey(PCSTR connectKey, PCHAR clientName, size_t len) {
321 char *p_div = strchr(connectKey, ':');
326 strncpy(clientName, p_div + 1, len);
327 clientName[len - 1] = '\0';
331 int mcGetServerNameFromConnectKey(PCSTR connectKey, PCHAR serverName, size_t len) {
332 char *p_div = strchr(connectKey, ':');
339 min_len = ((len - 1) < (p_div - connectKey)) ? len - 1 : (size_t)(p_div - connectKey);
340 strncpy(serverName, connectKey, min_len);
341 serverName[min_len] = '\0';
345 /////////////////////////////////////////
346 HANDLE McOpenSenderChild(PCSTR name, pthread_t childid) {
347 return OpenSenderChild(name, childid);
350 EFrameworkunifiedStatus McJoinChild(HANDLE hChildApp) {
351 EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
353 if (INVALID_HANDLE != hChildApp) { // LCOV_EXCL_BR_LINE 6: impossible to confirm because hChildApp checked is passed in the FrameworkunifiedDestroyChildThread function of the frameworkunified_multithreading.cpp
354 eStatus = JoinChild(hChildApp);
356 // LCOV_EXCL_START 6: impossible to confirm because hChildApp checked is passed in the FrameworkunifiedDestroyChildThread function of the frameworkunified_multithreading.cpp
357 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
358 eStatus = eFrameworkunifiedStatusInvldHandle;
365 EFrameworkunifiedStatus McGetChildThreadPriority(HANDLE hChildApp, PSI_32 threadPrio) {
366 EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK;
368 if (INVALID_HANDLE != hChildApp) {
369 eStatus = GetChildThreadPriority(hChildApp, threadPrio);
371 eStatus = eFrameworkunifiedStatusInvldHandle;
378 /////////////////////////////////////////
380 static EFrameworkunifiedStatus mcReceiveInternal(HANDLE hMessage, PSTR source, UI_32 *cmd, UI_32 *sessionid, UI_32 length,
382 PSSystemMsgHeader sysHdr = NULL;
384 // check if handle is valid
385 if (hMessage == INVALID_HANDLE) {
386 return eFrameworkunifiedStatusInvldHandle;
389 // check if buffer is null
391 return eFrameworkunifiedStatusInvldBuf;
394 // check for invalid length.
396 return eFrameworkunifiedStatusInvldBuf;
399 // check if the source is null
400 if (source == NULL) {
401 return eFrameworkunifiedStatusInvldQName;
405 return eFrameworkunifiedStatusInvldParam;
408 if (-1 != ReceiveMessage(hMessage, length, data)) {
409 sysHdr = (PSSystemMsgHeader)data;
410 if (strlen(sysHdr->info.source) < MAX_QUEUE_NAME_SIZE) {
411 *cmd = sysHdr->info.command;
413 *sessionid = sysHdr->info.sessionid;
415 strlcpy(source, sysHdr->info.source, MAX_NAME_SIZE_APP);
416 return eFrameworkunifiedStatusOK;
418 return eFrameworkunifiedStatusInvldBuf;
421 return TranslateError(errno);
424 return eFrameworkunifiedStatusFail;
427 EFrameworkunifiedStatus McReceive(HANDLE hMessage, PSTR source, UI_32 *cmd, UI_32 length, PVOID data) {
428 return mcReceiveInternal(hMessage, source, cmd, NULL, length, data);
431 EFrameworkunifiedStatus McReceiveWithSession(HANDLE hMessage, PSTR source, UI_32 *cmd, UI_32 *sessionid, UI_32 length, PVOID data) {
432 if (sessionid == NULL) {
433 return eFrameworkunifiedStatusInvldParam;
435 return mcReceiveInternal(hMessage, source, cmd, sessionid, length, data);
438 static EFrameworkunifiedStatus mcSendInternal(HANDLE hMessage, PCSTR source, UI_32 cmd, PCSTR sysInfo, UI_32 length, PCVOID data,
439 EFrameworkunifiedMessagePriorties priority, UI_32 sessionid, BOOL is_sync) {
440 assert_static(_NSFW_MSG_LEN_ == sizeof(SSystemMsgHeader));
441 assert_static(_NSFW_SYSINFO_SIZE_ == MAX_SYS_INFO_SIZE);
442 assert_static(_NSFW_SYSINFO_FLAG_ == MC_EMSGT_SYSINFO_MASK);
444 // check if handle is valid
445 if (mqCheckValidHandle(hMessage) == FALSE) {
446 return eFrameworkunifiedStatusInvldHandle;
449 // check if buffer is null
450 if (data == NULL && length > 0) {
451 return eFrameworkunifiedStatusInvldBuf;
454 // check if the source is null
455 if (source == NULL) {
456 return eFrameworkunifiedStatusInvldQName;
459 // check if the source length exceeds than expected
462 * Although a send message queue handle can be created using a 19-byte message queue name, messages cannot be sent using the created send message queue handle.
463 * Because "/" is added to the queue name in the send message queue handle, a judgment error of MAX_QUEUE_NAME_SIZE (20 bytes) occurs during transmission and transmission cannot be performed.
465 if (strlen(source) >= MAX_QUEUE_NAME_SIZE) {
466 return eFrameworkunifiedStatusInvldQName;
469 // notification name size should be less than MAX_SYS_INFO_SIZE
471 UI_32 max_length = 0;
472 if (NULL != sysInfo) {
473 if (strlen(sysInfo) >= MAX_SYS_INFO_SIZE) {
474 return eFrameworkunifiedStatusInvldParam;
476 // If there is an sysInfo, the maximum send data length is the maximum send data length of UI_32 minus (header + sysInfo size).
477 max_length = 0xFFFFFFFF - sizeof(SSystemMsgHeader) - sizeof(TSysMsgSystemInfo);
479 // If there is no sysInfo, the maximum send data length is the maximum value of UI_32 minus the headers.
480 max_length = 0xFFFFFFFF - sizeof(SSystemMsgHeader);
483 if (length > max_length) {
484 return eFrameworkunifiedStatusInvldParam;
486 EFrameworkunifiedStatus rtnStatus = eFrameworkunifiedStatusOK;
488 UI_8 sndBuf[ MAX_QUEUE_MSG_SIZE ];
489 SQhandle *sndHndl = (SQhandle *)hMessage;
490 SSystemMsgHeader *msgHdr = (SSystemMsgHeader *)sndBuf;
491 UI_32 send_length = 0;
492 UI_32 offset = sizeof(SSystemMsgHeader);
494 if (NULL == sndHndl->q_name) {
495 return eFrameworkunifiedStatusInvldHandle;
498 // check if the dest length exceeds than expected
499 if (strlen(sndHndl->q_name) >= MAX_QUEUE_NAME_SIZE) {
500 return eFrameworkunifiedStatusInvldHandle;
504 strcpy(msgHdr->info.source, source);
505 msgHdr->info.length = length; // this is length of the messages data...
506 msgHdr->info.command = cmd;
507 msgHdr->info.sessionid = sessionid;
509 msgHdr->eType = (UI_32)MC_EMSGT_VALID_TOKEN;
510 msgHdr->memId = 0; // not set...
511 if (NULL != sysInfo) {
512 msgHdr->eType |= MC_EMSGT_SYSINFO_MASK;
513 strcpy((char *)(sndBuf + offset), sysInfo);
514 offset += (UI_32)sizeof(TSysMsgSystemInfo);
517 msgHdr->eType |= MC_EMSGT_SYNC_MASK;
520 // Build buffer to send...
525 * Do not throw an error even if the data size of the argument is set to 0.
526 * When "length + offset" is MAX_QUEUE_MSG_SIZE (4096) or more, the length becomes 0 in the process that is executed cannot be checked.
527 * Sizeof(SSystemMsgHeader) is 40, sizeof(TSysMsgSystemInfo) is 64, maximal. offset is 104, min. is 40
529 if ((length + offset) >= MAX_QUEUE_MSG_SIZE) {
530 // set the shared mem info in header....
531 msgHdr->eType |= MC_EMSGT_SHM_MASK;
534 msgHdr->memId = SetDataToShared(data, length, source, sndHndl->q_name);
536 if (BAD_MEM_ID != msgHdr->memId) {
537 // update the send length
538 send_length += offset;
540 rtnStatus = eFrameworkunifiedStatusErrOther;
542 } else { // was less than the max
543 // update the send length
544 send_length += offset;
548 * If UINT_MAX (4294967295) is specified in the iLength of FrameworkunifiedNPPublishNotification,
549 * the comparison by (length + offset) >= MAX_QUEUE_MSG_SIZE fails to compare correctly because of an overflow,
550 * and the comparison is judged to be less than the max.
551 * Once in the else block, the data is treated as a sysHeader block of up to 4096 bytes,
552 * and the memcpy is performed again without size checking, resulting in a segmentation fault.
553 * Maximum message length that can be sent by FrameworkunifiedNPPublishNotification must be specified and the maximum message length must be checked.
555 // copy the msg to send buffer
556 memcpy(&sndBuf[0] + offset, data, length);
558 // update the send length
559 send_length += length;
562 if (eFrameworkunifiedStatusOK == rtnStatus) {
563 rtnStatus = SendMessageWithPriority(hMessage, send_length, (PVOID)&sndBuf[0], priority);
566 if (rtnStatus != eFrameworkunifiedStatusOK) {
567 // remove the shared mem since this failed.
574 EFrameworkunifiedStatus McSendPrioWithSysInfo(HANDLE hMessage, PCSTR source, UI_32 cmd, PCSTR sysInfo, UI_32 length, PCVOID data,
575 EFrameworkunifiedMessagePriorties priority, UI_32 sessionid) {
576 if (NULL == sysInfo) {
577 return eFrameworkunifiedStatusInvldParam;
579 return mcSendInternal(hMessage, source, cmd, sysInfo, length, data, priority, sessionid, FALSE);
582 EFrameworkunifiedStatus McSendWithSysInfo(HANDLE hMessage, PCSTR source, UI_32 cmd, PCSTR sysInfo, UI_32 length, PCVOID data,
584 if (NULL == sysInfo) {
585 return eFrameworkunifiedStatusInvldParam;
587 return mcSendInternal(hMessage, source, cmd, sysInfo, length, data, eFrameworkunifiedMsgPrioNormal, sessionid, FALSE);
590 EFrameworkunifiedStatus McSend(HANDLE hMessage, PCSTR source, UI_32 cmd, UI_32 length, PCVOID data) {
591 return mcSendInternal(hMessage, source, cmd, NULL, length, data, eFrameworkunifiedMsgPrioNormal, 0, FALSE);
594 EFrameworkunifiedStatus McSendWithPriority(HANDLE hMessage, PCSTR source, UI_32 cmd, UI_32 length, PCVOID data,
595 EFrameworkunifiedMessagePriorties priority, UI_32 sessionid) {
596 return mcSendInternal(hMessage, source, cmd, NULL, length, data, priority, sessionid, FALSE);
599 EFrameworkunifiedStatus McSendWithSession(HANDLE hMessage, PCSTR source, UI_32 cmd, UI_32 length, PCVOID data, UI_32 sessionid) {
600 return mcSendInternal(hMessage, source, cmd, NULL, length, data, eFrameworkunifiedMsgPrioNormal, sessionid, FALSE);
603 EFrameworkunifiedStatus McSendSyncResponse(HANDLE hMessage, PCSTR source, UI_32 cmd, UI_32 seq_id, EFrameworkunifiedStatus ret_val, UI_32 length,
605 EFrameworkunifiedStatus eStatus;
606 ResponseHeader *resHdr;
609 if ((UINT_MAX - sizeof(ResponseHeader)) < length) {
610 return eFrameworkunifiedStatusInvldBufSize;
613 // check if buffer is null
614 if (data == NULL && length > 0) {
615 return eFrameworkunifiedStatusInvldBuf;
618 if ((res_data = calloc(length + sizeof(ResponseHeader), 1)) == NULL) { // LCOV_EXCL_BR_LINE 5: calloc's error case
619 // LCOV_EXCL_START 5: calloc's error case
620 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
621 eStatus = eFrameworkunifiedStatusFail;
626 resHdr = (ResponseHeader *)res_data;
627 resHdr->seq_id = seq_id;
628 resHdr->ret_val = ret_val;
629 resHdr->res_size = length;
631 memcpy(res_data + sizeof(ResponseHeader), data, length);
633 eStatus = mcSendInternal(hMessage, source, cmd, NULL, (UI_32)(length + sizeof(ResponseHeader)), res_data, eFrameworkunifiedMsgPrioNormal, 0,
647 static inline unsigned int xor128(void) {
649 t = (mcSeed[0] ^ (mcSeed[0] << 11));
650 mcSeed[0] = mcSeed[1];
651 mcSeed[1] = mcSeed[2];
652 mcSeed[2] = mcSeed[3];
653 return (mcSeed[3] = (mcSeed[3] ^ (mcSeed[3] >> 19)) ^ (t ^ (t >> 8)));
656 static inline char *ultoa(unsigned long value, char *buf, int radix) {
657 const static char c[] = "0123456789abcdef";
659 char *p = b + sizeof(b);
663 *--p = c[value % (unsigned long)radix];
664 value /= (unsigned long)radix;
667 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "buf is NULL");
675 EFrameworkunifiedStatus McInvokeSync(HANDLE hMessage, PCSTR source, UI_32 cmd, UI_32 msgLength, PCVOID msgData, UI_32 sessionid,
676 HANDLE hRcvMessage, UI_32 responseLength, PVOID responseData, UI_32 *receivedLength) {
677 EFrameworkunifiedStatus eStatus;
678 TSysMsgSystemInfo sysInfo;
680 ResponseHeader *resHdr;
681 UI_8 *rcv_buf = NULL;
682 CHAR resSource[MAX_NAME_SIZE_APP];
684 struct epoll_event events[2];
685 struct epoll_event ev;
686 int connect_sock = -1;
687 SQhandle *sndHndl = (SQhandle *)hMessage;
689 if (mqCheckValidHandle(hMessage) == FALSE || mqCheckValidHandle(hRcvMessage) == FALSE || (responseLength != 0 &&
690 responseData == NULL)) {
691 eStatus = eFrameworkunifiedStatusInvldHandle;
695 * The system performs rcv_buf free without NULL determination.
700 if (NULL == receivedLength) {
701 eStatus = eFrameworkunifiedStatusInvldParam;
704 if ((rcv_buf = malloc(MAX_QUEUE_MSG_SIZE)) == NULL) { // LCOV_EXCL_BR_LINE 5: malloc's error case.
705 // LCOV_EXCL_START 5: malloc's error case.
706 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
707 eStatus = eFrameworkunifiedStatusFail;
712 if (mcSeed[0] == 0) {
714 if ((fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) < 0) {
715 eStatus = eFrameworkunifiedStatusFail;
719 if (read(fd, &mcSeed, sizeof(mcSeed)) < 0) {
721 eStatus = eFrameworkunifiedStatusFail;
730 ultoa(seq_id, &sysInfo[2], 16);
734 eStatus = mcSendInternal(hMessage, source, cmd, sysInfo, msgLength, msgData, eFrameworkunifiedMsgPrioNormal, sessionid, TRUE);
735 if (eStatus != eFrameworkunifiedStatusOK) {
739 if ((connect_sock = mcConnectMonitor(sndHndl->q_name + 1, source)) < 0) {
740 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "connect:%s", strerror(errno));
741 eStatus = eFrameworkunifiedStatusFail;
745 if ((efd = epoll_create1(EPOLL_CLOEXEC)) < 0) { // LCOV_EXCL_BR_LINE 5: epoll_create1's error case.
746 // LCOV_EXCL_START 5: epoll_create1's error case.
747 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
748 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_create1:%s", strerror(errno));
749 eStatus = eFrameworkunifiedStatusFail;
754 ev.data.fd = McGetQueueFD(hRcvMessage);
755 if (epoll_ctl(efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) { // LCOV_EXCL_BR_LINE 5: epoll_ctl's error case.
756 // LCOV_EXCL_START 5: epoll_ctl's error case.
757 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
758 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_ctl:%s", strerror(errno));
759 eStatus = eFrameworkunifiedStatusFail;
763 ev.events = EPOLLRDHUP;
764 ev.data.fd = connect_sock;
765 if (epoll_ctl(efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) { // LCOV_EXCL_BR_LINE 5: epoll_ctl's error case.
766 // LCOV_EXCL_START 5: epoll_ctl's error case.
767 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
768 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_ctl:%s", strerror(errno));
769 eStatus = eFrameworkunifiedStatusFail;
777 nfds = epoll_wait(efd, events, 2, MC_INVOKE_SYNC_TIMEOUT);
778 if (nfds == -1) { // LCOV_EXCL_BR_LINE 5: epoll_wait's error case.
779 // LCOV_EXCL_START 5: epoll_wait's error case.
780 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
781 if (errno == EINTR) {
784 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_wait:%s", strerror(errno));
785 eStatus = eFrameworkunifiedStatusFail;
788 } else if (nfds == 0) { // LCOV_EXCL_BR_LINE 5: epoll_wait return value equal 0.
789 // LCOV_EXCL_START 5: epoll_wait return value equal 0.
790 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
791 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_wait:time out");
792 eStatus = eFrameworkunifiedStatusAccessError;
797 for (n = 0; n < nfds; n++) {
798 if (events[n].data.fd == connect_sock) {
802 char connect_key[32];
803 mcSetConnectKey(connect_key, sizeof(connect_key), sndHndl->q_name + 1, source);
805 if (epoll_ctl(efd, EPOLL_CTL_DEL, connect_sock, events) < 0) {
806 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_ctl:%s", strerror(errno));
808 if (close(connect_sock) < 0) {
809 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "close:%s", strerror(errno));
811 frameworkunifiedUnregistResouce(FRAMEWORKUNIFIED_RES_ABNMLMON, connect_key);
813 if ((connect_sock = mcConnectMonitor(sndHndl->q_name + 1, source)) < 0) {
814 eStatus = eFrameworkunifiedStatusBadConnection;
817 ev.events = EPOLLRDHUP;
818 ev.data.fd = connect_sock;
819 if (epoll_ctl(efd, EPOLL_CTL_ADD, ev.data.fd, &ev) < 0) {
820 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "epoll_ctl:%s", strerror(errno));
821 eStatus = eFrameworkunifiedStatusFail;
828 if ((eStatus = McReceive(hRcvMessage, resSource, &cmd, MAX_QUEUE_MSG_SIZE, rcv_buf)) != eFrameworkunifiedStatusOK) {
832 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)rcv_buf;
833 if (MC_EMSGT_IS_SHM(sysHdr->eType)) {
834 UI_32 shmLength = GetLengthOfDataFromShared(sysHdr->memId);
835 TMemID memId = sysHdr->memId;
837 if (shmLength == 0) {
838 eStatus = eFrameworkunifiedStatusErrOther;
843 if ((rcv_buf = calloc(shmLength, 1)) == NULL) {
844 eStatus = eFrameworkunifiedStatusFail;
848 if ((eStatus = GetDataFromShared(memId, rcv_buf, shmLength)) != eFrameworkunifiedStatusOK) {
849 eStatus = eFrameworkunifiedStatusErrOther;
853 DiscardDataFromShared(memId);
854 resHdr = (ResponseHeader *)rcv_buf;
856 resHdr = (ResponseHeader *)(rcv_buf + sizeof(SSystemMsgHeader));
859 if (resHdr->seq_id == seq_id) {
860 if (resHdr->res_size > 0 && responseLength > 0)
861 memcpy(responseData, (const void *)((char *)resHdr + sizeof(ResponseHeader)),
862 resHdr->res_size > responseLength ? responseLength : resHdr->res_size);
864 *receivedLength = resHdr->res_size;
865 eStatus = resHdr->ret_val;
866 goto exit; // success
884 EFrameworkunifiedStatus McCreateInvokerName(PCSTR source, UI_32 sessionid, PSTR invokerName, UI_32 size) {
885 if (source == NULL || invokerName == NULL) {
886 return eFrameworkunifiedStatusInvldParam;
889 // When the size of the synchronous communication message queue name storage area is 0.
891 return eFrameworkunifiedStatusInvldParam;
893 snprintf(invokerName, size - 1, "%s_r0", source);
894 return eFrameworkunifiedStatusOK;
897 EFrameworkunifiedStatus McForward(HANDLE hMessage, PCSTR source, UI_32 iCmd, TMemID USID) {
898 // check if handle is valid
899 if (mqCheckValidHandle(hMessage) == FALSE) {
900 return eFrameworkunifiedStatusInvldHandle;
903 // check if the source is null
904 if (source == NULL) {
905 return eFrameworkunifiedStatusInvldQName;
908 // check the shared memory id
909 if (USID == BAD_MEM_ID) {
910 return eFrameworkunifiedStatusErrOther;
913 // check if the source length exceeds than expected
914 if (strlen(source) >= MAX_QUEUE_NAME_SIZE) {
915 return eFrameworkunifiedStatusInvldQName;
918 UI_8 sndBuf[ MAX_QUEUE_MSG_SIZE ] = {};
919 SQhandle *sndHndl = (SQhandle *)hMessage;
920 SSystemMsgHeader msgHdr = {};
922 // check if the dest length exceeds than expected
923 if (strlen(sndHndl->q_name) >= MAX_QUEUE_NAME_SIZE) {
924 return eFrameworkunifiedStatusInvldHandle;
928 strlcpy(msgHdr.info.source, source, sizeof(msgHdr.info.source));
929 msgHdr.info.length = GetLengthOfDataFromShared(USID); // this is length of the messages data...
930 msgHdr.info.command = iCmd;
931 msgHdr.eType = (UI_32)(MC_EMSGT_VALID_TOKEN | MC_EMSGT_SHM_MASK);
933 msgHdr.info.sessionid = 0;
936 UI_8 offset = sizeof(SSystemMsgHeader);
937 // write header to send buffer
938 memcpy(&sndBuf[0], &msgHdr, offset);
940 return SendMessage(hMessage, MAX_QUEUE_MSG_SIZE, (PVOID)&sndBuf[0]);
943 PCSTR McGetMsgSrc(PVOID data) {
944 // check if buffer is null
946 return NULL; // The data is invalid return zero length.
949 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
950 return (PCSTR)sysHdr->info.source;
953 UI_32 mcGetMsgSsessionId(PVOID data) {
954 // check if buffer is null
956 return 0; // The data is invalid return zero.
959 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
960 return sysHdr->info.sessionid;
963 UI_32 McGetLength(PVOID data) {
964 // check if buffer is null
966 return 0; // The data is invalid return zero length.
969 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
970 return sysHdr->info.length;
973 PVOID McGetDataPointer(PVOID data) {
978 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
979 int offset = sizeof(SSystemMsgHeader);
981 if (MC_EMSGT_HAS_SYSINFO(sysHdr->eType)) {
982 offset += (int)sizeof(TSysMsgSystemInfo);
985 return (PVOID)((long)data + offset);
988 EFrameworkunifiedStatus McGetSysInfoData(PVOID data, PVOID to) {
989 // check if buffers are null
990 if (data == NULL || to == NULL) {
991 return eFrameworkunifiedStatusInvldBuf;
994 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
995 if (MC_EMSGT_VALID((int)sysHdr->eType)) {
996 if (MC_EMSGT_HAS_SYSINFO(sysHdr->eType)) {
997 strlcpy(to, (char *)data + sizeof(SSystemMsgHeader), MAX_SYS_INFO_SIZE);
1001 return eFrameworkunifiedStatusOK;
1004 return eFrameworkunifiedStatusInvldHandle;
1007 EFrameworkunifiedStatus McGetDataOfSize(PVOID data, PVOID to, UI_32 uiSize) {
1008 if (McGetLength(data) > uiSize) {
1009 return eFrameworkunifiedStatusInvldBufSize;
1011 return GetData(data, to, FALSE);
1014 EFrameworkunifiedStatus McGetDataOfSizeWithSMRetain(PVOID data, PVOID to, UI_32 uiSize) {
1015 if (McGetLength(data) > uiSize) {
1016 return eFrameworkunifiedStatusInvldBufSize;
1018 return GetData(data, to, TRUE);
1021 BOOL mcGetIsTypeOfSync(PVOID data) {
1026 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
1028 if (MC_EMSGT_VALID((int)sysHdr->eType)) {
1029 if (MC_EMSGT_IS_SYNC(sysHdr->eType)) {
1037 EFrameworkunifiedStatus McClearData(PVOID data) {
1038 // check if buffers are null
1040 return eFrameworkunifiedStatusInvldBuf;
1043 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
1045 if (MC_EMSGT_VALID((int)sysHdr->eType)) {
1046 if (MC_EMSGT_IS_SHM(sysHdr->eType)) {
1047 return DiscardDataFromShared(sysHdr->memId);
1049 return eFrameworkunifiedStatusOK;
1053 return eFrameworkunifiedStatusInvldParam;
1056 EFrameworkunifiedStatus McClose(HANDLE hMessage) {
1057 EFrameworkunifiedStatus rtnStatus = eFrameworkunifiedStatusInvldHandle;
1059 if (NULL != hMessage) {
1060 EQType qType = GetQueueType(hMessage);
1062 if (eQTypeSender == qType) {
1063 rtnStatus = CloseSender(hMessage);
1064 } else if (eQTypeReveiver == qType) {
1065 rtnStatus = CloseReceiver(hMessage);
1073 void McFlushReceiver(HANDLE hMessage) {
1074 if (hMessage != INVALID_HANDLE) {
1075 // proxy to the real function in msg queue
1080 TMemID McGetDataUSID(PVOID pData) {
1081 // check if buffer is null
1082 if (pData == NULL) {
1086 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)pData;
1088 if (MC_EMSGT_VALID((int)sysHdr->eType)) {
1089 if (MC_EMSGT_IS_SHM(sysHdr->eType)) {
1090 return sysHdr->memId;
1099 ////////////////////////////////////////////////////////////////////////////////////////////
1101 ////////////////////////////////////////////////////////////////////////////////////////////
1102 EFrameworkunifiedStatus GetData(PVOID data, PVOID to, BOOL retain) {
1103 EFrameworkunifiedStatus rtnStatus = eFrameworkunifiedStatusInvldHandle;
1105 // check if buffers are null
1106 if (data == NULL || to == NULL) {
1107 return eFrameworkunifiedStatusInvldBuf;
1110 PSSystemMsgHeader sysHdr = (PSSystemMsgHeader)data;
1111 int offset = sizeof(SSystemMsgHeader);
1113 if (MC_EMSGT_VALID((int)sysHdr->eType)) {
1114 if (MC_EMSGT_HAS_SYSINFO(sysHdr->eType)) {
1115 offset += (int)sizeof(TSysMsgSystemInfo);
1118 if (MC_EMSGT_IS_SHM(sysHdr->eType)) {
1119 // need to get the message from shared memory
1121 // get the length based on the memId
1122 UI_32 shmLength = GetLengthOfDataFromShared(sysHdr->memId);
1125 * When a eFrameworkunifiedStatusInvldID error occurs in GetDataFromShared, the abnormal values are also returned in eFrameworkunifiedStatusErrOther.
1127 if (0 != shmLength && eFrameworkunifiedStatusOK == GetDataFromShared(sysHdr->memId, to, shmLength)) {
1129 // now that the data has been retrieved we may now discard it.
1132 rtnStatus = eFrameworkunifiedStatusOK;
1134 rtnStatus = eFrameworkunifiedStatusErrOther;
1137 // memcpy the data to the buffer provided.
1138 memcpy(to, (PVOID)((long)data + offset), sysHdr->info.length);
1139 rtnStatus = eFrameworkunifiedStatusOK;
1142 rtnStatus = eFrameworkunifiedStatusInvldHndlType;
1148 PCSTR McGetQueueName(HANDLE hMessage) {
1151 if (NULL != hMessage) {
1152 name = GetQueueName(hMessage);
1158 int McGetQueueFD(HANDLE hMessage) {
1161 if (NULL != hMessage) {
1162 fd = GetQueueFD(hMessage);
1168 EFrameworkunifiedStatus McTranslateError(int error) {
1169 return TranslateError(error);
1172 EFrameworkunifiedStatus McZcSetParam(HANDLE handle, UI_32 cmd, UI_32 length) {
1173 if (handle == NULL) {
1174 return eFrameworkunifiedStatusInvldHandle;
1177 SQhandle *sndHndl = (SQhandle *)handle;
1178 SSystemMsgHeader *msgHdr = (SSystemMsgHeader *)(sndHndl->sendbuf);
1180 // QueueType checking
1181 EQType qType = GetQueueType(handle);
1182 if (eQTypeSender != qType) {
1183 return eFrameworkunifiedStatusInvldHndlType;
1186 if (mqCheckValidHandle(handle) == FALSE) {
1187 return eFrameworkunifiedStatusInvldHandle;
1189 if (sndHndl->sendbuf == NULL) {
1190 return eFrameworkunifiedStatusInvldBuf;
1192 if (length > (MAX_QUEUE_MSG_SIZE - sizeof(SSystemMsgHeader))) {
1193 return eFrameworkunifiedStatusInvldBufSize;
1196 msgHdr->info.command = cmd;
1197 msgHdr->info.length = length;
1198 return eFrameworkunifiedStatusOK;
1201 PVOID McZcGetBuf(HANDLE handle) {
1202 if (handle == NULL) {
1206 SQhandle *sndHndl = (SQhandle *)handle;
1208 // QueueType checking
1209 EQType qType = GetQueueType(handle);
1210 if (eQTypeSender != qType) {
1214 if (mqCheckValidHandle(handle) == FALSE) {
1217 if (sndHndl->sendbuf == NULL) {
1220 return (char *)(sndHndl->sendbuf) + sizeof(SSystemMsgHeader);
1223 EFrameworkunifiedStatus McZcSend(HANDLE hMessage) {
1224 if (hMessage == NULL) {
1225 return eFrameworkunifiedStatusInvldHandle;
1228 // QueueType checking
1229 EQType qType = GetQueueType(hMessage);
1230 if (eQTypeSender != qType) {
1231 return eFrameworkunifiedStatusInvldHndlType;
1234 SQhandle *sndHndl = (SQhandle *)hMessage;
1236 SSystemMsgHeader *msgHdr = (SSystemMsgHeader *)(sndHndl->sendbuf);
1238 if (mqCheckValidHandle(hMessage) == FALSE) {
1239 return eFrameworkunifiedStatusInvldHandle;
1241 if (sndHndl->sendbuf == NULL) {
1242 return eFrameworkunifiedStatusInvldBuf;
1245 return SendMessageWithPriority(hMessage, (UI_32)(msgHdr->info.length + sizeof(SSystemMsgHeader)), sndHndl->sendbuf,
1246 eFrameworkunifiedMsgPrioNormal);
1249 HANDLE McZcOpenSender(PCSTR source) {
1250 HANDLE handle = openSenderZc(source);
1252 if (handle != NULL) {
1253 SQhandle *sndHndl = (SQhandle *)handle;
1254 SSystemMsgHeader *msgHdr = (SSystemMsgHeader *)(sndHndl->sendbuf);
1256 strlcpy(msgHdr->info.source, source, sizeof(msgHdr->info.source));
1257 msgHdr->info.command = 0;
1258 msgHdr->info.length = 0;
1259 msgHdr->info.sessionid = 0;
1260 msgHdr->eType = (UI_32)MC_EMSGT_VALID_TOKEN;
1267 EFrameworkunifiedStatus McZcClose(HANDLE handle) {
1268 return CloseSender(handle);