From 9585f876733b62fb29aaeb163f0f8c408765c9e3 Mon Sep 17 00:00:00 2001 From: Alexander Wenzel Date: Tue, 11 Oct 2011 13:09:24 +0200 Subject: Added new API dlt_set_log_mode to enable/disable internal/external trace. --- include/dlt/dlt_user.h | 21 ++++++++ src/daemon/dlt-daemon.c | 80 +++++++++++++++++++--------- src/daemon/dlt-daemon.h | 1 + src/daemon/dlt_daemon_common.c | 105 ++++++++++++++++++++++++++++++++++++- src/daemon/dlt_daemon_common.h | 20 +++++++ src/daemon/dlt_daemon_common_cfg.h | 2 + src/examples/dlt-example-user.c | 16 +++++- src/lib/dlt_user.c | 40 ++++++++++++++ src/shared/dlt_user_shared.h | 17 ++++++ src/shared/dlt_user_shared_cfg.h | 3 ++ 10 files changed, 278 insertions(+), 27 deletions(-) diff --git a/include/dlt/dlt_user.h b/include/dlt/dlt_user.h index f2a1400..6f64255 100755 --- a/include/dlt/dlt_user.h +++ b/include/dlt/dlt_user.h @@ -149,6 +149,18 @@ typedef enum DLT_NW_TRACE_USER_DEFINED7 = 0x0F } DltNetworkTraceType; +/** + * This are the log modes. + */ +typedef enum +{ + DLT_USER_MODE_UNDEFINED = -1, + DLT_USER_MODE_OFF = 0, + DLT_USER_MODE_EXTERNAL , + DLT_USER_MODE_INTERNAL , + DLT_USER_MODE_BOTH +} DltUserLogMode; + #define DLT_USER_BUF_MAX_SIZE 2048 /**< maximum size of each user buffer, also used for injection buffer */ /* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */ @@ -424,6 +436,15 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const */ int dlt_unregister_context(DltContext *handle); +/** + * Set the logging mode used by the daemon. + * The logging mode is stored persistantly by the daemon. + * @see DltUserLogMode + * @param mode the new logging mode used by the daemon: off, extern, internal, both. + * @return negative value if there was an error + */ +int dlt_set_log_mode(DltUserLogMode mode); + /** * Register callback function called when injection message was received * @param handle pointer to an object containing information about one special logging context diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 7dcf025..86315c6 100755 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -464,7 +464,7 @@ int main(int argc, char* argv[]) { if (FD_ISSET(i, &(daemon_local.read_fds))) { - if (i == daemon_local.sock) + if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH))) { /* event from TCP server socket, new connection */ if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) @@ -562,7 +562,7 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in } /* if */ #endif /* init offline trace */ - if(daemon_local->flags.offlineTraceDirectory[0]) + if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0]) { if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1) { @@ -1234,6 +1234,7 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l break; } case DLT_USER_MESSAGE_LOG: + case DLT_USER_MESSAGE_LOG_SHM: { if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1) { @@ -1265,6 +1266,14 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l } break; } + case DLT_USER_MESSAGE_LOG_MODE: + { + if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } default: { dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n"); @@ -1770,26 +1779,11 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo } /* print message header only */ } /* if */ - -#if 0 - /* if file output enabled write message */ - if (daemon_local->flags.ovalue[0]) - { - /* write message to output buffer */ - if (dlt_user_log_out2(daemon_local->ohandle, - daemon_local->msg.headerbuffer, - daemon_local->msg.headersize, - daemon_local->msg.databuffer, - daemon_local->msg.datasize) !=DLT_RETURN_OK) - { - dlt_log(LOG_ERR,"Writing to output file failed!\n"); - } - } /* if */ -#endif + sent=0; /* write message to offline trace */ - if(daemon_local->flags.offlineTraceDirectory[0]) + if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0]) { dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize, daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0); @@ -1797,7 +1791,7 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo } /* look if TCP connection to client is available */ - for (j = 0; j <= daemon_local->fdmax; j++) + for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++) { /* send to everyone! */ if (FD_ISSET(j, &(daemon_local->master))) @@ -1848,16 +1842,16 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo } /* for */ /* Message was not sent to client, so store it in client ringbuffer */ - if (sent==0) + if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF)) { - /* dlt message was not sent, keep in buffer */ - break; + /* dlt message was sent, remove from buffer */ + dlt_shm_remove(&(daemon_local->dlt_shm)); } else { - /* dlt message was sent, remove from buffer */ - dlt_shm_remove(&(daemon_local->dlt_shm)); + /* dlt message was not sent, keep in buffer */ + break; } } @@ -1948,6 +1942,42 @@ int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLo return 0; } +int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + DltUserControlMsgLogMode *logmode; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))) + { + /* Not enough bytes received */ + return -1; + } + + logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + + /* set the new log mode */ + daemon->mode = logmode->log_mode; + + /* write configuration persistantly */ + dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose); + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n"); + return -1; + } + + return 0; +} + void dlt_daemon_timingpacket_thread(void *ptr) { DltDaemonPeriodicData info; diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h index 4c8f121..9d71a6e 100755 --- a/src/daemon/dlt-daemon.h +++ b/src/daemon/dlt-daemon.h @@ -169,6 +169,7 @@ int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemo int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); +int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); void dlt_daemon_timingpacket_thread(void *ptr); int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose); diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c index 003dc33..e10b20d 100755 --- a/src/daemon/dlt_daemon_common.c +++ b/src/daemon/dlt_daemon_common.c @@ -152,6 +152,8 @@ int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; daemon->runtime_context_cfg_loaded = 0; + + daemon->mode = DLT_USER_MODE_EXTERNAL; /* prepare filenames for configuration */ if(runtime_directory[0]) @@ -164,6 +166,11 @@ int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose else strcpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY); strcat(daemon->runtime_context_cfg,DLT_RUNTIME_CONTEXT_CFG); + if(runtime_directory[0]) + strcpy(daemon->runtime_configuration,runtime_directory); + else + strcpy(daemon->runtime_configuration,DLT_RUNTIME_DEFAULT_DIRECTORY); + strcat(daemon->runtime_configuration,DLT_RUNTIME_CONFIGURATION); /* Check for runtime cfg, if it is loadable, load it! */ if ((dlt_daemon_applications_load(daemon,daemon->runtime_application_cfg, verbose)==0) && @@ -171,7 +178,10 @@ int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose { daemon->runtime_context_cfg_loaded = 1; } - + + /* load configuration if available */ + dlt_daemon_configuration_load(daemon,daemon->runtime_configuration, verbose); + daemon->sendserialheader = 0; daemon->timingpackets = 0; @@ -827,6 +837,99 @@ int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose return 0; } +int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE *fd; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) ||( filename[0]=='\0')) + { + return -1; + } + + fd=fopen(filename, "w"); + if (fd!=0) + { + fprintf(fd,"# 0 = off, 1 = external, 2 = internal, 3 = both\n"); + fprintf(fd,"LoggingMode = %d\n",daemon->mode); + + fclose(fd); + } + + return 0; +} + +int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE * pFile; + char line[1024]; + char token[1024]; + char value[1024]; + char *pch; + + PRINT_FUNCTION_VERBOSE(verbose); + + pFile = fopen (filename,"r"); + + if (pFile!=NULL) + { + while(1) + { + /* fetch line from configuration file */ + if ( fgets (line , 1024 , pFile) != NULL ) + { + pch = strtok (line," =\r\n"); + token[0]=0; + value[0]=0; + + while (pch != NULL) + { + if(strcmp(pch,"#")==0) + break; + + if(token[0]==0) + { + strncpy(token,pch,sizeof(token)); + } + else + { + strncpy(value,pch,sizeof(value)); + break; + } + + pch = strtok (NULL, " =\r\n"); + } + + if(token[0] && value[0]) + { + /* parse arguments here */ + if(strcmp(token,"LoggingMode")==0) + { + daemon->mode = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else + { + fprintf(stderr, "Unknown option: %s=%s\n",token,value); + } + } + } + else + { + break; + } + } + fclose (pFile); + } + else + { + fprintf(stderr, "Cannot open configuration file: %s\n",filename); + } + + return 0; +} + int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose) { DltUserHeader userheader; diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h index bdacfd7..1fd3d2e 100755 --- a/src/daemon/dlt_daemon_common.h +++ b/src/daemon/dlt_daemon_common.h @@ -90,6 +90,7 @@ #include #include "dlt_common.h" +#include "dlt_user.h" #ifdef __cplusplus extern "C" { @@ -150,6 +151,8 @@ typedef struct int timingpackets; /**< 1: send continous timing packets; 0 don't send continous timing packets */ char runtime_application_cfg[256]; /**< Path and filename of persistent application configuration */ char runtime_context_cfg[256]; /**< Path and filename of persistent context configuration */ + char runtime_configuration[256]; /**< Path and filename of persistent configuration */ + DltUserLogMode mode; /**< Mode used for tracing: off, external, internal, both */ } DltDaemon; /** @@ -273,6 +276,23 @@ int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose * @return negative value if there was an error */ int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose); +/** + * Load persistant configuration + * @param daemon pointer to dlt daemon structure + * @param filename name of file to be used for loading + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ +int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose); +/** + * Save configuration persistantly + * @param daemon pointer to dlt daemon structure + * @param filename name of file to be used for saving + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ +int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose); + /** * Send user message DLT_USER_MESSAGE_LOG_LEVEL to user application diff --git a/src/daemon/dlt_daemon_common_cfg.h b/src/daemon/dlt_daemon_common_cfg.h index 0d076fe..9248bfb 100755 --- a/src/daemon/dlt_daemon_common_cfg.h +++ b/src/daemon/dlt_daemon_common_cfg.h @@ -90,6 +90,8 @@ #define DLT_RUNTIME_APPLICATION_CFG "/dlt-runtime-application.cfg" /* Path and filename for runtime configuration (contexts) */ #define DLT_RUNTIME_CONTEXT_CFG "/dlt-runtime-context.cfg" +/* Path and filename for runtime configuration */ +#define DLT_RUNTIME_CONFIGURATION "/dlt-runtime.cfg" /* Size of text buffer */ #define DLT_DAEMON_TEXTBUFSIZE 255 diff --git a/src/examples/dlt-example-user.c b/src/examples/dlt-example-user.c index 98d4e3a..62b539f 100755 --- a/src/examples/dlt-example-user.c +++ b/src/examples/dlt-example-user.c @@ -111,6 +111,7 @@ void usage() printf(" -n count Number of messages to be generated (Default: 10)\n"); printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); + printf(" -m mode Set log mode 0=off,1=external,2=internal,3=both\n"); } /** @@ -124,6 +125,7 @@ int main(int argc, char* argv[]) char *dvalue = 0; char *fvalue = 0; char *nvalue = 0; + char *mvalue = 0; char *message = 0; int index; @@ -135,7 +137,7 @@ int main(int argc, char* argv[]) opterr = 0; - while ((c = getopt (argc, argv, "vgad:f:n:")) != -1) + while ((c = getopt (argc, argv, "vgad:f:n:m:")) != -1) { switch (c) { @@ -169,6 +171,11 @@ int main(int argc, char* argv[]) nvalue = optarg; break; } + case 'm': + { + mvalue = optarg; + break; + } case '?': { if (optopt == 'd' || optopt == 'f' || optopt == 'n') @@ -224,6 +231,13 @@ int main(int argc, char* argv[]) text = message; + if(mvalue) + { + printf("Set log mode to %d\n",atoi(mvalue)); + dlt_set_log_mode(atoi(mvalue)); + } + + if (gflag) { DLT_NONVERBOSE_MODE(); diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 391b167..7886320 100755 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -119,6 +119,7 @@ static int dlt_user_log_send_unregister_application(void); static int dlt_user_log_send_register_context(DltContextData *log); static int dlt_user_log_send_unregister_context(DltContextData *log); static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus); +static int dlt_user_log_send_log_mode(DltUserLogMode mode); static int dlt_user_print_msg(DltMessage *msg, DltContextData *log); static int dlt_user_log_check_user_message(void); static void dlt_user_log_reattach_to_daemon(void); @@ -811,6 +812,19 @@ int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType return ret; } +int dlt_set_log_mode(DltUserLogMode mode) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + return dlt_user_log_send_log_mode(mode); +} + int dlt_forward_msg(void *msgdata,size_t size) { DltUserHeader userheader; @@ -2424,6 +2438,32 @@ int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTra return ((ret==DLT_RETURN_OK)?0:-1); } +int dlt_user_log_send_log_mode(DltUserLogMode mode) +{ + DltUserHeader userheader; + DltUserControlMsgLogMode logmode; + + DltReturnValue ret; + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1) + { + return -1; + } + + /* set data */ + logmode.log_mode = (unsigned char) mode; + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode)); + return ((ret==DLT_RETURN_OK)?0:-1); +} + int dlt_user_print_msg(DltMessage *msg, DltContextData *log) { uint8_t *databuffer_tmp; diff --git a/src/shared/dlt_user_shared.h b/src/shared/dlt_user_shared.h index a9d1628..a29a045 100755 --- a/src/shared/dlt_user_shared.h +++ b/src/shared/dlt_user_shared.h @@ -179,6 +179,23 @@ typedef struct uint8_t trace_status; /**< trace status */ } PACKED DltUserControlMsgAppLogLevelTraceStatus; +/** + * This is the internal message content to set the logging mode: off, external, internal, both. + */ +typedef struct +{ + uint8_t log_mode; /**< the mode to be used for logging: off, external, internal, both */ +} PACKED DltUserControlMsgLogMode; + +/** + * This is the internal message content to get the logging state, broadcast to each application, + * when client connects or disconnects. + */ +typedef struct +{ + uint8_t log_state; /**< the mode to be used for logging: off, on */ +} PACKED DltUserControlMsgLogState; + /************************************************************************************************** * The folowing functions are used shared between the user lib and the daemon implementation **************************************************************************************************/ diff --git a/src/shared/dlt_user_shared_cfg.h b/src/shared/dlt_user_shared_cfg.h index 08f919c..b784566 100755 --- a/src/shared/dlt_user_shared_cfg.h +++ b/src/shared/dlt_user_shared_cfg.h @@ -104,6 +104,9 @@ #define DLT_USER_MESSAGE_INJECTION 7 #define DLT_USER_MESSAGE_OVERFLOW 8 #define DLT_USER_MESSAGE_APP_LL_TS 9 +#define DLT_USER_MESSAGE_LOG_SHM 10 +#define DLT_USER_MESSAGE_LOG_MODE 11 +#define DLT_USER_MESSAGE_LOG_STATE 12 /* Internal defined values */ -- cgit v1.2.1