Implemented new DLT user library function dlt_get_log_state.
authorAlexander Wenzel <Alexander.AW.Wenzel@bmw.de>
Wed, 12 Oct 2011 11:51:03 +0000 (13:51 +0200)
committerAlexander Wenzel <Alexander.AW.Wenzel@bmw.de>
Wed, 12 Oct 2011 11:51:03 +0000 (13:51 +0200)
include/dlt/dlt_user.h
src/daemon/dlt-daemon.c
src/daemon/dlt_daemon_common.c
src/daemon/dlt_daemon_common.h
src/examples/dlt-example-user.c
src/lib/dlt_user.c
src/shared/dlt_user_shared.h

index 6f64255..6fb95a3 100755 (executable)
@@ -238,6 +238,8 @@ typedef struct
     int8_t enable_local_print;            /**< Local printing of log messages: 1 enabled, 0 disabled */
     int8_t local_print_mode;              /**< Local print mode, controlled by environment variable */
 
+    int8_t log_state;                                    /**< Log state of external connection: 1 client connected, 0 not connected, -1 unknown */
+
     DltShm dlt_shm;
 } DltUser;
 
@@ -446,6 +448,16 @@ int dlt_unregister_context(DltContext *handle);
 int dlt_set_log_mode(DltUserLogMode mode);
 
 /**
+ * Get the state of the connected client to the daemon.
+ * The user application gets a message, when client is connected or disconnected.
+ * This value contains the last state.
+ * It needs some time until the application gets state from the daemon.
+ * Until then the state is "unknown state".
+ * @return -1 = unknown state, 0 = client not connected, 1 = client connected
+ */
+int dlt_get_log_state();
+
+/**
  * Register callback function called when injection message was received
  * @param handle pointer to an object containing information about one special logging context
  * @param service_id the service id to be waited for
index 0e52d3c..4ab628f 100755 (executable)
@@ -1016,6 +1016,10 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_
     {
                /* send ringbuffer done in old implementation */
                /* nothing to do with shared memory */
+               
+               /* send new log state to all applications */
+               daemon->state = 1;              
+               dlt_daemon_user_send_all_log_state(daemon,verbose);
     }
 
     return 0;
@@ -1043,6 +1047,13 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon
             daemon_local->client_connections--;
         }
 
+               if(daemon_local->client_connections==0)
+               {
+                       /* send new log state to all applications */
+                       daemon->state = 0;              
+                       dlt_daemon_user_send_all_log_state(daemon,verbose);
+               }
+                               
         if (daemon_local->flags.vflag)
         {
             sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
@@ -1389,6 +1400,9 @@ int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltD
 
     application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
 
+       /* send log state to new application */
+       dlt_daemon_user_send_log_state(daemon,application,verbose);
+
     /* keep not read data in buffer */
     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
        {
index e10b20d..dbb1e7a 100755 (executable)
@@ -969,6 +969,42 @@ int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,i
     return ((ret==DLT_RETURN_OK)?0:-1);
 }
 
+int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose)
+{
+    DltUserHeader userheader;
+    DltUserControlMsgLogState logstate;
+    DltReturnValue ret;
+
+    PRINT_FUNCTION_VERBOSE(verbose);
+
+    if ((daemon==0) || (app==0))
+    {
+        return -1;
+    }
+
+    if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE)==-1)
+    {
+       return -1;
+    }
+
+    logstate.log_state = daemon->state;
+
+    /* log to FIFO */
+    ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader),  &(logstate), sizeof(DltUserControlMsgLogState));
+
+    if (ret!=DLT_RETURN_OK)
+    {
+        if (errno==EPIPE)
+        {
+            /* Close connection */
+            close(app->user_handle);
+            app->user_handle=0;
+        }
+    }
+
+    return ((ret==DLT_RETURN_OK)?0:-1);
+}
+
 int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
 {
     uint32_t id,id_tmp=0;
@@ -2179,6 +2215,35 @@ void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
     }
 }
 
+void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
+{
+    int32_t count;
+    DltDaemonApplication *app;
+
+    PRINT_FUNCTION_VERBOSE(verbose);
+
+    if (daemon==0)
+    {
+        return;
+    }
+
+    for (count=0;count<daemon->num_applications; count ++)
+    {
+        app = &(daemon->applications[count]);
+
+        if (app)
+        {
+                       if (app->user_handle!=0)
+                       {
+                               if (dlt_daemon_user_send_log_state(daemon, app, verbose)==-1)
+                               {
+                                       return;
+                               }
+                       }
+        }
+    }
+}
+
 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose)
 {
     DltMessage msg;
index 1fd3d2e..2bdb637 100755 (executable)
@@ -153,6 +153,7 @@ typedef struct
        char runtime_context_cfg[256]; /**< Path and filename of persistent context configuration */\r
        char runtime_configuration[256]; /**< Path and filename of persistent configuration */\r
     DltUserLogMode mode;       /**< Mode used for tracing: off, external, internal, both */\r
+    char state;                                /**< state for tracing: 0 = no client connected, 1 = client connected */\r
 } DltDaemon;\r
 \r
 /**\r
@@ -302,6 +303,16 @@ int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int ve
  * @return negative value if there was an error\r
  */\r
 int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context, int verbose);\r
