diff options
Diffstat (limited to 'nsframework/framework_unified/client/NS_Timer/src')
4 files changed, 948 insertions, 0 deletions
diff --git a/nsframework/framework_unified/client/NS_Timer/src/makefile_PosixBasedOS001 b/nsframework/framework_unified/client/NS_Timer/src/makefile_PosixBasedOS001 new file mode 100644 index 00000000..b3eb74da --- /dev/null +++ b/nsframework/framework_unified/client/NS_Timer/src/makefile_PosixBasedOS001 @@ -0,0 +1,206 @@ +# +# @copyright Copyright (c) 2016-2020 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. +# + +# +# Standard Module Makefile version 2.0 +# + +# Name of the componet (team/domain prefix '_' component name) +COMPONENT_NAME = NS_Timer + +ifndef PRJ_ROOT +export PRJ_ROOT = $(CURDIR)/../ +endif +include $(PRJ_ROOT)cfg/depends.mk + +# Name of the componet (team/domain prefix '_' component name) +# This must be the same as the RTC Component name and Eclipse Project Name +COMPONENT_NAME = NS_Timer + + +# Additive Compile Flags (Flags from initiating make process will still apply) +DEFS += + +# Set local includes and then the reference includes (priority order determines search path) +# Default pattern are any configuration includes (which would be things like PosixBasedOS001), local (Team) component directories, +# dependencies includes (other teams) +# Local (current component references should be in the form of +# $(CC_IFLAG)$(TEAM_ROOT)$(COMPONENT_NAME)/directory +# Example your public include directory would be +# $(CC_IFLAG)$(TEAM_ROOT)$(COMPONENT_NAME)/inc +# Team references should only be to other's public includes such as +# $(CC_IFLAG)$(TEAM_ROOT)NS_MessageCenter/inc +# Global (non-team) references should be only to other's public includes such +# these are found in the depends include file and captured in the (DEPENDS_INCLUDES) variable +INCLUDES = \ + $(CFG_INCS) \ + $(CC_IFLAG)./ \ + $(DEPENDS_INCLUDES) \ + $(CC_IFLAG)$(TEAM_ROOT)$(COMPONENT_NAME)/inc + + +# Do the same if you need to include library paths as well +# Do an incremental in case additional library paths are defined +# at the top-level make. Use similar guidelines as for includes +# for example to include a team component library it would be +# $(TEAM_ROOT)NS_MessageCenter/lib/NS_MessageCenter/ +LIB_PATHS += \ + $(DEPENDS_LIB_PATHS) \ + + + +# Define binary outputs. These can be libraries or executables. +# Name a variable for each deliverable. Suffixes should be +# EXEC - For Executables -> output to the bin directory +#TIME_EXEC = $(BIN_PATH)time +# LIB - For Static Libraries -> output to lib directory with specific naming +#MATH_LIB = $(LIB_PATH)$(LIB_PREFIX)math.$(LIB_EXT) +# SLIB - For Shared Objects +#FRMWRK_SLIB = $(SLIB_PATH)frmwrk.$(SO_EXT) +# LIB - Define the static library for Message Queue +# +# +ifdef DYNAMIC + COMPONENT_LIB = $(SLIB_PATH)$(LIB_PREFIX)$(COMPONENT_NAME)$(DEBUG_EXT).$(SO_EXT) +else + COMPONENT_LIB = $(LIB_PATH)$(LIB_PREFIX)$(COMPONENT_NAME)$(DEBUG_EXT).$(LIB_EXT) +endif + +## Sources Section + +# Define Library & Executable Sources (on a per deliverable basis) +# This includes sources located in subdirectories. + +# Define generic line that pulls all c, cc, cpp files +# since your in the src folder is pull only files from there +COMPONENT_SRCS = \ + $(wildcard *.c) \ + $(wildcard *.cpp) + +# Define sources that my not be local to your component +# here, you can define indivial files or wildcard from +# a different folder. +NON_LOCAL_SRCS = \ + + +# List of all sources to be built. Can be assembled from the other defintitions. +# This only defines sources for the current directory, so if there are subdirectories +# those are not included. (Those are found in simple subdirectory makefiles that only +# direct the building of sources, but no linking into a binary) +SOURCES = \ + $(COMPONENT_SRCS) \ + $(NON_LOCAL_SRCS) \ + + + +# +# Convert the source files to object files with correct folder location. +# +# +C_LANG_OBJECTS = $(addprefix $(BLD_PATH),$(addsuffix .$(OBJ_EXT),$(basename $(filter %.c ,$(SOURCES) ) ) ) ) +CPP_LANG_OBJECTS = $(addprefix $(BLD_PATH),$(addsuffix .$(OBJ_EXT),$(basename $(filter %.cpp %.cc %.cxx,$(SOURCES) ) ) ) ) + + +# List of all sources to be generated. Can be assembled from the other defintitions. +OBJECTS = \ + $(C_LANG_OBJECTS) \ + $(CPP_LANG_OBJECTS) + + + +# All headers that are dependencies. Wildcard is easy to pickup local headers. +# This is only to automate the rebuilding, all builds on the servers are cleans +# So this is not a huge deal when building on a component level. +HEADERS = \ + $(wildcard *.h) \ + $(wildcard $(PRJ_ROOT)../$(COMPONENT_NAME)/inc/*.h) \ + + +LIBRARIES = \ + $(COMPONENT_LIB) \ + +ifdef DYNAMIC + DYNAMIC_LIBS += \ + NS_MessageCenter$(DEBUG_EXT) +else + STATIC_LIBS += +endif + +# Make targets +# Standard +all: banner module_dirs subdirs local library binary + +debug: + $(MAKE) TARGET=arm DEBUG=TRUE all + +base: banner module_dirs subdirs local + +# Standard Building of Source Files (Default builds for all objects defined above) +$(C_LANG_OBJECTS): $(SOURCES) $(HEADERS) + $(CC_CMD) + +$(CPP_LANG_OBJECTS): $(SOURCES) $(HEADERS) + $(CPP_CMD) + +local: $(OBJECTS) + +# Defines specific for each deliverable + +# For a static library +$(COMPONENT_LIB): $(OBJECTS) +ifdef DYNAMIC +# For a dynamic library + $(SLIB_CMD) + $(HIDE_ECHO_FLAG)$(OBJCPY) --only-keep-debug $(@) $(@).debug + $(HIDE_ECHO_FLAG)$(OBJCPY) --strip-all $(@) + $(HIDE_ECHO_FLAG)$(OBJCPY) --add-gnu-debuglink=$(@).debug $(@) +else +# For a static library + $(AR_CMD) +endif + +# Standard set of derived targets +library: base \ + $(LIBRARIES) + @echo "***** `date` Done building library: $(COMPONENT_NAME) ******" + +binary: base \ + $(BINARIES) + +# Subdirs should be to jump to subdirectories +# standard form is of +# $(MAKE) -C subdirectory_name $(MAKECMDGOALS) +subdirs: + +clean: + -rm -f $(BINARIES) + -rm -f $(LIBRARIES) + -rm -f $(OBJECTS) + -rm -f $(COMPONENT_LIB).map + -rm -f $(COMPONENT_LIB).debug + +-v: + @echo "objs: --> $(OBJECTS)" + @echo "sources: --> $(SOURCES)" + @echo "headers: --> $(HEADERS)" + @echo "includes: --> $(INCLUDES)" + @echo "lib paths: --> $(LIB_PATHS)" + @echo "static libs: --> $(LD_STATIC_LIBS)" + @echo "dynamic libs: --> $(LD_DYNAMIC_LIBS)" + @echo "lib: --> $(LIBRARIES)" + @echo "bin: --> $(BINARIES)" + +module_dirs: build_dirs diff --git a/nsframework/framework_unified/client/NS_Timer/src/mod_version.c b/nsframework/framework_unified/client/NS_Timer/src/mod_version.c new file mode 100644 index 00000000..c6e28eb5 --- /dev/null +++ b/nsframework/framework_unified/client/NS_Timer/src/mod_version.c @@ -0,0 +1,51 @@ +/* + * @copyright Copyright (c) 2016-2020 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. + */ + +/////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_ModVersion +/// \brief Identifies module version +/// +/// +/// +/////////////////////////////////////////////////////////////////////////////// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <native_service/frameworkunified_types.h> + +#define MOD_VERSION_LENGTH 12 + + + +static CHAR s_ModVersion[MOD_VERSION_LENGTH + 1] = "0.0.0"; + +SI_8 GetModuleVersion(CHAR *pRetBuf, UI_8 nBufLen) { // LCOV_EXCL_START 8: dead code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + UI_8 CopyLen = 0; + SI_8 RetVal = -1; + + if (NULL != pRetBuf) { + CopyLen = MIN_VAL(nBufLen, MOD_VERSION_LENGTH); + strncpy(pRetBuf, s_ModVersion, CopyLen); + pRetBuf[CopyLen] = '\0'; + RetVal = 0; + } + return RetVal; +} +// LCOV_EXCL_STOP + diff --git a/nsframework/framework_unified/client/NS_Timer/src/ns_timer.c b/nsframework/framework_unified/client/NS_Timer/src/ns_timer.c new file mode 100644 index 00000000..d24264b1 --- /dev/null +++ b/nsframework/framework_unified/client/NS_Timer/src/ns_timer.c @@ -0,0 +1,514 @@ +/* + * @copyright Copyright (c) 2016-2020 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. + */ + +/////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_NSTimer +/// \brief Native Services Timer Interface code +/// +/// +/// +/////////////////////////////////////////////////////////////////////////////// + +#include <unistd.h> +#include <string.h> +#include <malloc.h> +#include <errno.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> +#include <sys/timerfd.h> +#include <sys/prctl.h> + +#include <native_service/ns_timer_if.h> +#include <ns_timer_handle.h> +#include <native_service/ns_message_center_if.h> +#include <ns_timer_internal.h> +#include <native_service/ns_logger_if.h> +#include <native_service/ns_resource_controler.h> + +#define INVALID_TIMERFD -1 + +#define RUNNING_STATE 0 +#define DELETING_STATE 1 +#define DELETED_STATE 2 + +#define MAX_FD_EPOLL 10 + +int epollFd; // To listen to multiple timerfd events. +int eventFd; // To use not complete at epoll_wait +pthread_t timerTh_id = 0; // Thread ID of the TimerMonitoringThread +pthread_mutex_t m_mtx = PTHREAD_MUTEX_INITIALIZER; + +const UI_32 MS_IN_SEC = 1000; +const UI_64 NS_IN_MS = 1000000; + +BOOL DebugFlag = FALSE; + +static PVOID TimerMonitoringThread(PVOID args) { + struct epoll_event events[MAX_FD_EPOLL]; + int nfds; // The number of events received + int n; // Loop counter + PNSTimerHandle hTimer; + char *p, name[32]; + uint64_t exp; + + // Thread naming +#define NSTIMER_APPEND_NAME "_T" +#ifndef NSTIMER_SIZE_PROCESSNAME +#define NSTIMER_SIZE_PROCESSNAME 15 // Profiler analysis tool name length limitations +#endif + prctl(PR_GET_NAME, name); + name[NSTIMER_SIZE_PROCESSNAME] = '\0'; + if (strlen(name) + strlen(NSTIMER_APPEND_NAME) > NSTIMER_SIZE_PROCESSNAME) { + p = name + NSTIMER_SIZE_PROCESSNAME - strlen(NSTIMER_APPEND_NAME); + } else { + p = name + strlen(name); + } + strcpy(p, NSTIMER_APPEND_NAME); + prctl(PR_SET_NAME, name); + + for (;;) { + nfds = epoll_wait(epollFd, events, MAX_FD_EPOLL, -1); + if (-1 != nfds) { + for (n = 0; n < nfds; ++n) { + hTimer = (PNSTimerHandle)events[n].data.ptr; + if (NULL != hTimer) { + if (-1 == read(hTimer->timerfd, &exp, sizeof(uint64_t))) { + if (errno != EAGAIN) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Failed to read in timeout : fd=%d, errno=%d", + hTimer->timerfd, errno); + // LCOV_EXCL_BR_STOP + } + continue; + } + + if (RUNNING_STATE == hTimer->timerState) { + if (NULL != hTimer->tTimerInfo) { + EFrameworkunifiedStatus eStatus; + HANDLE hReceiver = NULL; + if (frameworkunifiedAcquireResouce(FRAMEWORKUNIFIED_RES_TIMER, hTimer->tTimerInfo->q_name, (long *)&hReceiver) < 0) { + if ((hReceiver = McOpenSender(hTimer->tTimerInfo->q_name)) == NULL) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : McOpenSender is Failed"); + // LCOV_EXCL_BR_STOP + continue; + } else { + if (frameworkunifiedRegistResouce(FRAMEWORKUNIFIED_RES_TIMER, hTimer->tTimerInfo->q_name, (long)hReceiver, 1) < 0) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : frameworkunifiedRegistResouce is Failed : q_name=%s", + hTimer->tTimerInfo->q_name); + // LCOV_EXCL_BR_STOP + } + } + } + + eStatus = McSendWithPriority(hReceiver, + TIMER_QUE, + hTimer->tTimerInfo->iCmd, + 0, + NULL, + eFrameworkunifiedMsgPrioEmergency, + 0); + if (eFrameworkunifiedStatusOK != eStatus) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : McSendWithPriority to %s is Failed, eStatus=%d", hTimer->tTimerInfo->q_name, + eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR(RUNNING_STATE) : tTimerInfo is NULL"); + // LCOV_EXCL_BR_STOP + } + } else if (DELETED_STATE == hTimer->timerState) { + if (-1 == epoll_ctl(epollFd, EPOLL_CTL_DEL, hTimer->timerfd, events)) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : epoll_ctl(DEL) Failed, fd=%d, errno=%d", + hTimer->timerfd, errno); + // LCOV_EXCL_BR_STOP + } + + if (-1 == close(hTimer->timerfd)) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : close(fd=%d) Failed, errno=%d", hTimer->timerfd, errno); + // LCOV_EXCL_BR_STOP + } + + hTimer->timerfd = INVALID_TIMERFD; + + if (NULL != hTimer->tTimerInfo) { + HANDLE hReceiver; + if (frameworkunifiedAcquireResouce(FRAMEWORKUNIFIED_RES_TIMER, hTimer->tTimerInfo->q_name, (long *)&hReceiver) >= 0) { + if (frameworkunifiedReleaseResouce(FRAMEWORKUNIFIED_RES_TIMER, hTimer->tTimerInfo->q_name) <= 0) { + frameworkunifiedUnregistResouce(FRAMEWORKUNIFIED_RES_TIMER, hTimer->tTimerInfo->q_name); + McClose(hReceiver); + } + } + free(hTimer->tTimerInfo->q_name); + free(hTimer->tTimerInfo); // delete the timer info + hTimer->tTimerInfo = NULL; + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR(DELETED_STATE) : tTimerInfo is NULL"); + // LCOV_EXCL_BR_STOP + } + + free(hTimer); // delete the handle + events[n].data.ptr = NULL; + } else { + // do nothing + } + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : hTimer is NULL"); + // LCOV_EXCL_BR_STOP + } + } + } else { + if (errno == EINTR) { + // signal interrupt + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : epoll_wait Failed, errno=%d", errno); + // LCOV_EXCL_BR_STOP + } + } + } + return NULL; +} + +static EFrameworkunifiedStatus CreateTimerMonitoringThread() { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + struct epoll_event ev; // Info struct to associate with multiwaiting FD + int ret; + + pthread_mutex_lock(&m_mtx); + + // Create the TimerMonitoringThread If the thread has not been generated. + if (0 == timerTh_id) { + epollFd = epoll_create1(EPOLL_CLOEXEC); + if (-1 != epollFd) { + eventFd = eventfd(0, EFD_CLOEXEC); + if (-1 != eventFd) { + ev.events = EPOLLIN; + ev.data.fd = eventFd; + if (-1 != epoll_ctl(epollFd, EPOLL_CTL_ADD, eventFd, &ev)) { + if (0 != (ret = pthread_create(&timerTh_id, NULL, TimerMonitoringThread, NULL))) { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Failed to pthread_create : errno %d", ret); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : epoll_ctl(eventFd=%d, ADD) Failed, status=%d, errno=%d", eventFd, eStatus, + errno); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR :eventfd Failed, status=%d, errno=%d", eStatus, errno); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : epoll_create1 Failed, status=%d, errno=%d", + eStatus, errno); + // LCOV_EXCL_BR_STOP + } + + } + + if (TRUE == DebugFlag) { // LCOV_EXCL_BR_LINE 7: debug code + // LCOV_EXCL_START 7: debug code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_NS_IMP_INFO, __FUNCTION__, "[DEBUG] sleep 3 Sec START."); + sleep(3); + FRAMEWORKUNIFIEDLOG(ZONE_NS_IMP_INFO, __FUNCTION__, "[DEBUG] sleep 3 Sec END."); + // LCOV_EXCL_STOP + } + pthread_mutex_unlock(&m_mtx); + + return eStatus; +} + +HANDLE NS_TimerCreate(NSTimerInfo timer_info, eNSTimerCallbackMechanism cbMech, HANDLE sndMqHndl) { + PNSTimerHandle hTimer = NULL; + + if ((NULL != sndMqHndl) && (cbMech == CALLBACK_MESSAGE)) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + + PTimerInfo pTimerInfo = NULL; + struct epoll_event ev; // Info struct to associate with multiwaiting FD + int timerfd = INVALID_TIMERFD; + + eStatus = CreateTimerMonitoringThread(); + if (eFrameworkunifiedStatusOK == eStatus) { + hTimer = (PNSTimerHandle)malloc(sizeof(NSTimerHandle)); + if (NULL != hTimer) { // LCOV_EXCL_BR_LINE 5: malloc's error case + pTimerInfo = (PTimerInfo)malloc(sizeof(TTimerInfo)); + + if (NULL != pTimerInfo) { // LCOV_EXCL_BR_LINE 5: malloc's error case + hTimer->timerState = RUNNING_STATE; + + // set the timer info structure + PCSTR pName = McGetQueueName(sndMqHndl); + if (NULL != pName) { + pTimerInfo->q_name = strdup(pName); + } else { + pTimerInfo->q_name = NULL; + eStatus = eFrameworkunifiedStatusNullPointer; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : McGetQueueName(sndMqHndl) Failed, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + + if (eFrameworkunifiedStatusOK == eStatus) { + pTimerInfo->iCmd = timer_info.iCmd; + + hTimer->tTimerInfo = pTimerInfo; + if (INVALID_TIMERFD != (timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC|TFD_NONBLOCK))) { + ev.events = EPOLLIN; + ev.data.ptr = hTimer; + if (-1 != epoll_ctl(epollFd, EPOLL_CTL_ADD, timerfd, &ev)) { + hTimer->timerfd = timerfd; + if (eFrameworkunifiedStatusOK == NS_TimerSetTime(hTimer, timer_info)) { + // set the interval in timer handle + hTimer->itime.it_value.tv_sec = (__time_t)timer_info.t_sec; + hTimer->itime.it_value.tv_nsec = (__syscall_slong_t)timer_info.t_nsec; + hTimer->itime.it_interval.tv_sec = (__time_t)timer_info.rpt_sec; + hTimer->itime.it_interval.tv_nsec = (__syscall_slong_t)timer_info.rpt_nsec; + + } else { + eStatus = eFrameworkunifiedStatusErrOther; + + // if timer interval is not set or memory is not allocated for hTimer + close(timerfd); + timerfd = INVALID_TIMERFD; + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : epoll_ctl(timerfd=%d, ADD) Failed, status=%d, errno=%d", timerfd, eStatus, + errno); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusErrOther; + } + } + } else { + // LCOV_EXCL_START 5: malloc's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + eStatus = eFrameworkunifiedStatusNullPointer; + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : (PTimerInfo)malloc(sizeof(TTimerInfo)) Failed, status=%d", eStatus); + // LCOV_EXCL_STOP + } + + if (eFrameworkunifiedStatusOK != eStatus) { + if (NULL != pTimerInfo) { + if (NULL != pTimerInfo->q_name) { + free(pTimerInfo->q_name); + pTimerInfo->q_name = NULL; + } + + free(pTimerInfo); + pTimerInfo = NULL; + } + + if (NULL != hTimer) { + free(hTimer); + hTimer = NULL; + } + } + } else { + // LCOV_EXCL_START 5: malloc's error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : malloc(sizeof(NSTimerHandle)) Failed"); + // LCOV_EXCL_STOP + } + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : CreateTimerMonitoringThread Failed, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : Invalid param"); + // LCOV_EXCL_BR_STOP + } + + return hTimer; +} + +EFrameworkunifiedStatus NS_TimerDelete(HANDLE hTimer) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + if (NULL != hTimer) { + PNSTimerHandle tTimerHndl = (PNSTimerHandle)hTimer; + /** + * @todo + * Dropping by typing the service handle instead of the timer handle + */ + if (DELETED_STATE != tTimerHndl->timerState) { + if (NULL != tTimerHndl->tTimerInfo) { + tTimerHndl->timerState = DELETING_STATE; + NSTimerInfo timer_info = {1, 0, tTimerHndl->tTimerInfo->iCmd, 0, 0}; + + if (eFrameworkunifiedStatusOK != (eStatus = NS_TimerSetTime(tTimerHndl, timer_info))) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_WAR, __FUNCTION__, "ERROR : NS_TimerSetTime for Timer delete Failed, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + + tTimerHndl->timerState = DELETED_STATE; + } else { + eStatus = eFrameworkunifiedStatusInvldParam; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : tTimerInfo is NULL, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : Timer is not RUNNING State, timerStatus=%d, status=%d", + tTimerHndl->timerState, eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusInvldParam; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : hTimer is NULL, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + + return eStatus; +} + +EFrameworkunifiedStatus NS_TimerSetTime(HANDLE hTimer, NSTimerInfo timer_info) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + + if (NULL != hTimer) { + PNSTimerHandle tTimerHndl = (PNSTimerHandle)hTimer; + struct itimerspec itime; + + if (DELETED_STATE != tTimerHndl->timerState) { + // set periodic interval values + itime.it_value.tv_sec = (__time_t)timer_info.t_sec; + itime.it_value.tv_nsec = (__syscall_slong_t)timer_info.t_nsec; + + // set periodic interval values + itime.it_interval.tv_sec = (__time_t)timer_info.rpt_sec; + itime.it_interval.tv_nsec = (__syscall_slong_t)timer_info.rpt_nsec; + + if (-1 != timerfd_settime(tTimerHndl->timerfd, 0, &itime, NULL)) { + // updated the value of the timer values in the handler + tTimerHndl->itime = itime; + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : timerfd_settime is failed, status=%d, errno=%d", eStatus, errno); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : Timer is not RUNNING State, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusInvldHandle; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : hTimer is NULL, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + + return eStatus; +} + +EFrameworkunifiedStatus NS_TimerGetTime(HANDLE hTimer, NSTimerInfo *timer_info) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + + if ((NULL != hTimer) && (NULL != timer_info)) { + PNSTimerHandle tTimerHndl = (PNSTimerHandle)hTimer; + struct itimerspec itime; + + if (DELETED_STATE != tTimerHndl->timerState) { + if (-1 != timerfd_gettime(tTimerHndl->timerfd, &itime)) { + // set periodic interval values + +// timer_info->t_sec = (UI_32)itime.it_value.tv_sec; + timer_info->t_sec = itime.it_value.tv_sec; + timer_info->t_nsec = (UI_64)itime.it_value.tv_nsec; + + // set periodic interval values + +// timer_info->rpt_sec = (UI_32)itime.it_interval.tv_sec; + timer_info->rpt_sec = itime.it_interval.tv_sec; + timer_info->rpt_nsec = (UI_64)itime.it_interval.tv_nsec; + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : timerfd_gettime is failed, status=%d, errno=%d", eStatus, errno); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusFail; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : Timer is not RUNNING State, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + } else { + eStatus = eFrameworkunifiedStatusInvldHandle; + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "ERROR : Invalid param, status=%d", eStatus); + // LCOV_EXCL_BR_STOP + } + + return eStatus; +} + + +//UI_32 WholeSeconds(UI_32 ms) { +// return ms / MS_IN_SEC; +//} +time_t WholeSeconds(UI_32 ms) { + return (time_t)(ms / MS_IN_SEC); +} + + +UI_32 RemainderMs(UI_32 ms) { + return ms % MS_IN_SEC; +} + +UI_64 MSToNS(UI_32 ms) { + return (UI_64)ms * NS_IN_MS; +} + +void NS_TimerDebugOn(BOOL FlagState) { // LCOV_EXCL_START 7: debug code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (DebugFlag != FlagState) { + DebugFlag = FlagState; + if (TRUE == DebugFlag) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_IMP_INFO, __FUNCTION__, "NS_Timer debugging is enabled."); + } else { + FRAMEWORKUNIFIEDLOG(ZONE_NS_IMP_INFO, __FUNCTION__, "NS_Timer debugging is disabled."); + } + } +} +// LCOV_EXCL_STOP diff --git a/nsframework/framework_unified/client/NS_Timer/src/ns_timer_class.cpp b/nsframework/framework_unified/client/NS_Timer/src/ns_timer_class.cpp new file mode 100644 index 00000000..47b41e9a --- /dev/null +++ b/nsframework/framework_unified/client/NS_Timer/src/ns_timer_class.cpp @@ -0,0 +1,177 @@ +/* + * @copyright Copyright (c) 2016-2020 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. + */ + +////////////////////////////////////////////////////////////////////////////////////////////////// +/// \ingroup tag_NSTimer +/// \brief +/// +/// Timer class for setting timers. +/// +////////////////////////////////////////////////////////////////////////////////////////////////// + +#include <native_service/ns_timer_if.hpp> +#include <native_service/ns_message_center_if.h> +#include <string.h> + +////////////////////////////////////////////////////////////////////////////////////////////// +///// Constructor +////////////////////////////////////////////////////////////////////////////////////////////// +NSTimer::NSTimer(): + m_hTimer(NULL), + m_u64TimeInterval(0), + m_bRepeatTimer(FALSE) { +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// Destructor +////////////////////////////////////////////////////////////////////////////////////////////// +NSTimer::~NSTimer() { + if (NULL != m_hTimer) { + NS_TimerDelete(m_hTimer); + m_hTimer = NULL; + } +} + + +////////////////////////////////////////////////////////////////////////////////////////////// +///// SetNotifyMethod +////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus NSTimer::SetNotifyMethod(UI_16 notifyCmdId, PCSTR notifyToAppName) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + NSTimerInfo l_tTimerInfo = {}; + + if ((NULL != notifyToAppName) && (strlen(notifyToAppName) <= MAX_SERVICE_NAME)) { + HANDLE l_hSenderHandle = McOpenSender(notifyToAppName); + + if (NULL != l_hSenderHandle) { // reset previous notify method, and set new + // resets previous timer timeout action if any + if (NULL != m_hTimer) { + NS_TimerDelete(m_hTimer); + m_hTimer = NULL; + } + + l_tTimerInfo.iCmd = notifyCmdId; + // Create timer. Do not start. + if (NULL == (m_hTimer = NS_TimerCreate(l_tTimerInfo, CALLBACK_MESSAGE, l_hSenderHandle))) { + l_eStatus = eFrameworkunifiedStatusFail; + } + + McClose(l_hSenderHandle); + } else { + // just return fail. Don't reset any previous notify method + l_eStatus = eFrameworkunifiedStatusFail; + } + } else { + l_eStatus = eFrameworkunifiedStatusInvldParam; + } + + return l_eStatus; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// SetRepeatTimer +////////////////////////////////////////////////////////////////////////////////////////////// +VOID NSTimer::SetRepeatTimer(BOOL repeatTimer) { + m_bRepeatTimer = repeatTimer; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// SetTime +////////////////////////////////////////////////////////////////////////////////////////////// +VOID NSTimer::SetTime(UI_32 seconds, UI_64 msecs) { + m_u64TimeInterval = msecs + seconds * 1000ULL; // internally, set interval as milliseconds +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// SetTime +////////////////////////////////////////////////////////////////////////////////////////////// +VOID NSTimer::SetTime(UI_32 hrs, UI_32 mins, UI_32 seconds, UI_64 msecs) { + // internally, set interval as milliseconds + m_u64TimeInterval = msecs + seconds * 1000ULL + mins * 60000ULL + hrs * 3600000ULL; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// Start +////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus NSTimer::Start(UI_32 seconds, UI_64 msecs) { + this->SetTime(seconds, msecs); + return (this->Start()); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// Start +////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus NSTimer::Start() { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + if (NULL != m_hTimer) { + NSTimerInfo l_tTimerInfo = {}; + + l_tTimerInfo.t_sec = WholeSeconds(static_cast<UI_32>(m_u64TimeInterval)); /// Converts to seconds + l_tTimerInfo.t_nsec = MSToNS(RemainderMs(static_cast<UI_32>(m_u64TimeInterval))); /// Converts to nano seconds + + if (TRUE == m_bRepeatTimer) { + l_tTimerInfo.rpt_sec = l_tTimerInfo.t_sec; + l_tTimerInfo.rpt_nsec = l_tTimerInfo.t_nsec; + } + l_eStatus = NS_TimerSetTime(m_hTimer, l_tTimerInfo); + } else { + l_eStatus = eFrameworkunifiedStatusFail; + } + + return l_eStatus; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// Stop +////////////////////////////////////////////////////////////////////////////////////////////// +EFrameworkunifiedStatus NSTimer::Stop() { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + + if (NULL != m_hTimer) { + NSTimerInfo l_tTimerInfo = {}; + l_eStatus = NS_TimerSetTime(m_hTimer, l_tTimerInfo); + } else { + l_eStatus = eFrameworkunifiedStatusFail; + } + + return l_eStatus; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// IsRunning +////////////////////////////////////////////////////////////////////////////////////////////// +BOOL NSTimer::IsRunning() { + BOOL l_bIsRunning = FALSE; + + if (NULL != m_hTimer) { + NSTimerInfo l_tTimerInfo = {}; + NS_TimerGetTime(m_hTimer, &l_tTimerInfo); + if ((0 != l_tTimerInfo.t_sec) || (0 != l_tTimerInfo.t_nsec) || (0 != l_tTimerInfo.rpt_sec) || + (0 != l_tTimerInfo.rpt_nsec)) { + l_bIsRunning = TRUE; + } + } + return l_bIsRunning; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +///// GetInterval +////////////////////////////////////////////////////////////////////////////////////////////// +UI_64 NSTimer::GetInterval() { + return m_u64TimeInterval; +} + +// EOF |