summaryrefslogtreecommitdiffstats
path: root/task_manager/server/src
diff options
context:
space:
mode:
authorToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:42:55 +0900
committerToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:42:55 +0900
commit7ba873861b02b878d0dcefa3104981c57e71deac (patch)
tree14dd72c4875ee1de16f07b73a1f3e38ea2d3f4a0 /task_manager/server/src
parent706ad73eb02caf8532deaf5d38995bd258725cb8 (diff)
ss-taskmanager branch
Diffstat (limited to 'task_manager/server/src')
-rw-r--r--task_manager/server/src/pri_main.cpp840
-rw-r--r--task_manager/server/src/tskm_api.cpp268
-rw-r--r--task_manager/server/src/tskm_comm.cpp402
-rw-r--r--task_manager/server/src/tskm_debug.cpp357
-rw-r--r--task_manager/server/src/tskm_main.cpp727
-rw-r--r--task_manager/server/src/tskm_port_pf.cpp884
-rw-r--r--task_manager/server/src/tskm_port_subsys.cpp303
-rw-r--r--task_manager/server/src/tskm_shutdown.cpp242
-rw-r--r--task_manager/server/src/tskm_state.cpp452
-rw-r--r--task_manager/server/src/tskm_svc.cpp978
-rw-r--r--task_manager/server/src/tskm_wakeup.cpp201
-rw-r--r--task_manager/server/src/tskm_watch.cpp101
12 files changed, 5755 insertions, 0 deletions
diff --git a/task_manager/server/src/pri_main.cpp b/task_manager/server/src/pri_main.cpp
new file mode 100644
index 00000000..e572e7a4
--- /dev/null
+++ b/task_manager/server/src/pri_main.cpp
@@ -0,0 +1,840 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pri_main.h"
+#include <string.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/eventfd.h>
+#include <stdlib.h>
+#include <native_service/frameworkunified_dispatcher.h>
+#include <system_service/ss_system_if.h>
+
+#include "tskm_debug.h"
+#include "tskm_comm.h"
+#include "tskm_port_pf.h"
+#include "tskm_port_subsys.h"
+#include "tskm_util.h"
+
+
+
+#define PRI_PROC_NAME_MAX 32
+
+// Context
+typedef struct {
+ T_PRIM_PRM prm;
+
+ TSKM_SVCID_t svcId; // Set valid value by REQ_WAKEUP
+ char procName[PRI_PROC_NAME_MAX];
+ // State
+ TSKM_BOOL_t isExec;
+ T_SS_SM_START_DataStructType bootInfo;
+ T_SS_SM_START_ExtDataStructType extBootInfo; TSKM_BOOL_t isDynamic;
+ uint32_t wakeupStepDone; // Executed local step
+ TSKM_BOOL_t shmDone;
+ uint32_t downStepDone; // Executed local step
+ TSKM_BOOL_t isExitStart;
+
+#define PRI_MONITOR_DEFAULT_TIMEOUT 50
+ uint32_t timeout; // Service monitoring timeout period (valid only for the INI_Main type service)
+
+ // Resources
+ int connFd; // TSKM communication socket
+ int nsFd; // NSFW socket
+ int pipeFd[2]; // for exitDone
+ HANDLE hApp; // appHandle
+} PRI_CTX_t;
+
+static PRI_CTX_t g_pri;
+
+/*********************************************
+ * Create shared memory
+ *********************************************/
+TSKM_STATIC void shmMake(PRI_CTX_t* p_ctx) {
+ const PRIM_SHAREDATA_TBL* shmEntry;
+ for (shmEntry = p_ctx->prm.shmTbl; shmEntry->shmName[0] != '\0'; shmEntry++) {
+ int ret;
+ ret = tskm_pf_shmCreate(shmEntry->shmName, shmEntry->size, NULL);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+ }
+ p_ctx->shmDone = TSKM_TRUE;
+ return;
+
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************
+ * Call backup check CB
+ *********************************************/
+TSKM_STATIC uint32_t wakeupExFuncCallback(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
+ const PRIM_EXFUNC_TBL* funcEntry;
+ uint32_t maxStep = 0;
+
+ for (funcEntry = p_ctx->prm.wakeupExFuncTbl; funcEntry->localStep != 0;
+ funcEntry++) {
+ if (funcEntry->localStep == p_prm->localStep) {
+ funcEntry->func(funcEntry->prm);
+ }
+ maxStep = TSKM_MAX(maxStep, funcEntry->localStep);
+ }
+ return maxStep;
+}
+
+/*********************************************
+ * Gradual startup request
+ *********************************************/
+TSKM_STATIC void wakeupRequest(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
+ TSKM_EV_PRI_REQ_WAKEUP_PRM_t prm = *p_prm;
+ uint32_t max = 0;
+
+ // Execute step by step
+ for (prm.localStep = p_ctx->wakeupStepDone + 1;
+ (prm.localStep <= p_prm->localStep && prm.localStep < PRIM_STEPFORK_MAX);
+ prm.localStep++) {
+ max = wakeupExFuncCallback(p_ctx, &prm);
+ }
+
+ if (max <= p_prm->localStep) {
+ // Completed gradual startup
+ p_ctx->wakeupStepDone = PRIM_STEPFORK_MAX;
+ } else {
+ p_ctx->wakeupStepDone = p_prm->localStep;
+ }
+}
+
+/*********************************************
+ * All startup requests
+ *********************************************/
+TSKM_STATIC void allWakeup(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
+ if (!p_ctx->shmDone) {
+ shmMake(p_ctx);
+ }
+
+ if (p_ctx->wakeupStepDone < PRIM_STEPFORK_MAX) {
+ wakeupRequest(p_ctx, p_prm);
+ }
+}
+
+/*********************************************
+ * Startup request handles
+ *********************************************/
+TSKM_STATIC void wakeupRequestHandle(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_WAKEUP_PRM_t* p_prm) {
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+
+ bzero(&ev, sizeof(ev));
+
+ p_ctx->svcId = p_prm->svcId;
+ memcpy(&p_ctx->bootInfo, &p_prm->bootInfo, sizeof(p_ctx->bootInfo));
+ memcpy(&p_ctx->extBootInfo, &p_prm->extBootInfo, sizeof(p_ctx->extBootInfo));
+ p_ctx->isDynamic = p_prm->isDynamic;
+
+ if (p_prm->localStep == TSKM_LSTEP_ALL) {
+ allWakeup(p_ctx, p_prm);
+ } else if (p_prm->localStep == TSKM_LSTEP_LAST) {
+ wakeupRequest(p_ctx, p_prm);
+ } else if (p_prm->localStep == TSKM_LSTEP_SHM) {
+ shmMake(p_ctx);
+ } else {
+ wakeupRequest(p_ctx, p_prm);
+ }
+
+ ev.prm.resWakeup.isShmDone = p_ctx->shmDone;
+ ev.prm.resWakeup.isStepDone =
+ (p_ctx->wakeupStepDone >= PRIM_STEPFORK_MAX) ?
+ TSKM_TRUE :
+ TSKM_FALSE;
+
+ // LCOV_EXCL_BR_START 6: Because it depends on the test order
+ if (ev.prm.resWakeup.isShmDone && ev.prm.resWakeup.isStepDone) {
+ // LCOV_EXCL_BR_STOP
+ ev.prm.resWakeup.isLast = TSKM_TRUE;
+ }
+
+ ev.event = TSKM_EV_PRI_RES_WAKEUP;
+ ev.errCode = TSKM_E_OK;
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+}
+
+/*********************************************
+ * Gradual termination callback
+ *********************************************/
+TSKM_STATIC uint32_t downExFuncCallback(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
+ const PRIM_EXFUNC_TBL* funcEntry;
+ uint32_t maxStep = 0;
+
+ for (funcEntry = p_ctx->prm.downExFuncTbl; funcEntry->localStep != 0;
+ funcEntry++) {
+ if (funcEntry->localStep == p_prm->localStep) {
+ funcEntry->func(funcEntry->prm);
+ }
+ maxStep = TSKM_MAX(maxStep, funcEntry->localStep);
+ }
+ return maxStep;
+}
+
+/*********************************************
+ * Gradual termination requests
+ *********************************************/
+TSKM_STATIC void downRequest(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
+ TSKM_EV_PRI_REQ_DOWN_PRM_t prm = *p_prm;
+ uint32_t max = 0;
+
+ // Execute step by step
+ for (prm.localStep = p_ctx->downStepDone + 1;
+ (prm.localStep <= p_prm->localStep && prm.localStep < PRIM_ACCOFF_MAX);
+ prm.localStep++) {
+ max = downExFuncCallback(p_ctx, &prm);
+ }
+
+ if (max <= p_prm->localStep) {
+ p_ctx->downStepDone = PRIM_ACCOFF_MAX; // Completed all steps
+ } else {
+ p_ctx->downStepDone = p_prm->localStep;
+ }
+}
+
+TSKM_STATIC void downRequestHandle(PRI_CTX_t* p_ctx,
+ TSKM_EV_PRI_REQ_DOWN_PRM_t* p_prm) {
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+
+ bzero(&ev, sizeof(ev));
+
+ if (p_prm->localStep == TSKM_LSTEP_ALL || p_prm->localStep == TSKM_LSTEP_LAST) {
+ downRequest(p_ctx, p_prm);
+ } else if (p_prm->localStep == TSKM_LSTEP_SHM) {
+ TSKM_ASSERT(0);
+ } else if (p_prm->localStep == TSKM_LSTEP_BUPCHK) {
+ TSKM_ASSERT(0);
+ } else {
+ downRequest(p_ctx, p_prm);
+ }
+
+ if (p_ctx->downStepDone >= PRIM_ACCOFF_MAX) {
+ /* It is not notified when the last function is executed, and it is left to the exitDone.
+ TSKM_PRINTF(TSKM_LOG_DEBUG,"ACCOFF DONE");
+ ev.prm.resDown.isLast = TSKM_TRUE;
+ p_ctx->isExec = TSKM_FALSE;
+ ret = tskm_sockSend(p_ctx->connFd,&ev);
+ if(ret <= 0){
+ TSKM_ASSERT(0);
+ tskm_pf_abort();
+ }
+ */
+ } else {
+ ev.event = TSKM_EV_PRI_RES_DOWN;
+ ev.errCode = TSKM_E_OK;
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+ }
+}
+
+/*********************************************
+ * Termination completion notification to the TSKM
+ *********************************************/
+TSKM_STATIC void sendLastDoneRes(PRI_CTX_t* p_ctx) {
+ int ret;
+ TSKM_EVENT_INFO_t ev;
+
+ bzero(&ev, sizeof(ev));
+
+ ev.event = TSKM_EV_PRI_RES_DOWN;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.resDown.isLast = TSKM_TRUE;
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+}
+
+/*********************************************
+ * Call Touch CB
+ *********************************************/
+TSKM_STATIC void touchService(PRI_CTX_t* p_ctx) {
+ char touchName[32];
+
+ if (p_ctx->isExitStart) {
+ // If termination has already begun, the system just processes as timeout for retrying not respond Touch
+ return;
+ }
+
+ p_ctx->prm.onTouch(p_ctx->hApp);
+
+ tskm_pf_mkTouchFileName(getpid(), touchName);
+
+ if ((access(touchName, F_OK) == 0)) {
+ // Synchronize by deleting files.
+ TSKM_PRINTF(TSKM_LOG_STATE, "del:%s", touchName);
+ unlink(touchName);
+ } else {
+ TSKM_ASSERT_PRINT(0, "%s", touchName);
+ }
+}
+
+/*********************************************
+ * Call Debugdump CB
+ *********************************************/
+TSKM_STATIC void callDebugDump(PRI_CTX_t* p_ctx) {
+ if (!p_ctx->prm.onDebugDump) { // LCOV_EXCL_BR_LINE 6: As NULL checked by INI_Init
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: As NULL checked by INI_Init
+ } else {
+ p_ctx->prm.onDebugDump(p_ctx->hApp);
+ }
+}
+
+/*********************************************
+ * Call LowMemory detection
+ *********************************************/
+TSKM_STATIC void callLowMem(PRI_CTX_t* p_ctx) {
+ if (!p_ctx->prm.onLowMem) {
+ TSKM_ASSERT(0);
+ } else if (!p_ctx->isExitStart) {
+ // Notify LowMemory only before starting terminating process
+ p_ctx->prm.onLowMem(p_ctx->hApp);
+ }
+}
+
+/*********************************************
+ * Event handles
+ *********************************************/
+TSKM_STATIC void eventHandle(PRI_CTX_t* p_ctx, TSKM_EVENT_INFO_t* p_ev) {
+ //Processing according to the request
+ switch (p_ev->event) {
+ case TSKM_EV_PRI_REQ_WAKEUP:
+ wakeupRequestHandle(p_ctx, &p_ev->prm.reqWakeup);
+ break;
+ case TSKM_EV_PRI_REQ_DOWN:
+ downRequestHandle(p_ctx, &p_ev->prm.reqDown);
+ break;
+ case TSKM_EV_PRI_REQ_TOUCH:
+ touchService(p_ctx);
+ break;
+ case TSKM_EV_PRI_REQ_DEBUGDUMP:
+ callDebugDump(p_ctx);
+ break;
+ case TSKM_EV_PRI_REP_LOWMEM:
+ callLowMem(p_ctx);
+ break;
+ default:
+ TSKM_ASSERT(0);
+ break;
+ }
+}
+
+/*********************************************
+ * Initialize Context
+ *********************************************/
+TSKM_STATIC void initCtx(T_PRIM_PRM* p_prm, PRI_CTX_t* p_ctx, int argc,
+ char* argv[]) {
+ FrameworkunifiedDefaultCallbackHandler cbFuncs;
+
+ p_ctx->prm = *p_prm;
+
+ cbFuncs.onInitilization = p_ctx->prm.onInit;
+ cbFuncs.onDestroy = p_ctx->prm.onDestory;
+ cbFuncs.onDebugDump = p_ctx->prm.onDebugDump;
+ cbFuncs.onStart = FrameworkunifiedOnStart;
+ cbFuncs.onStop = FrameworkunifiedOnStop;
+ cbFuncs.createStateMachine = FrameworkunifiedCreateStateMachine;
+ cbFuncs.ssFrameworkInterface = FrameworkunifiedSSFrameworkInterface;
+
+ EFrameworkunifiedStatus taskmanagerRet;
+ taskmanagerRet = FrameworkunifiedCreateDispatcherWithoutLoop(p_ctx->prm.name, p_ctx->hApp, argc,
+ argv, &cbFuncs, FALSE);
+ if (eFrameworkunifiedStatusOK != taskmanagerRet) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+
+ taskmanagerRet = FrameworkunifiedGetDispatcherFD(p_ctx->hApp, &p_ctx->nsFd);
+ if (taskmanagerRet != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
+ exit(EXIT_FAILURE);
+ }
+ p_ctx->connFd = tskm_cliSockConnect(TSKM_SOCKET_NAME);
+ if (p_ctx->connFd < 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+ if (pipe(p_ctx->pipeFd) != 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+
+ return;
+
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************
+ * Destroy context
+ *********************************************/
+TSKM_STATIC void termCtx(PRI_CTX_t* p_ctx) {
+ if (p_ctx->shmDone) { // LCOV_EXCL_BR_LINE 6: Since it has been set to True by INI_Handler and cannot be changed
+ const PRIM_SHAREDATA_TBL* shmEntry = p_ctx->prm.shmTbl;
+ for (shmEntry = p_ctx->prm.shmTbl; shmEntry->shmName[0] != '\0';
+ shmEntry++) {
+ TSKM_ASSERT(0 == tskm_pf_shmDelete(shmEntry->shmName)); // LCOV_EXCL_BR_LINE 8: For processing in which only return value 0 is set
+ }
+ }
+
+ if (p_ctx->connFd > 0) { // LCOV_EXCL_BR_LINE 6: For processing in which only return value 0 is set
+ tskm_sockDestory(p_ctx->connFd);
+ }
+
+ EFrameworkunifiedStatus taskmanagerRet;
+ taskmanagerRet = FrameworkunifiedDestroyDispatcherWithoutLoop(p_ctx->hApp);
+ TSKM_ASSERT(taskmanagerRet == eFrameworkunifiedStatusOK);
+
+ if (p_ctx->isDynamic) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "EXIT %s", p_ctx->procName);
+ } else {
+ // Hung up running services to prevent adversely affecting to system termination processing during process termination processing
+ sleep(TSKM_CFG_WAIT_SHUTDOWN);
+ }
+}
+
+/*******************************************************************
+ * Initialize PRI context
+ *******************************************************************/
+void pri_init(T_PRIM_PRM* p_prm, int argc, char* argv[], int *fdNum,
+ int fdlist[INI_FD_MAX]) {
+ int ret = 0;
+ PRI_CTX_t* p_ctx = &g_pri;
+
+ strncpy(p_ctx->procName, basename(argv[0]), sizeof(p_ctx->procName) - 1);
+
+ ret = tskm_pf_procInit();
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 6: Return value of 0 only
+ // LCOV_EXCL_START 6: Return value of 0 only
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 6: Return value of 0 only
+ }
+
+ ret = tskm_comm_procInit();
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ }
+
+ initCtx(p_prm, p_ctx, argc, argv);
+
+ *fdNum = 3;
+ fdlist[0] = p_ctx->connFd;
+ fdlist[1] = p_ctx->pipeFd[0];
+ fdlist[2] = p_ctx->nsFd;
+
+ p_ctx->svcId = TSKM_SVCID_NONE;
+ p_ctx->isExec = TSKM_TRUE;
+
+ p_ctx->bootInfo.startupReason = epswfINVALID;
+ p_ctx->bootInfo.isUserModeOn = FALSE;
+ p_ctx->bootInfo.dataResetMode = e_SS_SM_DATA_RESET_MODE_NONE;
+ p_ctx->bootInfo.securityStatus = epsssINVALID;
+ p_ctx->bootInfo.wakeupType = epsstINVALID;
+ p_ctx->bootInfo.dramBackupStatus = e_SS_SM_DRAM_BACKUP_UNSET;
+ p_ctx->bootInfo.resetStatus = e_SS_SM_RESET_STATUS_UNSET;
+
+ memset(&p_ctx->extBootInfo, 0, sizeof(p_ctx->extBootInfo));
+
+ p_ctx->timeout = PRI_MONITOR_DEFAULT_TIMEOUT;
+
+ return;
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_abort(); // ABORT
+// LCOV_EXCL_STOP
+}
+
+/*******************************************************************
+ * Primary library handler
+ *******************************************************************/
+BOOL pri_handler(fd_set* p_fds) {
+ PRI_CTX_t* p_ctx = &g_pri;
+
+ if (FD_ISSET(p_ctx->connFd, p_fds)) {
+ int ret;
+ TSKM_EVENT_INFO_t ev;
+ ret = tskm_sockRcv(p_ctx->connFd, &ev);
+ // LCOV_EXCL_BR_START 5: True condition is checked in Death tests, but not reflected in coverage and excluded
+ if (ret > 0) {
+ // LCOV_EXCL_BR_STOP
+ eventHandle(p_ctx, &ev);
+ } else { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ if (FD_ISSET(p_ctx->pipeFd[0], p_fds)) {
+ // only use exitDone
+ uint32_t tmp;
+ TSKM_ASSERT(sizeof(tmp) == read(p_ctx->pipeFd[0], &tmp, sizeof(tmp)));
+ TSKM_ASSERT(p_ctx->downStepDone == PRIM_ACCOFF_MAX); // Check if all exit functions are complete
+ if (p_ctx->isDynamic) {
+ // A nonresident service completes its termination processing by terminating the process (because the SIGNAL will overtake the sockets)
+ } else {
+ // The resident service completes termination processing with a termination notice (Do not terminate processes to reduce the impact on system termination)
+ sendLastDoneRes(p_ctx);
+ }
+ p_ctx->isExec = TSKM_FALSE;
+ }
+
+ if (FD_ISSET(p_ctx->nsFd, p_fds)) {
+ FrameworkunifiedDispatchProcessWithoutLoop(p_ctx->hApp);
+ }
+ return p_ctx->isExec;
+
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_abort(); // ABORT
+ return 0;
+// LCOV_EXCL_STOP
+}
+
+/*******************************************************************
+ * Process termination
+ *******************************************************************/
+void pri_term(void) {
+ PRI_CTX_t* p_ctx = &g_pri;
+ termCtx(p_ctx);
+}
+
+/*******************************************************************
+ * Service Monitoring Status Setting
+ *******************************************************************/
+int pri_setMonitorState(BOOL bIsRun, uint32_t timeout) {
+ PRI_CTX_t* p_ctx = &g_pri;
+ int ret = INI_SUCCESS;
+
+ if (TSKM_SVCID_NONE == p_ctx->svcId) {
+ // Ignore requests until svcId is acquired
+ } else if ((TRUE == bIsRun) && (0 == timeout)) {
+ // When RUN is specified with timeout = 0, monitoring is disabled
+ } else {
+ ret = tskm_comm_setSvcWatchState(p_ctx->svcId, bIsRun, timeout);
+ if (INI_SUCCESS != ret) {
+ TSKM_ASSERT(0);
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+ * MAIN function
+ *******************************************************************/
+int pri_main(T_PRIM_PRM* p_prm, int argc, char* argv[]) {
+ int mainRet = -1;
+ int fdlist[INI_FD_MAX];
+ int fdNum;
+ int ii;
+ BOOL isExec = TRUE;
+
+ pri_init(p_prm, argc, argv, &fdNum, fdlist);
+
+ while (isExec) {
+ PRI_CTX_t* p_ctx = &g_pri;
+ int maxFd = 0;
+ fd_set fds;
+ int ret;
+
+ FD_ZERO(&fds);
+
+ for (ii = 0; ii < fdNum; ii++) {
+ FD_SET(fdlist[ii], &fds);
+ maxFd = TSKM_MAX(fdlist[ii], maxFd);
+ }
+
+ TSKM_ASSERT(INI_SUCCESS == pri_setMonitorState(FALSE, 0));
+ ret = select(maxFd + 1, &fds, NULL, NULL, NULL);
+ TSKM_ASSERT(INI_SUCCESS == pri_setMonitorState(TRUE, p_ctx->timeout));
+ if (ret < 1) {
+ if (errno != EINTR) {
+ TSKM_ASSERT(0);
+ }
+ continue;
+ }
+
+ isExec = pri_handler(&fds);
+ }
+
+ mainRet = 0;
+
+ pri_term();
+ return mainRet;
+}
+
+/*******************************************************************
+ * Termination request
+ *******************************************************************/
+void pri_exitStart(void *rsv) {
+ int ret;
+ PRI_CTX_t* p_ctx = &g_pri;
+ TSKM_EVENT_INFO_t ev;
+
+ bzero(&ev, sizeof(ev));
+ p_ctx->isExitStart = TRUE;
+ ev.event = TSKM_EV_PRI_REQ_EXIT;
+ ev.errCode = TSKM_E_OK;
+
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) { // LCOV_EXCL_BR_LINE 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ return;
+ // LCOV_EXCL_START 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_abort();
+ // LCOV_EXCL_STOP
+}
+
+void pri_exitDone(int status) {
+ PRI_CTX_t* p_ctx = &g_pri;
+ uint32_t l_status = (uint32_t) status;
+
+ // LCOV_EXCL_BR_START 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
+ if (p_ctx->pipeFd[1] > 0) {
+ // LCOV_EXCL_BR_STOP
+ // LCOV_EXCL_START 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(
+ write(p_ctx->pipeFd[1], &l_status, sizeof(l_status))
+ == sizeof(l_status));
+ // LCOV_EXCL_STOP
+ } else {
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: The caller's external API does not execute the second or subsequent processing and cannot be checked
+ }
+}
+
+/*******************************************************************
+ * Event completion notification at startup
+ *******************************************************************/
+int32_t pri_stepForkComp(uint64_t id) {
+ int ret;
+ PRI_CTX_t* p_ctx = &g_pri;
+ TSKM_EVENT_INFO_t ev;
+
+ bzero(&ev, sizeof(ev));
+ ev.event = TSKM_EV_PRI_REP_WAKEUP_COMP;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.repWakeupComp.compId = id;
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ return INI_SUCCESS;
+ ERROR: return INI_FALSE;
+}
+
+/*******************************************************************
+ * Event completion notification at termination
+ *******************************************************************/
+int32_t pri_accOffComp(uint64_t id) {
+ int ret;
+ PRI_CTX_t* p_ctx = &g_pri;
+ TSKM_EVENT_INFO_t ev;
+
+ bzero(&ev, sizeof(ev));
+
+ ev.event = TSKM_EV_PRI_REP_DOWN_COMP;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.repDownComp.compId = id;
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ return INI_SUCCESS;
+ ERROR: return INI_FALSE;
+}
+
+/*******************************************************************
+ * Get private info
+ *******************************************************************/
+void*
+pri_getPrivate() {
+ PRI_CTX_t* p_ctx = &g_pri;
+ return p_ctx->prm.priv;
+}
+
+/*******************************************************************
+ * Get app-handle
+ *******************************************************************/
+HANDLE pri_getHandle() {
+ PRI_CTX_t* p_ctx = &g_pri;
+ return p_ctx->hApp;
+}
+
+/*******************************************************************
+ * Service monitoring status setting timeout setting
+ *******************************************************************/
+int32_t pri_setMonitorTimeout(uint32_t timeout) {
+ PRI_CTX_t* p_ctx = &g_pri;
+ p_ctx->timeout = timeout;
+ return INI_SUCCESS;
+}
+
+/*******************************************************************
+ * Get boot info
+ *******************************************************************/
+int32_t pri_getBootInfo(T_SS_SM_START_DataStructType *info) {
+ PRI_CTX_t* p_ctx = &g_pri;
+
+ if (p_ctx->bootInfo.startupReason == epswfINVALID) {
+ TSKM_ASSERT(0);
+ return INI_FALSE;
+ }
+
+ *info = p_ctx->bootInfo;
+
+ return INI_SUCCESS;
+}
+
+/*******************************************************************
+ * Get extended boot info
+ *******************************************************************/
+int32_t pri_getExtBootInfo(T_SS_SM_START_ExtDataStructType *info) {
+ PRI_CTX_t* p_ctx = &g_pri;
+
+ if (p_ctx->bootInfo.startupReason == epswfINVALID) {
+ TSKM_ASSERT(0);
+ return INI_FALSE;
+ }
+
+ *info = p_ctx->extBootInfo;
+
+ return INI_SUCCESS;
+}
+
+/*******************************************************************
+ * DebugDump response
+ *******************************************************************/
+void pri_sendDebugDumpRes(const char *buf) { // LCOV_EXCL_START 7: Debugging code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ int ret;
+ PRI_CTX_t* p_ctx = &g_pri;
+ TSKM_EVENT_INFO_t ev;
+ TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *p_prm;
+
+ ev.event = TSKM_EV_PRI_RES_DEBUGDUMP;
+ ev.errCode = TSKM_E_OK;
+ ev.hasExtend = TSKM_TRUE;
+
+ ev.extendPrm = malloc(sizeof(TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t));
+ if (!ev.extendPrm) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ ev.extendSize = sizeof(TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t);
+
+ p_prm = (TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *) ev.extendPrm; // NOLINT (readability/casting)
+ snprintf(p_prm->dumpMsg, TSKM_EV_DEBUGDUMP_SIZE, "%s", buf);
+
+ ret = tskm_sockSend(p_ctx->connFd, &ev);
+ if (ret <= 0) {
+ TSKM_ASSERT(0);
+ }
+
+ ERROR: return;
+}
+// LCOV_EXCL_STOP
+/*************************************************
+ * Empty functions implemented for building software
+ **************************************************/
+EFrameworkunifiedStatus FrameworkunifiedOnStart(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+EFrameworkunifiedStatus FrameworkunifiedOnStop(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedCreateStateMachine(HANDLE hApp) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+// LCOV_EXCL_STOP
diff --git a/task_manager/server/src/tskm_api.cpp b/task_manager/server/src/tskm_api.cpp
new file mode 100644
index 00000000..a9943ba1
--- /dev/null
+++ b/task_manager/server/src/tskm_api.cpp
@@ -0,0 +1,268 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_debug.h"
+#include "tskm_main.h"
+#include "tskm_state.h"
+#include "tskm_util.h"
+
+#include "tskm_srvr.h"
+#include "tskm_port_pf.h"
+#include "tskm_port_subsys.h"
+
+/**
+ * _TSKM_SvcCtl Sub-func Task-startup-process
+ * @param svcId service id
+ * @param p_main TSKM_MAIN_CTX_t*
+ * @param p_svc TSKM_SVC_CTX_t*
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+
+TSKM_ERR_t tskm_svcExecRequest(TSKM_SVCID_t svcId, TSKM_MAIN_CTX_t* p_main, TSKM_SVC_CTX_t* p_svc) {
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ // Startup tasks
+ TSKM_GSTEP_REQ_INFO_t req = { 0 };
+
+ if (p_main->isOnStartDone == TSKM_FALSE) {
+ TSKM_PRINTF(TSKM_LOG_WARN, "Transient SVC cannot exec before get BootInfo");
+ return TSKM_E_STATE;
+ } else if (p_main->isOnStopDone == TSKM_TRUE) {
+ TSKM_PRINTF(TSKM_LOG_WARN, "Transient SVC cannot exec after FrameworkunifiedOnStop");
+ return TSKM_E_STATE;
+ }
+
+ tskmRet = tskm_svcExec(p_svc);
+ TSKM_ERR_CHK_DFT;
+ if (p_svc->state == TSKM_SVC_WAITCONNECT) {
+ // In the state of waiting to execute
+ req.svcId = svcId;
+ req.localStep = TSKM_LSTEP_ALL;
+ tskmRet = tskm_svcWakeupRequest(p_svc, &req);
+ TSKM_ERR_CHK_DFT; // LCOV_EXCL_BR_LINE 6: Because TSKM_ERR_CHK_DFT does not specify a condition for goto to ERROR
+ }
+ ERROR: return tskmRet;
+}
+
+/**
+ * _TSKM_SvcCtl Sub-func Task-startup-process
+ * @param p_main TSKM_MAIN_CTX_t*
+ * @param svcId TSKM_SVCID_t
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+
+TSKM_ERR_t tskm_svcReserveRequest(TSKM_MAIN_CTX_t* p_main, TSKM_SVCID_t svcId) {
+ uint8_t rsvSvcNum = p_main->nvInfo.body.rsvSvcNum;
+ TSKM_SVCID_t* p_rsvSvcs = p_main->nvInfo.body.rsvSvcs;
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ if (rsvSvcNum >= TSKM_SVC_RESERVE_MAX) {
+ tskmRet = TSKM_E_STATE;
+ } else {
+ int ii;
+ int ret;
+
+ for (ii = 0; ii < rsvSvcNum; ii++) {
+ if (p_rsvSvcs[ii] == svcId) {
+ TSKM_ASSERT_PRINT(0, "Rsv Req already registered(%d)", svcId);
+ // Return OK as continuable
+ return tskmRet;
+ }
+ }
+
+ p_rsvSvcs[rsvSvcNum] = svcId;
+ p_main->nvInfo.body.rsvSvcNum++;
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "Rsv Svc registered(%#x)", svcId);
+
+ ret = tskm_pf_nvFileWrite(&p_main->nvInfo); // LCOV_EXCL_BR_LINE 6: Return value of 0 only
+ if (ret == -1) {
+ TSKM_ASSERT(0);
+ tskmRet = TSKM_E_NG;
+ return tskmRet;
+ }
+ }
+ return tskmRet;
+}
+
+/**
+ * Service control
+ * @param svcId service id
+ * @param ctl control command
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+TSKM_ERR_t _TSKM_SvcCtl(TSKM_SVCID_t svcId, const TSKM_SVC_CTL_t* ctl) {
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+
+ TSKM_SVC_CTX_t* p_svc;
+
+ if (ctl == NULL) {
+ TSKM_ASSERT(0);
+ return TSKM_E_PAR;
+ }
+
+ p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs, svcId);
+ if (p_svc == NULL) {
+ TSKM_ASSERT(0);
+ TSKM_PRINTF(TSKM_LOG_ERROR, "unknown svcId:%#x", svcId);
+ return TSKM_E_PAR;
+ }
+
+ TSKM_PRINTF(TSKM_LOG_API, "%s(%#x,%d)", __FUNCTION__, svcId, ctl->cmd);
+
+ if (ctl->cmd == TSKM_SVC_CMD_EXEC) {
+ tskmRet = tskm_svcExecRequest(svcId, p_main, p_svc);
+ } else if (ctl->cmd == TSKM_SVC_CMD_ENABLE) {
+ tskmRet = tskm_svcEnableRequest(p_svc);
+ TSKM_ERR_CHK_DFT; // LCOV_EXCL_BR_LINE 8: Because TSKM_ERR_CHK_DFT does not specify a condition for goto to ERROR
+
+ } else if (ctl->cmd == TSKM_SVC_CMD_DISABLE) {
+ tskmRet = tskm_svcDisableRequest(p_svc);
+ TSKM_ERR_CHK_DFT;
+
+ } else if (ctl->cmd == TSKM_SVC_CMD_RESERVE) {
+ tskmRet = tskm_svcReserveRequest(p_main, svcId);
+
+ } else {
+ return TSKM_E_PAR;
+ }
+
+ ERROR: return tskmRet;
+}
+
+/**
+ * Get service info
+ * @param svcId service id
+ * @param svcInfo[O] service info
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+TSKM_ERR_t TSKM_SvcGetInfo(TSKM_SVCID_t svcId, TSKM_SVC_INFO_t* svcInfo) {
+// Do not LOG acquisition APIs TSKM_PRINTF(TSKM_LOG_API,"%s()",__FUNCTION__)
+
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+ TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs, svcId);
+
+ if (p_svc == NULL || svcInfo == NULL) {
+ return TSKM_E_PAR;
+ }
+
+ svcInfo->svcId = p_svc->attr->svcId;
+ svcInfo->isExecDisable =
+ (p_svc->state == TSKM_SVC_DISABLE) ? TSKM_TRUE : TSKM_FALSE;
+
+ return TSKM_E_OK;
+}
+
+RPC_Result _TSKM_ErrorReboot(const TSKM_ERROR_REBOOT_t* p_info) {
+ RPC_Result rpcRet = RPC_OK;
+ TSKM_ERROR_REBOOT_t rebootInfo;
+
+ if (!p_info || (p_info->type != TSKM_ERROR_REBOOT_NORMAL)) {
+ TSKM_ASSERT(0);
+ return RPC_ERR_Fatal;
+ }
+
+ memset(&rebootInfo, 0, sizeof(TSKM_ERROR_REBOOT_t));
+ rebootInfo.type = p_info->type;
+ snprintf(rebootInfo.log.messageStr, TSKM_LOGGING_MSG_STR_SIZE, "%s",
+ p_info->log.messageStr);
+
+ TSKM_PRINTF(TSKM_LOG_API, "%s(%d)", __FUNCTION__, p_info->type);
+
+ tskm_sub_reboot(&rebootInfo);
+
+ return rpcRet;
+}
+
+/**
+ * Reboot service
+ * @param p_rsv Reserved
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+TSKM_ERR_t TSKM_Reboot(const TSKM_RSV_t * p_rsv) {
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ TSKM_PRINTF(TSKM_LOG_API, "%s()", __FUNCTION__)
+ if (p_rsv != NULL) {
+ TSKM_ASSERT(0);
+ return TSKM_E_PAR;
+ }
+
+ tskm_sub_reboot_normal();
+
+ return tskmRet;
+}
+
+/**
+ * Save LOGs
+ * @param p_info LOG storage info
+ * @return TSKM_E_OK Succeeded
+ * @return other Failed
+ */
+TSKM_ERR_t TSKM_Logging(const TSKM_LOGGING_INFO_t* p_info) {
+ TSKM_LOGGING_INFO_t logInfo;
+ TSKM_PRINTF(TSKM_LOG_API, "%s()", __FUNCTION__)
+
+ if (!p_info) {
+ TSKM_ASSERT(0);
+ return TSKM_E_PAR;
+ } else {
+ switch (p_info->type) {
+ case TSKM_LOGGING_TYPE_MODULE_LOGS:
+ case TSKM_LOGGING_TYPE_GRP_RELAUNCH:
+ break;
+ default:
+ TSKM_ASSERT(0);
+ return TSKM_E_PAR;
+ }
+ }
+
+ logInfo.type = p_info->type;
+ snprintf(logInfo.messageStr, TSKM_LOGGING_MSG_STR_SIZE, "%s",
+ p_info->messageStr);
+
+ tskm_sub_logging(&logInfo);
+
+ return TSKM_E_OK;
+}
+
+TSKM_ERR_t TSKM_SetWakeupOrder(const TSKM_WAKEUP_ORDER_t* p_order) {
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ TSKM_PRINTF(TSKM_LOG_API, "%s()", __FUNCTION__)
+
+ if (p_order == NULL) {
+ return TSKM_E_PAR;
+ }
+
+ if (strnlen(p_order->orderName, TSKM_ORDER_NAME_MAX) >= TSKM_ORDER_NAME_MAX) {
+ return TSKM_E_PAR;
+ }
+
+ if (tskm_sub_setWakeupOrder(p_order->orderName) != 0) {
+ TSKM_ASSERT(0);
+ tskmRet = TSKM_E_NG;
+ }
+
+ return tskmRet;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_comm.cpp b/task_manager/server/src/tskm_comm.cpp
new file mode 100644
index 00000000..c110c135
--- /dev/null
+++ b/task_manager/server/src/tskm_comm.cpp
@@ -0,0 +1,402 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _GNU_SOURCE
+#warning "_GNU_SOURCE not defined, so define here"
+#define _GNU_SOURCE
+#endif
+#include "tskm_comm.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <native_service/cl_monitor.h>
+
+#include "tskm_debug.h"
+#include "tskm_util.h"
+
+
+/**********************************************************
+ * Internal functions
+ **********************************************************/
+TSKM_STATIC TSKM_SRV_CONNENT_t*
+addConnFd(TSKM_SRV_CONNENT_LIST_t* list, TSKM_SRV_CONNENT_t* conn) {
+ TSKM_SRV_CONNENT_t* retConn;
+ if (list->num >= TSKM_COMM_CONNECT_MAX) {
+ TSKM_ASSERT(0)
+ return NULL;
+ }
+
+ retConn = &list->conn[list->num];
+ list->conn[list->num] = *conn;
+ list->num++;
+ return retConn;
+}
+
+TSKM_STATIC void delConnFd(TSKM_SRV_CONNENT_LIST_t* list,
+ TSKM_SRV_CONNENT_t* conn) {
+ uint32_t ii;
+ TSKM_BOOL_t isFind = TSKM_FALSE;
+ for (ii = 0; ii < list->num; ii++) {
+ if (!isFind && list->conn[ii].connFd == conn->connFd) {
+ isFind = TSKM_TRUE;
+ list->num--;
+ }
+
+ if (isFind && (ii < list->num)) {
+ list->conn[ii] = list->conn[ii + 1];
+ }
+ }
+ TSKM_ASSERT(isFind);
+}
+
+/**********************************************************
+ * Public functions
+ **********************************************************/
+TSKM_ERR_t tskm_srvSockCreate(const char *sockName,
+ TSKM_SRV_SOCK_CTX_t* p_sock) {
+ int fd = -1;
+ int ret;
+ int sockRet;
+ int enable = 1;
+ int listenNum = TSKM_COMM_CONNECT_MAX;
+
+ struct sockaddr_un unix_addr = { };
+
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (fd < 0) { // LCOV_EXCL_BR_LINE 5: For processing initializing process
+ // LCOV_EXCL_START 5: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (0 == access(sockName, F_OK)) { // LCOV_EXCL_BR_LINE 5: For processing initializing process
+ TSKM_ASSERT(0);
+ unlink(sockName);
+ }
+
+ unix_addr.sun_family = AF_UNIX;
+ strncpy(unix_addr.sun_path, sockName, sizeof(unix_addr.sun_path) - 1);
+
+ sockRet = bind(fd, (struct sockaddr *) &unix_addr, sizeof(unix_addr));
+ if (sockRet != 0) { // LCOV_EXCL_BR_LINE 5: For processing initializing process
+ // LCOV_EXCL_START 5: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ ret = chmod(sockName, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 5: For processing initializing process
+ // LCOV_EXCL_START 5: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ sockRet = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
+ if (sockRet != 0) { // LCOV_EXCL_BR_LINE 5:For processing initializing process
+ // LCOV_EXCL_START 5: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ sockRet = listen(fd, listenNum);
+ if (sockRet != 0) { // LCOV_EXCL_BR_LINE 5: For process initialization processing
+ // LCOV_EXCL_START 5: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ memset(p_sock, 0, sizeof(*p_sock));
+ p_sock->sockFd = fd;
+ p_sock->sockName = sockName;
+
+ return TSKM_E_OK;
+ // LCOV_EXCL_START 5: For process initialization processing
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (fd != -1) {
+ close(fd);
+ }
+ return TSKM_E_NG;
+ // LCOV_EXCL_STOP
+}
+
+TSKM_SRV_CONNENT_t*
+tskm_srvSockConnect(TSKM_SRV_SOCK_CTX_t* p_sock) {
+ int fd = -1;
+ socklen_t len;
+ int sockRet;
+ TSKM_SRV_CONNENT_t conn;
+ TSKM_SRV_CONNENT_t *retConn;
+ struct ucred credent;
+ struct sockaddr_un unix_addr;
+
+ memset(&conn, 0, sizeof(conn));
+ conn.connFd = -1;
+
+ len = sizeof(unix_addr);
+ fd = accept(p_sock->sockFd, (struct sockaddr*) &unix_addr,
+ (socklen_t *) &len); // NOLINT (readability/casting)
+ if (fd < 0) { // LCOV_EXCL_BR_LINE 5: Accept's Error-Handling Process
+ // LCOV_EXCL_START 5: Accept's Error-Handling Process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ conn.connFd = fd;
+
+ len = sizeof(credent);
+ sockRet = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credent, &len);
+ if (sockRet != 0) { // LCOV_EXCL_BR_LINE 5: Getsockopt's Error-Handling Process
+ // LCOV_EXCL_START 5: Getsockopt's Error-Handling Process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ conn.pid = credent.pid;
+
+ retConn = addConnFd(&p_sock->connList, &conn);
+ if (retConn == NULL) { // LCOV_EXCL_BR_LINE 5: Connect's Error-Handling Process
+ // LCOV_EXCL_START 5: Connect's Error-Handling Process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ return retConn;
+ // LCOV_EXCL_START 5: Error-Handling Process
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (conn.connFd != -1) {
+ tskm_sockDestory(conn.connFd);
+ }
+ return NULL;
+ // LCOV_EXCL_STOP
+}
+
+void tskm_srvSockDisconnect(TSKM_SRV_SOCK_CTX_t* p_sock,
+ TSKM_SRV_CONNENT_t *p_conn) {
+ int fd = p_conn->connFd;
+ delConnFd(&p_sock->connList, p_conn);
+ tskm_sockDestory(fd);
+}
+
+void tskm_srvSockDestory(TSKM_SRV_SOCK_CTX_t* p_sock) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (p_sock->sockFd) {
+ tskm_sockDestory(p_sock->sockFd);
+ p_sock->sockFd = 0;
+
+ TSKM_ASSERT_ERRNO(0 == unlink(p_sock->sockName));
+ }
+}
+// LCOV_EXCL_STOP
+int tskm_cliSockConnect(const char* sockName) {
+ int fd = -1;
+ int sockRet;
+ struct sockaddr_un unix_addr = { };
+
+ /* Create socket */
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if (fd < 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ unix_addr.sun_family = AF_UNIX;
+ strncpy(unix_addr.sun_path, sockName, sizeof(unix_addr.sun_path) - 1);
+ sockRet = connect(fd, (struct sockaddr*) &unix_addr, sizeof(unix_addr));
+ if (sockRet < 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ return fd;
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (fd != -1) {
+ TSKM_ASSERT_ERRNO(0 == close(fd));
+ }
+ return -1;
+ // LCOV_EXCL_STOP
+}
+
+int tskm_sockRcv(int fd, TSKM_EVENT_INFO_t* p_ev) {
+ int ret;
+ TSKM_EVENT_INFO_t ev;
+ ret = static_cast<int>(recv(fd, &ev, sizeof(ev), 0));
+
+ // LCOV_EXCL_BR_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ if (ret > (int) sizeof(ev)) { // NOLINT (readability/casting)
+ // LCOV_EXCL_BR_STOP
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (ret < 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ if (ret > 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ TSKM_PRINTF(TSKM_LOG_MSG, "recv:%s from:%d ret:%d",
+ tskm_convEvent2Str(ev.event), ev.fromPid, ret);
+ }
+
+ *p_ev = ev;
+
+ if (p_ev->hasExtend && (0 != p_ev->extendSize)) {
+ TSKM_PRINTF(TSKM_LOG_MSG, "rcv:ex(%d) ", p_ev->extendSize);
+
+ p_ev->extendPrm = malloc(p_ev->extendSize);
+ if (!p_ev->extendPrm) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ ret = static_cast<int>(recv(fd, p_ev->extendPrm, p_ev->extendSize, 0));
+
+ // LCOV_EXCL_BR_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ if (ret > (int) p_ev->extendSize) { // NOLINT (readability/casting)
+ // LCOV_EXCL_BR_STOP
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (ret < 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ return ret;
+
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return -1;
+ // LCOV_EXCL_STOP
+}
+
+int tskm_sockSend(int fd, TSKM_EVENT_INFO_t* p_ev) {
+ int ret;
+ p_ev->fromPid = getpid();
+ TSKM_PRINTF(TSKM_LOG_MSG, "send:%s ", tskm_convEvent2Str(p_ev->event));
+ ret = static_cast<int>(send(fd, p_ev, sizeof(*p_ev), MSG_NOSIGNAL));
+ if (ret != sizeof(*p_ev)) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ // Because it is entered only when called from a debugging function (pri_sendDebugDumpRes)
+ if (p_ev->hasExtend && p_ev->extendPrm && (0 != p_ev->extendSize)) {
+ TSKM_PRINTF(TSKM_LOG_MSG, "send:ex(%d) ", p_ev->extendSize);
+
+ ret = static_cast<int>(send(fd, p_ev->extendPrm, p_ev->extendSize, MSG_NOSIGNAL));
+ if (ret != (int)p_ev->extendSize) { // NOLINT (readability/casting)
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ }
+
+ return ret;
+
+ ERROR: return -1;
+}
+
+void tskm_sockDestory(int fd) {
+ TSKM_ASSERT_ERRNO(0 == shutdown(fd, SHUT_RDWR));
+ TSKM_ASSERT_ERRNO(0 == close(fd));
+}
+
+/******************************************************************
+ * Initializing (Process)
+ ******************************************************************/
+int tskm_comm_procInit(void) {
+ int ret;
+
+ ret = CL_MonitorInit(CL_MONITOR_INIT_USER);
+
+ if (ret != 0) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ return 0;
+
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return -1;
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************************
+ * Service Error Monitoring Status Setting
+ *********************************************************/
+int tskm_comm_setSvcWatchState(uint32_t id, BOOL bIsRun, uint32_t timeout) {
+ int ret = 0;
+
+ CL_MonitorState_t state = CL_MONITOR_STATE_SLEEP;
+
+ if (bIsRun) {
+ state = CL_MONITOR_STATE_RUN;
+ }
+
+ ret = CL_MonitorSetEntry(CL_MONITOR_TYPE_GENERIC, id, state, timeout, 0);
+ if (0 != ret) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ return 0;
+ ERROR: return -1;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_debug.cpp b/task_manager/server/src/tskm_debug.cpp
new file mode 100644
index 00000000..225c4b5c
--- /dev/null
+++ b/task_manager/server/src/tskm_debug.cpp
@@ -0,0 +1,357 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_debug.h"
+
+const char*
+tskm_convState2Str(TSKM_STATE_t state) {
+ const char* ret = "UNKNONW";
+ switch (state) { // LCOV_EXCL_BR_LINE 7:debug code
+ case TSKM_ST_ACCOFF:
+ ret = "ACCOFF";
+ break;
+ case TSKM_ST_ACCON:
+ ret = "ACCON";
+ break;
+ case TSKM_ST_WAKEUP:
+ ret = "WAKEUP";
+ break;
+ case TSKM_ST_RUNNING:
+ ret = "RUNNING";
+ break;
+ case TSKM_ST_DOWN:
+ ret = "DOWN";
+ break;
+ }
+ return ret;
+}
+
+const char*
+tskm_convLocalStep2Str(TSKM_LOCAL_STEP_t localStep) {
+ switch (localStep) { // LCOV_EXCL_BR_LINE 7:debug code
+ case TSKM_LSTEP_LAST:
+ return "LAST";
+ case TSKM_LSTEP_SHM:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "SHM";
+ case TSKM_LSTEP_BUPCHK:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "BUPCHK";
+ case TSKM_LSTEP_ALL:
+ return "ALL";
+ case 0:
+ return "0";
+ case 1:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "1";
+ // LCOV_EXCL_STOP
+ case 2:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "2";
+ // LCOV_EXCL_STOP
+ case 3:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "3";
+ // LCOV_EXCL_STOP
+ case 4:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "4";
+ // LCOV_EXCL_STOP
+ case 5:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "5";
+ // LCOV_EXCL_STOP
+ case 6:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "6";
+ // LCOV_EXCL_STOP
+ case 7:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "7";
+ // LCOV_EXCL_STOP
+ case 8:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "8";
+ // LCOV_EXCL_STOP
+ case 9:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "9";
+ // LCOV_EXCL_STOP
+ default:
+ break;
+ }
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "UNKNONW";
+ // LCOV_EXCL_STOP
+}
+
+const char*
+tskm_convEvent2Str(TSKM_EVENT_t event) {
+ switch (event) { // LCOV_EXCL_BR_LINE 7:debug code
+ case TSKM_EV_NOP:
+ return "NOP";
+ case TSKM_EV_PRI_REQ_WAKEUP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REQ_WAKEUP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REQ_DOWN:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REQ_DOWN";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REQ_TOUCH:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REQ_TOUCH";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REQ_DEBUGDUMP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REQ_DEBUGDUMP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REP_LOWMEM:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REP_LOWMEM";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REP_WAKEUP_COMP:
+ return "PRI_REP_WAKEUP_COMP";
+ case TSKM_EV_PRI_REP_DOWN_COMP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REP_DOWN_COMP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REP_CONNECT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REP_CONNECT";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REP_DISCONNECT:
+ return "PRI_REP_DISCONNECT";
+ case TSKM_EV_PRI_RES_WAKEUP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_RES_WAKEUP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_RES_DOWN:
+ return "PRI_RES_DOWN";
+ case TSKM_EV_PRI_RES_DEBUGDUMP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_RES_DEBUGDUMP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_PRI_REQ_EXIT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "PRI_REQ_EXIT";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_SVC_REP_TERM:
+ return "SVC_REP_TERM";
+ case TSKM_EV_API_REQ_REBOOT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "API_REQ_REBOOT";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_API_REQ_SVC_CTL:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "API_REQ_SVC_CTL";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_API_REQ_SVC_DISABLE:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "API_REQ_SVC_DISABLE";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REQ_STOP:
+ return "API_REQ_STOP";
+ case TSKM_EV_LCL_CHG_SVC_STATE:
+ return "LCL_CHG_SVC_STATE";
+ case TSKM_EV_LCL_REQ_SDUMP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "LCL_REQ_SDUMP";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REP_TIMEOUT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "LCL_REP_TIMEOUT";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REP_POLLING:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "LCL_REP_POLLING";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REP_LOWMEM:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "LCL_REP_LOWMEM";
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REQ_TRANS_STEP:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "LCL_REQ_TRANS_STEP";
+ // LCOV_EXCL_STOP
+ default:
+ break;
+ }
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "UNKNOWN";
+ // LCOV_EXCL_STOP
+}
+
+const char*
+tskm_convInitCompId2Str(uint64_t compId) {
+ switch (compId) { // LCOV_EXCL_BR_LINE 7:debug code
+ case INI_INITCOMP_NONE:
+ return "NONE";
+ case INI_INITCOMP_ON_START:
+ return "ONSTART";
+ case INI_INITCOMP_NVM_ACCESS:
+ return "NVM_ACCESS";
+ case INI_INITCOMP_TEST0:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST0";
+ // LCOV_EXCL_STOP
+ case INI_INITCOMP_TEST1:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST1";
+ // LCOV_EXCL_STOP
+ case INI_INITCOMP_TEST2:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST2";
+ // LCOV_EXCL_STOP
+ case INI_INITCOMP_TEST3:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST3";
+ // LCOV_EXCL_STOP
+ }
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "UNKNONW";
+ // LCOV_EXCL_STOP
+}
+
+const char*
+tskm_convTermCompId2Str(uint64_t compId) {
+ switch (compId) { // LCOV_EXCL_BR_LINE 7:debug code
+ case INI_TERMCOMP_NONE:
+ return "NONE";
+ case INI_TERMCOMP_ACTIVITYMGR:
+ return "ACTIVITYMGR";
+ case INI_TERMCOMP_RESIDENT:
+ return "RESIDENT";
+ case INI_TERMCOMP_TRANSIENT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TRANSIENT";
+ // LCOV_EXCL_STOP
+ case INI_TERMCOMP_TEST0:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST0";
+ // LCOV_EXCL_STOP
+ case INI_TERMCOMP_TEST1:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST1";
+ // LCOV_EXCL_STOP
+ case INI_TERMCOMP_TEST2:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST2";
+ // LCOV_EXCL_STOP
+ case INI_TERMCOMP_TEST3:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "TEST3";
+ // LCOV_EXCL_STOP
+ }
+ return "UNKNONW";
+}
+
+const char*
+tskm_convSvcState2Str(TSKM_SVC_STATE_t state) {
+ switch (state) { // LCOV_EXCL_BR_LINE 7:debug code
+ case TSKM_SVC_DORMANT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "DORMANT";
+ // LCOV_EXCL_STOP
+ case TSKM_SVC_WAITCONNECT:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "WAITCONNECT";
+ // LCOV_EXCL_STOP
+ case TSKM_SVC_WAKEUP:
+ return "WAKEUP";
+ case TSKM_SVC_RUNNING:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "RUNNING";
+ // LCOV_EXCL_STOP
+ case TSKM_SVC_DOWN:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "DOWN";
+ // LCOV_EXCL_STOP
+ case TSKM_SVC_FINDOWN:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "FINDOWN";
+ // LCOV_EXCL_STOP
+ case TSKM_SVC_DISABLE:
+ // LCOV_EXCL_START 7:debug code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return "DISABLE";
+ // LCOV_EXCL_STOP
+ default:
+ break;
+ }
+ return "UNKNONW";
+}
+
+TSKM_STATIC void svcDump(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "<%s>", p_svc->attr->name);
+ TSKM_PRINTF(TSKM_LOG_STATE, " pid:%d svcId:%#x state:%s waitResCnt:%d",
+ p_svc->pid, p_svc->attr->svcId,
+ tskm_convSvcState2Str(p_svc->state), p_svc->waitResCnt);
+}
+
+void tskm_svcsDump(TSKM_SVCS_CTX_t* p_svcs) {
+ uint32_t ii;
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ svcDump(&p_svcs->svcList[ii]);
+ }
+}
+
diff --git a/task_manager/server/src/tskm_main.cpp b/task_manager/server/src/tskm_main.cpp
new file mode 100644
index 00000000..66a0b296
--- /dev/null
+++ b/task_manager/server/src/tskm_main.cpp
@@ -0,0 +1,727 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_main.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/inotify.h>
+#include <getopt.h>
+#include <system_service/ss_services.h>
+#include <native_service/ns_version_if.h>
+#include <native_service/ns_np_service_protocol.h>
+#include <system_service/ss_system_if.h>
+#include <system_service/ss_version.h>
+#include <system_service/ss_templates.h>
+#include <native_service/frameworkunified_dispatcher.h>
+#include <other_service/rpc.h>
+#include <system_service/resm.h>
+
+#include "tskm_data_init_local.h"
+#include "tskm_port_pf.h"
+#include "tskm_port_subsys.h"
+#include "tskm_debug.h"
+#include "tskm_util.h"
+#include "tskm_srvr.h"
+#include "tskm_comm.h"
+#include "tskm_watch.h"
+#include "system_service/tskm_local_type.h"
+#include "system_service/tskm_xml_data.h"
+#include "tskm_state.h"
+
+#define TSKM_DATA_KEY "TSKM_KEY"
+
+TSKM_STATIC TSKM_MAIN_CTX_t g_mainCtx; // Main context
+
+TSKM_STATIC BOOL s_isVupMode = FALSE;
+
+CFrameworkunifiedVersion g_FrameworkunifiedVersion(MAJORNO, MINORNO, REVISION);
+
+// For NsLog
+FRAMEWORKUNIFIEDLOGPARAM g_FrameworkunifiedLogParams = {
+FRAMEWORKUNIFIEDLOGOPTIONS, {
+ZONE_TEXT_10, ZONE_TEXT_11, ZONE_TEXT_12,
+ZONE_TEXT_13, ZONE_TEXT_14, ZONE_TEXT_15,
+ZONE_TEXT_16, ZONE_TEXT_17, ZONE_TEXT_18,
+ZONE_TEXT_19, ZONE_TEXT_20, ZONE_TEXT_21,
+ZONE_TEXT_22, ZONE_TEXT_23, ZONE_TEXT_24,
+ZONE_TEXT_25, ZONE_TEXT_26, ZONE_TEXT_27,
+ZONE_TEXT_28, ZONE_TEXT_29, ZONE_TEXT_30,
+ZONE_TEXT_31 }, FRAMEWORKUNIFIEDLOGZONES };
+
+EFrameworkunifiedStatus OnFinishLoadFile(HANDLE hApp) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+
+ int ret;
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+ TSKM_EVENT_INFO_t ev;
+
+ ret = tskm_pf_nvFileRead(hApp, &p_main->nvInfo);
+ if (ret != 0) {
+ TSKM_ASSERT(0);
+ }
+
+ // issure INI_INITCOMP_NVM_ACCESS
+ bzero(&ev, sizeof(ev));
+ ev.event = TSKM_EV_PRI_REP_WAKEUP_COMP;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.repWakeupComp.compId = INI_INITCOMP_NVM_ACCESS;
+ tskm_handleEvent(p_main, &ev);
+
+ return l_eStatus;
+}
+// LCOV_EXCL_STOP
+
+EFrameworkunifiedStatus onDataInitRequest(HANDLE hApp) {
+ TSKM_ERR_t l_tskmRet = TSKM_E_OK;
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+
+ TSKM_PRINTF(TSKM_LOG_API, "%s()", __FUNCTION__)
+
+ if (p_main->bootInfo.startupReason == epswfINVALID) {
+ // Before issuing FrameworkunifiedOnStart = Requests before TaskManager became Availabile are not accepted
+ TSKM_ASSERT(0);
+ l_tskmRet = TSKM_E_STATE;
+ } else {
+ T_SS_SM_START_DataStructType bootInfo(epswfIGN_ACC, TRUE,
+ e_SS_SM_DATA_RESET_MODE_USER,
+ epsssUNLOCK, epsstWARMSTART,
+ e_SS_SM_DRAM_BACKUP_OK,
+ e_SS_SM_RESET_STATUS_NONE, 0);
+
+ T_SS_SM_START_ExtDataStructType extBootInfo;
+
+ memcpy(&extBootInfo, &p_main->extBootInfo, sizeof(extBootInfo));
+
+ // After updating the program,
+ // FALSE is notified here because it is notified when data initialization I/F is called at startup
+ extBootInfo.isProgUpdated = FALSE;
+
+ tskm_dataInitAll(&bootInfo, &extBootInfo);
+ }
+
+ PCSTR l_senderName = FrameworkunifiedGetMsgSrc(hApp);
+ if (NULL != l_senderName) {
+ HANDLE hSession = FrameworkunifiedMcOpenSender(hApp, l_senderName);
+ if (hSession == NULL) {
+ TSKM_ASSERT(0);
+ } else {
+ TSKM_ASSERT(
+ eFrameworkunifiedStatusOK
+ == FrameworkunifiedSendMsg(hSession, TSKM_DATAINIT_RESP, sizeof(l_tskmRet),
+ &l_tskmRet));
+ TSKM_ASSERT(eFrameworkunifiedStatusOK == FrameworkunifiedMcClose(hSession));
+ }
+ }
+
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus onTransStepRequest(HANDLE hApp) { // LCOV_EXCL_START 6:Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+
+ TSKM_EVENT_INFO_t ev;
+ bzero(&ev, sizeof(ev));
+
+ ev.event = TSKM_EV_LCL_REQ_TRANS_STEP;
+ ev.errCode = TSKM_E_OK;
+ tskm_handleEvent(p_main, &ev);
+
+ return l_eStatus;
+}
+// LCOV_EXCL_STOP
+
+EFrameworkunifiedStatus OnResmAvailability(HANDLE hApp) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+
+ if (0 != strcmp(NTFY_ResourceMgr_Availability, FrameworkunifiedGetLastNotification(hApp))) {
+ TSKM_ASSERT(0);
+ } else if (FrameworkunifiedIsServiceAvailable(hApp)) {
+ // Availability = TRUE
+
+ p_main->resmFd = tskm_sub_resmInit();
+ if (-1 == p_main->resmFd) {
+ TSKM_ASSERT(0);
+ }
+ }
+ return eFrameworkunifiedStatusOK;
+}
+// LCOV_EXCL_STOP
+
+//************ NS Framework Callback : must implemet ******************
+EFrameworkunifiedStatus FrameworkunifiedOnInitialization(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ TSKM_PRINTF(TSKM_LOG_STATE, "+");
+
+ l_eStatus = FrameworkunifiedRegisterServiceAvailabilityNotification(hApp, NTFY_SS_TaskManager_Availability);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ l_eStatus = FrameworkunifiedPublishServiceAvailability(hApp, FALSE);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ l_eStatus = FrameworkunifiedAttachCallbackToDispatcher(hApp, FRAMEWORKUNIFIED_NS_NPSERVICE,
+ NPS_GET_PERS_FILE_ACK,
+ OnFinishLoadFile);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ l_eStatus = FrameworkunifiedAttachCallbackToDispatcher(hApp, FRAMEWORKUNIFIED_ANY_SOURCE,
+ TSKM_DATAINIT_REQ,
+ onDataInitRequest);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ l_eStatus = FrameworkunifiedAttachCallbackToDispatcher(hApp, FrameworkunifiedGetAppName(hApp),
+ TSKM_TRANS_STEP_REQ,
+ onTransStepRequest);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ l_eStatus = FrameworkunifiedSubscribeNotificationWithCallback(hApp, NTFY_ResourceMgr_Availability, OnResmAvailability);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "-");
+
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnStart(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ TSKM_PRINTF(TSKM_LOG_STATE, "+");
+ l_eStatus = OnStart(hApp);
+ TSKM_PRINTF(TSKM_LOG_STATE, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnPreStart(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ TSKM_PRINTF(TSKM_LOG_STATE, "+");
+ l_eStatus = OnStart(hApp);
+ TSKM_PRINTF(TSKM_LOG_STATE, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStart(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ TSKM_PRINTF(TSKM_LOG_STATE, "+");
+ l_eStatus = OnStart(hApp);
+ TSKM_PRINTF(TSKM_LOG_STATE, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnStop(HANDLE hApp) {
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+ // Returns Fail to send asynchronous STOP reply to SM
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
+
+ TSKM_EVENT_INFO_t ev;
+ bzero(&ev, sizeof(ev));
+
+ ev.event = TSKM_EV_LCL_REQ_STOP;
+ ev.errCode = TSKM_E_OK;
+ tskm_handleEvent(p_main, &ev);
+
+ p_main->isOnStopDone = TSKM_TRUE;
+
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnPreStop(HANDLE hApp) {
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return eFrameworkunifiedStatusOK;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStop(HANDLE hApp) {
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return eFrameworkunifiedStatusOK;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnDestroy(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedOnDebugDump(HANDLE hApp) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+ TSKM_ERR_t l_tskmRet;
+
+ // Call DebugDump of all running SVCs
+ l_tskmRet = tskm_svcsCallDebugDump(&p_main->svcs);
+ if (TSKM_E_OK != l_tskmRet) {
+ TSKM_ASSERT(0);
+ }
+
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+
+EFrameworkunifiedStatus FrameworkunifiedCreateStateMachine(HANDLE hApp) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
+ FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
+ return l_eStatus;
+}
+// LCOV_EXCL_STOP
+
+/*********************************************************
+ * System start process
+ *********************************************************/
+EFrameworkunifiedStatus OnStart(const HANDLE hApp) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "+");
+ TSKM_MAIN_CTX_t* const p_main = &g_mainCtx;
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+
+ if (p_main->isOnStartDone == TSKM_FALSE) {
+ T_SS_SM_START_DataStructType startupInfo;
+ TSKM_EVENT_INFO_t ev;
+ l_eStatus = ReadMsg<T_SS_SM_START_DataStructType>(hApp, startupInfo);
+ if (l_eStatus != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT(0);
+ } else {
+ memcpy(&p_main->bootInfo, &startupInfo, sizeof(T_SS_SM_START_DataStructType));
+ }
+
+ if (0 != tskm_sub_getExtBootInfo(&p_main->extBootInfo)) {
+ TSKM_ASSERT(0);
+ }
+
+ tskm_dataInitAll(&p_main->bootInfo, &p_main->extBootInfo);
+
+ tskm_svcsSetBootInfo(&p_main->svcs, &p_main->bootInfo, &p_main->extBootInfo);
+ p_main->isOnStartDone = TSKM_TRUE;
+
+ l_eStatus = FrameworkunifiedPublishServiceAvailability(hApp, TRUE);
+ if (l_eStatus != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT(0);
+ } else {
+ TSKM_PRINTF(TSKM_LOG_STATE, "Availability TRUE");
+ }
+
+ // Issure INI_INITCOMP_ON_START
+ bzero(&ev, sizeof(ev));
+ ev.event = TSKM_EV_PRI_REP_WAKEUP_COMP;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.repWakeupComp.compId = INI_INITCOMP_ON_START;
+ tskm_handleEvent(p_main, &ev);
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "-");
+ return l_eStatus;
+}
+
+/*********************************************************
+ * Argument analysis process
+ *********************************************************/
+TSKM_STATIC EFrameworkunifiedStatus argParser(SI_32 argument, PCHAR argumentValue) { // LCOV_EXCL_START 6: for process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if ('v' == argument) {
+ s_isVupMode = TRUE;
+ }
+
+ return eFrameworkunifiedStatusOK;
+}
+// LCOV_EXCL_STOP
+/*********************************************************
+ * Creating process for TSKM internal context
+ *********************************************************/
+TSKM_STATIC void ctxCreate(TSKM_MAIN_CTX_t* p_main, int argc, char* argv[]) {
+ int ret;
+ EFrameworkunifiedStatus taskmanagerRet;
+ TSKM_ERR_t tskmRet;
+ FrameworkunifiedDefaultCallbackHandler cbFuncs;
+ FRAMEWORKUNIFIED_MAKE_DEFAULT_CALLBACK(cbFuncs);
+ CustomCommandLineOptions cmdLineOpt = { "v", NULL, argParser };
+
+ p_main->state = TSKM_ST_ACCOFF;
+ p_main->isOnStartDone = TSKM_FALSE;
+
+ // Create dispatcher
+ taskmanagerRet = FrameworkunifiedCreateDispatcherWithoutLoop(SS_TASK_MANAGER, p_main->hApp, argc,
+ argv, &cbFuncs, TRUE, &cmdLineOpt);
+ if (eFrameworkunifiedStatusOK != taskmanagerRet) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "s_isVupMode :%s", s_isVupMode ? "TRUE" : "FALSE");
+
+ taskmanagerRet = FrameworkunifiedGetDispatcherFD(p_main->hApp, &p_main->nsFd);
+ if (taskmanagerRet != eFrameworkunifiedStatusOK) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_PRINT(0, "%d", taskmanagerRet);
+ exit(EXIT_FAILURE);
+ // LCOV_EXCL_STOP
+ }
+
+ p_main->sigFd = tskm_pf_sysInit(); // Platform initialization
+ if (p_main->sigFd == -1) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_LINE 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ p_main->iFd = inotify_init1(IN_CLOEXEC);
+ if (p_main->sigFd == -1) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_LINE 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ // Obtain RESM FDs after waiting for Availability
+ p_main->resmFd = -1;
+
+ tskmRet = tskm_srvSockCreate(TSKM_SOCKET_NAME, &p_main->sock);
+ TSKM_ERR_CHK(tskmRet, TSKM_E_OK, ERROR); // LCOV_EXCL_BR_LINE 6: For process initialization processing
+
+ ret = tskm_pf_nvFileInit(p_main->hApp);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ ret = tskm_initServiceList(&p_main->svcs, p_main->iFd); // Service to be started
+ if (0 != ret) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For For process initialization process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ tskm_initWakeupCtx(&p_main->wakeup, s_isVupMode); // Gradual startup info
+ tskm_initDownCtx(&p_main->down, s_isVupMode); // Gradual termination info
+ return;
+
+ // LCOV_EXCL_START 6: For process initialization processing
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_exit(EXIT_FAILURE);
+ return;
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************************
+ * Get main context
+ *********************************************************/
+TSKM_MAIN_CTX_t*
+tskm_getMainCtx(void) {
+ return &g_mainCtx;
+}
+
+/*********************************************************
+ * Process initialization process (MAIN function sub)
+ *********************************************************/
+int Init_Process(int* rpcFd, int* sockFd, int* maxFd, fd_set* fds, TSKM_MAIN_CTX_t* p_main) {
+ int ret;
+ uint32_t ii;
+
+ TSKM_SRV_CONNENT_LIST_t* p_connList = &p_main->sock.connList;
+
+ FD_ZERO(fds);
+
+ FD_SET(*rpcFd, fds);
+ *maxFd = TSKM_MAX(*rpcFd, *maxFd); // LCOV_EXCL_BR_LINE 6: For process initialization processing
+
+ FD_SET(*sockFd, fds);
+ *maxFd = TSKM_MAX(*sockFd, *maxFd); // LCOV_EXCL_BR_LINE 6: For process initialization processing
+
+ FD_SET(p_main->nsFd, fds);
+ *maxFd = TSKM_MAX(p_main->nsFd, *maxFd); // LCOV_EXCL_BR_LINE 6: For process initialization processing
+
+ FD_SET(p_main->sigFd, fds);
+ *maxFd = TSKM_MAX(p_main->sigFd, *maxFd); // LCOV_EXCL_BR_LINE 6: For process initialization processing
+
+ if (-1 != p_main->resmFd) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ FD_SET(p_main->resmFd, fds);
+ *maxFd = TSKM_MAX(p_main->resmFd, *maxFd);
+ // LCOV_EXCL_STOP
+ }
+
+ for (ii = 0; ii < p_connList->num; ii++) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ // LCOV_EXCL_START 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_SRV_CONNENT_t* p_conn = &p_connList->conn[ii];
+ FD_SET(p_conn->connFd, fds);
+ *maxFd = TSKM_MAX(p_conn->connFd, *maxFd);
+ // LCOV_EXCL_STOP
+ }
+
+ TSKM_PRINTF(TSKM_LOG_FUNC, "SELECT IN");
+ ret = select(*maxFd + 1, fds, NULL, NULL, NULL);
+ if (ret < 1) {
+ if (errno != EINTR) {
+ TSKM_ASSERT(0);
+ }
+ return ret;
+ }
+ TSKM_PRINTF(TSKM_LOG_FUNC, "SELECT OUT");
+ return 0;
+}
+
+/*********************************************************
+ * Receiving Messages from CONNECT Clients (MAIN Functions Sub)
+ *********************************************************/
+void Recv_Msg_FromConnectClient(fd_set* fds, TSKM_MAIN_CTX_t* p_main) {
+ uint32_t ii;
+ TSKM_SRV_CONNENT_LIST_t* p_connList = &p_main->sock.connList;
+
+ // Messages from CONNECT clients
+ for (ii = 0; ii < p_connList->num; ii++) {
+ TSKM_SRV_CONNENT_t* p_conn = &p_connList->conn[ii];
+ if (FD_ISSET(p_conn->connFd, fds)) {
+ TSKM_PRINTF(TSKM_LOG_FUNC, "connFd IN");
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+ ret = tskm_sockRcv(p_conn->connFd, &ev);
+
+ if (ret < 0) {
+ TSKM_ASSERT(0);
+ } else {
+ TSKM_SVC_CTX_t* p_svc;
+
+ if (ret == 0) {
+ // Closed Connection
+ TSKM_PRINTF(TSKM_LOG_STATE, "DISSCON pid:%d", p_conn->pid);
+ ev.event = TSKM_EV_PRI_REP_DISCONNECT;
+ ev.errCode = TSKM_E_OK;
+ ev.fromPid = p_conn->pid;
+ tskm_srvSockDisconnect(&p_main->sock, p_conn);
+ p_conn = NULL; // If the connection is lost, it cannot be referenced.
+ }
+
+ p_svc = tskm_svcsGetSvcByPid(&p_main->svcs, ev.fromPid);
+ if (p_svc) { // Events from service
+ TSKM_ERR_t tskmRet;
+ tskmRet = tskm_svcEventHandle(p_svc, &ev); // Service handler
+ if (tskmRet != TSKM_E_OK) {
+ TSKM_ASSERT(0);
+ }
+ }
+ if (ev.event != TSKM_EV_NOP) {
+ tskm_handleEvent(p_main, &ev); // Main handler
+ }
+ }
+ TSKM_PRINTF(TSKM_LOG_FUNC, "connFd OUT");
+ }
+ }
+}
+
+/*********************************************************
+ * CONNECT Requests (MAIN Functions Sub)
+ *********************************************************/
+void Recv_Req_Connect(fd_set* fds, TSKM_MAIN_CTX_t* p_main, int sockFd) {
+ // CONNECT requests
+ if (FD_ISSET(sockFd, fds)) {
+ TSKM_PRINTF(TSKM_LOG_FUNC, "sockFd IN");
+
+ TSKM_SRV_CONNENT_t* conn;
+ conn = tskm_srvSockConnect(&p_main->sock);
+ if (conn == NULL) {
+ TSKM_ASSERT(0);
+ } else {
+ TSKM_SVC_CTX_t* p_svc;
+ TSKM_PRINTF(TSKM_LOG_STATE, "CONNECT pid:%d", conn->pid);
+
+ p_svc = tskm_svcsGetSvcByPid(&p_main->svcs, conn->pid);
+ if (p_svc) {
+ TSKM_ERR_t tskmRet;
+ TSKM_EVENT_INFO_t ev;
+
+ ev.event = TSKM_EV_PRI_REP_CONNECT;
+ ev.errCode = TSKM_E_OK;
+ ev.fromPid = conn->pid;
+ ev.prm.repConnect.connFd = conn->connFd;
+
+ tskmRet = tskm_svcEventHandle(p_svc, &ev); // Service handler
+ if (tskmRet != TSKM_E_OK) {
+ TSKM_ASSERT(0);
+ } else if (ev.event != TSKM_EV_NOP) {
+ tskm_handleEvent(p_main, &ev); // Main hander
+ }
+ }
+ }
+ TSKM_PRINTF(TSKM_LOG_FUNC, "sockFd OUT");
+ }
+}
+
+/*********************************************************
+ * MAIN Function
+ *********************************************************/
+int main(int argc, char* argv[]) {
+ RPC_ID rpcId = TSKM_RPC_ID;
+ int rpcFd = 0;
+ int maxFd = 0;
+ int ret;
+ fd_set fds;
+ TSKM_MAIN_CTX_t* p_main = &g_mainCtx;
+
+ // Logging setting
+ FRAMEWORKUNIFIED_SET_ZONES();
+
+ ctxCreate(p_main, argc, argv); // Initialize context
+
+ tskm_sub_init(); // Initialize sub systems
+
+ RPC_START_SECURE_SERVER(rpcId);
+ RPC_get_fd(rpcId, &rpcFd);
+
+ uid_t uid[2];
+ gid_t gid[2];
+
+ uid[0] = 0;
+ gid[0] = 0;
+ uid[1] = getuid();
+ gid[1] = getgid();
+
+ if (RPC_OK != RPC_regist_credential(2, uid, 2, gid)) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For process initialization processing
+ }
+
+ // Start periodic timer thread
+ ret = tskm_watch_startTimer();
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For process initialization processing
+ }
+
+ tskm_stateTransit(p_main, TSKM_ST_ACCOFF, TSKM_ST_ACCON);
+
+ p_main->isExec = TSKM_TRUE;
+ while (p_main->isExec) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ int sockFd = p_main->sock.sockFd;
+
+ // Initialization processing
+ if (Init_Process(&rpcFd, &sockFd, &maxFd, &fds, p_main) != 0) { // LCOV_EXCL_BR_LINE 6: For process initialization processing
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ continue; // LCOV_EXCL_LINE 6: For process initialization processing
+ }
+
+ // RPC API
+ if (FD_ISSET(rpcFd, &fds)) {
+ RPC_process_API_request(rpcId);
+ }
+
+ // Process termination signal
+ if (FD_ISSET(p_main->sigFd, &fds)) {
+ int count = 0;
+
+ do {
+ TSKM_EVENT_INFO_t ev;
+ ev.event = TSKM_EV_SVC_REP_TERM;
+
+ count++;
+
+ ret = tskm_pf_cleanupProc(p_main->sigFd, &ev.fromPid, &ev.errCode);
+ if (ret == -1) {
+ TSKM_ASSERT(0);
+ break;
+ }
+
+ TSKM_SVC_CTX_t* p_svc;
+
+ p_svc = tskm_svcsGetSvcByPid(&p_main->svcs, ev.fromPid);
+ if (p_svc) {
+ TSKM_ERR_t tskmRet;
+
+ tskmRet = tskm_svcEventHandle(p_svc, &ev); // Service handler
+ if (tskmRet != TSKM_E_OK) {
+ TSKM_ASSERT(0);
+ }
+ if (ev.event != TSKM_EV_NOP) {
+ tskm_handleEvent(p_main, &ev); // Main handler
+ }
+ }
+ } while (ret == 1 && count < 50);
+ }
+
+ if (FD_ISSET(p_main->nsFd, &fds)) {
+ FrameworkunifiedDispatchProcessWithoutLoop(p_main->hApp);
+ }
+
+ // EV from RESM
+ if (-1 != p_main->resmFd) {
+ if (FD_ISSET(p_main->resmFd, &fds)) {
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+ ret = tskm_sub_resmRcv(&ev);
+
+ if (-1 == ret) {
+ TSKM_ASSERT(0);
+ } else {
+ tskm_handleEvent(p_main, &ev);
+ }
+ }
+ }
+
+ // Messages from connected clients
+ Recv_Msg_FromConnectClient(&fds, p_main);
+
+ // CONNECT request
+ Recv_Req_Connect(&fds, p_main, sockFd);
+ }
+
+ tskm_srvSockDestory(&p_main->sock);
+
+ RPC_end(rpcId);
+
+ FrameworkunifiedDestroyDispatcherWithoutLoop(p_main->hApp);
+ TSKM_PRINTF(TSKM_LOG_STATE, "tskm end");
+
+ sleep(TSKM_CFG_WAIT_SHUTDOWN);
+ return 0;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_port_pf.cpp b/task_manager/server/src/tskm_port_pf.cpp
new file mode 100644
index 00000000..72a52dd2
--- /dev/null
+++ b/task_manager/server/src/tskm_port_pf.cpp
@@ -0,0 +1,884 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_port_pf.h"
+#include <pthread.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <native_service/cl_process.h>
+#include <native_service/cl_monitor.h>
+#include <system_service/ss_services.h>
+#include <system_service/ss_sm_client_if.h>
+
+#include "system_service/tskm_svc.h"
+#include "tskm_debug.h"
+
+#define TSKM_PORTPF_IN() TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:IN", __FUNCTION__)
+#define TSKM_PORTPF_IN_ARG(format, ...) TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:IN:" format, __FUNCTION__, __VA_ARGS__)
+#define TSKM_PORTPF_OUT() TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:OUT", __FUNCTION__)
+
+#define TSKM_PRIO_MIN 1
+#define TSKM_PRIO_MAX 99
+#define TSKM_PRIO_MIN_TSS -20
+#define TSKM_PRIO_MAX_TSS 19
+
+#define TSKM_TMP_DIRECTORY "/tmp"
+#define TSKM_TMP_TSKM_DIRECTORY TSKM_TMP_DIRECTORY "/tskm"
+#define TSKM_TMP_NV_INFO_FILEPATH TSKM_TMP_TSKM_DIRECTORY "/nvInfo"
+
+#define TSKM_NPP_NV_FILE_TAG SS_TASK_MANAGER "/nvInfo"
+
+/*********************************************************
+ * user->uid/gid conversion
+ *********************************************************/
+TSKM_STATIC int cnvUserName2UidGid(const char *user, uid_t *uid, gid_t *gid) {
+ int ret = -1;
+
+ if (0 == strcmp(user, "")) {
+ *uid = geteuid();
+ *gid = getegid();
+ } else {
+ static __thread size_t bufSize = 0;
+ static __thread char *buf = NULL;
+ struct passwd pwd;
+ struct passwd *result;
+
+ if (0 == bufSize) {
+ struct stat statInfo;
+
+ bufSize = -1;
+
+ if (0 != stat("/etc/passwd", &statInfo) || 0 >= statInfo.st_size) { // LCOV_EXCL_START 8: Because buf is a static variable and cannot be passed test
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ // LCOV_EXCL_STOP
+
+ bufSize = statInfo.st_size * 2;
+
+ // Since TaskManager is a resident service, the area allocated here is expected to be released at process termination and is not explicitly released by free()
+ buf = (char *) malloc(sizeof(char) * bufSize); // NOLINT (runtime/printf)
+ if (NULL == buf) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function malloc
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Error branching of the standard-function malloc
+ goto ERROR; // LCOV_EXCL_LINE 5: Error branching of the standard-function malloc
+ }
+ }
+
+ if (NULL == buf) { // LCOV_EXCL_BR_LINE 8: Because buf is a static variable and cannot be passed test
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 8: Because buf is a static variable and cannot be passed test
+ goto ERROR; // LCOV_EXCL_LINE 8: Because buf is a static variable and cannot be passed test
+ }
+
+ ret = getpwnam_r(user, &pwd, buf, bufSize, &result);
+ if (ret != 0 || result == NULL) {
+ TSKM_ASSERT_PRINT(0, "ret = %d[%s]", ret, user);
+ goto ERROR;
+ }
+
+ *uid = pwd.pw_uid;
+ *gid = pwd.pw_gid;
+ }
+
+ ret = 0;
+
+ ERROR:
+
+ return ret;
+}
+
+/*********************************************************
+ * Convert Scheduling Policy Definitions Values (TSKM -> CL)
+ *********************************************************/
+TSKM_STATIC CL_ProcessSchedPolicy_t cnvTskmPolicy2ClPolicy(
+ TSKM_SVC_POLICY_t policy) {
+ switch (policy) {
+ case TSKM_SVC_POLICY_FIFO:
+ return CL_PROCESS_SCHED_POLICY_FIFO;
+ case TSKM_SVC_POLICY_TSS:
+ return CL_PROCESS_SCHED_POLICY_OTHER;
+ case TSKM_SVC_POLICY_RR:
+ return CL_PROCESS_SCHED_POLICY_RR;
+ default:
+ TSKM_ASSERT(0);
+ break;
+ }
+ return CL_PROCESS_SCHED_POLICY_OTHER;
+}
+
+/*********************************************************
+ * Process priority valid value determination
+ *********************************************************/
+TSKM_STATIC int chkPrioValue(TSKM_SVC_POLICY_t policy, int prio) {
+ switch (policy) {
+ case TSKM_SVC_POLICY_FIFO:
+ case TSKM_SVC_POLICY_RR:
+ if ((TSKM_PRIO_MIN > prio) || (prio > TSKM_PRIO_MAX)) {
+ TSKM_ASSERT(0);
+ }
+ break;
+ case TSKM_SVC_POLICY_TSS:
+ default:
+ if ((TSKM_PRIO_MIN_TSS > prio) || (prio > TSKM_PRIO_MAX_TSS)) {
+ TSKM_ASSERT(0);
+ }
+ break;
+ }
+
+ return prio;
+}
+
+/*********************************************************
+ * COMMONLIB initialization (at system startup)
+ *********************************************************/
+int tskm_pf_sysInit() {
+ int fd = 0;
+ int ret = 0;
+
+ TSKM_PORTPF_IN();
+
+ fd = CL_ProcessInit();
+ if (fd == -1) { // LCOV_EXCL_BR_LINE 6: Error branching during process initialization
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: Error branching during process initialization
+ goto ERROR; // LCOV_EXCL_LINE 6: Error branching during process initialization
+ }
+
+ ret = CL_MonitorInit(CL_MONITOR_INIT_USER);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ TSKM_ASSERT_ERRNO(0);
+ }
+
+ TSKM_PORTPF_OUT();
+ return fd;
+ // LCOV_EXCL_START 6: Error branching during process initialization
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return -1;
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************************
+ * COMMONLIB initialization (at process startup)
+ *********************************************************/
+int tskm_pf_procInit() {
+ TSKM_PORTPF_IN();
+ // Originally called the _sys_Setup_CWORD64_API (NULL), but changed to empty function along to derete "_sys"
+
+ TSKM_PORTPF_OUT();
+ return 0;
+}
+
+/*********************************************************
+ * Process startup
+ *********************************************************/
+pid_t tskm_pf_createProc(TSKM_SVC_ATTR_t* p_svcAttr) {
+ TSKM_PORTPF_IN();
+ pid_t retPid = -1;
+ pid_t pid = -1;
+
+ CL_ProcessAttr_t attr;
+ char procPath[255];
+ char* procName;
+ uid_t setUid = 0;
+ gid_t setGid = 0;
+
+ if (0 != CL_ProcessCreateAttrInit(&attr)) { // LCOV_EXCL_BR_LINE 6: Error branching during process initialization
+ // LCOV_EXCL_START 6: Error branching during process initialization
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ // Process name setting(from basename)
+ if (strlen(p_svcAttr->path) < sizeof(procPath)) {
+ strcpy(procPath, p_svcAttr->path); // NOLINT (runtime/printf)
+ } else {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ procName = basename(procPath);
+ if (strlen(procName) >= 16) {
+ TSKM_ASSERT(0);
+ procName[16] = '\0';
+ }
+
+ if (0 != CL_ProcessCreateAttrSetName(&attr, procName)) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ // LCOV_EXCL_START 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (0 != cnvUserName2UidGid(p_svcAttr->user, &setUid, &setGid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ // LCOV_EXCL_START 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ setUid = geteuid();
+ setGid = getegid();
+ // LCOV_EXCL_STOP
+ }
+
+ if (0 != CL_ProcessCreateAttrSetUid(&attr, setUid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ // LCOV_EXCL_START 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (0 != CL_ProcessCreateAttrSetGid(&attr, setGid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ // LCOV_EXCL_START 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ // All are group leaders in order to recover to the child processes of the service
+ if (0 != CL_ProcessCreateAttrSetGroup(&attr, 1)) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ // LCOV_EXCL_START 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ if (0 != CL_ProcessCreateAttrSetCpuAssign(&attr, p_svcAttr->cpuAssign)) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ if (0
+ != CL_ProcessCreateAttrSetSchedule(
+ &attr, cnvTskmPolicy2ClPolicy(p_svcAttr->policy),
+ chkPrioValue(p_svcAttr->policy, p_svcAttr->prio))) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ pid = CL_ProcessCreate(p_svcAttr->path, p_svcAttr->args, NULL, &attr);
+ if (pid == -1) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ retPid = pid;
+ ERROR:
+
+ TSKM_PORTPF_OUT();
+ return retPid;
+}
+
+/*********************************************************
+ * Recover termination processes
+ *********************************************************/
+int tskm_pf_cleanupProc(int sigFd, pid_t* p_pid, TSKM_ERR_t* p_err) {
+ int ret;
+ CL_ProcessCleanupInfo_t info;
+
+ ret = CL_ProcessCleanup(sigFd, &info);
+ if (ret != 0 && ret != 1) {
+ TSKM_ASSERT_PRINT(0, "ret = %d", ret);
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "SVC TERM:pid:%d code:%d status:%d", info.pid,
+ info.code, info.status);
+
+ switch (info.code) {
+ case CLD_STOPPED:
+ // Not comes here usually
+ TSKM_PRINTF(TSKM_LOG_STATE, "svc stoped\n");
+ goto ERROR;
+ case CLD_TRAPPED:
+ // Comes here only during debugging
+ TSKM_PRINTF(TSKM_LOG_STATE, "svc traped\n");
+ goto ERROR;
+ case CLD_CONTINUED:
+ // Not comes here usually
+ TSKM_PRINTF(TSKM_LOG_STATE, "svc continue\n");
+ goto ERROR;
+ default:
+ break;
+ }
+
+ *p_pid = info.pid;
+ *p_err =
+ (info.code != CLD_EXITED) ? TSKM_E_NG :
+ (info.code == CLD_EXITED && info.status != EXIT_SUCCESS) ?
+ TSKM_E_NG : TSKM_E_OK;
+
+ if (TSKM_E_OK != *p_err) {
+ TSKM_PRINTF(TSKM_LOG_SYSTEMDATA, "SVC ERR TERM:pid:%d code:%d status:%d",
+ info.pid, info.code, info.status);
+ }
+
+ return ret;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Force Terminating a Process Group
+ *********************************************************/
+int tskm_pf_terminateProcGroup(uint16_t pid) {
+ int ret;
+ pid_t pgid;
+
+ pgid = getpgid(pid);
+ if (pgid < 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "TERM SVC GROUP:pid:%dpgid:%d", pid, pgid);
+
+ ret = CL_ProcessEuthanizeGroup(pgid);
+ if (ret != 0) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ return 0;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Opening shared memory and trancating
+ *********************************************************/
+int tskm_pf_shmCreate_Open_Ftrn(const char* name, int32_t size, void** p_addr) {
+ int ret = 0;
+ int fd = 0;
+
+ fd = shm_open(name, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
+ if (fd == -1) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ ret = -1; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ if (fd > 0) { // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ TSKM_ASSERT_ERRNO(close(fd) == 0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ } // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ return ret; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ }
+
+ ret = ftruncate(fd, size);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ if (fd > 0) { // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ TSKM_ASSERT_ERRNO(close(fd) == 0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ } // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ return ret; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded.
+ }
+
+ if (p_addr) { // LCOV_EXCL_BR_LINE 8: Because p_addr is set to NULL only
+ // LCOV_EXCL_START 8: Because p_addr is set to NULL only
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ // Not supported
+ TSKM_ASSERT_ERRNO(0);
+ ret = -1;
+ if (fd > 0) {
+ TSKM_ASSERT_ERRNO(close(fd) == 0);
+ }
+ return ret;
+ // LCOV_EXCL_STOP
+ }
+
+ ret = 0;
+ if (fd > 0) {
+ TSKM_ASSERT_ERRNO(close(fd) == 0);
+ }
+ return ret;
+}
+
+/*********************************************************
+ * Creating shared memory
+ *********************************************************/
+int tskm_pf_shmCreate(const char* name, int32_t size, void** p_addr) {
+ TSKM_PORTPF_IN_ARG("%s,%d", name, size);
+ struct stat statInfo;
+ int ret = -1;
+
+ if (stat(name, &statInfo) == 0) {
+ TSKM_ASSERT_PRINT(0, "Already Exist %s", name);
+ ret = 0; // To be Succeeded
+ TSKM_PORTPF_OUT();
+ return ret;
+ }
+
+ ret = tskm_pf_shmCreate_Open_Ftrn(name, size, p_addr);
+
+ TSKM_PORTPF_OUT();
+ return ret;
+}
+
+/*********************************************************
+ * Deleting shared memory
+ *********************************************************/
+int tskm_pf_shmDelete(const char* name) {
+ TSKM_PORTPF_IN_ARG("%s", name);
+ int ret = 0;
+
+ if (0 != shm_unlink(name)) {
+ TSKM_ASSERT_ERRNO(0);
+ }
+
+ TSKM_PORTPF_OUT();
+ return ret;
+}
+
+/*********************************************************
+ * Starting thread
+ *********************************************************/
+int tskm_pf_createThread(void* (*threadFunc)(void*), void* prm,
+ uint32_t priority, const char* threadName,
+ pthread_t* p_thId) {
+ TSKM_PORTPF_IN();
+
+ int ret;
+ CL_ThreadAttr_t cl_attr;
+
+ ret = CL_ThreadCreateAttrInit(&cl_attr);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: For processing initializing process
+ goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process
+ }
+
+ if (threadName) {
+ ret = CL_ThreadCreateAttrSetName(&cl_attr, threadName);
+ TSKM_ASSERT_ERRNO(ret == 0);
+ }
+
+ ret = CL_ThreadCreate(p_thId, NULL, &cl_attr, threadFunc, prm);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: For processing initializing process
+ goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process
+ }
+ int sched_policy;
+ struct sched_param sparam;
+
+ pthread_getschedparam(*p_thId, &sched_policy, &sparam);
+
+ sparam.sched_priority = priority;
+ if ((priority != 0) && (sched_policy == SCHED_OTHER)) {
+ sched_policy = SCHED_FIFO;
+ } else if ((priority == 0) && (sched_policy != SCHED_OTHER)) {
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ sched_policy = SCHED_OTHER; // LCOV_EXCL_LINE 6: For processing initializing process
+ }
+
+ ret = pthread_setschedparam(*p_thId, sched_policy, &sparam);
+ TSKM_ASSERT(ret == 0);
+ TSKM_PORTPF_OUT();
+ return 0;
+ ERROR: return -1;
+}
+/*********************************************************
+ * Send Stop Complete Response
+ *********************************************************/
+int tskm_pf_sendStopCompResp() {
+ EFrameworkunifiedStatus l_eStatus;
+ TSKM_PORTPF_IN();
+
+ l_eStatus = SendInterfaceunifiedOnStopResponseToSystemManager(eFrameworkunifiedStatusOK);
+ if (l_eStatus != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT(0);
+ }
+
+ TSKM_PORTPF_OUT();
+ return 0;
+}
+
+/*********************************************************
+ * ABORT
+ *********************************************************/
+int tskm_pf_abort() {
+ TSKM_PORTPF_IN();
+
+ TSKM_ASSERT(0);
+ sleep(1); // Sleep a little so that the logging at the time of abnormality may be interrupted
+
+ // Issure SIGSEG
+ printf("%d\n", *(int *) 0); // NOLINT (readability/casting)
+
+ TSKM_PORTPF_OUT();
+ return 0;
+}
+
+/*********************************************************
+ * EXIT
+ *********************************************************/
+int tskm_pf_exit(int status) { //LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_PORTPF_IN();
+
+ exit(status);
+
+ TSKM_PORTPF_OUT();
+ return 0;
+}
+// LCOV_EXCL_STOP
+
+/*********************************************************
+ * TOUCH
+ *********************************************************/
+int tskm_pf_touch(char* path) {
+ TSKM_PORTPF_IN();
+ int fd;
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ TSKM_ASSERT_ERRNO(close(fd) == 0);
+ TSKM_PORTPF_OUT();
+ return 0;
+ ERROR:
+ return -1;
+}
+
+/*********************************************************
+ * Touch
+ *********************************************************/
+int tskm_pf_mkTouchFileName(pid_t pid, char name[32]) {
+ TSKM_PORTPF_IN();
+
+ sprintf(name, "/tmp/tskm_touch%d", pid); // NOLINT (runtime/printf)
+
+ TSKM_PORTPF_OUT();
+ return 0;
+}
+
+/*********************************************************
+ * Read file
+ *********************************************************/
+static ssize_t readFile(const char* filePath, void* l_buf, ssize_t bufSize) {
+ int fd = -1;
+ ssize_t readSize, totalReadSize = 0;
+ char *p_buf = (char*) l_buf; // NOLINT (readability/casting)
+ fd = open(filePath, O_RDONLY);
+ if (fd == -1) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ do {
+ readSize = read(fd, p_buf, bufSize);
+ if (readSize == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ } else if (readSize == 0) {
+ break;
+ }
+
+ p_buf += readSize;
+ bufSize -= readSize;
+ totalReadSize += readSize;
+ } while (bufSize > 0);
+
+ ERROR: if (fd != -1) {
+ close(fd);
+ }
+
+ return totalReadSize;
+}
+
+/*********************************************************
+ * Write to file
+ *********************************************************/
+static ssize_t writeFile(const char *filePath, const void* l_buf,
+ ssize_t bufSize) {
+ int ret = -1;
+ int fd = -1;
+
+ const char *p_buf = (const char*) l_buf;
+
+ ssize_t writeSize, totalWriteSize = 0;
+
+ fd = open(filePath, O_RDWR | O_TRUNC | O_CREAT, S_IRWXU);
+ if (fd == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function open()
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Error branching of the standard-function open()
+ goto ERROR; // LCOV_EXCL_LINE 5: Error branching of the standard-function open()
+ }
+
+ do {
+ writeSize = write(fd, p_buf, bufSize);
+ if (writeSize == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write()
+ // LCOV_EXCL_START 5: Error branching of the standard-function write()
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (errno == EINTR) {
+ continue;
+ } else {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ // LCOV_EXCL_STOP
+ } else if (writeSize == 0) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write()
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ break; // LCOV_EXCL_LINE 5: Error branching of the standard-function write()
+ }
+ p_buf += writeSize;
+ bufSize -= writeSize;
+ totalWriteSize += writeSize;
+ } while (bufSize > 0); // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write()
+
+ ret = fsync(fd);
+ if (ret == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function fsync()
+ // LCOV_EXCL_START 5: Error branching of the standard-function fsync()
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ ERROR: if (fd != -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function open()
+ close(fd);
+ }
+
+ return totalWriteSize;
+}
+
+/*********************************************************
+ * Checksum calculation
+ *********************************************************/
+static uint32_t calcCheckSum(const void* p_buf, size_t bufSize) {
+ int ii;
+ int blockNum;
+ uint32_t sum = 0;
+ uint32_t *p_calcBuf = (uint32_t*) p_buf; // NOLINT (readability/casting)
+
+ blockNum = static_cast<int>(bufSize) / static_cast<int>(sizeof(uint32_t));
+
+ for (ii = 0; ii < blockNum; ii++) {
+ sum += p_calcBuf[ii];
+ }
+
+ return sum;
+}
+
+/*********************************************************
+ * Checking files
+ *********************************************************/
+static TSKM_BOOL_t checkFile(const char *filePath) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ uint32_t checkSum;
+ struct stat st;
+ ssize_t readSize;
+ TSKM_NV_INFO_t nvInfo;
+ TSKM_BOOL_t isFileOk = TSKM_FALSE;
+
+ if (stat(filePath, &st) != 0) {
+ goto ERROR;
+ }
+
+ readSize = readFile(filePath, &nvInfo, sizeof(TSKM_NV_INFO_t));
+ if (readSize != sizeof(TSKM_NV_INFO_t)) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ checkSum = calcCheckSum(&nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum));
+
+ if (checkSum != nvInfo.footer.checkSum) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ if (strncmp(nvInfo.header.version, TSKM_NV_STRUCT_VERSION,
+ sizeof(TSKM_NV_STRUCT_VERSION)) != 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ isFileOk = TSKM_TRUE;
+ ERROR: return isFileOk;
+}
+// LCOV_EXCL_STOP
+/*********************************************************
+ * Non-volatile file initialization (Including checksum write)
+ *********************************************************/
+static int initNvFile() {
+ int ii;
+ ssize_t writeSize;
+ TSKM_NV_INFO_t nvInfo;
+
+ TSKM_STATIC_ASSERT(sizeof(TSKM_NV_INFO_t) == TSKM_NV_SIZE_ALL);
+ TSKM_STATIC_ASSERT(
+ offsetof(TSKM_NV_INFO_t, footer.checkSum) % sizeof(uint32_t) == 0);
+
+ memset(&nvInfo, 0, sizeof(TSKM_NV_INFO_t));
+ sprintf(nvInfo.header.version, TSKM_NV_STRUCT_VERSION); // NOLINT (readability/casting)
+ nvInfo.body.rsvSvcNum = 0;
+ for (ii = 0; ii < TSKM_SVC_RESERVE_MAX; ii++) {
+ nvInfo.body.rsvSvcs[ii] = TSKM_SVCID_NONE;
+ }
+ nvInfo.footer.checkSum = calcCheckSum(
+ &nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum));
+
+ writeSize = writeFile(TSKM_TMP_NV_INFO_FILEPATH, &nvInfo,
+ sizeof(TSKM_NV_INFO_t));
+ if (writeSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: writeSize must be the size of TSKM_NV_INFO_t
+ // LCOV_EXCL_START 6: writeSize must be the size of TSKM_NV_INFO_t
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ return 0;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Non-volatile file initialization
+ *********************************************************/
+int tskm_pf_nvFileInit(HANDLE hApp) {
+ int ret = -1;
+ struct stat st;
+ EFrameworkunifiedStatus l_eStatus;
+
+ if (stat(TSKM_TMP_TSKM_DIRECTORY, &st) != 0) { // LCOV_EXCL_BR_LINE 5:Standard C function return value
+ // LCOV_EXCL_START 5:Standard C function return value
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ ret = mkdir(TSKM_TMP_TSKM_DIRECTORY, S_IRWXU);
+ if (ret == -1) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ // LCOV_EXCL_STOP
+ }
+
+ l_eStatus = FrameworkunifiedNPRegisterPersistentFile(hApp, TSKM_NPP_NV_FILE_TAG);
+ if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 6: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For processing initializing process
+ goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process
+ }
+
+ l_eStatus = FrameworkunifiedNPLoadPersistentFile(hApp, TSKM_TMP_NV_INFO_FILEPATH, TSKM_NPP_NV_FILE_TAG);
+ if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 6: For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For processing initializing process
+ goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process
+ }
+
+ return 0;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Non-volatile file read
+ *********************************************************/
+int tskm_pf_nvFileRead(HANDLE hApp, TSKM_NV_INFO_t* p_nvInfo) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ NC_LoadPersistedAck l_tMsgAck;
+ ssize_t readSize;
+ TSKM_BOOL_t isTmpFileOk = TSKM_FALSE;
+
+ if (sizeof(l_tMsgAck) != FrameworkunifiedGetMsgLength(hApp)) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, &l_tMsgAck, sizeof(l_tMsgAck)))) { // LCOV_EXCL_BR_LINE 4: NSFW error case // NOLINT[whitespace/line_length]
+ // LCOV_EXCL_START 4: NSFW error case
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if ((strncmp(l_tMsgAck.cTag, TSKM_NPP_NV_FILE_TAG, sizeof(TSKM_NPP_NV_FILE_TAG)) == 0)
+ && (eFrameworkunifiedStatusOK == l_tMsgAck.eStatus)) {
+ if (checkFile(TSKM_TMP_NV_INFO_FILEPATH) == TSKM_TRUE) {
+ isTmpFileOk = TSKM_TRUE;
+ }
+ }
+
+ if (isTmpFileOk == TSKM_FALSE) {
+ int ret;
+
+ ret = initNvFile();
+ if (ret == -1) { // LCOV_EXCL_BR_LINE 6: must return ok
+ // LCOV_EXCL_START 6: must return ok
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ readSize = readFile(TSKM_TMP_NV_INFO_FILEPATH, p_nvInfo,
+ sizeof(TSKM_NV_INFO_t));
+ if (readSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: readSize must be the size of TSKM_NV_INFO_t
+ // LCOV_EXCL_START 6: readSize must be the size of TSKM_NV_INFO_t
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ l_eStatus = FrameworkunifiedNPReleasePersistentFile(hApp, eFrameworkunifiedPersistOnShutdown, TSKM_NPP_NV_FILE_TAG, TSKM_TMP_NV_INFO_FILEPATH);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ return 0;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Write non-volatile file (Including checksum)
+ *********************************************************/
+int tskm_pf_nvFileWrite(const TSKM_NV_INFO_t* p_nvInfo) {
+ ssize_t writeSize;
+ TSKM_NV_INFO_t nvInfo;
+
+ memcpy(&nvInfo, p_nvInfo, sizeof(TSKM_NV_INFO_t));
+
+ nvInfo.footer.checkSum = calcCheckSum(
+ &nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum));
+
+ writeSize = writeFile(TSKM_TMP_NV_INFO_FILEPATH, &nvInfo,
+ sizeof(TSKM_NV_INFO_t));
+ if (writeSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: writeSize must be the size of TSKM_NV_INFO_t
+ // LCOV_EXCL_START 6: writeSize must be the size of TSKM_NV_INFO_t
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ return -1;
+ // LCOV_EXCL_STOP
+ }
+ return 0;
+} // LCOV_EXCL_BR_LINE 10: Final line
diff --git a/task_manager/server/src/tskm_port_subsys.cpp b/task_manager/server/src/tskm_port_subsys.cpp
new file mode 100644
index 00000000..a90fa4bc
--- /dev/null
+++ b/task_manager/server/src/tskm_port_subsys.cpp
@@ -0,0 +1,303 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_port_subsys.h"
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <native_service/cl_monitor.h>
+#include <system_service/ss_sm_client_if.h>
+#include <system_service/resm.h>
+//#include <stub/ss_diag.h>
+#include <string>
+
+#include "agl_thread.h"
+
+#include "tskm_main.h"
+#include "tskm_debug.h"
+#include "tskm_util.h"
+#include "tskm_port_pf.h"
+
+
+#ifndef oops_name2pid
+ #define oops_name2pid(processname) syscall(OOPSTRACE_SYSCALL, 17, processname)
+#endif
+
+
+typedef struct {
+ CL_MonitorSearch_t clMonSearch;
+ uint32_t resmId; // Session ID of RESM
+} SUB_SYS_CTX_t;
+
+static SUB_SYS_CTX_t g_sub;
+
+/******************************************************************
+ * Subsystem initialization
+ ******************************************************************/
+int tskm_sub_init(void) {
+ int clRet;
+ SUB_SYS_CTX_t* p_ctx = &g_sub;
+
+ clRet = CL_MonitorSearchInit(&p_ctx->clMonSearch);
+ if (clRet != 0) { // LCOV_EXCL_BR_LINE 6: For processing intializing process
+ // LCOV_EXCL_START 6:For processing initializing process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 6: For processing initializing process
+ }
+
+ return 0;
+ // LCOV_EXCL_START 6:For processing initializing process
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return 1;
+ // LCOV_EXCL_STOP
+}
+
+/******************************************************************
+ * Subsystem termination
+ ******************************************************************/
+int tskm_sub_term(void) {
+ int ret;
+ SUB_SYS_CTX_t* p_ctx = &g_sub;
+
+ ret = CL_MonitorSearchDestroy(&p_ctx->clMonSearch);
+ if (ret != 0) {
+ TSKM_ASSERT_ERRNO(0);
+ }
+
+ return 0;
+}
+/*********************************************************
+ * REBOOT
+ *********************************************************/
+void tskm_sub_reboot(const TSKM_ERROR_REBOOT_t* p_info) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+
+ TSKM_ASSERT(0);
+
+ l_eStatus = SendCpuResetRequestToSystemManager(
+ e_SS_SM_CPU_RESET_REASON_GENERIC_ERR, p_info->log.messageStr);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+}
+
+/*********************************************************
+ * REBOOT NORMAL
+ *********************************************************/
+void tskm_sub_reboot_normal(void) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+
+ l_eStatus = SendCpuResetRequestToSystemManager(
+ e_SS_SM_CPU_RESET_REASON_NORMAL);
+ if (l_eStatus != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT(0);
+ }
+}
+
+/*********************************************************
+ * LOGGING
+ *********************************************************/
+void tskm_sub_logging(const TSKM_LOGGING_INFO_t* p_info) {
+ EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
+ eSMUserLogType l_eType;
+
+ switch (p_info->type) {
+ case TSKM_LOGGING_TYPE_GRP_RELAUNCH:
+ l_eType = e_SS_SM_CAPTURE_GROUP_RELAUNCH;
+ break;
+ case TSKM_LOGGING_TYPE_MODULE_LOGS:
+ default:
+ l_eType = e_SS_SM_CAPTURE_MODULE_LOGS;
+ break;
+ }
+
+ l_eStatus = SendUserInvokedLoggingRequestToSystemManager(l_eType,
+ p_info->messageStr);
+ if (eFrameworkunifiedStatusOK != l_eStatus) {
+ TSKM_ASSERT(0);
+ }
+}
+
+/*********************************************************
+ * DEBUG DUMP
+ *********************************************************/
+void tskm_sub_debugDumpRes(BOOL bIsNeedSvcName, const char *p_dumpMsg) {
+ if (bIsNeedSvcName) { // LCOV_EXCL_BR_LINE 8: As the bIsNeedSvcName is set to FALSE only
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ SSDEBUGDUMP("%s", p_dumpMsg); // LCOV_EXCL_LINE 8: As the bIsNeedSvcName is set to FALSE only
+ } else {
+ SSDEBUGDUMP_RAW("%s", p_dumpMsg);
+ }
+}
+
+/*********************************************************
+ * EXT BOOT INFO
+ *********************************************************/
+int tskm_sub_getExtBootInfo(T_SS_SM_START_ExtDataStructType *p_info) {
+ EFrameworkunifiedStatus l_eStatus;
+ T_SS_SM_START_ExtDataStructType extStartupInfo;
+
+ l_eStatus = GetInterfaceunifiedOnStartExtInfo(extStartupInfo);
+ if (l_eStatus != eFrameworkunifiedStatusOK) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ memcpy(p_info, &extStartupInfo, sizeof(extStartupInfo));
+
+ return 0;
+ ERROR: return -1;
+}
+
+/*********************************************************
+ * Service Error Monitoring Check
+ *********************************************************/
+TSKM_HUNG_INFO_t*
+tskm_sub_searchHungSvcs() {
+ int ret;
+ TSKM_HUNG_INFO_t *p_hungList = NULL;
+ SUB_SYS_CTX_t* p_ctx = &g_sub;
+
+ ret = CL_MonitorSearchTimeout(&p_ctx->clMonSearch);
+ if (ret == -1) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ if (0 < p_ctx->clMonSearch.entry_num) {
+ int ii;
+
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "TimeoutSvcNum = %d",
+ p_ctx->clMonSearch.entry_num);
+
+ if (NULL == p_ctx->clMonSearch.entry_list) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ p_hungList = (TSKM_HUNG_INFO_t *) malloc( // NOLINT (readability/casting)
+ sizeof(TSKM_HUNG_INFO_t) * (p_ctx->clMonSearch.entry_num + 1));
+ if (p_hungList == NULL) { // LCOV_EXCL_BR_LINE 5: malloc's error case.
+ // LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ for (ii = 0; ii < p_ctx->clMonSearch.entry_num; ii++) {
+ p_hungList[ii].pid = p_ctx->clMonSearch.entry_list[ii].pid;
+ p_hungList[ii].type = p_ctx->clMonSearch.entry_list[ii].type;
+ }
+ // set "-1" to pid at the end of list.
+ p_hungList[p_ctx->clMonSearch.entry_num].pid = -1;
+ }
+
+ ERROR: return p_hungList;
+}
+
+/*********************************************************
+ * RESM Initialization
+ *********************************************************/
+int tskm_sub_resmInit(void) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ int redmFd;
+ SUB_SYS_CTX_t* p_ctx = &g_sub;
+ RESM_ERR_t resmRet = RESM_E_OK;
+ RESM_REQ_EVENT_t ev;
+
+ int pid;
+
+ resmRet = RESM_Open(NULL, &(p_ctx->resmId));
+ if (RESM_E_OK != resmRet) {
+ TSKM_ASSERT(0);
+
+#warning RESM backtrace disabled, because 'print_backtrace_pid' not support.
+#if 0
+ // Backtrace outoutput of the RESM
+ pid = oops_name2pid(MN_SS_RESOURCEMGR);
+ if(pid > 0){
+ TSKM_ASSERT(-1 != print_backtrace_pid(pid));
+ }else{
+ TSKM_PRINTF(TSKM_LOG_ERROR, "ERR : oops_name2pid %d , err:%d, msg:%s",
+ pid, errno, strerror(errno));
+ }
+#endif
+
+ goto ERROR;
+ }
+
+ resmRet = RESM_GetEventFd(p_ctx->resmId, &redmFd);
+ if (RESM_E_OK != resmRet) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ ev.reqEvent = RESM_EV_MEM;
+ ev.prm.restMemThresh = 512; // Threshold(BYTE)
+
+ resmRet = RESM_ReqEvent(p_ctx->resmId, &ev);
+ if (RESM_E_OK != resmRet) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ return redmFd;
+ ERROR: return -1;
+}
+// LCOV_EXCL_STOP
+/*********************************************************
+ * Get EV of RESM
+ *********************************************************/
+int tskm_sub_resmRcv(TSKM_EVENT_INFO_t* p_ev) {
+ SUB_SYS_CTX_t* p_ctx = &g_sub;
+ RESM_ERR_t resmRet = RESM_E_OK;
+ RESM_EV_t evFlag;
+
+ resmRet = RESM_GetEvent(p_ctx->resmId, &evFlag);
+ if (RESM_E_OK != resmRet) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ if (RESM_EV_MEM != evFlag) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ TSKM_PRINTF(TSKM_LOG_ERROR, "Detect LowMem");
+
+ p_ev->event = TSKM_EV_LCL_REP_LOWMEM;
+
+ return 0;
+ ERROR: return -1;
+}
+
+int tskm_sub_setWakeupOrder(const char* p_order) {
+ EFrameworkunifiedStatus taskmanagerRet;
+ std::string order = p_order;
+
+ taskmanagerRet = SetWakeupOrderToSystemManager(order);
+ if (taskmanagerRet != eFrameworkunifiedStatusOK) {
+ return -1;
+ }
+ return 0;
+} // LCOV_EXCL_BR_LINE 10: Gcov constraints (last row)
diff --git a/task_manager/server/src/tskm_shutdown.cpp b/task_manager/server/src/tskm_shutdown.cpp
new file mode 100644
index 00000000..abee7297
--- /dev/null
+++ b/task_manager/server/src/tskm_shutdown.cpp
@@ -0,0 +1,242 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_shutdown.h"
+#include "tskm_util.h"
+#include "tskm_debug.h"
+#include "tskm_state.h"
+
+#include "tskm_port_pf.h"
+#include "tskm_port_subsys.h"
+#include "tskm_gstep.h"
+
+
+/*********************************************************
+ * Get context of gradual startup
+ *********************************************************/
+TSKM_STATIC TSKM_GSTEP_CTX_t*
+gstepGetDownCtx(TSKM_MAIN_CTX_t* p_main) {
+ return &p_main->down;
+}
+
+/*********************************************************
+ * System shutdown completed
+ *********************************************************/
+TSKM_STATIC void downFinish(TSKM_MAIN_CTX_t* p_main) {
+ int ret;
+
+ // Send FrameworkunifiedOnStop response
+ ret = tskm_pf_sendStopCompResp();
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 8: As ret never becomes non-zero
+ // LCOV_EXCL_START 8: As ret never becomes non-zero
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ // LCOV_EXCL_STOP
+ }
+
+ // Terminate subsystems
+ tskm_sub_term();
+}
+/*********************************************************
+ * Challenge for a transition to the next state
+ *********************************************************/
+TSKM_STATIC void tryTransNextState(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_GSTEP_CTX_t* p_down;
+ TSKM_GSTEP_t* p_current;
+
+ p_down = gstepGetDownCtx(p_main);
+ p_current = gstepGetCurrent(p_down);
+
+ if (gstepIsLast(p_down)) {
+ TSKM_SVC_WAIT_STATE_t waitState;
+
+ // Checking the ShutdownWaitSVC termination status
+ waitState = tskm_svcsGetSvcTermWaitState(&p_main->svcs);
+ switch (waitState) {
+ case TSKM_SVC_WAIT_BOTH:
+ break;
+ case TSKM_SVC_WAIT_TRANSIENT:
+ if ((p_down->compState & INI_TERMCOMP_RESIDENT) != INI_TERMCOMP_RESIDENT) {
+ // Nonresident service termination processing
+ if (TSKM_E_OK != tskm_svcsAvtiveSvcTerm(&p_main->svcs)) { // LCOV_EXCL_BR_LINE 5: tskm_svcsAvtiveSvcTerm is always return TSKM_E_OK
+ // LCOV_EXCL_START 5: tskm_svcsAvtiveSvcTerm is always return TSKM_E_OK
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ // LCOV_EXCL_STOP
+ }
+ // Nonresident SVC terminated and started
+ p_down->compState |= INI_TERMCOMP_RESIDENT;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx)",
+ tskm_convTermCompId2Str(INI_TERMCOMP_RESIDENT),
+ INI_TERMCOMP_RESIDENT);
+ }
+ break;
+ case TSKM_SVC_WAIT_NONE:
+ // Complete ShutdownWaitSVC
+ // Nonresident SVC terminated and started
+ p_down->compState |= INI_TERMCOMP_TRANSIENT;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx)",
+ tskm_convTermCompId2Str(INI_TERMCOMP_TRANSIENT),
+ INI_TERMCOMP_TRANSIENT);
+ break;
+ default:
+ // LCOV_EXCL_START 8: As it does not meet the default requirements
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ break;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ if (tskm_svcsIsWaiting(&p_main->svcs) == TSKM_FALSE && // No waiting services
+ ((p_down->compState & p_current->nextTransCond)
+ == p_current->nextTransCond)) { // Event completion condition
+ if (gstepIsLast(p_down)) {
+ tskm_stateTransit(p_main, TSKM_ST_ACCON, TSKM_ST_ACCOFF);
+ } else {
+ tskm_stateTransit(p_main, TSKM_ST_DOWN, TSKM_ST_DOWN);
+ }
+ }
+}
+
+/*********************************************************
+ * Check and process gradual termination request
+ *********************************************************/
+TSKM_ERR_t tskm_entryDown_Check_Req(TSKM_MAIN_CTX_t* p_main,
+ TSKM_GSTEP_t* p_current) {
+ uint32_t ii;
+
+ if (0 == p_current->reqNum) {
+ EFrameworkunifiedStatus l_eStatus;
+
+ // If there is no gradual termination request, check the transition to the next step.
+ l_eStatus = FrameworkunifiedSendSelf(p_main->hApp, TSKM_TRANS_STEP_REQ, 0, NULL);
+ if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 5: Checked in death testing, but it is not reflected in the coverage and excluded
+ // LCOV_EXCL_START 5: Checked in death testing, but it is not reflected in the coverage and excluded
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ return TSKM_E_NG;
+ // LCOV_EXCL_STOP
+ }
+
+ } else {
+ // Gradual termination request
+ for (ii = 0; ii < p_current->reqNum; ii++) {
+ TSKM_ERR_t tskmRet;
+ TSKM_GSTEP_REQ_INFO_t* p_req = &p_current->reqList[ii];
+ TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs,
+ p_req->svcId);
+
+ tskmRet = tskm_svcDownRequest(p_svc, p_req);
+ if (tskmRet != TSKM_E_OK) {
+ TSKM_ASSERT(0);
+ }
+ }
+ }
+ return TSKM_E_OK;
+}
+
+/*********************************************************
+ * Gradual termination entry process
+ *********************************************************/
+TSKM_ERR_t tskm_entryDown(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+
+ TSKM_GSTEP_CTX_t* p_down;
+ TSKM_GSTEP_t* p_current;
+
+ p_main->state = TSKM_ST_DOWN;
+ p_down = gstepGetDownCtx(p_main);
+ p_current = gstepGetCurrent(p_down);
+ if (p_current == NULL) { // LCOV_EXCL_BR_LINE 200:p_current can not be null
+ // LCOV_EXCL_START 200:p_current can not be null
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "DOWN GSTEP:%d", p_down->gstepIdx);
+
+ if (tskm_entryDown_Check_Req(p_main, p_current) == TSKM_E_NG) { // LCOV_EXCL_BR_LINE 200:the function of tskm_entryDown_Check_Req can not be TSKM_E_NG at this case // NOLINT(whitespace/line_length)
+ // LCOV_EXCL_START 200:tskm_entryDown_Check_Req can not be TSKM_E_NG at this case
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (p_current->nextTransCond) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "WAIT COMP:%s(%llx)",
+ tskm_convTermCompId2Str(p_current->nextTransCond),
+ p_current->nextTransCond);
+ }
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+
+ ERROR: tskm_pf_abort();
+ return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Gradual termination exit process
+ *********************************************************/
+TSKM_ERR_t tskm_exitDown(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+ TSKM_GSTEP_CTX_t* p_down;
+
+ p_down = gstepGetDownCtx(p_main);
+
+ if (gstepIsLast(p_down)) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "DOWN FINISH");
+ downFinish(p_main); // Final process of termination
+ }
+
+ changeNextStep(p_down); // Proceed to the next step
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+/*********************************************************
+ * Hander during gradual termination
+ *********************************************************/
+TSKM_ERR_t tskm_handleDown(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_FUNC_IN();
+
+ switch (p_ev->event) {
+ case TSKM_EV_PRI_REP_DOWN_COMP: // Notificaton for event completion in termination
+ {
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "TERM COMP :%s(%#llx) from:%d",
+ tskm_convTermCompId2Str(p_ev->prm.repDownComp.compId),
+ p_ev->prm.repDownComp.compId, p_ev->fromPid);
+ TSKM_GSTEP_CTX_t* p_down = gstepGetDownCtx(p_main);
+ p_down->compState |= p_ev->prm.repDownComp.compId;
+ tryTransNextState(p_main);
+ }
+ break;
+ case TSKM_EV_LCL_CHG_SVC_STATE: // Service state change
+ tryTransNextState(p_main);
+ break;
+ case TSKM_EV_LCL_REQ_TRANS_STEP: //Step transition request
+ tryTransNextState(p_main);
+ break;
+ default:
+ tskm_handleAccon(p_main, p_ev);
+ break;
+ }
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_state.cpp b/task_manager/server/src/tskm_state.cpp
new file mode 100644
index 00000000..1018eb3c
--- /dev/null
+++ b/task_manager/server/src/tskm_state.cpp
@@ -0,0 +1,452 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_state.h"
+#include <stdlib.h>
+#include "tskm_util.h"
+#include "tskm_debug.h"
+#include "tskm_wakeup.h"
+#include "tskm_shutdown.h"
+#include "tskm_port_subsys.h"
+#include "tskm_port_pf.h"
+
+
+
+// Prototype declarations
+TSKM_ERR_t tskm_entryAccoff(TSKM_MAIN_CTX_t* p_main);
+TSKM_ERR_t tskm_exitAccoff(TSKM_MAIN_CTX_t* p_main);
+TSKM_ERR_t tskm_handleAccoff(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev);
+
+TSKM_ERR_t tskm_entryAccon(TSKM_MAIN_CTX_t* p_main);
+TSKM_ERR_t tskm_exitAccon(TSKM_MAIN_CTX_t* p_main);
+
+TSKM_ERR_t tskm_entryRunning(TSKM_MAIN_CTX_t* p_main);
+TSKM_ERR_t tskm_exitRunning(TSKM_MAIN_CTX_t* p_main);
+TSKM_ERR_t tskm_handleRunning(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev);
+
+// Structures of state transitioning callback functions
+typedef TSKM_ERR_t (*entry_state_t)(TSKM_MAIN_CTX_t* p_main);
+typedef TSKM_ERR_t (*exit_state_t)(TSKM_MAIN_CTX_t* p_main);
+typedef TSKM_ERR_t (*event_handler_t)(TSKM_MAIN_CTX_t* p_main,
+ TSKM_EVENT_INFO_t* p_ev);
+
+typedef struct {
+ TSKM_STATE_t state;
+ entry_state_t entry_func;
+ exit_state_t exit_func;
+ event_handler_t event_handler;
+} state_func_table_t;
+
+// State specific function table
+static const state_func_table_t state_func_table[] = { { TSKM_ST_ACCOFF,
+ tskm_entryAccoff, tskm_exitAccoff, tskm_handleAccoff }, { TSKM_ST_ACCON,
+ tskm_entryAccon, tskm_exitAccon, tskm_handleAccon }, { TSKM_ST_WAKEUP,
+ tskm_entryWakeup, tskm_exitWakeup, tskm_handleWakeup }, { TSKM_ST_RUNNING,
+ tskm_entryRunning, tskm_exitRunning, tskm_handleRunning }, { TSKM_ST_DOWN,
+ tskm_entryDown, tskm_exitDown, tskm_handleDown }, { 0, 0, 0, 0 } };
+
+/****************************************************
+ * ACC OFF ENTRY
+ ****************************************************/
+TSKM_ERR_t tskm_entryAccoff(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+ p_main->state = TSKM_ST_ACCOFF;
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * ACC OFF EXIT
+ *************************************************************************/
+TSKM_ERR_t tskm_exitAccoff(TSKM_MAIN_CTX_t* p_main) {
+ // Do nothing
+ // Called only once at startup
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * ACC OFF HANDLE
+ *************************************************************************/
+TSKM_ERR_t tskm_handleAccoff(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_ASSERT(0); // Do nothing
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * ACC ON ENTRY
+ *************************************************************************/
+TSKM_ERR_t tskm_entryAccon(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+ p_main->state = TSKM_ST_ACCON;
+
+ tskm_entryState(p_main, TSKM_ST_WAKEUP);
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * ACC ON HANDLE
+ *************************************************************************/
+TSKM_ERR_t tskm_exitAccon(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ if (TSKM_SUB_STATE_IS(p_main, TSKM_ST_WAKEUP)) { // LCOV_EXCL_BR_LINE 8:Because the condition is never true
+ // LCOV_EXCL_START 8: Because the condition is never true
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskmRet = tskm_exitState(p_main, TSKM_ST_WAKEUP);
+ // LCOV_EXCL_STOP
+ } else if (TSKM_SUB_STATE_IS(p_main, TSKM_ST_RUNNING)) { // LCOV_EXCL_BR_LINE 8: Because the condition is never true
+ // LCOV_EXCL_START 8: Because the condition is never true
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskmRet = tskm_exitState(p_main, TSKM_ST_RUNNING);
+ // LCOV_EXCL_STOP
+ } else if (TSKM_SUB_STATE_IS(p_main, TSKM_ST_DOWN)) { // LCOV_EXCL_BR_LINE 8:Because the condition is never false
+ tskmRet = tskm_exitState(p_main, TSKM_ST_DOWN);
+ }
+
+ TSKM_ERR_CHK(tskmRet, TSKM_E_OK, ERROR); // LCOV_EXCL_BR_LINE 8: Because the tskmRet does not change to NG
+ p_main->isExec = TSKM_FALSE;
+ ERROR:
+ TSKM_FUNC_OUT();
+ return tskmRet;
+}
+
+/*************************************************************************
+ * POLL EVENT HANDLE
+ *************************************************************************/
+TSKM_STATIC void checkHungSvcs(TSKM_MAIN_CTX_t* p_main) {
+ int ret;
+ TSKM_HUNG_INFO_t *p_hungSvcList = NULL;
+
+ p_hungSvcList = tskm_sub_searchHungSvcs();
+ if (p_hungSvcList != NULL) {
+ int hungSvcNum = 0;
+
+ while (p_hungSvcList[hungSvcNum].pid != -1) {
+ pid_t pid = p_hungSvcList[hungSvcNum].pid;
+
+ TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcByPid(&p_main->svcs, pid);
+
+ if (p_svc) {
+ TSKM_PRINTF(TSKM_LOG_SYSTEMDATA, "HUNG SVC(%s:%d), TYPE(%d)",
+ p_svc->attr->name, pid, p_hungSvcList[hungSvcNum].type);
+
+ ret = tskm_pf_terminateProcGroup(static_cast<uint16_t>(pid));
+ if (ret != 0) {
+ TSKM_ASSERT(0);
+ }
+
+ } else {
+ TSKM_PRINTF(TSKM_LOG_WARN, "UNKNOWN HUNG SVC(%d), TYPE(%d)", pid,
+ p_hungSvcList[hungSvcNum].type);
+ }
+
+ hungSvcNum++;
+ }
+
+ free(p_hungSvcList);
+ }
+
+ return;
+}
+
+#define AVAILABILITY_CHECK_RETRY_COUNT 24
+
+/*************************************************************************
+ * CHECK SVC AVAILABILITY
+ *************************************************************************/
+TSKM_STATIC void checkSvcAvailability(TSKM_MAIN_CTX_t* p_main) {
+ for (uint32_t ii = 0; ii < p_main->svcs.svcNum; ii++) {
+ if (p_main->svcs.svcList[ii].state == TSKM_SVC_RUNNING
+ && !p_main->svcs.svcList[ii].isAvailable) {
+ p_main->svcs.svcList[ii].watchCnt++;
+ TSKM_ASSERT_PRINT(0, "WAIT AVAILABILITY FOR %s(%d) (%d/%d)",
+ p_main->svcs.svcList[ii].attr->name,
+ p_main->svcs.svcList[ii].pid,
+ p_main->svcs.svcList[ii].watchCnt,
+ AVAILABILITY_CHECK_RETRY_COUNT);
+
+ if (p_main->svcs.svcList[ii].watchCnt > AVAILABILITY_CHECK_RETRY_COUNT) {
+ int ret;
+
+ ret = tskm_pf_terminateProcGroup(static_cast<uint16_t>(p_main->svcs.svcList[ii].pid));
+ if (ret != 0) {
+ TSKM_ASSERT(0);
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/*************************************************************************
+ * POLL EVENT HANDLE
+ *************************************************************************/
+TSKM_STATIC void handlePolling(TSKM_MAIN_CTX_t* p_main) {
+ checkHungSvcs(p_main);
+
+ checkSvcAvailability(p_main);
+
+ return;
+}
+
+/*************************************************************************
+ * LOW MEMORY EVENT HANDLE
+ *************************************************************************/
+TSKM_STATIC void handleLowMem(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ tskmRet = tskm_svcsCallLowMem(&p_main->svcs);
+ if (TSKM_E_OK != tskmRet) {
+ TSKM_ASSERT(0);
+ }
+
+ return;
+}
+/*************************************************************************
+ * ACC ON HANDLE
+ *************************************************************************/
+TSKM_ERR_t tskm_handleAccon(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_FUNC_IN();
+
+ switch (p_ev->event) {
+ case TSKM_EV_LCL_REQ_SDUMP:
+ tskm_svcsDump(&p_main->svcs);
+ break;
+ // LCOV_EXCL_STOP
+ case TSKM_EV_LCL_REP_POLLING:
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "watch timer polling event.");
+ handlePolling(p_main);
+ break;
+ default:
+ TSKM_PRINTF(TSKM_LOG_STATE, "IGNORE:%s(%d)",
+ tskm_convEvent2Str(p_ev->event), p_ev->event);
+ break;
+ }
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * BOOT RESERVED SERVICES
+ *************************************************************************/
+static int bootRsvSvcs(TSKM_MAIN_CTX_t* p_main) {
+ uint32_t ii;
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+ uint8_t rsvSvcNum = p_main->nvInfo.body.rsvSvcNum;
+ TSKM_SVCID_t* p_rsvSvcs = p_main->nvInfo.body.rsvSvcs;
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "RSV SVC NUM = %d", rsvSvcNum);
+
+ for (ii = 0; ii < rsvSvcNum; ii++) {
+ TSKM_GSTEP_REQ_INFO_t req = { 0 };
+ TSKM_SVC_CTX_t* p_svc;
+
+ p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs, p_rsvSvcs[ii]);
+ if (p_svc == NULL) {
+ TSKM_ASSERT(0);
+ continue;
+ }
+
+ tskmRet = tskm_svcExec(p_svc);
+ if (TSKM_E_OK != tskmRet) {
+ TSKM_ASSERT(0);
+ continue;
+ }
+ if (p_svc->state == TSKM_SVC_WAITCONNECT) {
+ // In the state waiting for execution
+ req.svcId = p_rsvSvcs[ii];
+ req.localStep = TSKM_LSTEP_ALL;
+ tskmRet = tskm_svcWakeupRequest(p_svc, &req);
+ if (TSKM_E_OK != tskmRet) { // LCOV_EXCL_BR_LINE 8: Because the condition is never true
+ // LCOV_EXCL_START 8: Because the condition is never true
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT_PRINT(0, "tskmRet = %d", tskmRet);
+ continue;
+ // LCOV_EXCL_STOP
+ }
+ }
+ }
+
+ if (rsvSvcNum != 0) {
+ int ret;
+
+ for (ii = 0; ii < TSKM_SVC_RESERVE_MAX; ii++) {
+ p_rsvSvcs[ii] = TSKM_SVCID_NONE;
+ }
+
+ p_main->nvInfo.body.rsvSvcNum = 0;
+
+ ret = tskm_pf_nvFileWrite(&p_main->nvInfo);
+ if (ret == -1) { // LCOV_EXCL_BR_LINE 8: Because the tskm_pf_nvFileWrite() only returns a return value of 0
+ // LCOV_EXCL_START 8:Because the condition is never true
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+ }
+
+ return 0;
+ // LCOV_EXCL_START 8: Because the tskm_pf_nvFileWrite() only returns a return value of 0
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return -1;
+ // LCOV_EXCL_STOP
+}
+
+/*************************************************************************
+ * RUN ENTRY
+ *************************************************************************/
+TSKM_ERR_t tskm_entryRunning(TSKM_MAIN_CTX_t* p_main) {
+ int ret;
+
+ TSKM_FUNC_IN();
+ p_main->state = TSKM_ST_RUNNING;
+
+ ret = bootRsvSvcs(p_main);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 8: Because bootRsvSvcs returns only a return value of 0
+ // LCOV_EXCL_START 8: Because bootRsvSvcs returns only a return value of 0
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ // LCOV_EXCL_STOP
+ }
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * RUN EXIT
+ *************************************************************************/
+TSKM_ERR_t tskm_exitRunning(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * RUN HANDLE
+ *************************************************************************/
+TSKM_ERR_t tskm_handleRunning(TSKM_MAIN_CTX_t* p_main,
+ TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_FUNC_IN();
+
+ switch (p_ev->event) {
+ case TSKM_EV_LCL_REQ_STOP:
+ tskm_stateTransit(p_main, TSKM_ST_RUNNING, TSKM_ST_DOWN);
+ break;
+ case TSKM_EV_LCL_REP_LOWMEM:
+ handleLowMem(p_main);
+ break;
+ default:
+ tskm_handleAccon(p_main, p_ev);
+ break;
+ }
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*************************************************************************
+ * Get transition table
+ *************************************************************************/
+static const state_func_table_t*
+tskm_getFuncTable(TSKM_STATE_t state) {
+ int i;
+ for (i = 0; state_func_table[i].state != 0; i++) {
+ if (state == state_func_table[i].state) {
+ return &state_func_table[i];
+ }
+ }
+ TSKM_ASSERT(0);
+ return &state_func_table[0];
+}
+
+/*************************************************************************
+ * State transition instructions
+ *************************************************************************/
+TSKM_ERR_t tskm_stateTransit(TSKM_MAIN_CTX_t* p_main, TSKM_STATE_t srcState,
+ TSKM_STATE_t dstState) {
+ TSKM_ERR_t tskmRet;
+ TSKM_PRINTF(TSKM_LOG_STATE, "STATE:%s(%s) -> %s",
+ tskm_convState2Str(srcState), tskm_convState2Str(p_main->state),
+ tskm_convState2Str(dstState));
+
+ tskmRet = tskm_exitState(p_main, srcState);
+ TSKM_ERR_CHK(tskmRet, TSKM_E_OK, ERROR); // LCOV_EXCL_BR_LINE 8: Because TSKM_ERR_CHK does not specify a goto ERROR condition
+ tskmRet = tskm_entryState(p_main, dstState);
+ TSKM_ERR_CHK(tskmRet, TSKM_E_OK, ERROR); // LCOV_EXCL_BR_LINE 8: Because TSKM_ERR_CHK does not specify a goto ERROR condition
+ return TSKM_E_OK;
+
+ // LCOV_EXCL_START 8: Because TSKM_ERR_CHK does not specify a goto ERROR condition
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return TSKM_E_NG;
+ // LCOV_EXCL_STOP
+}
+
+/*************************************************************************
+ * Event handler
+ *************************************************************************/
+void tskm_handleEvent(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
+ event_handler_t handlerFunc;
+ handlerFunc = tskm_getFuncTable(p_main->state)->event_handler;
+ handlerFunc(p_main, p_ev);
+}
+
+/****************************************************
+ * State transitioning entry process
+ ****************************************************/
+TSKM_ERR_t tskm_entryState(TSKM_MAIN_CTX_t* p_rec, TSKM_STATE_t state) {
+ TSKM_ERR_t ret = TSKM_E_NG;
+ const state_func_table_t* p_table = tskm_getFuncTable(state);
+
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "entry :%s", tskm_convState2Str(state));
+ if (p_table->entry_func) { // LCOV_EXCL_BR_LINE 8: Because p_table->entry_func never becomes 0
+ ret = ((*p_table->entry_func)(p_rec));
+ } else {
+ // LCOV_EXCL_START 8: Because p_table->entry_func never becomes 0
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ // LCOV_EXCL_STOP
+ }
+ return ret;
+}
+
+/****************************************************
+ * State transitioning exit process
+ ****************************************************/
+TSKM_ERR_t tskm_exitState(TSKM_MAIN_CTX_t* p_rec, TSKM_STATE_t state) {
+ TSKM_ERR_t ret = TSKM_E_NG;
+ const state_func_table_t* p_table = tskm_getFuncTable(state);
+
+ if (p_table->exit_func) { // LCOV_EXCL_BR_LINE 8: Because p_table->exit_func never becomes 0
+ ret = (*p_table->exit_func)(p_rec);
+ } else {
+ // LCOV_EXCL_START 8: Because p_table->exit_func never becomes 0
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ // LCOV_EXCL_STOP
+ }
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "exit :%s", tskm_convState2Str(state));
+ return ret;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_svc.cpp b/task_manager/server/src/tskm_svc.cpp
new file mode 100644
index 00000000..a7dda206
--- /dev/null
+++ b/task_manager/server/src/tskm_svc.cpp
@@ -0,0 +1,978 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "system_service/tskm_svc.h"
+#include <string.h>
+#include <stdlib.h>
+#include <sys/inotify.h>
+#include <errno.h>
+
+#include <native_service/ns_np_service_if.h>
+#include <string>
+
+#include "tskm_debug.h"
+#include "tskm_util.h"
+#include "tskm_port_pf.h"
+#include "tskm_port_subsys.h"
+#include "tskm_comm.h"
+
+
+/*********************************************************
+ * Is the target event of the service handler?
+
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t isSvcEvent(const TSKM_EVENT_INFO_t* p_ev) {
+ switch (p_ev->event) {
+ case TSKM_EV_PRI_REP_CONNECT:
+ case TSKM_EV_PRI_REP_DISCONNECT:
+ case TSKM_EV_PRI_RES_WAKEUP:
+ case TSKM_EV_PRI_RES_DOWN:
+ case TSKM_EV_PRI_RES_DEBUGDUMP:
+ case TSKM_EV_PRI_REQ_EXIT:
+ case TSKM_EV_SVC_REP_TERM:
+ return TSKM_TRUE;
+ break;
+ default:
+ break;
+ }
+ return TSKM_FALSE;
+}
+
+/*********************************************************
+ * Get service context
+ *********************************************************/
+TSKM_STATIC TSKM_SVC_CTX_t*
+getSvcCtxBySvcId(TSKM_SVCS_CTX_t* p_svcs, TSKM_SVCID_t svcId) {
+ uint32_t ii;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ if (p_svcs->svcList[ii].attr->svcId == svcId) {
+ return &p_svcs->svcList[ii];
+ }
+ }
+ TSKM_ASSERT(0);
+ return NULL;
+}
+
+/*********************************************************
+ * Get service context
+ *********************************************************/
+TSKM_STATIC TSKM_SVC_CTX_t*
+getSvcCtxByPid(TSKM_SVCS_CTX_t* p_svcs, pid_t pid) {
+ uint32_t ii;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ if (p_svcs->svcList[ii].pid == pid) {
+ return &p_svcs->svcList[ii];
+ }
+ }
+ return NULL;
+}
+
+/*********************************************************
+ * Get service context
+ *********************************************************/
+TSKM_STATIC TSKM_SVC_CTX_t*
+getSvcCtxByName(TSKM_SVCS_CTX_t* p_svcs, const char *p_name) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ uint32_t ii;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ if (0
+ == strncmp(p_svcs->svcList[ii].attr->name, p_name,
+ strlen(p_svcs->svcList[ii].attr->name))) {
+ return &p_svcs->svcList[ii];
+ }
+ }
+ return NULL;
+}
+// LCOV_EXCL_STOP
+/*********************************************************
+ * Issuing a start request to the service
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t wakeupRequest(TSKM_SVC_CTX_t* p_svc,
+ TSKM_GSTEP_REQ_INFO_t* p_req) {
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+ bzero(&ev, sizeof(ev));
+
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "WAKEUPREQ %s to %s(%d)",
+ tskm_convLocalStep2Str(p_req->localStep), p_svc->attr->name,
+ p_svc->pid);
+
+ ev.event = TSKM_EV_PRI_REQ_WAKEUP;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.reqWakeup.svcId = p_svc->attr->svcId;
+ ev.prm.reqWakeup.localStep = p_req->localStep;
+ ev.prm.reqWakeup.isDynamic =
+ (p_svc->attr->lifeCycle == TSKM_SVC_LC_DYNAMIC) ? TSKM_TRUE : TSKM_FALSE;
+ // Since there is no startup in the P_CWORD72_ but only communication in the ALL/LAST,
+ // the startup information is optimized including the startup information in the communication of the WakeupRequest.
+ memcpy(&ev.prm.reqWakeup.bootInfo, &p_svc->bootInfo,
+ sizeof(ev.prm.reqWakeup.bootInfo));
+ memcpy(&ev.prm.reqWakeup.extBootInfo, &p_svc->extBootInfo,
+ sizeof(ev.prm.reqWakeup.extBootInfo));
+
+ ret = tskm_sockSend(p_svc->connFd, &ev);
+ if (ret <= 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ p_svc->waitResCnt++;
+ p_svc->state = TSKM_SVC_WAKEUP;
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Touch services and extend EXIT timeouts
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t reqTouch(TSKM_SVC_CTX_t* p_svc) {
+#define TSKM_BUF_LEN ( 4 * ( sizeof(struct inotify_event) ) ) /* read size */
+ TSKM_ERR_t funcRet = TSKM_E_NG;
+ char touchFileName[32];
+ BOOL isNeedRetry = FALSE;
+
+ int iFd = p_svc->iFd;
+ int wd = 0;
+
+ TSKM_EVENT_INFO_t ev;
+ int ret;
+ bzero(&ev, sizeof(ev));
+
+ // Create monitoring files
+ tskm_pf_mkTouchFileName(p_svc->pid, touchFileName);
+ if (0 != tskm_pf_touch(touchFileName)) {
+ goto ERROR;
+ }
+
+ // Synchronize by iNortify
+ wd = inotify_add_watch(iFd, touchFileName, IN_DELETE_SELF);
+ if (wd == -1) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+
+ // Send Touch request
+ ev.event = TSKM_EV_PRI_REQ_TOUCH;
+ ev.errCode = TSKM_E_OK;
+ ret = tskm_sockSend(p_svc->connFd, &ev);
+ if (ret <= 0) {
+ // Immediately after the nonresident service process terminates, since the TaskManager service status is other than DORMANT
+ // (mainly DOWN), the socket may be discarded and communication may fail, so retry
+ funcRet = TSKM_E_RETRY;
+ TSKM_PRINTF(TSKM_LOG_WARN, "ret = %d", ret);
+ goto ERROR;
+ }
+
+ // Wait for Touch completion
+ while (1) {
+ int maxFd = 0;
+ int ret;
+ fd_set fds;
+ FD_ZERO(&fds);
+ struct timeval timeout = { 0 };
+ timeout.tv_sec = TSKM_CFG_TOUCH_TIMEOUT;
+
+ FD_SET(iFd, &fds);
+ maxFd = iFd;
+
+ ret = select(maxFd + 1, &fds, NULL, NULL, &timeout);
+ if (ret == 0) {
+ TSKM_ASSERT_PRINT(0, "TIMEOUT:%s", touchFileName); // Timeout occurs
+ isNeedRetry = TRUE;
+ break;
+ } else if (ret < 1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ }
+
+ if (FD_ISSET(iFd, &fds)) {
+ int length;
+ uint8_t buf[TSKM_BUF_LEN];
+
+ length = static_cast<int>(read(iFd, buf, TSKM_BUF_LEN));
+ if (length < 0) {
+ TSKM_ASSERT_ERRNO(0);
+ goto ERROR;
+ }
+ struct inotify_event *event = (struct inotify_event *) buf;
+ if (event->mask & IN_DELETE_SELF) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "TouchOK");
+ wd = 0;
+ // When a file is deleted, the association with the monitoring target is automatically released and inotify_rm_watch is no longer needed.
+ break;
+ } else {
+ TSKM_ASSERT_PRINT(0, "%x", event->mask);
+ }
+ }
+ }
+
+ if (isNeedRetry) {
+ funcRet = TSKM_E_RETRY;
+ } else {
+ funcRet = TSKM_E_OK;
+ }
+
+ ERROR: if (wd > 0) {
+ TSKM_ASSERT_ERRNO(0 == inotify_rm_watch(iFd, wd))
+ }
+
+ if (access(touchFileName, F_OK) == 0) {
+ // Timeout care
+ unlink(touchFileName);
+ }
+
+ return funcRet;
+}
+
+/*********************************************************
+ * Availability Monitoring Callbacks for Services
+ *********************************************************/
+EFrameworkunifiedStatus OnSvcAvailability(HANDLE hApp) { // LCOV_EXCL_START 6: Because the condition cannot be set
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ PCSTR availabilityName;
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+ TSKM_SVC_CTX_t* p_svc;
+
+ availabilityName = FrameworkunifiedGetLastNotification(hApp);
+
+ std::string str = availabilityName;
+
+// unsigned int position;
+// if (std::string::npos != (position = static_cast<unsigned int>(str.find("/Availability", 0)))) {
+ ssize_t position;
+ if (0 <= (position = str.find("/Availability", 0))) {
+ str.erase(position, position + strlen("/Availability"));
+ }
+
+ p_svc = getSvcCtxByName(&p_main->svcs, str.c_str());
+ if (p_svc) {
+ p_svc->isAvailable = FrameworkunifiedIsServiceAvailable(hApp) ? TSKM_TRUE : TSKM_FALSE;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "%s Availability %s", p_svc->attr->name,
+ (p_svc->isAvailable == TSKM_TRUE) ? "TRUE" : "FALSE");
+ }
+
+ return eFrameworkunifiedStatusOK;
+}
+// LCOV_EXCL_STOP
+/*********************************************************
+ * Starting Availability Monitoring of Services
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t startWatchAvailability(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_ERR_t funcRet = TSKM_E_OK;
+
+ // LCOV_EXCL_BR_START 8: Since the condition is checked by the caller, it is not true.
+ if (p_svc->attr->type == TSKM_SVC_TYPE_UNKNONW) {
+ // LCOV_EXCL_BR_STOP
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ p_svc->isAvailable = TSKM_TRUE; // LCOV_EXCL_LINE 8: Since the condition is checked by the caller, it is not true.
+ } else {
+ EFrameworkunifiedStatus taskmanagerStatus;
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+ SS_String availabilityName = p_svc->attr->name;
+
+ availabilityName.append("/Availability");
+
+ taskmanagerStatus = FrameworkunifiedSubscribeNotificationWithCallback(p_main->hApp,
+ availabilityName.c_str(),
+ OnSvcAvailability);
+ if (eFrameworkunifiedStatusOK != taskmanagerStatus) {
+ TSKM_ASSERT(0);
+ funcRet = TSKM_E_NG;
+ }
+ }
+
+ return funcRet;
+}
+
+/*********************************************************
+ * Service startup sub
+ *********************************************************/
+void svcExec_Process(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_ERR_t funcRet;
+
+ if (p_svc->attr->type == TSKM_SVC_TYPE_NATIVE) {
+ p_svc->state = TSKM_SVC_WAITCONNECT;
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "[ST:%d] WAIT_EXEC", p_svc->pid);
+ funcRet = startWatchAvailability(p_svc);
+ if (TSKM_E_OK != funcRet) {
+ TSKM_ASSERT(0);
+ p_svc->isAvailable = TSKM_TRUE;
+ }
+ } else {
+ p_svc->state = TSKM_SVC_RUNNING;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "[ST:%d] RUN", p_svc->pid);
+ p_svc->isAvailable = TSKM_TRUE;
+ }
+ return;
+}
+
+/*********************************************************
+ * Service startup main
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t svcExec(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_ERR_t funcRet = TSKM_E_NG;
+ pid_t pid;
+
+ if (p_svc == NULL) { // LCOV_EXCL_BR_LINE 6:double check
+ // LCOV_EXCL_START 6: double check
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP
+ }
+
+ if (p_svc->state == TSKM_SVC_DISABLE) {
+ // Prohibited startup
+ TSKM_ASSERT(0);
+ return TSKM_E_STATE;
+ } else if (p_svc->state == TSKM_SVC_WAITCONNECT) {
+ return TSKM_E_OK;
+ } else if (p_svc->state != TSKM_SVC_DORMANT) {
+ // Already started
+ funcRet = reqTouch(p_svc);
+ if (TSKM_E_OK != funcRet) {
+ TSKM_PRINTF(TSKM_LOG_WARN, "funcRet = %d", funcRet);
+ goto ERROR;
+ }
+ return TSKM_E_OK;
+ }
+
+ pid = tskm_pf_createProc(p_svc->attr);
+ if (pid <= 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ TSKM_PRINTF(TSKM_LOG_STATE, "EXEC %s:%d", p_svc->attr->name, pid);
+
+ p_svc->pid = pid;
+ p_svc->waitReqCnt = 0;
+
+ // Startup service
+ svcExec_Process(p_svc);
+
+ funcRet = TSKM_E_OK;
+ ERROR: return funcRet;
+}
+
+/*********************************************************
+ * Issuing a start request to the service
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t svcWakeupRequest(TSKM_SVC_CTX_t* p_svc,
+ TSKM_GSTEP_REQ_INFO_t* p_req) {
+ if (p_svc == NULL || p_svc->state == TSKM_SVC_DISABLE) { // LCOV_EXCL_BR_LINE 6: Since this function has always been called after checking // NOLINT(whitespace/line_length)
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return TSKM_E_STATE; // LCOV_EXCL_LINE 6: Since this function has always been called after checking
+ } else if (p_svc->state == TSKM_SVC_WAITCONNECT) {
+ // Remember it once and issue a request when the CONNECT completes.
+ p_svc->request[p_svc->waitReqCnt] = *p_req;
+ p_svc->waitReqCnt++;
+ } else {
+ TSKM_ERR_t tskmRet;
+ tskmRet = wakeupRequest(p_svc, p_req);
+ TSKM_ERR_CHK_DFT;
+ }
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Service reboot processing
+ *********************************************************/
+TSKM_STATIC TSKM_ERR_t svcErrTermPost(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+
+ TSKM_PRINTF(TSKM_LOG_SYSTEMDATA, "ERR TERM SVC(%s:%d)", p_svc->attr->name,
+ p_svc->pid);
+
+ if (p_svc->attr->lifeCycle == TSKM_SVC_LC_ALWAYS || (p_svc->errTermCnt > p_svc->attr->retryCnt && (uint32_t) -1 != p_svc->attr->retryCnt)) { // NOLINT(whitespace/line_length)
+ TSKM_ERROR_REBOOT_t rebootInfo;
+
+ TSKM_ASSERT(0);
+ memset(&rebootInfo, 0, sizeof(TSKM_ERROR_REBOOT_t));
+ rebootInfo.type = TSKM_ERROR_REBOOT_NORMAL;
+ snprintf(rebootInfo.log.messageStr, TSKM_LOGGING_MSG_STR_SIZE,
+ "TaskManager:SVC ErrTerm");
+ tskm_sub_reboot(&rebootInfo);
+ } else {
+ TSKM_LOGGING_INFO_t logInfo;
+ logInfo.type = TSKM_LOGGING_TYPE_MODULE_LOGS;
+
+ snprintf(logInfo.messageStr, TSKM_LOGGING_MSG_STR_SIZE,
+ "TaskManager:SVC ErrTerm");
+ tskm_sub_logging(&logInfo);
+
+ if (p_svc->attr->lifeCycle == TSKM_SVC_LC_ALWAYS_RECOVERABLE) {
+ TSKM_ERR_t ret;
+ TSKM_GSTEP_REQ_INFO_t req = { 0 };
+
+ ret = svcExec(p_svc);
+
+ if (TSKM_E_OK != ret) {
+ TSKM_ASSERT_PRINT(0, "ret = %d", ret);
+ goto ERROR;
+ } else if (p_svc->state == TSKM_SVC_WAITCONNECT) {
+ // In the state waiting for execution
+ req.svcId = p_svc->attr->svcId;
+ req.localStep = TSKM_LSTEP_ALL;
+ ret = svcWakeupRequest(p_svc, &req);
+ if (TSKM_E_OK != ret) {
+ TSKM_ASSERT_PRINT(0, "ret = %d", ret);
+ goto ERROR;
+ }
+ }
+ }
+ }
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Connection handler
+ * ret:TRUE SVC status changed
+ * ret:FALSE SVC status not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t connectHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ uint32_t ii;
+
+ TSKM_ASSERT(p_svc->state == TSKM_SVC_WAITCONNECT);
+
+ p_svc->connFd = p_inEv->prm.repConnect.connFd;
+ p_svc->state = TSKM_SVC_WAKEUP;
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "[ST:%d] WAKEUP", p_svc->pid);
+
+ p_svc->waitResCnt = 0;
+
+ if (p_svc->waitReqCnt) {
+ for (ii = 0; ii < p_svc->waitReqCnt; ii++) {
+ TSKM_ASSERT(TSKM_E_OK == wakeupRequest(p_svc, &p_svc->request[ii]));
+ }
+ p_svc->waitReqCnt = 0;
+ }
+
+ return TSKM_TRUE;
+}
+
+/*********************************************************
+ * Disconnection handler
+ * ret:TRUE SVC status changed
+ * ret:FALSE SVC status not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t disConnectHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ // No status change
+
+ return TSKM_TRUE;
+}
+
+/*********************************************************
+ * Response handler for the activation request
+ * ret:TRUE SVC status changed
+ * ret:FALSE SVC status not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t resWakeupHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ TSKM_ASSERT(p_svc->state == TSKM_SVC_WAKEUP);
+ TSKM_ASSERT(p_svc->waitResCnt > 0);
+ TSKM_BOOL_t isStateChg = TSKM_FALSE;
+
+ if (p_svc->isShmDone == TSKM_FALSE && p_inEv->prm.resWakeup.isShmDone) {
+ p_svc->isShmDone = TSKM_TRUE;
+ isStateChg = TSKM_TRUE;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "%s:SHM DONE", p_svc->attr->name);
+ }
+ if (p_svc->isStepDone == TSKM_FALSE && p_inEv->prm.resWakeup.isStepDone) {
+ p_svc->isStepDone = TSKM_TRUE;
+ isStateChg = TSKM_TRUE;
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "%s:STEP DONE", p_svc->attr->name);
+ }
+
+ if (p_svc->waitResCnt > 0) {
+ p_svc->waitResCnt--;
+ if (p_svc->waitResCnt == 0) { // Transition when the wait runs out
+ if (p_inEv->prm.resWakeup.isLast) {
+ p_svc->state = TSKM_SVC_RUNNING; // Startup completed
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "[ST:%d] RUN", p_svc->pid);
+ }
+ isStateChg = TSKM_TRUE;
+ }
+ }
+ return isStateChg;
+}
+
+/*********************************************************
+ * Response handler for the termination request
+ * ret:TRUE SVC state changed
+ * ret:FALSE SVC state not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t resDownHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ TSKM_ASSERT(p_svc->state == TSKM_SVC_DOWN);
+ TSKM_ASSERT(p_svc->waitResCnt > 0);
+ TSKM_BOOL_t isStateChg = TSKM_FALSE;
+
+ TSKM_PRINTF(TSKM_LOG_DEBUG, "pid:%d waitCnt:%d", p_svc->pid,
+ p_svc->waitResCnt);
+ if (p_svc->waitResCnt > 0) {
+ p_svc->waitResCnt--;
+ if (p_svc->waitResCnt == 0) { // Transition when the wait runs out
+ if (p_inEv->prm.resWakeup.isLast) {
+ p_svc->state = TSKM_SVC_FINDOWN; // Termination complete
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "[ST:%d] FIN_DOWN", p_svc->pid);
+ }
+ isStateChg = TSKM_TRUE;
+ }
+ }
+ return isStateChg;
+}
+
+/*********************************************************
+ * Response Handlers for DebugDump Requests
+ * ret:TRUE SVC state changed
+ * ret:FALSE SVC state not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t resDebugDumpHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ TSKM_BOOL_t isStateChg = TSKM_FALSE;
+ TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *p_prm;
+
+ if (!p_inEv->hasExtend || !p_inEv->extendPrm) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+
+ p_prm = (TSKM_EV_PRI_EX_RES_DEBUGDUMP_PRM_t *) p_inEv->extendPrm; // NOLINT (readability/casting)
+
+ // FALSE is specified here because the required service names have been added in the PrimaryLib.
+ tskm_sub_debugDumpRes(FALSE, p_prm->dumpMsg);
+
+ ERROR: return isStateChg;
+}
+
+/*********************************************************
+ * Service termination request
+ * ret:TRUE SVC state changed
+ * ret:FALSE SVC state not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t reqExit(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ int ret;
+ TSKM_ERR_t tskmRet;
+ TSKM_ASSERT(p_svc->state == TSKM_SVC_RUNNING);
+ TSKM_ASSERT(p_svc->waitResCnt == 0);
+ TSKM_GSTEP_REQ_INFO_t req = { 0 };
+
+ req.svcId = p_svc->attr->svcId;
+ req.localStep = TSKM_LSTEP_ALL;
+ tskmRet = tskm_svcDownRequest(p_svc, &req);
+ TSKM_ERR_CHK_DFT;
+
+ return TSKM_TRUE;
+
+ // LCOV_EXCL_START 8: dead code
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ ERROR: ret = tskm_pf_terminateProcGroup(static_cast<uint16_t>(p_svc->pid));
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 8: dead code
+ TSKM_PRINTF(TSKM_LOG_WARN, "ret = %d", ret);
+ }
+
+ return TSKM_TRUE;
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************************
+ * Service termination handler
+ * ret:TRUE SVC state changed
+ * ret:FALSE SVC state not changed
+ *********************************************************/
+TSKM_STATIC TSKM_BOOL_t repTermHandle(TSKM_SVC_CTX_t* p_svc,
+ const TSKM_EVENT_INFO_t* p_inEv) {
+ int ret;
+
+ // Check error
+ if (p_svc->attr->lifeCycle == TSKM_SVC_LC_DYNAMIC) {
+ if (p_svc->state != TSKM_SVC_DOWN) {
+ // A STATE other than DOWN does not terminate.
+ TSKM_PRINTF(TSKM_LOG_ERROR, "ERR TERM %s(%d) waitCnt:%d",
+ p_svc->attr->name, p_svc->pid, p_svc->waitResCnt);
+ TSKM_ASSERT(0);
+ }
+ } else {
+ // The resident service terminated.
+ TSKM_PRINTF(TSKM_LOG_ERROR, "ERR TERM %s(%d) waitCnt:%d", p_svc->attr->name,
+ p_svc->pid, p_svc->waitResCnt);
+ TSKM_ASSERT(0);
+ }
+
+ TSKM_PRINTF(TSKM_LOG_STATE, "[ST:%d] DORMANT", p_svc->pid);
+
+ p_svc->state = TSKM_SVC_DORMANT;
+ p_svc->waitResCnt = 0;
+ p_svc->pid = 0;
+
+ if (p_svc->attr->type == TSKM_SVC_TYPE_NATIVE) {
+ EFrameworkunifiedStatus taskmanagerStatus;
+ TSKM_MAIN_CTX_t* p_main = tskm_getMainCtx();
+ SS_String availabilityName = p_svc->attr->name;
+ availabilityName.append("/Availability");
+
+ taskmanagerStatus = FrameworkunifiedUnsubscribeNotificationWithCallback(
+ p_main->hApp, availabilityName.c_str());
+ if (eFrameworkunifiedStatusOK != taskmanagerStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ p_svc->isAvailable = TSKM_FALSE;
+ p_svc->watchCnt = 0;
+
+ HANDLE hMq = McOpenSender(FRAMEWORKUNIFIED_NS_NPSERVICE);
+ if (NULL == hMq) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 4: NSFW error case.
+ } else {
+ ServiceAvailability availInfo = { };
+
+ snprintf(availInfo.cServiceName, MAX_NAME_SIZE_APP, "%s",
+ p_svc->attr->name);
+ availInfo.eServiceAvailability = eFrameworkunifiedServiceNotAvailable;
+
+ taskmanagerStatus = NPPublishNotification(hMq, p_svc->attr->name,
+ availabilityName.c_str(), &availInfo,
+ sizeof(availInfo));
+ if (eFrameworkunifiedStatusOK != taskmanagerStatus) {
+ TSKM_ASSERT(0);
+ }
+
+ taskmanagerStatus = McClose(hMq);
+ if (eFrameworkunifiedStatusOK != taskmanagerStatus) { // LCOV_EXCL_BR_LINE 4: NSFW error case.
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0); // LCOV_EXCL_LINE 4: NSFW error case.
+ }
+ }
+ }
+
+ if (p_inEv->errCode != TSKM_E_OK) {
+ p_svc->errTermCnt++;
+ // Notify 'NG' at Relaunch after abnormal termination
+ p_svc->bootInfo.resetStatus = e_SS_SM_RESET_STATUS_NG;
+
+ ret = svcErrTermPost(p_svc);
+ if (ret != TSKM_E_OK) {
+ TSKM_ASSERT(0);
+ }
+ } else {
+ // NONE is notified at Relaunch after normal completion.
+ p_svc->bootInfo.resetStatus = e_SS_SM_RESET_STATUS_NONE;
+ }
+
+ return TSKM_TRUE;
+}
+
+/*********************************************************
+ * Get service context
+ *********************************************************/
+TSKM_SVC_CTX_t*
+tskm_svcsGetSvcBySvcId(TSKM_SVCS_CTX_t* p_svcs, TSKM_SVCID_t svcId) {
+ return getSvcCtxBySvcId(p_svcs, svcId);
+}
+
+/*********************************************************
+ * Get service context
+ *********************************************************/
+TSKM_SVC_CTX_t*
+tskm_svcsGetSvcByPid(TSKM_SVCS_CTX_t* p_svcs, pid_t pid) {
+ return getSvcCtxByPid(p_svcs, pid);
+}
+
+/*********************************************************
+ * Check for waiting services
+ *********************************************************/
+TSKM_BOOL_t tskm_svcsIsWaiting(TSKM_SVCS_CTX_t* p_svcs) {
+ uint32_t ii;
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ if (p_svcs->svcList[ii].waitResCnt > 0
+ || p_svcs->svcList[ii].state == TSKM_SVC_WAITCONNECT) {
+ return TSKM_TRUE;
+ }
+ }
+ return TSKM_FALSE;
+}
+
+/*********************************************************
+ * Check if ShutdownWait services are terminated
+ *********************************************************/
+TSKM_SVC_WAIT_STATE_t tskm_svcsGetSvcTermWaitState(TSKM_SVCS_CTX_t* p_svcs) {
+ uint32_t ii;
+ TSKM_SVC_WAIT_STATE_t waitState = TSKM_SVC_WAIT_NONE;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ if (p_svcs->svcList[ii].attr->shotdownWait) {
+ // Check shutdownWait SVC Only
+ if (p_svcs->svcList[ii].state != TSKM_SVC_DORMANT) {
+ // DORMANT is terminated or not started, so no checking is required
+ if (TSKM_SVC_LC_DYNAMIC != p_svcs->svcList[ii].attr->lifeCycle
+ && p_svcs->svcList[ii].state != TSKM_SVC_FINDOWN) { // Check of termination of resident SVCs
+ waitState = TSKM_SVC_WAIT_BOTH;
+ break;
+ } else if (TSKM_SVC_LC_DYNAMIC == p_svcs->svcList[ii].attr->lifeCycle) { // Check of termination of non-resident SVCs
+ waitState = TSKM_SVC_WAIT_TRANSIENT;
+ }
+ }
+ }
+ }
+ return waitState;
+}
+
+/*********************************************************
+ * Update boot info of all services
+ *********************************************************/
+TSKM_ERR_t tskm_svcsSetBootInfo(TSKM_SVCS_CTX_t* p_svcs,
+ T_SS_SM_START_DataStructType* p_info,
+ T_SS_SM_START_ExtDataStructType *p_exInfo) {
+ uint32_t ii = 0;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ p_svcs->svcList[ii].bootInfo = *p_info;
+ p_svcs->svcList[ii].extBootInfo = *p_exInfo;
+ }
+ return TSKM_E_OK;
+}
+
+/*********************************************************
+ * Terminates a running non-resident services
+ *********************************************************/
+TSKM_ERR_t tskm_svcsAvtiveSvcTerm(TSKM_SVCS_CTX_t* p_svcs) {
+ uint32_t ii;
+
+ for (ii = 0; ii < p_svcs->svcNum; ii++) {
+ TSKM_SVC_CTX_t* p_svc = &p_svcs->svcList[ii];
+
+ if (TSKM_SVC_LC_DYNAMIC == p_svc->attr->lifeCycle && // Non-resident SVC
+ TSKM_SVC_RUNNING == p_svc->state && p_svc->waitResCnt == 0) { // Running
+ TSKM_ERR_t tskmRet;
+ TSKM_GSTEP_REQ_INFO_t req = { 0 };
+
+ req.svcId = p_svc->attr->svcId;
+ req.localStep = TSKM_LSTEP_ALL;
+ tskmRet = tskm_svcDownRequest(p_svc, &req);
+ TSKM_ERR_CHK_DFT;
+ }
+ }
+
+ return TSKM_E_OK;
+
+ ERROR:
+ return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Calls back the DebugDump of the running services
+ *********************************************************/
+TSKM_ERR_t tskm_svcsCallDebugDump(TSKM_SVCS_CTX_t* p_svcs) {
+ for (uint32_t ii = 0; ii < p_svcs->svcNum; ii++) {
+ TSKM_SVC_CTX_t* p_svc = &p_svcs->svcList[ii];
+
+ if (TSKM_SVC_RUNNING == p_svc->state) { // Running
+ TSKM_EVENT_INFO_t ev;
+ bzero(&ev, sizeof(ev));
+
+ // Send DebugDump request
+ ev.event = TSKM_EV_PRI_REQ_DEBUGDUMP;
+ ev.errCode = TSKM_E_OK;
+ if (0 >= tskm_sockSend(p_svc->connFd, &ev)) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ }
+ }
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Calls back the LowMemory of the running services
+ *********************************************************/
+TSKM_ERR_t tskm_svcsCallLowMem(TSKM_SVCS_CTX_t* p_svcs) {
+ for (uint32_t ii = 0; ii < p_svcs->svcNum; ii++) {
+ TSKM_SVC_CTX_t* p_svc = &p_svcs->svcList[ii];
+ if (TSKM_SVC_RUNNING == p_svc->state) { // Running
+ TSKM_EVENT_INFO_t ev;
+ bzero(&ev, sizeof(ev));
+
+ // Send LowMemory detection notification
+ ev.event = TSKM_EV_PRI_REP_LOWMEM;
+ ev.errCode = TSKM_E_OK;
+ if (0 >= tskm_sockSend(p_svc->connFd, &ev)) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ }
+ }
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Event handler
+ *********************************************************/
+TSKM_ERR_t tskm_svcEventHandle(TSKM_SVC_CTX_t* p_svc, TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_FUNC_IN();
+ TSKM_BOOL_t isStateChg = TSKM_FALSE;
+
+ if (isSvcEvent(p_ev) == TSKM_FALSE) {
+ // If it is not an event for the service, it will be sent as follows.
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+ }
+
+ switch (p_ev->event) {
+ case TSKM_EV_PRI_REP_CONNECT: // Connection Registration from Service
+ isStateChg = connectHandle(p_svc, p_ev);
+ break;
+ case TSKM_EV_PRI_REP_DISCONNECT: // Disconnection Registration from Service
+ isStateChg = disConnectHandle(p_svc, p_ev);
+ break;
+ case TSKM_EV_PRI_RES_WAKEUP: // Response to a startup request from a service
+ isStateChg = resWakeupHandle(p_svc, p_ev);
+ break;
+ case TSKM_EV_PRI_RES_DOWN:
+ isStateChg = resDownHandle(p_svc, p_ev);
+ break;
+ case TSKM_EV_PRI_RES_DEBUGDUMP:
+ isStateChg = resDebugDumpHandle(p_svc, p_ev);
+ break;
+ case TSKM_EV_PRI_REQ_EXIT:
+ isStateChg = reqExit(p_svc, p_ev);
+ break;
+ case TSKM_EV_SVC_REP_TERM: // Service termination
+ isStateChg = repTermHandle(p_svc, p_ev);
+ break;
+ default:
+ break;
+ }
+
+ // Overwrite service state change
+ if (isStateChg) {
+ p_ev->event = TSKM_EV_LCL_CHG_SVC_STATE;
+ p_ev->prm.chgSvc.svcId = p_svc->attr->svcId;
+ } else {
+ p_ev->event = TSKM_EV_NOP;
+ }
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+/*********************************************************
+ * Startup service
+ *********************************************************/
+TSKM_ERR_t tskm_svcExec(TSKM_SVC_CTX_t* p_svc) {
+ return svcExec(p_svc);
+}
+
+/*********************************************************
+ * Issue a startup request to the service
+ *********************************************************/
+TSKM_ERR_t tskm_svcWakeupRequest(TSKM_SVC_CTX_t* p_svc,
+ TSKM_GSTEP_REQ_INFO_t* p_req) {
+ return svcWakeupRequest(p_svc, p_req);
+}
+
+/*********************************************************
+ * Issue a termination request to the service
+ *********************************************************/
+TSKM_ERR_t tskm_svcDownRequest(TSKM_SVC_CTX_t* p_svc,
+ TSKM_GSTEP_REQ_INFO_t* p_req) {
+ int ret;
+ TSKM_EVENT_INFO_t ev;
+
+ bzero(&ev, sizeof(ev));
+
+ if (tskm_svcIsCommunicatable(p_svc) == TSKM_FALSE) {
+ return TSKM_E_OK;
+ }
+
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "DOWNREQ %s to %s(%d)",
+ tskm_convLocalStep2Str(p_req->localStep), p_svc->attr->name,
+ p_svc->pid);
+
+ ev.event = TSKM_EV_PRI_REQ_DOWN;
+ ev.errCode = TSKM_E_OK;
+ ev.prm.reqDown.localStep = p_req->localStep;
+
+ ret = tskm_sockSend(p_svc->connFd, &ev);
+ if (ret <= 0) {
+ TSKM_ASSERT(0);
+ goto ERROR;
+ }
+ p_svc->waitResCnt++;
+ p_svc->state = TSKM_SVC_DOWN;
+
+ return TSKM_E_OK;
+ ERROR: return TSKM_E_NG;
+}
+
+/*********************************************************
+ * Prohibit starting service
+ *********************************************************/
+TSKM_ERR_t tskm_svcDisableRequest(TSKM_SVC_CTX_t* p_svc) {
+ if (p_svc->state == TSKM_SVC_DORMANT || p_svc->state == TSKM_SVC_DISABLE) {
+ p_svc->state = TSKM_SVC_DISABLE;
+ return TSKM_E_OK;
+ }
+ return TSKM_E_STATE;
+}
+
+/*********************************************************
+ * Allow starting service
+ *********************************************************/
+TSKM_ERR_t tskm_svcEnableRequest(TSKM_SVC_CTX_t* p_svc) {
+ if (p_svc->state == TSKM_SVC_DISABLE) {
+ p_svc->state = TSKM_SVC_DORMANT;
+ }
+ return TSKM_E_OK;
+}
+
+/*********************************************************
+ * Queriy whether the service is ready for communication
+ *********************************************************/
+TSKM_BOOL_t tskm_svcIsCommunicatable(TSKM_SVC_CTX_t* p_svc) {
+ TSKM_BOOL_t ret = TSKM_FALSE;
+ if (p_svc == NULL || p_svc->attr->type == TSKM_SVC_TYPE_UNKNONW) {
+ } else {
+ switch (p_svc->state) {
+ case TSKM_SVC_WAKEUP:
+ case TSKM_SVC_RUNNING:
+ case TSKM_SVC_DOWN:
+ ret = TSKM_TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ return ret;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_wakeup.cpp b/task_manager/server/src/tskm_wakeup.cpp
new file mode 100644
index 00000000..5988e228
--- /dev/null
+++ b/task_manager/server/src/tskm_wakeup.cpp
@@ -0,0 +1,201 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_wakeup.h"
+#include "tskm_debug.h"
+#include "tskm_util.h"
+#include "tskm_state.h"
+#include "tskm_port_subsys.h"
+#include "tskm_port_pf.h"
+
+#include "tskm_gstep.h"
+
+
+/*********************************************************
+ * Get gradual startup context
+ *********************************************************/
+TSKM_STATIC TSKM_GSTEP_CTX_t*
+gstepGetWakeupCtx(TSKM_MAIN_CTX_t* p_main) {
+ return &p_main->wakeup;
+}
+
+/***********************************************************************
+ * Startup completion process
+ ***********************************************************************/
+TSKM_STATIC void wakeupFinish(TSKM_MAIN_CTX_t* p_main) {
+ return;
+}
+
+/*********************************************************
+ * Challenge for a transition to the next state
+ *********************************************************/
+TSKM_STATIC void tryTransNextState(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_GSTEP_CTX_t* p_wakeup;
+ TSKM_GSTEP_t* p_current;
+
+ p_wakeup = gstepGetWakeupCtx(p_main);
+ p_current = gstepGetCurrent(p_wakeup);
+
+ if (!p_current) {
+ return;
+ }
+
+ // LCOV_EXCL_BR_START 8: Because the second condition in the if statement is never false
+ if (tskm_svcsIsWaiting(&p_main->svcs) == TSKM_FALSE && // No waiting services
+ ((p_wakeup->compState & p_current->nextTransCond)
+ == p_current->nextTransCond)) { // Event completion condition
+ // LCOV_EXCL_BR_STOP
+ if (gstepIsLast(p_wakeup)) {
+ tskm_stateTransit(p_main, TSKM_ST_WAKEUP, TSKM_ST_RUNNING);
+ } else {
+ tskm_stateTransit(p_main, TSKM_ST_WAKEUP, TSKM_ST_WAKEUP);
+ }
+ }
+}
+
+/*********************************************************
+ * Gradual startup request issuance process
+ *********************************************************/
+TSKM_ERR_t tskm_entryWakeup_Req(TSKM_MAIN_CTX_t* p_main,
+ TSKM_GSTEP_t* p_current) {
+ uint32_t ii;
+
+ // Refer to the stepId and perform preprocessing if needed.
+ if (p_current->gstepId == TSKM_GSTEP_BUPCHK) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "BUPCHK EXE");
+ // When TaskManager is used as a system Launcher, system data is initialized here.
+ }
+
+ // Start process
+ for (ii = 0; ii < p_current->execSvcNum; ii++) {
+ TSKM_ERR_t tskmRet;
+ TSKM_SVCID_t svcId = p_current->execSvcIdList[ii];
+ TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs, svcId);
+
+ tskmRet = tskm_svcExec(p_svc);
+ TSKM_ERR_CHK_DFT;
+ }
+
+ // Issue gradual startup request
+ for (ii = 0; ii < p_current->reqNum; ii++) {
+ TSKM_ERR_t tskmRet;
+ TSKM_GSTEP_REQ_INFO_t* p_req = &p_current->reqList[ii];
+ TSKM_SVC_CTX_t* p_svc = tskm_svcsGetSvcBySvcId(&p_main->svcs, p_req->svcId);
+
+ // Queuing in the SVC layer even for services that are not started.
+ tskmRet = tskm_svcWakeupRequest(p_svc, p_req);
+ TSKM_ERR_CHK_DFT; // LCOV_EXCL_BR_LINE 6: Because TSKM_ERR_CHK_DFT does not specify a condition for goto to ERROR
+ }
+
+ if (p_current->nextTransCond) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "WAIT COMP:%s(%llx)",
+ tskm_convInitCompId2Str(p_current->nextTransCond),
+ p_current->nextTransCond);
+ }
+
+ return TSKM_E_OK;
+
+ // LCOV_EXCL_START 6: Checked in Death testing, but it is not reflected in the coverage and excluded
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return TSKM_E_NG;
+ // LCOV_EXCL_STOP
+}
+
+/*********************************************************
+ * Gradual startup entry process
+ *********************************************************/
+TSKM_ERR_t tskm_entryWakeup(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_FUNC_IN();
+
+ TSKM_GSTEP_CTX_t* p_wakeup;
+ TSKM_GSTEP_t* p_current;
+
+ p_main->state = TSKM_ST_WAKEUP;
+ p_wakeup = gstepGetWakeupCtx(p_main);
+ p_current = gstepGetCurrent(p_wakeup);
+
+ if (p_current == NULL) { // LCOV_EXCL_BR_LINE 8: Because condition false setting is not possible
+ // LCOV_EXCL_START 8: Because condition false setting is not possible
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ tskm_pf_exit(EXIT_FAILURE);
+ // LCOV_EXCL_STOP
+ }
+
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "WAKEUP GSTEP:%d", p_wakeup->gstepIdx);
+
+ if (tskm_entryWakeup_Req(p_main, p_current) == TSKM_E_NG) { // LCOV_EXCL_BR_LINE 200:the function of tskm_entryWakeup_Req can not be TSKM_E_NG at this case // NOLINT(whitespace/line_length)
+ // LCOV_EXCL_START 200:the function of tskm_entryWakeup_Req can not be TSKM_E_NG at this case // NOLINT(whitespace/line_length)
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ tskm_pf_exit(EXIT_FAILURE);
+ // LCOV_EXCL_STOP
+ }
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*********************************************************
+ * Gradual startup exit process
+ *********************************************************/
+TSKM_ERR_t tskm_exitWakeup(TSKM_MAIN_CTX_t* p_main) {
+ TSKM_GSTEP_CTX_t* p_wakeup;
+
+ TSKM_FUNC_IN();
+ p_wakeup = gstepGetWakeupCtx(p_main);
+
+ // Exit process at the end of the gradual startup
+ if (gstepIsLast(p_wakeup)) {
+ TSKM_PRINTF(TSKM_LOG_STATE, "WAKEUP FIN");
+ wakeupFinish(p_main);
+ }
+
+ changeNextStep(p_wakeup); // Transition to next step
+
+ TSKM_FUNC_OUT();
+ return TSKM_E_OK;
+}
+
+/*********************************************************
+ * Gradual startup handler
+ *********************************************************/
+TSKM_ERR_t tskm_handleWakeup(TSKM_MAIN_CTX_t* p_main, TSKM_EVENT_INFO_t* p_ev) {
+ TSKM_FUNC_IN();
+ TSKM_ERR_t tskmRet = TSKM_E_OK;
+
+ switch (p_ev->event) {
+ case TSKM_EV_PRI_REP_WAKEUP_COMP: // Event completion notification at startup
+ {
+ TSKM_PRINTF(TSKM_LOG_SVCSTATE, "INIT COMP :%s(%#llx) from:%d",
+ tskm_convInitCompId2Str(p_ev->prm.repWakeupComp.compId),
+ p_ev->prm.repWakeupComp.compId, p_ev->fromPid);
+ TSKM_GSTEP_CTX_t* p_wakeup = gstepGetWakeupCtx(p_main);
+ p_wakeup->compState |= p_ev->prm.repWakeupComp.compId;
+ tryTransNextState(p_main);
+ }
+ break;
+ case TSKM_EV_LCL_CHG_SVC_STATE: // Service state change
+ tryTransNextState(p_main);
+ break;
+ default:
+ tskmRet = tskm_handleAccon(p_main, p_ev);
+ break;
+ }
+ TSKM_FUNC_OUT();
+ return tskmRet;
+} // LCOV_EXCL_BR_LINE 10: Final line
+
diff --git a/task_manager/server/src/tskm_watch.cpp b/task_manager/server/src/tskm_watch.cpp
new file mode 100644
index 00000000..5ed9313c
--- /dev/null
+++ b/task_manager/server/src/tskm_watch.cpp
@@ -0,0 +1,101 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tskm_watch.h"
+#include <agl_thread.h>
+
+#include "tskm_debug.h"
+#include "tskm_port_pf.h"
+#include "tskm_comm.h"
+
+
+#define WATCH_CYCLE 5
+
+#define TIMER_THREAD_NAME "SS_TskmTimer"
+
+/*******************************************************************
+ * Periodic Timer-Thread MAIN Function
+ *******************************************************************/
+void *
+watchMain(void *arg) {
+ int connFd = -1;
+
+ connFd = tskm_cliSockConnect(TSKM_SOCKET_NAME);
+ if (connFd < 0) { // LCOV_EXCL_BR_LINE 5: system function(uinx) "socket" fail process
+ // LCOV_EXCL_START 5: system function(uinx) "socket" fail process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5
+ }
+
+ while (1) {
+ int ret;
+ TSKM_EVENT_INFO_t ev;
+
+ sleep(WATCH_CYCLE);
+
+ ev.event = TSKM_EV_LCL_REP_POLLING;
+ ev.errCode = TSKM_E_OK;
+ ret = tskm_sockSend(connFd, &ev);
+ if (ret <= 0) { // LCOV_EXCL_BR_LINE 5: system function(uinx) "send" fail process
+ // LCOV_EXCL_START 5: system function(uinx) "send" fail process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5
+ }
+ }
+
+ // LCOV_EXCL_START 6: system function(uinx) call fail process
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ if (connFd != -1) {
+ tskm_sockDestory(connFd);
+ }
+
+ return 0;
+ // LCOV_EXCL_STOP
+}
+
+/*******************************************************************
+ * Periodic Timer thread start
+ *******************************************************************/
+int tskm_watch_startTimer() {
+ int ret;
+ pthread_t thId = { 0 };
+
+ ret = tskm_pf_createThread(watchMain, NULL, PR_SS_TSKMTIMER,
+ TIMER_THREAD_NAME, &thId);
+ if (ret != 0) { // LCOV_EXCL_BR_LINE 5: system function(uinx) "pthread_*" fail process
+ // LCOV_EXCL_START 5: system function(uinx) "pthread_*" fail process
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ TSKM_ASSERT(0);
+ goto ERROR;
+ // LCOV_EXCL_STOP 5
+ } else {
+ TSKM_PRINTF(TSKM_LOG_STATE, "watch thread created.");
+ }
+
+ return 0;
+
+ // LCOV_EXCL_LINE 6: system function(uinx) "pthread_*" fail process
+ ERROR:
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return -1;
+ // LCOV_EXCL_STOP
+}
+