+\r
+/**\r
+ * Send user message DLT_USER_MESSAGE_LOG_STATE to user application\r
+ * @param daemon pointer to dlt daemon structure\r
+ * @param app pointer to application for response\r
+ * @param verbose if set to true verbose information is printed out.\r
+ * @return negative value if there was an error\r
+ */\r
+int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose);\r
+\r
 /**\r
  * Send user messages to all user applications using default context, or trace status\r
  * to update those values\r
@@ -311,6 +322,14 @@ int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,
 void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose);\r
 \r
 /**\r
+ * Send user messages to all user applications the log status\r
+ * everytime the client is connected or disconnected.\r
+ * @param daemon pointer to dlt daemon structure\r
+ * @param verbose if set to true verbose information is printed out.\r
+ */\r
+void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose);\r
+\r
+/**\r
  * Process received control message from dlt client\r
  * @param sock connection handle used for sending response\r
  * @param daemon pointer to dlt daemon structure\r
index 62b539f..bdca2d5 100755 (executable)
@@ -134,6 +134,8 @@ int main(int argc, char* argv[])
        char *text;
        int num,maxnum;
        int delay;
+       
+       int state=-1,newstate;
 
     opterr = 0;
 
@@ -280,7 +282,21 @@ int main(int argc, char* argv[])
     {
         printf("Send %d %s\n",num,text);
 
-
+               newstate = dlt_get_log_state();
+               if(state!=newstate)
+               {
+                       state = newstate;
+                       if(state == -1) {
+                               printf("Client unknown state!\n");
+                       }
+                       else if(state == 0) {
+                               printf("Client disconnected!\n");
+                       }
+                       else if(state == 1) {
+                               printf("Client connected!\n");
+                       }
+               }
+                               
         if (gflag)
         {
             /* Non-verbose mode */
index da4f9e4..459a5d1 100755 (executable)
@@ -279,6 +279,9 @@ int dlt_init_common(void)
         return -1;
     }
 
+       /* set to unknown state of connected client */
+       dlt_user.log_state = -1;
+
     dlt_user.dlt_log_handle=-1;
     dlt_user.dlt_user_handle=-1;
 
@@ -812,6 +815,11 @@ int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType
     return ret;
 }
 
+int dlt_get_log_state()
+{
+       return dlt_user.log_state;
+}
+
 int dlt_set_log_mode(DltUserLogMode mode)
 {
     if (dlt_user_initialised==0)
@@ -2512,8 +2520,8 @@ int dlt_user_log_check_user_message(void)
     DltReceiver *receiver = &(dlt_user.receiver);
 
     DltUserControlMsgLogLevel *usercontextll;
-
     DltUserControlMsgInjection *usercontextinj;
+    DltUserControlMsgLogState *userlogstate;
     unsigned char *userbuffer;
     unsigned char *inject_buffer;
 
@@ -2670,6 +2678,25 @@ int dlt_user_log_check_user_message(void)
                     }
                 }
                 break;
+                case DLT_USER_MESSAGE_LOG_STATE:
+                {
+                    /* At least, user header, user context, and service id and data_length of injected message is available */
+                    if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
+                    {
+                        leave_while = 1;
+                        break;
+                    }
+
+                    userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
+                                       dlt_user.log_state = userlogstate->log_state;
+
+                                       /* keep not read data in buffer */
+                                       if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
+                                       {
+                                               return -1;
+                                       }
+                }
+                break;
                 default:
                 {
                     dlt_log(LOG_ERR,"Invalid user message type received!\n");
index a29a045..0fd6367 100755 (executable)
@@ -184,16 +184,15 @@ typedef struct
  */\r
 typedef struct\r
 {\r
-       uint8_t log_mode;          /**< the mode to be used for logging: off, external, internal, both */\r
+       int8_t log_mode;          /**< the mode to be used for logging: off, external, internal, both */\r
 } PACKED DltUserControlMsgLogMode;\r
 \r
 /**\r
- * This is the internal message content to get the logging state, broadcast to each application,\r
- * when client connects or disconnects.\r
+ * This is the internal message content to get the logging state: 0 = off, 1 = external client connected.\r
  */\r
 typedef struct\r
 {\r
-       uint8_t log_state;          /**< the mode to be used for logging: off, on */\r
+       int8_t log_state;          /**< the state to be used for logging state: 0 = off, 1 = external client connected */\r
 } PACKED DltUserControlMsgLogState;\r
 \r
 /**************************************************************************************************\r