X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdaemon%2Fdlt-daemon.c;h=87663c665196b9659fa01ae69ee7a0ead61f9dbd;hb=55df0f3aa8500619464bd080f0d58d2419da0c4c;hp=20cba66930ba97e728e9436db818fb98f5a945ca;hpb=e2943ff4cf2d7d2da4000e2ca35663a7c83675d7;p=profile%2Fivi%2Fdlt-daemon.git diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 20cba66..87663c6 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -99,21 +99,6 @@ /** Global text output buffer, mainly used for creation of error/warning strings */ static char str[DLT_DAEMON_TEXTBUFSIZE]; -static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data; - -static pthread_t dlt_daemon_timingpacket_thread_handle; -static pthread_attr_t dlt_daemon_timingpacket_thread_attr; - -static DltDaemonECUVersionThreadData dlt_daemon_ecu_version_thread_data; -static pthread_t dlt_daemon_ecu_version_thread_handle; - -#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) -// Allow main loop to execute every 100ms -#define DLT_SELECT_TIMEOUT_USEC (1000 * 100) -static DltDaemonTimingPacketThreadData dlt_daemon_systemd_watchdog_thread_data; -static pthread_t dlt_daemon_systemd_watchdog_thread_handle; -#endif - /** * Print usage information of tool. */ @@ -221,6 +206,7 @@ int option_file_parser(DltDaemonLocal *daemon_local) daemon_local->flags.loggingMode = 0; daemon_local->flags.loggingLevel = 6; strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename)); + daemon_local->timeoutOnSend = 4; daemon_local->flags.sendECUSoftwareVersion = 0; memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion)); @@ -344,6 +330,11 @@ int option_file_parser(DltDaemonLocal *daemon_local) strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1); //printf("Option: %s=%s\n",token,value); } + else if(strcmp(token,"TimeOutOnSend")==0) + { + daemon_local->timeoutOnSend = atoi(value); + //printf("Option: %s=%s\n",token,value); + } else if(strcmp(token,"SharedMemorySize")==0) { daemon_local->flags.sharedMemorySize = atoi(value); @@ -406,19 +397,6 @@ int main(int argc, char* argv[]) DltDaemon daemon; int i,back; -#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) - /* Timeout for select */ - struct timeval tvTimeout; - tvTimeout.tv_sec = 0; - tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC; - - /* Set watchdog flag immediately, not to timeout while init */ - if(sd_notify(0, "WATCHDOG=1") < 0) - { - fprintf (stderr, "Could not initialize systemd watchdog\n"); - return -1; - } -#endif /* Command line option handling */ if ((back = option_handling(&daemon_local,argc,argv))<0) { @@ -474,31 +452,33 @@ int main(int argc, char* argv[]) } /* --- Daemon init phase 2 end --- */ - while (1) + // create fd for watchdog +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE { -#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) - /* Set timeout to defined usecs - * select might modify this value: POSIX.1-2001 */ - tvTimeout.tv_sec = 0; - tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC; + char* watchdogUSec = getenv("WATCHDOG_USEC"); + int watchdogTimeoutSeconds = 0; - /* update the watchdog time structure */ - daemon_local.lastOperationTime = dlt_uptime(); - - /* wait for events from all FIFO and sockets, with timeout */ - daemon_local.read_fds = daemon_local.master; - int selectRet = select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, &tvTimeout); - if (selectRet == -1) + dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n"); + if( watchdogUSec ) { - dlt_log(LOG_CRIT, "select() failed!\n"); - return -1 ; - } /* if */ - else if(selectRet == 0) - { - /* No pending reads, continue while(1)*/ - continue; + watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000; } -#else + create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, &daemon_local.timer_wd, "Systemd watchdog"); + } +#endif + + // create fd for timer timing packets + create_timer_fd(&daemon_local, 1, 1, &daemon_local.timer_timingpacket, "Timing packet"); + + // create fd for timer ecu version + if(daemon_local.flags.sendECUSoftwareVersion > 0) + { + //dlt_daemon_init_ecuversion(&daemon_local); + create_timer_fd(&daemon_local, 60, 60, &daemon_local.timer_ecuversion, "ECU version"); + } + + while (1) + { /* wait for events from all FIFO and sockets */ daemon_local.read_fds = daemon_local.master; @@ -507,7 +487,7 @@ int main(int argc, char* argv[]) dlt_log(LOG_CRIT, "select() failed!\n"); return -1 ; } /* if */ -#endif + /* run through the existing FIFO and sockets to check for events */ for (i = 0; i <= daemon_local.fdmax; i++) { @@ -540,6 +520,55 @@ int main(int argc, char* argv[]) return -1; } } +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + else if (i == daemon_local.timer_wd) + { + uint64_t expir=0; + ssize_t res = read(daemon_local.timer_wd, &expir, sizeof(expir)); + if(res < 0) { + sprintf(str,"Failed to read timer_wd; %s\n", strerror(errno) ); + dlt_log(LOG_WARNING, str); + // Activity received on timer_wd, but unable to read the fd: + // let's go on sending notification + } + + dlt_log(LOG_DEBUG, "Timer watchdog\n"); + + if(sd_notify(0, "WATCHDOG=1") < 0) + { + dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n"); + } + } +#endif + else if (i == daemon_local.timer_timingpacket) + { + uint64_t expir=0; + ssize_t res = read(daemon_local.timer_timingpacket, &expir, sizeof(expir)); + if(res < 0) { + sprintf(str,"Failed to read timer_timingpacket; %s\n", strerror(errno) ); + dlt_log(LOG_WARNING, str); + // Activity received on timer_wd, but unable to read the fd: + // let's go on sending notification + } + dlt_daemon_send_timingpacket(&daemon, &daemon_local); + dlt_log(LOG_DEBUG, "Timer timingpacket\n"); + + } + + else if (i == daemon_local.timer_ecuversion) + { + uint64_t expir=0; + ssize_t res = read(daemon_local.timer_ecuversion, &expir, sizeof(expir)); + if(res < 0) { + sprintf(str,"Failed to read timer_ecuversion; %s\n", strerror(errno) ); + dlt_log(LOG_WARNING, str); + // Activity received on timer_wd, but unable to read the fd: + // let's go on sending notification + } + dlt_daemon_send_ecuversion(&daemon, &daemon_local); + dlt_log(LOG_DEBUG, "Timer ecuversion\n"); + + } else { /* event from tcp connection to client received */ @@ -696,19 +725,6 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } } - - /* setup period thread for timing packets */ - if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0) - { - dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n"); - } - else - { - if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0) - { - dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n"); - } - } /* configure sending timing packets */ if (daemon_local->flags.sendMessageTime) @@ -723,22 +739,6 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } - /* start thread */ - dlt_daemon_timingpacket_thread_data.daemon = daemon; - dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local; - - if (pthread_create(&(dlt_daemon_timingpacket_thread_handle), - &dlt_daemon_timingpacket_thread_attr, - (void *) &dlt_daemon_timingpacket_thread, - (void *)&dlt_daemon_timingpacket_thread_data)!=0) - { - dlt_log(LOG_ERR,"Could not initialize timing packet thread\n"); - pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr); - return -1; - } - - pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr); - /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */ if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0) { @@ -746,38 +746,6 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in dlt_get_version(daemon->ECUVersionString); } - /* start thread for ECU version, if enabled */ - if(daemon_local->flags.sendECUSoftwareVersion > 0) - { - dlt_daemon_ecu_version_thread_data.daemon = daemon; - dlt_daemon_ecu_version_thread_data.daemon_local = daemon_local; - - if (pthread_create(&(dlt_daemon_ecu_version_thread_handle), - NULL, - (void *) &dlt_daemon_ecu_version_thread, - (void *)&dlt_daemon_ecu_version_thread_data)!=0) - { - dlt_log(LOG_ERR,"Could not initialize ECU version thread\n"); - return -1; - } - } - -#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) - - dlt_daemon_systemd_watchdog_thread_data.daemon = daemon; - dlt_daemon_systemd_watchdog_thread_data.daemon_local = daemon_local; - - if (pthread_create(&(dlt_daemon_systemd_watchdog_thread_handle), - NULL, - (void *) &dlt_daemon_systemd_watchdog_thread, - (void *) &dlt_daemon_systemd_watchdog_thread_data)!=0) - { - dlt_log(LOG_ERR,"Could not initialize systemd watchdog thread\n"); - return -1; - } -#endif - - return 0; } @@ -800,10 +768,27 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_l /* open named pipe(FIFO) to receive DLT messages from users */ umask(0); + ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX ); + if (ret==-1 && errno != EEXIST) + { + sprintf(str,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR); + dlt_log(LOG_ERR, str); + return -1; + } + + // S_ISGID cannot be set by mkdir, let's reassign right bits + ret=chmod(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX ); + if (ret==-1) + { + sprintf(str,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR); + dlt_log(LOG_ERR, str); + return -1; + } + /* Try to delete existing pipe, ignore result of unlink */ unlink(DLT_USER_FIFO); - ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); if (ret==-1) { sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO); @@ -826,7 +811,12 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_l return -1; } /* if */ - setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + if ( -1 == setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))) + { + sprintf(str,"Setsockopt error in dlt_daemon_local_connection_init: %s\n",strerror(errno)); + dlt_log(LOG_ERR, str); + return -1; + } memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = INADDR_ANY; @@ -1177,6 +1167,13 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_ dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose); dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose); + /* Set socket timeout in reception */ + struct timeval timeout_send; + timeout_send.tv_sec = daemon_local->timeoutOnSend; + timeout_send.tv_usec = 0; + if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0) + dlt_log(LOG_ERR, "setsockopt failed\n"); + //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr)); //dlt_log(str); FD_SET(in_sock, &(daemon_local->master)); /* add to master set */ @@ -1193,6 +1190,15 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_ dlt_log(LOG_INFO, str); } + // send connection info about connected + dlt_daemon_control_message_connection_info(in_sock,daemon,DLT_CONNECTION_STATUS_CONNECTED,"",verbose); + + // send ecu version string + if(daemon_local->flags.sendECUSoftwareVersion > 0) + { + dlt_daemon_send_ecuversion(daemon,daemon_local); + } + if (daemon_local->client_connections==1) { if (daemon_local->flags.vflag) @@ -1227,9 +1233,9 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0) { - close(daemon_local->receiverSock.fd); - daemon_local->receiverSock.fd = 0; + close(daemon_local->receiverSock.fd); FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master)); + daemon_local->receiverSock.fd = -1; if (daemon_local->client_connections) { @@ -1249,6 +1255,7 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon dlt_log(LOG_INFO, str); } + dlt_daemon_control_message_connection_info(DLT_DAEMON_STORE_TO_BUFFER,daemon,DLT_CONNECTION_STATUS_DISCONNECTED,"",verbose); /* check: return 0; */ } @@ -1256,7 +1263,7 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0) { /* Check for control message */ - if ( 0 != daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) ) + if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) ) { dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag); } @@ -1517,6 +1524,7 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { int j, sent; + DltUserControlMsgBufferOverflow *userpayload; PRINT_FUNCTION_VERBOSE(verbose); @@ -1526,6 +1534,15 @@ int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal * return -1; } + if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))) + { + /* Not enough bytes received */ + return -1; + } + + /* get the payload of the user message */ + userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + /* Store in daemon, that a message buffer overflow has occured */ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW; @@ -1538,9 +1555,13 @@ int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal * if (FD_ISSET(j, &(daemon_local->master))) { /* except the listener and ourselves */ - if ((j != daemon_local->fp) && (j != daemon_local->sock)) + if ((j != daemon_local->fp) && (j != daemon_local->sock) +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) +#endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) { - dlt_daemon_control_message_buffer_overflow(j, daemon, verbose); + dlt_daemon_control_message_buffer_overflow(j, daemon, userpayload->overflow_counter,userpayload->apid,verbose); sent=1; /* Reset overflow state */ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; @@ -1551,11 +1572,17 @@ int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal * /* message was not sent, so store it in ringbuffer */ if (sent==0) { - dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose); + if(dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, userpayload->overflow_counter, + userpayload->apid,verbose)) + { + /* there was an error when storing message */ + /* add the counter of lost messages to the daemon counter */ + daemon->overflow_counter+=userpayload->overflow_counter; + } } /* keep not read data in buffer */ - if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1) + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1) { dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n"); return -1; @@ -1564,6 +1591,53 @@ int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal * return 0; } +int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int j, sent; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n"); + return -1; + } + + /* Store in daemon, that a message buffer overflow has occured */ + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW; + + /* look if TCP connection to client is available */ + sent = 0; + + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock) +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) +#endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) + { + dlt_daemon_control_message_buffer_overflow(j, daemon,daemon->overflow_counter,"", verbose); + sent=1; + /* Reset overflow state */ + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; + } /* if */ + } /* if */ + } /* for */ + + /* message was not sent, so report to caller that sending failed */ + if (sent==0) + { + return -1; + } + + return 0; +} + int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { uint32_t len=0; @@ -1763,7 +1837,11 @@ int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemo if (FD_ISSET(j, &(daemon_local->master))) { /* except the listener and ourselves */ - if ((j != daemon_local->fp) && (j != daemon_local->sock)) + if ((j != daemon_local->fp) && (j != daemon_local->sock) + #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) + #endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) { dlt_daemon_control_get_log_info(j , daemon, &msg, verbose); sent=1; @@ -1902,6 +1980,38 @@ int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDae } } + /* Create automatic unregister context response for unregistered context */ + if (daemon_local->flags.rflag) + { + int sent=0; + int j; + + /* Send response to get log info request to DLT clients */ + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock) + #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) + #endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) + { + dlt_daemon_control_message_unregister_context(j,daemon,usercontext->apid, usercontext->ctid, "remo",verbose); + sent=1; + } + } + } + + if (sent==0) + { + /* Store to buffer */ + dlt_daemon_control_message_unregister_context(DLT_DAEMON_STORE_TO_BUFFER,daemon,usercontext->apid, usercontext->ctid, "remo",verbose); + } + } + /* keep not read data in buffer */ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1) { @@ -1999,6 +2109,17 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo sent = 1; } + /* check if overflow occurred */ + if(daemon->overflow_counter) + { + if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0) + { + sprintf(str,"%u messages discarded!\n",daemon->overflow_counter); + dlt_log(LOG_ERR, str); + daemon->overflow_counter=0; + } + } + /* look if TCP connection to client is available */ for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++) { @@ -2015,7 +2136,11 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo third_value = daemon_local->sock; } - if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)) + if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value) + #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) + #endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) { DLT_DAEMON_SEM_LOCK(); @@ -2075,7 +2200,9 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo 0, 0 )<0) { - dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n"); + if(daemon->overflow_counter==0) + dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n"); + daemon->overflow_counter+=1; } DLT_DAEMON_SEM_FREE(); } @@ -2430,7 +2557,11 @@ int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daem third_value = daemon_local->sock; } - if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)) + if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value) + #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) + #endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) { DLT_DAEMON_SEM_LOCK(); @@ -2475,167 +2606,6 @@ int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daem return 0; } -void dlt_daemon_timingpacket_thread(void *ptr) -{ - DltDaemonPeriodicData info; - int j; - - DltDaemonTimingPacketThreadData *data; - DltDaemon *daemon; - DltDaemonLocal *daemon_local; - - if (ptr==0) - { - dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n"); - return; - } - - data = (DltDaemonTimingPacketThreadData*)ptr; - daemon = data->daemon; - daemon_local = data->daemon_local; - - if ((daemon==0) || (daemon_local==0)) - { - dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()"); - return; - } - - if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0) - { - dlt_log(LOG_CRIT,"Can't initialize thread timer!\n"); - return; - } - - while (1) - { - /* If enabled, send timing packets to all clients */ - if (daemon->timingpackets) - { - for (j = 0; j <= daemon_local->fdmax; j++) - { - /* send to everyone! */ - if (FD_ISSET(j, &(daemon_local->master))) - { - /* except the listener and ourselves */ - if ((j != daemon_local->fp) && (j != daemon_local->sock)) - { - dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag); - } - } - } - } - /* Wait for next period */ - dlt_daemon_wait_period (&info, daemon_local->flags.vflag); - } -} - -void dlt_daemon_ecu_version_thread(void *ptr) -{ - DltDaemonECUVersionThreadData *data = (DltDaemonECUVersionThreadData *)ptr; - DltDaemonPeriodicData info; - const unsigned int DLT_ECU_VERSION_PERIOD_TIME = 1000000*60; // 60 Seconds - - if (dlt_daemon_make_periodic (DLT_ECU_VERSION_PERIOD_TIME, &info, data->daemon_local->flags.vflag)<0) - { - dlt_log(LOG_CRIT,"Can't initialize thread timer!\n"); - return; - } - - while(1) - { - int i; - for (i = 0; i <= data->daemon_local->fdmax; i++) - { - /* send to everyone! */ - if (FD_ISSET(i, &(data->daemon_local->master))) - { - /* except the listener and ourselves */ - if ((i != data->daemon_local->fp) && (i != data->daemon_local->sock)) - { - dlt_daemon_control_get_software_version(i, data->daemon, data->daemon_local->flags.vflag); - } - } - } - dlt_daemon_wait_period (&info, data->daemon_local->flags.vflag); - } -} - -#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) -void dlt_daemon_systemd_watchdog_thread(void *ptr) -{ - char *watchdogUSec; - int watchdogTimeoutSeconds; - int notifyPeriodNSec; - DltDaemonPeriodicData info; - DltDaemonTimingPacketThreadData *data; - DltDaemon *daemon; - DltDaemonLocal *daemon_local; - static uint32_t lastDaemonOperation; - - if (ptr==0) - { - dlt_log(LOG_ERR, "No data pointer passed to systemd watchdog thread\n"); - return; - } - - data = (DltDaemonTimingPacketThreadData*)ptr; - daemon = data->daemon; - daemon_local = data->daemon_local; - - if ((daemon==0) || (daemon_local==0)) - { - dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()"); - return; - } - - watchdogUSec = getenv("WATCHDOG_USEC"); - - if(watchdogUSec) - { - watchdogTimeoutSeconds = atoi(watchdogUSec); - // Calculate half of WATCHDOG_USEC in ns for timer tick - notifyPeriodNSec = watchdogTimeoutSeconds / 2 ; - - if( notifyPeriodNSec > 0 ) - { - sprintf(str,"systemd watchdog timeout: %i nsec - timer will be initialized: %i nsec\n", watchdogTimeoutSeconds, notifyPeriodNSec ); - dlt_log(LOG_INFO, str); - - if (dlt_daemon_make_periodic (notifyPeriodNSec, &info, daemon_local->flags.vflag)<0) - { - dlt_log(LOG_CRIT, "Could not initialize systemd watchdog timer"); - return; - } - - while (1) - { - /* If main thread has changed its last operation time, reset watchdog */ - if(daemon_local->lastOperationTime != lastDaemonOperation) - { - if(sd_notify(0, "WATCHDOG=1") < 0) - { - dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n"); - } - lastDaemonOperation = daemon_local->lastOperationTime; - } - - /* Wait for next period */ - dlt_daemon_wait_period (&info, daemon_local->flags.vflag); - } - } - else - { - sprintf(str,"systemd watchdog timeout incorrect: %i\n", watchdogTimeoutSeconds); - dlt_log(LOG_CRIT, str); - } - } - else - { - dlt_log(LOG_CRIT, "systemd watchdog timeout (WATCHDOG_USEC) is null!\n"); - } -} -#endif - int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose) { int ret; @@ -2695,6 +2665,118 @@ void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose) } } +int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, int* fd, const char* timer_name) +{ + int local_fd; + struct itimerspec l_timer_spec; + + if(timer_name == NULL) + { + timer_name = "timer_not_named"; + } + + if( fd == NULL ) + { + snprintf(str, sizeof(str), "<%s> fd is NULL pointer\n", timer_name ); + dlt_log(DLT_LOG_ERROR, str); + return -1; + } + + if( period_sec > 0 ) { + local_fd = timerfd_create(CLOCK_MONOTONIC, 0); + if( local_fd < 0) + { + snprintf(str, sizeof(str), "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno)); + dlt_log(DLT_LOG_ERROR, str); + } + + l_timer_spec.it_interval.tv_sec = period_sec; + l_timer_spec.it_interval.tv_nsec = 0; + l_timer_spec.it_value.tv_sec = starts_in; + l_timer_spec.it_value.tv_nsec = 0; + + if( timerfd_settime( local_fd, 0, &l_timer_spec, NULL) < 0) + { + snprintf(str, sizeof(str), "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno)); + dlt_log(DLT_LOG_ERROR, str); + local_fd = -1; + } + } + else { + // timer not activated via the service file + snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name); + dlt_log(DLT_LOG_INFO, str); + local_fd = -1; + } + + // If fd is fully initialized, let's add it to the fd sets + if(local_fd>0) + { + snprintf(str, sizeof(str), "<%s> initialized with %ds timer\n", timer_name, period_sec); + dlt_log(DLT_LOG_INFO, str); + + FD_SET(local_fd, &(daemon_local->master)); + //FD_SET(local_fd, &(daemon_local->timer_fds)); + if (local_fd > daemon_local->fdmax) + { + daemon_local->fdmax = local_fd; + } + } + + *fd = local_fd; + + return local_fd; +} + +void dlt_daemon_send_timingpacket(DltDaemon *daemon, DltDaemonLocal *daemon_local) +{ + int j; + + if (daemon->timingpackets) + { + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock) +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) +#endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion) ) + { + dlt_log(LOG_DEBUG, "timingpacket\n"); + dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag); + } + } + } + } +} + +void dlt_daemon_send_ecuversion(DltDaemon *daemon, DltDaemonLocal *daemon_local) +{ + int j; + + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock) +#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE + && (j!=daemon_local->timer_wd) +#endif + && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion)) + { + dlt_log(LOG_DEBUG, "ecu_version\n"); + dlt_daemon_control_get_software_version(j, daemon, daemon_local->flags.vflag); + } + } + } +} + /** \} */