Init basesystem source codes.
[staging/basesystem.git] / video_in_hal / systemservice / task_manager / client / libprimary / src / pri_main.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 #include "pri_main.h"
18 #include <sys/eventfd.h>
19 #include <native_service/frameworkunified_dispatcher.h>
20 #include <system_service/ss_system_if.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <pthread.h>
24 #include <stdlib.h>
25 #include "tskm_debug.h"
26 #include "tskm_comm.h"
27 #include "tskm_port_pf.h"
28 #include "tskm_port_subsys.h"
29 #include "tskm_util.h"
30
31
32 #define PRI_PROC_NAME_MAX 32
33
34 // Context
35 typedef struct {
36   T_PRIM_PRM prm;
37
38   TSKM_SVCID_t svcId;      // Set valid value by REQ_WAKEUP
39   char procName[PRI_PROC_NAME_MAX];
40   // State
41   TSKM_BOOL_t isExec;
42   T_SS_SM_START_DataStructType bootInfo;
43   T_SS_SM_START_ExtDataStructType extBootInfo; TSKM_BOOL_t isDynamic;
44   uint32_t wakeupStepDone;  // Performed Local Step
45   TSKM_BOOL_t shmDone;
46   uint32_t downStepDone;    // Performed Local Step
47   TSKM_BOOL_t isExitStart;
48
49 #define PRI_MONITOR_DEFAULT_TIMEOUT 50
50   uint32_t timeout;    // Service monitoring timeout period (valid only for the INI_Main type service)
51
52   // Resources
53   int connFd;       // TSKM communication sockets
54   int nsFd;         // NSFW sockets
55   int pipeFd[2];    // For exitDone
56   HANDLE hApp;      // appHandle
57 } PRI_CTX_t;
58
59 static PRI_CTX_t g_pri;
60
61 /*********************************************
62  *    Create Shared Memory
63  *********************************************/
64 TSKM_STATIC void shmMake(PRI_CTX_t* p_ctx) {
65   const PRIM_SHAREDATA_TBL* shmEntry;
66   for (shmEntry = p_ctx->prm.shmTbl; shmEntry->shmName[0] != '\0'; shmEntry++) {
67     int ret;
68     ret = tskm_pf_shmCreate(shmEntry->shmName, shmEntry->size, NULL);
69     if (ret != 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
70       // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
71       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
72       TSKM_ASSERT(0);
73       goto ERROR;
74       // LCOV_EXCL_STOP
75     }
76   }
77   p_ctx->shmDone = TSKM_TRUE;
78   return;
79
80   // LCOV_EXCL_START 6: Checked by Death testing, but it is not reflected in the coverage and excluded
81   ERROR:
82   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
83   tskm_pf_abort();
84   // LCOV_EXCL_STOP
85 }
86
87 /*********************************************
88  *    Call Backup Check CB
89  *********************************************/
90 TSKM_STATIC uint32_t wakeupExFuncCallback(PRI_CTX_t* p_ctx,
91                                           TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
92   const PRIM_EXFUNC_TBL* funcEntry;
93   uint32_t maxStep = 0;
94
95   for (funcEntry = p_ctx->prm.wakeupExFuncTbl; funcEntry->localStep != 0;
96       funcEntry++) {
97     if (funcEntry->localStep == p_prm->localStep) {
98       funcEntry->func(funcEntry->prm);
99     }
100     maxStep = TSKM_MAX(maxStep, funcEntry->localStep);
101   }
102   return maxStep;
103 }
104
105 /*********************************************
106  *    Gradual Start Request
107  *********************************************/
108 TSKM_STATIC void wakeupRequest(PRI_CTX_t* p_ctx,
109                                TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
110   TSKM_EV_PRI_REQ_WAKEUP_PRM_t prm = *p_prm;
111   uint32_t max = 0;
112
113   // Execute one step at a time
114   for (prm.localStep = p_ctx->wakeupStepDone + 1;
115       (prm.localStep <= p_prm->localStep && prm.localStep < PRIM_STEPFORK_MAX);
116       prm.localStep++) {
117     max = wakeupExFuncCallback(p_ctx, &prm);
118   }
119
120   if (max <= p_prm->localStep) {
121     // Gradual start completed
122     p_ctx->wakeupStepDone = PRIM_STEPFORK_MAX;
123   } else {
124     p_ctx->wakeupStepDone = p_prm->localStep;
125   }
126 }
127
128 /*********************************************
129  *    All startup requests
130  *********************************************/
131 TSKM_STATIC void allWakeup(PRI_CTX_t* p_ctx,
132                            TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
133   if (!p_ctx->shmDone) {
134     shmMake(p_ctx);
135   }
136
137   if (p_ctx->wakeupStepDone < PRIM_STEPFORK_MAX) {
138     wakeupRequest(p_ctx, p_prm);
139   }
140 }
141
142 /*********************************************
143  *   Startup request handle
144  *********************************************/
145 TSKM_STATIC void wakeupRequestHandle(PRI_CTX_t* p_ctx,
146                                      TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
147   TSKM_EVENT_INFO_t ev;
148   int ret;
149
150   bzero(&ev, sizeof(ev));
151
152   p_ctx->svcId = p_prm->svcId;
153   memcpy(&p_ctx->bootInfo, &p_prm->bootInfo, sizeof(p_ctx->bootInfo));
154   memcpy(&p_ctx->extBootInfo, &p_prm->extBootInfo, sizeof(p_ctx->extBootInfo));
155   p_ctx->isDynamic = p_prm->isDynamic;
156
157   if (p_prm->localStep == TSKM_LSTEP_ALL) {
158     allWakeup(p_ctx, p_prm);
159   } else if (p_prm->localStep == TSKM_LSTEP_LAST) {
160     wakeupRequest(p_ctx, p_prm);
161   } else if (p_prm->localStep == TSKM_LSTEP_SHM) {
162     shmMake(p_ctx);
163   } else {
164     wakeupRequest(p_ctx, p_prm);
165   }
166
167   ev.prm.resWakeup.isShmDone = p_ctx->shmDone;
168   ev.prm.resWakeup.isStepDone =
169       (p_ctx->wakeupStepDone >= PRIM_STEPFORK_MAX) ?
170       TSKM_TRUE : TSKM_FALSE;
171
172   // LCOV_EXCL_BR_START 6: Because it depends on the test order
173   if (ev.prm.resWakeup.isShmDone && ev.prm.resWakeup.isStepDone) {
174     // LCOV_EXCL_BR_STOP
175     ev.prm.resWakeup.isLast = TSKM_TRUE;
176   }
177
178   ev.event = TSKM_EV_PRI_RES_WAKEUP;
179   ev.errCode = TSKM_E_OK;
180   ret = tskm_sockSend(p_ctx->connFd, &ev);
181   if (ret <= 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
182     // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
183     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
184     TSKM_ASSERT(0);
185     tskm_pf_abort();
186     // LCOV_EXCL_STOP
187   }
188 }
189
190 /*********************************************
191  *    Gradual Termination CALLBACK
192  *********************************************/
193 TSKM_STATIC uint32_t downExFuncCallback(PRI_CTX_t* p_ctx,
194                                         TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
195   const PRIM_EXFUNC_TBL* funcEntry;
196   uint32_t maxStep = 0;
197
198   for (funcEntry = p_ctx->prm.downExFuncTbl; funcEntry->localStep != 0;
199       funcEntry++) {
200     if (funcEntry->localStep == p_prm->localStep) {
201       funcEntry->func(funcEntry->prm);
202     }
203     maxStep = TSKM_MAX(maxStep, funcEntry->localStep);
204   }
205   return maxStep;
206 }
207
208 /*********************************************
209  *    Gradual Termination Request
210  *********************************************/
211 TSKM_STATIC void downRequest(PRI_CTX_t* p_ctx,
212                              TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
213   TSKM_EV_PRI_REQ_DOWN_PRM_t prm = *p_prm;
214   uint32_t max = 0;
215
216   // Execute one step at a time
217   for (prm.localStep = p_ctx->downStepDone + 1;
218       (prm.localStep <= p_prm->localStep && prm.localStep < PRIM_ACCOFF_MAX);
219       prm.localStep++) {
220     max = downExFuncCallback(p_ctx, &prm);
221   }
222
223   if (max <= p_prm->localStep) {
224     p_ctx->downStepDone = PRIM_ACCOFF_MAX;  // Completed all steps
225   } else {
226     p_ctx->downStepDone = p_prm->localStep;
227   }
228 }
229
230 TSKM_STATIC void downRequestHandle(PRI_CTX_t* p_ctx,
231                                    TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
232   TSKM_EVENT_INFO_t ev;
233   int ret;
234
235   bzero(&ev, sizeof(ev));
236
237   if (p_prm->localStep == TSKM_LSTEP_ALL || p_prm->localStep == TSKM_LSTEP_LAST) {
238     downRequest(p_ctx, p_prm);
239   } else if (p_prm->localStep == TSKM_LSTEP_SHM) {
240     TSKM_ASSERT(0);
241   } else if (p_prm->localStep == TSKM_LSTEP_BUPCHK) {
242     TSKM_ASSERT(0);
243   } else {
244     downRequest(p_ctx, p_prm);
245   }
246
247   if (p_ctx->downStepDone >= PRIM_ACCOFF_MAX) {
248     /* It is not notified when the last function is executed, and it is left to the exitDone.
249      TSKM_PRINTF(TSKM_LOG_DEBUG,"ACCOFF DONE");
250      ev.prm.resDown.isLast = TSKM_TRUE;
251      p_ctx->isExec = TSKM_FALSE;
252      ret =  tskm_sockSend(p_ctx->connFd,&ev);
253      if(ret <= 0){
254      TSKM_ASSERT(0);
255      tskm_pf_abort();
256      }
257      */
258   } else {
259     ev.event = TSKM_EV_PRI_RES_DOWN;
260     ev.errCode = TSKM_E_OK;
261     ret = tskm_sockSend(p_ctx->connFd, &ev);
262     if (ret <= 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
263       // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
264       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
265       TSKM_ASSERT(0);
266       tskm_pf_abort();
267       // LCOV_EXCL_STOP
268     }
269   }
270 }
271
272 /*********************************************
273  *  Termination completion is notified to the TSKM
274  *********************************************/
275 TSKM_STATIC void sendLastDoneRes(PRI_CTX_t* p_ctx) {
276   int ret;
277   TSKM_EVENT_INFO_t ev;
278
279   bzero(&ev, sizeof(ev));
280
281   ev.event = TSKM_EV_PRI_RES_DOWN;
282   ev.errCode = TSKM_E_OK;
283   ev.prm.resDown.isLast = TSKM_TRUE;
284   ret = tskm_sockSend(p_ctx->connFd, &ev);
285   if (ret <= 0) {  // LCOV_EXCL_BR_LINE 5: Termination completion is notified to the TSKM.
286     // LCOV_EXCL_START 5: Termination completion is notified to the TSKM.
287     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
288     TSKM_ASSERT(0);
289     tskm_pf_abort();
290     // LCOV_EXCL_STOP
291   }
292 }
293
294 /*********************************************
295  *  Invocation of Touch CB
296  *********************************************/
297 TSKM_STATIC void touchService(PRI_CTX_t* p_ctx) {
298   char touchName[32];
299
300   if (p_ctx->isExitStart) {
301     // If termination processing has already begun, the system does not respond Touch but TIMEOUT the processing for retrying.
302     return;
303   }
304
305   p_ctx->prm.onTouch(p_ctx->hApp);
306
307   tskm_pf_mkTouchFileName(getpid(), touchName);
308
309   if ((access(touchName, F_OK) == 0)) {
310     // Synchronize by deleting files.
311     TSKM_PRINTF(TSKM_LOG_STATE, "del:%s", touchName);
312     unlink(touchName);
313   } else {
314     TSKM_ASSERT_PRINT(0, "%s", touchName);
315   }
316 }
317
318 /*********************************************
319  *  Invocation of Debugdump CB
320  *********************************************/
321 TSKM_STATIC void callDebugDump(PRI_CTX_t* p_ctx) {
322   if (!p_ctx->prm.onDebugDump) {  // LCOV_EXCL_BR_LINE 6: As NULL checked by INI_Init
323     // LCOV_EXCL_START 6: As NULL checked by INI_Init
324     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
325     TSKM_ASSERT(0);
326     // LCOV_EXCL_STOP
327   } else {
328     p_ctx->prm.onDebugDump(p_ctx->hApp);
329   }
330 }
331
332 /*********************************************
333  *  Invocation of LowMemory detection CB
334  *********************************************/
335 TSKM_STATIC void callLowMem(PRI_CTX_t* p_ctx) {
336   if (!p_ctx->prm.onLowMem) {
337     TSKM_ASSERT(0);
338   } else if (!p_ctx->isExitStart) {
339     // Notify LowMemory only when the process is finished
340     p_ctx->prm.onLowMem(p_ctx->hApp);
341   }
342 }
343
344 /*********************************************
345  *   Event Handle
346  *********************************************/
347 TSKM_STATIC void eventHandle(PRI_CTX_t* p_ctx, TSKM_EVENT_INFO_t* p_ev) {
348   // Processing according to the request
349   switch (p_ev->event) {
350     case TSKM_EV_PRI_REQ_WAKEUP:
351       wakeupRequestHandle(p_ctx, &p_ev->prm.reqWakeup);
352       break;
353     case TSKM_EV_PRI_REQ_DOWN:
354       downRequestHandle(p_ctx, &p_ev->prm.reqDown);
355       break;
356     case TSKM_EV_PRI_REQ_TOUCH:
357       touchService(p_ctx);
358       break;
359     case TSKM_EV_PRI_REQ_DEBUGDUMP:
360       callDebugDump(p_ctx);
361       break;
362     case TSKM_EV_PRI_REP_LOWMEM:
363       callLowMem(p_ctx);
364       break;
365     default:
366       TSKM_ASSERT(0);
367       break;
368   }
369 }
370
371 /*********************************************
372  *   Initialize Context
373  *********************************************/
374 TSKM_STATIC void initCtx(T_PRIM_PRM* p_prm, PRI_CTX_t* p_ctx, int argc,
375                          char* argv[]) {
376   FrameworkunifiedDefaultCallbackHandler cbFuncs;
377
378   p_ctx->prm = *p_prm;
379
380   cbFuncs.onInitilization = p_ctx->prm.onInit;
381   cbFuncs.onDestroy = p_ctx->prm.onDestory;
382   cbFuncs.onDebugDump = p_ctx->prm.onDebugDump;
383   cbFuncs.onStart = FrameworkunifiedOnStart;
384   cbFuncs.onStop = FrameworkunifiedOnStop;
385   cbFuncs.onPreStart = FrameworkunifiedOnPreStart;
386   cbFuncs.onPreStop = FrameworkunifiedOnPreStop;
387   cbFuncs.onBackgroundStart = FrameworkunifiedOnBackgroundStart;
388   cbFuncs.onBackgroundStop = FrameworkunifiedOnBackgroundStop;
389   cbFuncs.createStateMachine = FrameworkunifiedCreateStateMachine;
390   cbFuncs.ssFrameworkInterface = FrameworkunifiedSSFrameworkInterface;
391
392   EFrameworkunifiedStatus taskmanagerRet;
393   taskmanagerRet = FrameworkunifiedCreateDispatcherWithoutLoop(p_ctx->prm.name, p_ctx->hApp, argc,
394                                           argv, &cbFuncs, FALSE);
395   if (eFrameworkunifiedStatusOK != taskmanagerRet) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
396     // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
397     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
398     TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
399     goto ERROR;
400     // LCOV_EXCL_STOP
401   }
402
403   taskmanagerRet = FrameworkunifiedGetDispatcherFD(p_ctx->hApp, &p_ctx->nsFd);
404   if (taskmanagerRet != eFrameworkunifiedStatusOK) {
405     TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
406     exit(EXIT_FAILURE);
407   }
408
409   p_ctx->connFd = tskm_cliSockConnect(TSKM_SOCKET_NAME);
410   if (p_ctx->connFd < 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
411     // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
412     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
413     TSKM_ASSERT(0);
414     goto ERROR;
415     // LCOV_EXCL_STOP
416   }
417   if (pipe(p_ctx->pipeFd) != 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
418     // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
419     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
420     TSKM_ASSERT_ERRNO(0);
421     goto ERROR;
422     // LCOV_EXCL_STOP
423   }
424
425   return;
426   // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
427   ERROR:
428   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
429   tskm_pf_abort();
430   // LCOV_EXCL_STOP
431 }
432
433 /*********************************************
434  *  Destroy Context
435  *********************************************/
436 TSKM_STATIC void termCtx(PRI_CTX_t* p_ctx) {
437   if (p_ctx->shmDone) {  // LCOV_EXCL_BR_LINE 6: Since it has been set to True by INI_Handler and cannot be changed
438     const PRIM_SHAREDATA_TBL* shmEntry = p_ctx->prm.shmTbl;
439     for (shmEntry = p_ctx->prm.shmTbl; shmEntry->shmName[0] != '\0';
440         shmEntry++) {
441       TSKM_ASSERT(0 == tskm_pf_shmDelete(shmEntry->shmName));  // LCOV_EXCL_BR_LINE 8: For processing in which only return value 0 is set
442     }
443   }
444
445   if (p_ctx->connFd > 0) {  // LCOV_EXCL_BR_LINE 6: As it is already set by INI_Init and cannot be changed
446     tskm_sockDestory(p_ctx->connFd);
447   }
448
449   EFrameworkunifiedStatus taskmanagerRet;
450   taskmanagerRet = FrameworkunifiedDestroyDispatcherWithoutLoop(p_ctx->hApp);
451   TSKM_ASSERT(taskmanagerRet == eFrameworkunifiedStatusOK);
452
453   if (p_ctx->isDynamic) {
454     TSKM_PRINTF(TSKM_LOG_STATE, "EXIT %s", p_ctx->procName);
455   } else {
456     // Hung up running services to prevent adversely affecting to system termination processing during process termination processing
457     sleep(TSKM_CFG_WAIT_SHUTDOWN);
458   }
459 }
460
461 /*******************************************************************
462  *    PRI Context Initialization
463  *******************************************************************/
464 void pri_init(T_PRIM_PRM* p_prm, int argc, char* argv[], int *fdNum,
465               int fdlist[INI_FD_MAX]) {
466   int ret = 0;
467   PRI_CTX_t* p_ctx = &g_pri;
468
469   strncpy(p_ctx->procName, basename(argv[0]), sizeof(p_ctx->procName) - 1);
470
471   ret = tskm_pf_procInit();
472   if (ret != 0) {  // LCOV_EXCL_BR_LINE 6: Return value of 0 only
473     // LCOV_EXCL_START 6: Return value of 0 only
474     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
475     TSKM_ASSERT(0);
476     goto ERROR;
477     // LCOV_EXCL_STOP
478   }
479
480   ret = tskm_comm_procInit();
481   if (ret != 0) {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
482     // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
483     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
484     TSKM_ASSERT(0);
485     goto ERROR;
486     // LCOV_EXCL_STOP
487   }
488
489   initCtx(p_prm, p_ctx, argc, argv);
490
491   *fdNum = 3;
492   fdlist[0] = p_ctx->connFd;
493   fdlist[1] = p_ctx->pipeFd[0];
494   fdlist[2] = p_ctx->nsFd;
495
496   p_ctx->svcId = TSKM_SVCID_NONE;
497   p_ctx->isExec = TSKM_TRUE;
498
499   p_ctx->bootInfo.startupReason = epswfINVALID;
500   p_ctx->bootInfo.isUserModeOn = FALSE;
501   p_ctx->bootInfo.dataResetMode = e_SS_SM_DATA_RESET_MODE_NONE;
502   p_ctx->bootInfo.securityStatus = epsssINVALID;
503   p_ctx->bootInfo.wakeupType = epsstINVALID;
504   p_ctx->bootInfo.dramBackupStatus = e_SS_SM_DRAM_BACKUP_UNSET;
505   p_ctx->bootInfo.resetStatus = e_SS_SM_RESET_STATUS_UNSET;
506
507   memset(&p_ctx->extBootInfo, 0, sizeof(p_ctx->extBootInfo));
508
509   p_ctx->timeout = PRI_MONITOR_DEFAULT_TIMEOUT;
510
511   return;
512   // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
513   ERROR:
514    AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
515    tskm_pf_abort();  // ABORT
516    // LCOV_EXCL_STOP
517 }
518
519 /*******************************************************************
520  *    Primary Library Handler
521  *******************************************************************/
522 BOOL pri_handler(fd_set* p_fds) {
523   PRI_CTX_t* p_ctx = &g_pri;
524
525   if (FD_ISSET(p_ctx->connFd, p_fds)) {
526     int ret;
527     TSKM_EVENT_INFO_t ev;
528     ret = tskm_sockRcv(p_ctx->connFd, &ev);
529     // LCOV_EXCL_BR_START 5: Condition is true. False condition is checked in Death tests, but not reflected in coverage and excluded
530     if (ret > 0) {
531     // LCOV_EXCL_BR_STOP
532       eventHandle(p_ctx, &ev);
533     } else {  // LCOV_EXCL_BR_LINE 5: Checked by Death testing, but it is not reflected in the coverage and excluded
534       // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
535       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
536       TSKM_ASSERT(0);
537       goto ERROR;
538       // LCOV_EXCL_STOP
539     }
540   }
541
542   if (FD_ISSET(p_ctx->pipeFd[0], p_fds)) {
543     // only use exitDone
544     uint32_t tmp;
545     TSKM_ASSERT(sizeof(tmp) == read(p_ctx->pipeFd[0], &tmp, sizeof(tmp)));
546     TSKM_ASSERT(p_ctx->downStepDone == PRIM_ACCOFF_MAX);  // Check if all exit functions are complete
547     if (p_ctx->isDynamic) {
548       // A nonresident service completes its termination processing by terminating the process.
549       // (because the SIGNAL will overtake the sockets)
550     } else {
551       // The resident service is a termination notice and completes termination processing.
552       // (Do not terminate processes to reduce the impact on system termination)
553       sendLastDoneRes(p_ctx);
554     }
555     p_ctx->isExec = TSKM_FALSE;
556   }
557
558   if (FD_ISSET(p_ctx->nsFd, p_fds)) {
559     FrameworkunifiedDispatchProcessWithoutLoop(p_ctx->hApp);
560   }
561   return p_ctx->isExec;
562
563   // LCOV_EXCL_START 5: Checked by Death testing, but it is not reflected in the coverage and excluded
564   ERROR:
565   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
566   tskm_pf_abort();  // ABORT
567   return 0;
568   // LCOV_EXCL_STOP
569 }
570
571 /*******************************************************************
572  *    Process termination
573  *******************************************************************/
574 void pri_term(void) {
575   PRI_CTX_t* p_ctx = &g_pri;
576   termCtx(p_ctx);
577 }
578
579 /*******************************************************************
580  *    Service Monitoring Status Setting
581  *******************************************************************/
582 int pri_setMonitorState(BOOL bIsRun, uint32_t timeout) {
583   PRI_CTX_t* p_ctx = &g_pri;
584   int ret = INI_SUCCESS;
585
586   if (TSKM_SVCID_NONE == p_ctx->svcId) {
587     // Ignore requests until svcId is acquired.
588   } else if ((TRUE == bIsRun) && (0 == timeout)) {
589     // When RUN is specified with timeout = 0, monitoring is disabled.
590   } else {
591     ret = tskm_comm_setSvcWatchState(p_ctx->svcId, bIsRun, timeout);
592     if (INI_SUCCESS != ret) {
593       TSKM_ASSERT(0);
594     }
595   }
596
597   return ret;
598 }
599
600 /*******************************************************************
601  *    MAIN Function
602  *******************************************************************/
603 int pri_main(T_PRIM_PRM* p_prm, int argc, char* argv[]) {
604   int mainRet = -1;
605   int fdlist[INI_FD_MAX];
606   int fdNum;
607   int ii;
608   BOOL isExec = TRUE;
609
610   pri_init(p_prm, argc, argv, &fdNum, fdlist);
611
612   while (isExec) {
613     PRI_CTX_t* p_ctx = &g_pri;
614     int maxFd = 0;
615     fd_set fds;
616     int ret;
617
618     FD_ZERO(&fds);
619
620     for (ii = 0; ii < fdNum; ii++) {
621       FD_SET(fdlist[ii], &fds);
622       maxFd = TSKM_MAX(fdlist[ii], maxFd);
623     }
624
625     TSKM_ASSERT(INI_SUCCESS == pri_setMonitorState(FALSE, 0));
626     ret = select(maxFd + 1, &fds, NULL, NULL, NULL);
627     TSKM_ASSERT(INI_SUCCESS == pri_setMonitorState(TRUE, p_ctx->timeout));
628     if (ret < 1) {
629       // LCOV_EXCL_START 5: Select's Error-Handling Process
630       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
631       if (errno != EINTR) {
632         TSKM_ASSERT(0);
633       }
634       continue;
635       // LCOV_EXCL_STOP
636     }
637
638     isExec = pri_handler(&fds);
639   }
640
641   mainRet = 0;
642
643   pri_term();
644   return mainRet;
645 }
646
647 /*******************************************************************
648  *    Termination Request
649  *******************************************************************/
650 void pri_exitStart(void *rsv) {
651   int ret;
652   PRI_CTX_t* p_ctx = &g_pri;
653   TSKM_EVENT_INFO_t ev;
654
655   bzero(&ev, sizeof(ev));
656   p_ctx->isExitStart = TRUE;
657   ev.event = TSKM_EV_PRI_REQ_EXIT;
658   ev.errCode = TSKM_E_OK;
659
660   ret = tskm_sockSend(p_ctx->connFd, &ev);
661   if (ret <= 0) {  // LCOV_EXCL_BR_LINE 5: The caller's external API does not execute the second or subsequent processing and cannot be checked.
662     // LCOV_EXCL_START 5: The caller's external API does not execute the second or subsequent processing and cannot be checked.
663     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
664     TSKM_ASSERT(0);
665     goto ERROR;
666     // LCOV_EXCL_STOP
667   }
668
669   return;
670   // LCOV_EXCL_START 6: The caller's external API does not execute the second or subsequent processing and cannot be checked.
671   ERROR:
672   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
673   tskm_pf_abort();
674   // LCOV_EXCL_STOP
675 }
676
677 void pri_exitDone(int status) {
678   PRI_CTX_t* p_ctx = &g_pri;
679   uint32_t l_status = (uint32_t) status;
680
681   if (p_ctx->pipeFd[1] > 0) {  // LCOV_EXCL_BR_LINE 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
682     // LCOV_EXCL_BR_START 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
683     TSKM_ASSERT_ERRNO(
684         write(p_ctx->pipeFd[1], &l_status, sizeof(l_status))
685             == sizeof(l_status));
686     // LCOV_EXCL_BR_STOP
687   } else {
688     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
689     TSKM_ASSERT(0);  // LCOV_EXCL_LINE 6: The caller's external API does not execute the second or subsequent processing and cannot be checked.
690   }
691 }
692
693 /*******************************************************************
694  *    Event completion notification at startup
695  *******************************************************************/
696 int32_t pri_stepForkComp(uint64_t id) {
697   int ret;
698   PRI_CTX_t* p_ctx = &g_pri;
699   TSKM_EVENT_INFO_t ev;
700
701   bzero(&ev, sizeof(ev));
702   ev.event = TSKM_EV_PRI_REP_WAKEUP_COMP;
703   ev.errCode = TSKM_E_OK;
704   ev.prm.repWakeupComp.compId = id;
705   ret = tskm_sockSend(p_ctx->connFd, &ev);
706   if (ret <= 0) {
707     TSKM_ASSERT(0);
708     goto ERROR;
709   }
710   return INI_SUCCESS;
711   ERROR: return INI_FALSE;
712 }
713
714 /*******************************************************************
715  *    Event completion notification at termination
716  *******************************************************************/
717 int32_t pri_accOffComp(uint64_t id) {
718   int ret;
719   PRI_CTX_t* p_ctx = &g_pri;
720   TSKM_EVENT_INFO_t ev;
721
722   bzero(&ev, sizeof(ev));
723
724   ev.event = TSKM_EV_PRI_REP_DOWN_COMP;
725   ev.errCode = TSKM_E_OK;
726   ev.prm.repDownComp.compId = id;
727   ret = tskm_sockSend(p_ctx->connFd, &ev);
728   if (ret <= 0) {
729     TSKM_ASSERT(0);
730     goto ERROR;
731   }
732   return INI_SUCCESS;
733   ERROR: return INI_FALSE;
734 }
735
736 /*******************************************************************
737  *    Private Information Acquisition
738  *******************************************************************/
739 void*
740 pri_getPrivate() {
741   PRI_CTX_t* p_ctx = &g_pri;
742   return p_ctx->prm.priv;
743 }
744
745 /*******************************************************************
746  *    App Handle Acquisition
747  *******************************************************************/
748 HANDLE pri_getHandle() {
749   PRI_CTX_t* p_ctx = &g_pri;
750   return p_ctx->hApp;
751 }
752
753 /*******************************************************************
754  *    Timeout setting for Service monitoring status setting
755  *******************************************************************/
756 int32_t pri_setMonitorTimeout(uint32_t timeout) {
757   PRI_CTX_t* p_ctx = &g_pri;
758   p_ctx->timeout = timeout;
759   return INI_SUCCESS;
760 }
761
762 /*******************************************************************
763  *    BOOT Info Acquisition
764  *******************************************************************/
765 int32_t pri_getBootInfo(T_SS_SM_START_DataStructType *info) {
766   PRI_CTX_t* p_ctx = &g_pri;
767
768   if (p_ctx->bootInfo.startupReason == epswfINVALID) {
769     TSKM_ASSERT(0);
770     return INI_FALSE;
771   }
772
773   *info = p_ctx->bootInfo;
774
775   return INI_SUCCESS;
776 }
777
778 /*******************************************************************
779  *    Extended BOOT Info Acquisition
780  *******************************************************************/
781 int32_t pri_getExtBootInfo(T_SS_SM_START_ExtDataStructType *info) {
782   PRI_CTX_t* p_ctx = &g_pri;
783
784   if (p_ctx->bootInfo.startupReason == epswfINVALID) {
785     TSKM_ASSERT(0);
786     return INI_FALSE;
787   }
788
789   *info = p_ctx->extBootInfo;
790
791   return INI_SUCCESS;
792 }
793
794 /*******************************************************************
795  *    DebugDump Responding
796  *******************************************************************/
797 void pri_sendDebugDumpRes(const char *buf) {  // LCOV_EXCL_START 7: for debugging
798   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
799   int ret;
800   PRI_CTX_t* p_ctx = &g_pri;
801   TSKM_EVENT_INFO_t ev;
802   TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *p_prm;
803
804   ev.event = TSKM_EV_PRI_RES_DEBUGDUMP;
805   ev.errCode = TSKM_E_OK;
806   ev.hasExtend = TSKM_TRUE;
807
808   ev.extendPrm = malloc(sizeof(TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t));
809   if (!ev.extendPrm) {
810     TSKM_ASSERT(0);
811     goto ERROR;
812   }
813
814   ev.extendSize = sizeof(TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t);
815
816   p_prm = (TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *) ev.extendPrm;  // NOLINT ( )
817   snprintf(p_prm->dumpMsg, TSKM_EV_DEBUGDUMP_SIZE, "%s", buf);
818
819   ret = tskm_sockSend(p_ctx->connFd, &ev);
820   if (ret <= 0) {
821     TSKM_ASSERT(0);
822   }
823
824   ERROR: return;
825 }
826 // LCOV_EXCL_STOP
827 /*************************************************
828  * Empty functions implemented for building software
829  **************************************************/
830 EFrameworkunifiedStatus FrameworkunifiedOnStart(HANDLE hApp) {  // LCOV_EXCL_START 6: Because the condition cannot be set
831   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
832   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
833   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
834   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
835   return l_eStatus;
836 }
837 // LCOV_EXCL_STOP
838 EFrameworkunifiedStatus FrameworkunifiedOnStop(HANDLE hApp) {  // LCOV_EXCL_START 6: Because the condition cannot be set
839   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
840   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
841   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
842   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
843   return l_eStatus;
844 }
845 // LCOV_EXCL_STOP
846 EFrameworkunifiedStatus FrameworkunifiedOnPreStart(HANDLE hApp) {
847   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
848   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
849   return eFrameworkunifiedStatusOK;
850 }
851 EFrameworkunifiedStatus FrameworkunifiedOnPreStop(HANDLE hApp) {
852   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
853   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
854   return eFrameworkunifiedStatusOK;
855 }
856 EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStart(HANDLE hApp) {
857   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
858   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
859   return eFrameworkunifiedStatusOK;
860 }
861 EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStop(HANDLE hApp) {
862   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
863   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
864   return eFrameworkunifiedStatusOK;
865 }
866 EFrameworkunifiedStatus FrameworkunifiedCreateStateMachine(HANDLE hApp) {  // LCOV_EXCL_START 6: Because the condition cannot be set
867   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
868   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
869   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
870   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
871   return l_eStatus;
872 }
873 // LCOV_EXCL_STOP