b177b9b8c7f404bdb7e2ca32c9f67efca0c34371
[staging/basesystem.git] / service / system / task_manager / server / src / tskm_comm.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 #ifndef _GNU_SOURCE
18 #warning "_GNU_SOURCE not defined, so define here"
19 #define _GNU_SOURCE
20 #endif
21 #include "tskm_comm.h"
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <errno.h>
28
29 #include <native_service/cl_monitor.h>
30
31 #include "tskm_debug.h"
32 #include "tskm_util.h"
33
34
35 /**********************************************************
36  * Internal functions
37  **********************************************************/
38 TSKM_STATIC TSKM_SRV_CONNENT_t*
39 addConnFd(TSKM_SRV_CONNENT_LIST_t* list, TSKM_SRV_CONNENT_t* conn) {
40   TSKM_SRV_CONNENT_t* retConn;
41   if (list->num >= TSKM_COMM_CONNECT_MAX) {
42     TSKM_ASSERT(0)
43     return NULL;
44   }
45
46   retConn = &list->conn[list->num];
47   list->conn[list->num] = *conn;
48   list->num++;
49   return retConn;
50 }
51
52 TSKM_STATIC void delConnFd(TSKM_SRV_CONNENT_LIST_t* list,
53                            TSKM_SRV_CONNENT_t* conn) {
54   uint32_t ii;
55   TSKM_BOOL_t isFind = TSKM_FALSE;
56   for (ii = 0; ii < list->num; ii++) {
57     if (!isFind && list->conn[ii].connFd == conn->connFd) {
58       isFind = TSKM_TRUE;
59       list->num--;
60     }
61
62     if (isFind && (ii < list->num)) {
63       list->conn[ii] = list->conn[ii + 1];
64     }
65   }
66   TSKM_ASSERT(isFind);
67 }
68
69 /**********************************************************
70  * Public functions
71  **********************************************************/
72 TSKM_ERR_t tskm_srvSockCreate(const char *sockName,
73                               TSKM_SRV_SOCK_CTX_t* p_sock) {
74   int fd = -1;
75   int ret;
76   int sockRet;
77   int enable = 1;
78   int listenNum = TSKM_COMM_CONNECT_MAX;
79
80   struct sockaddr_un unix_addr = { };
81
82   fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
83   if (fd < 0) {  // LCOV_EXCL_BR_LINE 5: For processing initializing process
84     // LCOV_EXCL_START 5: For processing initializing process
85     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
86     TSKM_ASSERT_ERRNO(0);
87     goto ERROR;
88     // LCOV_EXCL_STOP
89   }
90
91   if (0 == access(sockName, F_OK)) {  // LCOV_EXCL_BR_LINE 5: For processing initializing process
92     TSKM_ASSERT(0);
93     unlink(sockName);
94   }
95
96   unix_addr.sun_family = AF_UNIX;
97   strncpy(unix_addr.sun_path, sockName, sizeof(unix_addr.sun_path) - 1);
98
99   sockRet = bind(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr));
100   if (sockRet != 0) {  // LCOV_EXCL_BR_LINE 5: For processing initializing process
101     // LCOV_EXCL_START 5: For processing initializing process
102     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
103     TSKM_ASSERT_ERRNO(0);
104     goto ERROR;
105     // LCOV_EXCL_STOP
106   }
107
108   ret = chmod(sockName, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
109   if (ret != 0) {  // LCOV_EXCL_BR_LINE 5: For processing initializing process
110     // LCOV_EXCL_START 5: For processing initializing process
111     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
112     TSKM_ASSERT_ERRNO(0);
113     goto ERROR;
114     // LCOV_EXCL_STOP
115   }
116
117   sockRet = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
118   if (sockRet != 0) {  // LCOV_EXCL_BR_LINE 5:For processing initializing process
119     // LCOV_EXCL_START 5: For processing initializing process
120     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
121     TSKM_ASSERT_ERRNO(0);
122     goto ERROR;
123     // LCOV_EXCL_STOP
124   }
125
126   sockRet = listen(fd, listenNum);
127   if (sockRet != 0) {  // LCOV_EXCL_BR_LINE 5: For process initialization processing
128     // LCOV_EXCL_START 5: For process initialization processing
129     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
130     TSKM_ASSERT_ERRNO(0);
131     goto ERROR;
132     // LCOV_EXCL_STOP
133   }
134
135   memset(p_sock, 0, sizeof(*p_sock));
136   p_sock->sockFd = fd;
137   p_sock->sockName = sockName;
138
139   return TSKM_E_OK;
140   // LCOV_EXCL_START 5: For process initialization processing
141   ERROR:
142   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
143   if (fd != -1) {
144     close(fd);
145   }
146   return TSKM_E_NG;
147   // LCOV_EXCL_STOP
148 }
149
150 TSKM_SRV_CONNENT_t*
151 tskm_srvSockConnect(TSKM_SRV_SOCK_CTX_t* p_sock) {
152   int fd = -1;
153   socklen_t len;
154   int sockRet;
155   TSKM_SRV_CONNENT_t conn;
156   TSKM_SRV_CONNENT_t *retConn;
157   struct ucred credent;
158   struct sockaddr_un unix_addr;
159
160   memset(&conn, 0, sizeof(conn));
161   conn.connFd = -1;
162
163   len = sizeof(unix_addr);
164   fd = accept(p_sock->sockFd, (struct sockaddr*) &unix_addr,
165               (socklen_t *) &len);  // NOLINT (readability/casting)
166   if (fd < 0) {  // LCOV_EXCL_BR_LINE 5: Accept's Error-Handling Process
167     // LCOV_EXCL_START 5: Accept's Error-Handling Process
168     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
169     TSKM_ASSERT_ERRNO(0);
170     goto ERROR;
171     // LCOV_EXCL_STOP
172   }
173   conn.connFd = fd;
174
175   len = sizeof(credent);
176   sockRet = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credent, &len);
177   if (sockRet != 0) {  // LCOV_EXCL_BR_LINE 5: Getsockopt's Error-Handling Process
178     // LCOV_EXCL_START 5: Getsockopt's Error-Handling Process
179     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
180     TSKM_ASSERT_ERRNO(0);
181     goto ERROR;
182     // LCOV_EXCL_STOP
183   }
184   conn.pid = credent.pid;
185
186   retConn = addConnFd(&p_sock->connList, &conn);
187   if (retConn == NULL) {  // LCOV_EXCL_BR_LINE 5: Connect's Error-Handling Process
188     // LCOV_EXCL_START 5: Connect's Error-Handling Process
189     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
190     TSKM_ASSERT(0);
191     goto ERROR;
192     // LCOV_EXCL_STOP
193   }
194   return retConn;
195   // LCOV_EXCL_START 5: Error-Handling Process
196   ERROR:
197   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
198   if (conn.connFd != -1) {
199     tskm_sockDestory(conn.connFd);
200   }
201   return NULL;
202   // LCOV_EXCL_STOP
203 }
204
205 void tskm_srvSockDisconnect(TSKM_SRV_SOCK_CTX_t* p_sock,
206                             TSKM_SRV_CONNENT_t *p_conn) {
207   int fd = p_conn->connFd;
208   delConnFd(&p_sock->connList, p_conn);
209   tskm_sockDestory(fd);
210 }
211
212 void tskm_srvSockDestory(TSKM_SRV_SOCK_CTX_t* p_sock) {  // LCOV_EXCL_START 6: Because the condition cannot be set
213   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
214   if (p_sock->sockFd) {
215     tskm_sockDestory(p_sock->sockFd);
216     p_sock->sockFd = 0;
217
218     TSKM_ASSERT_ERRNO(0 == unlink(p_sock->sockName));
219   }
220 }
221 // LCOV_EXCL_STOP
222 int tskm_cliSockConnect(const char* sockName) {
223   int fd = -1;
224   int sockRet;
225   struct sockaddr_un unix_addr = { };
226
227   /* Create socket */
228   fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
229   if (fd < 0) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
230     // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
231     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
232     TSKM_ASSERT_ERRNO(0);
233     goto ERROR;
234     // LCOV_EXCL_STOP
235   }
236
237   unix_addr.sun_family = AF_UNIX;
238   strncpy(unix_addr.sun_path, sockName, sizeof(unix_addr.sun_path) - 1);
239   sockRet = connect(fd, (struct sockaddr*) &unix_addr, sizeof(unix_addr));
240   if (sockRet < 0) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
241     // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
242     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
243     TSKM_ASSERT_ERRNO(0);
244     goto ERROR;
245     // LCOV_EXCL_STOP
246   }
247   return fd;
248   // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
249   ERROR:
250   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
251   if (fd != -1) {
252     TSKM_ASSERT_ERRNO(0 == close(fd));
253   }
254   return -1;
255   // LCOV_EXCL_STOP
256 }
257
258 int tskm_sockRcv(int fd, TSKM_EVENT_INFO_t* p_ev) {
259   int ret;
260   TSKM_EVENT_INFO_t ev;
261   ret = static_cast<int>(recv(fd, &ev, sizeof(ev), 0));
262
263   // LCOV_EXCL_BR_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
264   if (ret > (int) sizeof(ev)) {  // NOLINT (readability/casting)
265     // LCOV_EXCL_BR_STOP
266     // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
267     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
268     TSKM_ASSERT_ERRNO(0);
269     goto ERROR;
270     // LCOV_EXCL_STOP
271   }
272
273   if (ret < 0) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
274     // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
275     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
276     TSKM_ASSERT_ERRNO(0);
277     goto ERROR;
278     // LCOV_EXCL_STOP
279   }
280   if (ret > 0) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
281     TSKM_PRINTF(TSKM_LOG_MSG, "recv:%s from:%d ret:%d",
282                 tskm_convEvent2Str(ev.event), ev.fromPid, ret);
283   }
284
285   *p_ev = ev;
286
287   if (p_ev->hasExtend && (0 != p_ev->extendSize)) {
288     TSKM_PRINTF(TSKM_LOG_MSG, "rcv:ex(%d) ", p_ev->extendSize);
289
290     p_ev->extendPrm = malloc(p_ev->extendSize);
291     if (!p_ev->extendPrm) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
292       // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
293       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
294       TSKM_ASSERT(0);
295       goto ERROR;
296       // LCOV_EXCL_STOP
297     }
298
299     ret = static_cast<int>(recv(fd, p_ev->extendPrm, p_ev->extendSize, 0));
300
301     // LCOV_EXCL_BR_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
302     if (ret > (int) p_ev->extendSize) {  // NOLINT (readability/casting)
303       // LCOV_EXCL_BR_STOP
304       // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
305       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
306       TSKM_ASSERT_ERRNO(0);
307       goto ERROR;
308       // LCOV_EXCL_STOP
309     }
310
311     if (ret < 0) {  // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
312       // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
313       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
314       TSKM_ASSERT_ERRNO(0);
315       goto ERROR;
316       // LCOV_EXCL_STOP
317     }
318   }
319
320   return ret;
321
322   // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
323   ERROR:
324   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
325   return -1;
326   // LCOV_EXCL_STOP
327 }
328
329 int tskm_sockSend(int fd, TSKM_EVENT_INFO_t* p_ev) {
330   int ret;
331   p_ev->fromPid = getpid();
332   TSKM_PRINTF(TSKM_LOG_MSG, "send:%s ", tskm_convEvent2Str(p_ev->event));
333   ret = static_cast<int>(send(fd, p_ev, sizeof(*p_ev), MSG_NOSIGNAL));
334   if (ret != sizeof(*p_ev)) {
335     TSKM_ASSERT_ERRNO(0);
336     goto ERROR;
337   }
338   // Because it is entered only when called from a debugging function (pri_sendDebugDumpRes)
339   if (p_ev->hasExtend && p_ev->extendPrm && (0 != p_ev->extendSize)) {
340     TSKM_PRINTF(TSKM_LOG_MSG, "send:ex(%d) ", p_ev->extendSize);
341
342     ret = static_cast<int>(send(fd, p_ev->extendPrm, p_ev->extendSize, MSG_NOSIGNAL));
343     if (ret != (int)p_ev->extendSize) {  // NOLINT (readability/casting)
344       TSKM_ASSERT_ERRNO(0);
345       goto ERROR;
346     }
347   }
348
349   return ret;
350
351   ERROR: return -1;
352 }
353
354 void tskm_sockDestory(int fd) {
355   TSKM_ASSERT_ERRNO(0 == shutdown(fd, SHUT_RDWR));
356   TSKM_ASSERT_ERRNO(0 == close(fd));
357 }
358
359 /******************************************************************
360  *        Initializing (Process)
361  ******************************************************************/
362 int tskm_comm_procInit(void) {
363   int ret;
364
365   ret = CL_MonitorInit(CL_MONITOR_INIT_USER);
366
367   if (ret != 0) {
368     TSKM_ASSERT_ERRNO(0);
369     goto ERROR;
370   }
371
372   return 0;
373
374   // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
375   ERROR:
376   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
377   return -1;
378   // LCOV_EXCL_STOP
379 }
380
381 /*********************************************************
382  *        Service Error Monitoring Status Setting
383  *********************************************************/
384 int tskm_comm_setSvcWatchState(uint32_t id, BOOL bIsRun, uint32_t timeout) {
385   int ret = 0;
386
387   CL_MonitorState_t state = CL_MONITOR_STATE_SLEEP;
388
389   if (bIsRun) {
390     state = CL_MONITOR_STATE_RUN;
391   }
392
393   ret = CL_MonitorSetEntry(CL_MONITOR_TYPE_GENERIC, id, state, timeout, 0);
394   if (0 != ret) {
395     TSKM_ASSERT_ERRNO(0);
396     goto ERROR;
397   }
398
399   return 0;
400   ERROR: return -1;
401 }  // LCOV_EXCL_BR_LINE 10: Final line
402