automotive-dlt
dlt-daemon.c
Go to the documentation of this file.
1 /*
2  * @licence app begin@
3  * SPDX license identifier: MPL-2.0
4  *
5  * Copyright (C) 2011-2015, BMW AG
6  *
7  * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
8  *
9  * This Source Code Form is subject to the terms of the
10  * Mozilla Public License (MPL), v. 2.0.
11  * If a copy of the MPL was not distributed with this file,
12  * You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  * For further information see http://www.genivi.org/.
15  * @licence end@
16  */
17 
30 #include <netdb.h>
31 #include <ctype.h>
32 #include <stdio.h> /* for printf() and fprintf() */
33 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
34 #include <sys/un.h>
35 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
36 #include <stdlib.h> /* for atoi() and exit() */
37 #include <string.h> /* for memset() */
38 #include <unistd.h> /* for close() */
39 #include <fcntl.h>
40 #include <signal.h>
41 #include <syslog.h>
42 #include <errno.h>
43 #include <pthread.h>
44 
45 #ifdef linux
46 #include <sys/timerfd.h>
47 #endif
48 #include <sys/stat.h>
49 #include <sys/time.h>
50 #ifdef linux
51 #include <linux/stat.h>
52 #endif
53 
54 #include "dlt_types.h"
55 #include "dlt-daemon.h"
56 #include "dlt-daemon_cfg.h"
57 #include "dlt_daemon_common_cfg.h"
58 
59 #include "dlt_daemon_socket.h"
60 #include "dlt_daemon_unix_socket.h"
61 #include "dlt_daemon_serial.h"
62 
63 #include "dlt_daemon_client.h"
64 #include "dlt_daemon_connection.h"
67 #include "dlt_gateway.h"
68 
69 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
70 #include "sd-daemon.h"
71 #endif
72 
81 
82 static int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *str, int verbose);
83 
84 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
85 static uint32_t watchdog_trigger_interval; // watchdog trigger interval in [s]
86 #endif
87 
88 /* used in main event loop and signal handler */
89 int g_exit = 0;
90 
94 void usage()
95 {
96  char version[DLT_DAEMON_TEXTBUFSIZE];
98 
99  //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
100  //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
101  printf("%s", version);
102  printf("Usage: dlt-daemon [options]\n");
103  printf("Options:\n");
104  printf(" -d Daemonize\n");
105  printf(" -h Usage\n");
106  printf(" -c filename DLT daemon configuration file (Default: " CONFIGURATION_FILES_DIR "/dlt.conf)\n");
107  printf(" -t directory Directory for local fifo and user-pipes (Default: /tmp)\n");
108  printf(" (Applications wanting to connect to a daemon using a\n");
109  printf(" custom directory need to be started with the environment \n");
110  printf(" variable DLT_PIPE_DIR set appropriately)\n");
111  printf(" -p port port to monitor for incoming requests (Default: 3490)\n");
112  printf(" (Applications wanting to connect to a daemon using a custom\n");
113  printf(" port need to be started with the environment variable\n");
114  printf(" DLT_DAEMON_TCP_PORT set appropriately)\n");
115 } /* usage() */
116 
120 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
121  {
122  int c;
123 
124  if (daemon_local==0)
125  {
126  fprintf (stderr, "Invalid parameter passed to option_handling()\n");
127  return -1;
128  }
129 
130  /* Initialize flags */
131  memset(daemon_local,0,sizeof(DltDaemonLocal));
132 
133  /* default values */
134  daemon_local->flags.port = DLT_DAEMON_TCP_PORT;
135  strncpy(dltFifoBaseDir, "/tmp", NAME_MAX);
136 
137  opterr = 0;
138 
139  while ((c = getopt (argc, argv, "hdc:t:p:")) != -1)
140  {
141  switch (c)
142  {
143  case 'd':
144  {
145  daemon_local->flags.dflag = 1;
146  break;
147  }
148  case 'c':
149  {
150  strncpy(daemon_local->flags.cvalue,optarg,NAME_MAX);
151  break;
152  }
153  case 't':
154  {
155  strncpy(dltFifoBaseDir, optarg, NAME_MAX);
156  break;
157  }
158  case 'p':
159  {
160  daemon_local->flags.port = atoi(optarg);
161  if (daemon_local->flags.port == 0)
162  {
163  fprintf (stderr, "Invalid port `%s' specified.\n", optarg);
164  return -1;
165  }
166  break;
167  }
168  case 'h':
169  {
170  usage();
171  return -2; /* return no error */
172  }
173  case '?':
174  {
175  if (optopt == 'c' || optopt == 't' || optopt == 'p')
176  {
177  fprintf (stderr, "Option -%c requires an argument.\n", optopt);
178  }
179  else if (isprint (optopt))
180  {
181  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
182  }
183  else
184  {
185  fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
186  }
187  /* unknown or wrong option used, show usage information and terminate */
188  usage();
189  return -1;
190  }
191  default:
192  {
193  fprintf (stderr, "Invalid option, this should never occur!\n");
194  return -1;
195  }
196  } /* switch() */
197  }
198 
199  snprintf(daemon_local->flags.userPipesDir, NAME_MAX + 1, "%s/dltpipes", dltFifoBaseDir);
200  snprintf(daemon_local->flags.daemonFifoName, NAME_MAX + 1, "%s/dlt", dltFifoBaseDir);
201 
202  return 0;
203 
204  } /* option_handling() */
205 
210 {
211  FILE * pFile;
212  int value_length = 1024;
213  char line[value_length-1];
214  char token[value_length];
215  char value[value_length];
216  char *pch;
217  const char *filename;
218 
219  /* set default values for configuration */
220  daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
221  daemon_local->flags.sendMessageTime = 0;
222  daemon_local->flags.offlineTraceDirectory[0] = 0;
223  daemon_local->flags.offlineTraceFileSize = 1000000;
224  daemon_local->flags.offlineTraceMaxSize = 0;
225  daemon_local->flags.offlineTraceFilenameTimestampBased = 1;
226  daemon_local->flags.loggingMode = DLT_LOG_TO_CONSOLE;
227  daemon_local->flags.loggingLevel = LOG_INFO;
228  snprintf(daemon_local->flags.loggingFilename, sizeof(daemon_local->flags.loggingFilename)-1, "%s/dlt.log", dltFifoBaseDir);
229  daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename)-1]=0;
230  daemon_local->timeoutOnSend = 4;
234  daemon_local->daemonFifoSize = 0;
235  daemon_local->flags.sendECUSoftwareVersion = 0;
236  memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
237  daemon_local->flags.sendTimezone = 0;
238  daemon_local->flags.offlineLogstorageMaxDevices = 0;
239  daemon_local->flags.offlineLogstorageDirPath[0] = 0;
240  daemon_local->flags.offlineLogstorageMaxDevices = 0;
241  daemon_local->flags.offlineLogstorageTimestamp = 1;
242  daemon_local->flags.offlineLogstorageDelimiter = '_';
243  daemon_local->flags.offlineLogstorageMaxCounter = UINT_MAX;
244  daemon_local->flags.offlineLogstorageMaxCounterIdx = 0;
245  daemon_local->flags.offlineLogstorageCacheSize = 30000; /* 30MB */
247  daemon_local->flags.offlineLogstorageCacheSize);
248  strncpy(daemon_local->flags.ctrlSockPath,
250  sizeof(daemon_local->flags.ctrlSockPath) - 1);
251  daemon_local->flags.gatewayMode = 0;
252  strncpy(daemon_local->flags.gatewayConfigFile,
254  DLT_DAEMON_FLAG_MAX - 1);
255  daemon_local->flags.autoResponseGetLogInfoOption = 7;
256  daemon_local->flags.contextLogLevel = DLT_LOG_INFO;
258  daemon_local->flags.enforceContextLLAndTS = 0; /* default is off */
259 
260  /* open configuration file */
261  if(daemon_local->flags.cvalue[0])
262  filename = daemon_local->flags.cvalue;
263  else
264  filename = CONFIGURATION_FILES_DIR "/dlt.conf";
265  //printf("Load configuration from file: %s\n",filename);
266  pFile = fopen (filename,"r");
267 
268  if (pFile!=NULL)
269  {
270  while(1)
271  {
272  /* fetch line from configuration file */
273  if ( fgets (line , value_length - 1 , pFile) != NULL )
274  {
275  pch = strtok (line," =\r\n");
276  token[0]=0;
277  value[0]=0;
278 
279  while (pch != NULL)
280  {
281  if(strcmp(pch,"#")==0)
282  break;
283 
284  if(token[0]==0)
285  {
286  strncpy(token,pch,sizeof(token) - 1);
287  token[sizeof(token) - 1]=0;
288  }
289  else
290  {
291  strncpy(value,pch,sizeof(value) - 1);
292  value[sizeof(value) - 1]=0;
293  break;
294  }
295 
296  pch = strtok (NULL, " =\r\n");
297  }
298 
299  if(token[0] && value[0])
300  {
301  /* parse arguments here */
302  if(strcmp(token,"Verbose")==0)
303  {
304  daemon_local->flags.vflag = atoi(value);
305  //printf("Option: %s=%s\n",token,value);
306  }
307  else if(strcmp(token,"PrintASCII")==0)
308  {
309  daemon_local->flags.aflag = atoi(value);
310  //printf("Option: %s=%s\n",token,value);
311  }
312  else if(strcmp(token,"PrintHex")==0)
313  {
314  daemon_local->flags.xflag = atoi(value);
315  //printf("Option: %s=%s\n",token,value);
316  }
317  else if(strcmp(token,"PrintHeadersOnly")==0)
318  {
319  daemon_local->flags.sflag = atoi(value);
320  //printf("Option: %s=%s\n",token,value);
321  }
322  else if(strcmp(token,"SendSerialHeader")==0)
323  {
324  daemon_local->flags.lflag = atoi(value);
325  //printf("Option: %s=%s\n",token,value);
326  }
327  else if(strcmp(token,"SendContextRegistration")==0)
328  {
329  daemon_local->flags.rflag = atoi(value);
330  //printf("Option: %s=%s\n",token,value);
331  }
332  else if(strcmp(token,"SendContextRegistrationOption")==0)
333  {
334  daemon_local->flags.autoResponseGetLogInfoOption = atoi(value);
335  //printf("Option: %s=%s\n",token,value);
336  }
337  else if(strcmp(token,"SendMessageTime")==0)
338  {
339  daemon_local->flags.sendMessageTime = atoi(value);
340  //printf("Option: %s=%s\n",token,value);
341  }
342  else if(strcmp(token,"RS232SyncSerialHeader")==0)
343  {
344  daemon_local->flags.mflag = atoi(value);
345  //printf("Option: %s=%s\n",token,value);
346  }
347  else if(strcmp(token,"TCPSyncSerialHeader")==0)
348  {
349  daemon_local->flags.nflag = atoi(value);
350  //printf("Option: %s=%s\n",token,value);
351  }
352  else if(strcmp(token,"RS232DeviceName")==0)
353  {
354  strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
355  daemon_local->flags.yvalue[NAME_MAX]=0;
356  //printf("Option: %s=%s\n",token,value);
357  }
358  else if(strcmp(token,"RS232Baudrate")==0)
359  {
360  strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
361  daemon_local->flags.bvalue[NAME_MAX]=0;
362  //printf("Option: %s=%s\n",token,value);
363  }
364  else if(strcmp(token,"ECUId")==0)
365  {
366  strncpy(daemon_local->flags.evalue,value,NAME_MAX);
367  daemon_local->flags.evalue[NAME_MAX]=0;
368  //printf("Option: %s=%s\n",token,value);
369  }
370  else if(strcmp(token,"PersistanceStoragePath")==0)
371  {
372  strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
373  daemon_local->flags.ivalue[NAME_MAX]=0;
374  //printf("Option: %s=%s\n",token,value);
375  }
376  else if(strcmp(token,"LoggingMode")==0)
377  {
378  daemon_local->flags.loggingMode = atoi(value);
379  //printf("Option: %s=%s\n",token,value);
380  }
381  else if(strcmp(token,"LoggingLevel")==0)
382  {
383  daemon_local->flags.loggingLevel = atoi(value);
384  //printf("Option: %s=%s\n",token,value);
385  }
386  else if(strcmp(token,"LoggingFilename")==0)
387  {
388  strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
389  daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename) - 1]=0;
390  //printf("Option: %s=%s\n",token,value);
391  }
392  else if(strcmp(token,"TimeOutOnSend")==0)
393  {
394  daemon_local->timeoutOnSend = atoi(value);
395  //printf("Option: %s=%s\n",token,value);
396  }
397  else if(strcmp(token,"RingbufferMinSize")==0)
398  {
399  sscanf(value,"%lu",&(daemon_local->RingbufferMinSize));
400  }
401  else if(strcmp(token,"RingbufferMaxSize")==0)
402  {
403  sscanf(value,"%lu",&(daemon_local->RingbufferMaxSize));
404  }
405  else if(strcmp(token,"RingbufferStepSize")==0)
406  {
407  sscanf(value,"%lu",&(daemon_local->RingbufferStepSize));
408  }
409  else if(strcmp(token,"DaemonFIFOSize")==0)
410  {
411  sscanf(value,"%lu",&(daemon_local->daemonFifoSize));
412  }
413  else if(strcmp(token,"SharedMemorySize")==0)
414  {
415  daemon_local->flags.sharedMemorySize = atoi(value);
416  //printf("Option: %s=%s\n",token,value);
417  }
418  else if(strcmp(token,"OfflineTraceDirectory")==0)
419  {
420  strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
421  daemon_local->flags.offlineTraceDirectory[sizeof(daemon_local->flags.offlineTraceDirectory) - 1]=0;
422  //printf("Option: %s=%s\n",token,value);
423  }
424  else if(strcmp(token,"OfflineTraceFileSize")==0)
425  {
426  daemon_local->flags.offlineTraceFileSize = atoi(value);
427  //printf("Option: %s=%s\n",token,value);
428  }
429  else if(strcmp(token,"OfflineTraceMaxSize")==0)
430  {
431  daemon_local->flags.offlineTraceMaxSize = atoi(value);
432  //printf("Option: %s=%s\n",token,value);
433  }
434  else if(strcmp(token,"OfflineTraceFileNameTimestampBased")==0)
435  {
436  daemon_local->flags.offlineTraceFilenameTimestampBased = atoi(value);
437  //printf("Option: %s=%s\n",token,value);
438  }
439  else if(strcmp(token,"SendECUSoftwareVersion")==0)
440  {
441  daemon_local->flags.sendECUSoftwareVersion = atoi(value);
442  //printf("Option: %s=%s\n",token,value);
443  }
444  else if(strcmp(token,"PathToECUSoftwareVersion")==0)
445  {
446  strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
447  daemon_local->flags.pathToECUSoftwareVersion[sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1]=0;
448  //printf("Option: %s=%s\n",token,value);
449  }
450  else if(strcmp(token,"SendTimezone")==0)
451  {
452  daemon_local->flags.sendTimezone = atoi(value);
453  //printf("Option: %s=%s\n",token,value);
454  }
455  else if(strcmp(token, "OfflineLogstorageMaxDevices") == 0)
456  {
457  daemon_local->flags.offlineLogstorageMaxDevices = atoi(value);
458  }
459  else if(strcmp(token, "OfflineLogstorageDirPath") == 0)
460  {
461  strncpy(daemon_local->flags.offlineLogstorageDirPath,
462  value,
463  sizeof(daemon_local->flags.offlineLogstorageDirPath) - 1);
464  }
465  else if(strcmp(token, "OfflineLogstorageTimestamp") == 0)
466  {
467  /* Check if set to 0, default otherwise */
468  if(atoi(value) == 0)
469  {
470  daemon_local->flags.offlineLogstorageTimestamp = 0;
471  }
472  }
473  else if(strcmp(token, "OfflineLogstorageDelimiter") == 0)
474  {
475  /* Check if valid punctuation, default otherwise*/
476  if(ispunct((char)value[0]))
477  {
478  daemon_local->flags.offlineLogstorageDelimiter = (char)value[0];
479  }
480  }
481  else if(strcmp(token, "OfflineLogstorageMaxCounter") == 0)
482  {
483  daemon_local->flags.offlineLogstorageMaxCounter = atoi(value);
484  daemon_local->flags.offlineLogstorageMaxCounterIdx = strlen(value);
485  }
486  else if(strcmp(token, "OfflineLogstorageCacheSize") == 0)
487  {
488  daemon_local->flags.offlineLogstorageCacheSize =
489  (unsigned int)atoi(value);
491  daemon_local->flags.offlineLogstorageCacheSize);
492  }
493  else if(strcmp(token,"ControlSocketPath") == 0)
494  {
495  memset(
496  daemon_local->flags.ctrlSockPath,
497  0,
499  strncpy(
500  daemon_local->flags.ctrlSockPath,
501  value,
503  }
504  else if(strcmp(token,"GatewayMode")==0)
505  {
506  daemon_local->flags.gatewayMode = atoi(value);
507  //printf("Option: %s=%s\n",token,value);
508  }
509  else if(strcmp(token,"GatewayConfigFile")==0)
510  {
511  memset(
512  daemon_local->flags.gatewayConfigFile,
513  0,
515  strncpy(
516  daemon_local->flags.gatewayConfigFile,
517  value,
519  }
520  else if(strcmp(token,"ContextLogLevel")==0)
521  {
522  int const intval = atoi(value);
523  if ( (intval >= DLT_LOG_OFF) && (intval <= DLT_LOG_VERBOSE))
524  {
525  daemon_local->flags.contextLogLevel = intval;
526  printf("Option: %s=%s\n",token,value);
527  }
528  else
529  {
530  fprintf(stderr, "Invalid value for ContextLogLevel: %i. Must be in range [%i..%i]\n", intval, DLT_LOG_OFF, DLT_LOG_VERBOSE);
531  }
532  }
533  else if(strcmp(token,"ContextTraceStatus")==0)
534  {
535  int const intval = atoi(value);
536  if ( (intval >= DLT_TRACE_STATUS_OFF) && (intval <= DLT_TRACE_STATUS_ON))
537  {
538  daemon_local->flags.contextTraceStatus = intval;
539  printf("Option: %s=%s\n",token,value);
540  }
541  else
542  {
543  fprintf(stderr, "Invalid value for ContextTraceStatus: %i. Must be in range [%i..%i]\n", intval, DLT_TRACE_STATUS_OFF, DLT_TRACE_STATUS_ON);
544  }
545  }
546  else if(strcmp(token,"ForceContextLogLevelAndTraceStatus")==0)
547  {
548  int const intval = atoi(value);
549  if ( (intval >= 0) && (intval <= 1))
550  {
551  daemon_local->flags.enforceContextLLAndTS = intval;
552  printf("Option: %s=%s\n",token,value);
553  }
554  else
555  {
556  fprintf(stderr, "Invalid value for ForceContextLogLevelAndTraceStatus: %i. Must be 0, 1\n", intval);
557  }
558  }
559  else
560  {
561  fprintf(stderr, "Unknown option: %s=%s\n",token,value);
562  }
563  }
564  }
565  else
566  {
567  break;
568  }
569  }
570  fclose (pFile);
571  }
572  else
573  {
574  fprintf(stderr, "Cannot open configuration file: %s\n",filename);
575  }
576 
577  return 0;
578 }
579 
583 int main(int argc, char* argv[])
584 {
585  char version[DLT_DAEMON_TEXTBUFSIZE];
586  DltDaemonLocal daemon_local;
587  DltDaemon daemon;
588  int back = 0;
589 
590  memset(&daemon_local, 0, sizeof(DltDaemonLocal));
591  memset(&daemon, 0, sizeof(DltDaemon));
592 
593  /* Command line option handling */
594  if ((back = option_handling(&daemon_local,argc,argv))<0)
595  {
596  if(back!=-2) {
597  fprintf (stderr, "option_handling() failed!\n");
598  }
599  return -1;
600  }
601 
602  /* Configuration file option handling */
603  if ((back = option_file_parser(&daemon_local))<0)
604  {
605  if(back!=-2) {
606  fprintf (stderr, "option_file_parser() failed!\n");
607  }
608  return -1;
609  }
610 
611  /* Initialize internal logging facility */
613  dlt_log_set_level(daemon_local.flags.loggingLevel);
614  dlt_log_init(daemon_local.flags.loggingMode);
615 
616  /* Print version information */
618 
619  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Starting DLT Daemon; %s\n", version );
620  dlt_log(LOG_NOTICE, str);
621 
622  PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
623 
624  /* Make sure the parent user directory is created */
626  {
627  snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "Base dir %s cannot be created!\n", dltFifoBaseDir);
628  dlt_log(LOG_ERR, str);
629  return -1;
630  }
631 
632  /* --- Daemon init phase 1 begin --- */
633  if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
634  {
635  dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
636  return -1;
637  }
638  /* --- Daemon init phase 1 end --- */
639 
640  if (dlt_daemon_prepare_event_handling(&daemon_local.pEvent))
641  {
642  /* TODO: Perform clean-up */
643  dlt_log(LOG_CRIT,"Initialization of event handling failed!\n");
644  return -1;
645  }
646 
647  /* --- Daemon connection init begin */
648  if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
649  {
650  dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
651  return -1;
652  }
653  /* --- Daemon connection init end */
654 
655  /* --- Daemon init phase 2 begin --- */
656  if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
657  {
658  dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
659  return -1;
660  }
661  /* --- Daemon init phase 2 end --- */
662 
663  if(daemon_local.flags.offlineLogstorageDirPath[0])
664  {
666  daemon_local.flags.offlineLogstorageDirPath,
667  daemon_local.flags.vflag)==-1)
668  {
669  dlt_log(LOG_INFO,"Setting up internal offline log storage failed!\n");
670  }
671  }
672 
673  // create fd for watchdog
674 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
675  {
676  char* watchdogUSec = getenv("WATCHDOG_USEC");
677  int watchdogTimeoutSeconds = 0;
678 
679  dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n");
680  if( watchdogUSec )
681  {
682  watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000;
683  }
684  watchdog_trigger_interval = watchdogTimeoutSeconds;
685  create_timer_fd(&daemon_local,
686  watchdogTimeoutSeconds,
687  watchdogTimeoutSeconds,
688  DLT_TIMER_SYSTEMD);
689  }
690 #endif
691 
692  // create fd for timer timing packets
693  create_timer_fd(&daemon_local, 1, 1, DLT_TIMER_PACKET);
694 
695  // create fd for timer ecu version
696  if((daemon_local.flags.sendECUSoftwareVersion > 0) ||
697  (daemon_local.flags.sendTimezone > 0))
698  {
699  create_timer_fd(&daemon_local, 60, 60, DLT_TIMER_ECU);
700  }
701 
702  /* initiate gateway */
703  if (daemon_local.flags.gatewayMode == 1)
704  {
705  if (dlt_gateway_init(&daemon_local, daemon_local.flags.vflag) == -1)
706  {
707  dlt_log(LOG_CRIT, "Fail to create gateway\n");
708  return -1;
709  }
710 
711  /* create gateway timer */
712  create_timer_fd(&daemon_local,
716  }
717 
718  // For offline tracing we still can use the same states
719  // as for socket sending. Using this trick we see the traces
720  // In the offline trace AND in the socket stream.
721  if(daemon_local.flags.yvalue[0])
723  else
725 
726  dlt_daemon_log_internal(&daemon, &daemon_local, "Daemon launched. Starting to output traces...", daemon_local.flags.vflag);
727 
728  /* Even handling loop. */
729  while ((back >= 0) && (g_exit >= 0))
730  {
731  back = dlt_daemon_handle_event(&daemon_local.pEvent,
732  &daemon,
733  &daemon_local);
734  }
735 
736  dlt_daemon_log_internal(&daemon, &daemon_local, "Exiting Daemon...", daemon_local.flags.vflag);
737 
738  dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
739 
740  dlt_daemon_free(&daemon, daemon_local.flags.vflag);
741 
742  dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
743 
744  return 0;
745 
746 } /* main() */
747 
748 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
749 {
750  int ret;
751 
752  PRINT_FUNCTION_VERBOSE(verbose);
753 
754  if ((daemon==0) || (daemon_local==0))
755  {
756  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
757  return -1;
758  }
759 
760 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
761  ret = sd_booted();
762 
763  if(ret == 0){
764  dlt_log(LOG_CRIT, "System not booted with systemd!\n");
765 // return -1;
766  }
767  else if(ret < 0)
768  {
769  dlt_log(LOG_CRIT, "sd_booted failed!\n");
770  return -1;
771  }
772  else
773  {
774  dlt_log(LOG_INFO, "System booted with systemd\n");
775  }
776 #endif
777 
778  const char *tmpFifo = daemon_local->flags.userPipesDir;
779 
780  /* create dlt pipes directory */
781  ret=mkdir(tmpFifo, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
782  if (ret==-1 && errno != EEXIST)
783  {
784  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user dir %s cannot be created (%s)!\n", tmpFifo, strerror(errno));
785  dlt_log(LOG_WARNING, str);
786  return -1;
787  }
788 
789  // S_ISGID cannot be set by mkdir, let's reassign right bits
790  ret=chmod(tmpFifo, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX );
791  if (ret==-1)
792  {
793  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user dir %s cannot be chmoded (%s)!\n", tmpFifo, strerror(errno));
794  dlt_log(LOG_WARNING, str);
795  return -1;
796  }
797 
798  /* Check for daemon mode */
799  if (daemon_local->flags.dflag)
800  {
801  dlt_daemon_daemonize(daemon_local->flags.vflag);
802  }
803 
804  /* initialise structure to use DLT file */
805  if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag) == DLT_RETURN_ERROR)
806  {
807  dlt_log(LOG_ERR,"Could not initialize file structure\n");
808  /* Return value ignored, dlt daemon will exit */
809  dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
810  return -1;
811  }
812 
813  signal(SIGPIPE,SIG_IGN);
814 
815  signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
816  signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
817  signal(SIGQUIT, dlt_daemon_signal_handler);
818  signal(SIGINT, dlt_daemon_signal_handler);
819 
820  return 0;
821 }
822 
823 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
824 {
825  PRINT_FUNCTION_VERBOSE(verbose);
826 
827  if ((daemon==0) || (daemon_local==0))
828  {
829  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
830  return -1;
831  }
832 
833  /* Daemon data */
834  if (dlt_daemon_init(daemon,daemon_local->RingbufferMinSize,daemon_local->RingbufferMaxSize,daemon_local->RingbufferStepSize, daemon_local->flags.ivalue,daemon_local->flags.contextLogLevel, daemon_local->flags.contextTraceStatus,daemon_local->flags.enforceContextLLAndTS,daemon_local->flags.vflag)==-1)
835  {
836  dlt_log(LOG_ERR,"Could not initialize daemon data\n");
837  return -1;
838  }
839 
840  /* init offline trace */
841  if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
842  {
843  if (dlt_offline_trace_init(&(daemon_local->offlineTrace),
844  daemon_local->flags.offlineTraceDirectory,
845  daemon_local->flags.offlineTraceFileSize,
846  daemon_local->flags.offlineTraceMaxSize,
847  daemon_local->flags.offlineTraceFilenameTimestampBased)==-1)
848  {
849  dlt_log(LOG_ERR,"Could not initialize offline trace\n");
850  return -1;
851  }
852  }
853 
854  /* Init offline logstorage for MAX devices */
855  if(daemon_local->flags.offlineLogstorageMaxDevices > 0)
856  {
857  daemon->storage_handle = malloc(sizeof(DltLogStorage) * daemon_local->flags.offlineLogstorageMaxDevices);
858 
859  if(daemon->storage_handle == NULL)
860  {
861  dlt_log(LOG_ERR,"Could not initialize offline logstorage\n");
862  return -1;
863  }
864  memset(daemon->storage_handle, 0, (sizeof(DltLogStorage) * daemon_local->flags.offlineLogstorageMaxDevices));
865  }
866 
867  /* Set ECU id of daemon */
868  if (daemon_local->flags.evalue[0])
869  {
870  dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
871  }
872  else
873  {
875  }
876 
877  /* Set flag for optional sending of serial header */
878  daemon->sendserialheader = daemon_local->flags.lflag;
879 
880 #ifdef DLT_SHM_ENABLE
881  /* init shared memory */
882  if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
883  {
884  dlt_log(LOG_ERR,"Could not initialize shared memory\n");
885  return -1;
886  }
887 #endif
888 
889  /* prepare main loop */
890  if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag) == DLT_RETURN_ERROR)
891  {
892  dlt_log(LOG_ERR,"Could not initialize message\n");
893  return -1;
894  }
895 
896  /* configure sending timing packets */
897  if (daemon_local->flags.sendMessageTime)
898  {
899  daemon->timingpackets = 1;
900  }
901 
902  /* Binary semaphore for thread */
903  if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
904  {
905  dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
906  return -1;
907  }
908 
909  /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
910  if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
911  {
912  daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
913  if(daemon->ECUVersionString==0)
914  {
915  dlt_log(LOG_WARNING,"Could not allocate memory for version string\n");
916  return -1;
917  }
919  }
920 
921  return 0;
922 }
923 
924 static int dlt_daemon_init_serial(DltDaemonLocal *daemon_local)
925 {
926  /* create and open serial connection from/to client */
927  /* open serial connection */
928  int fd = -1;
929 
930  if (daemon_local->flags.yvalue[0] == '\0') {
931  return 0;
932  }
933 
934  fd = open(daemon_local->flags.yvalue, O_RDWR);
935  if (fd < 0)
936  {
937  snprintf(str,
939  "Failed to open serial device %s\n",
940  daemon_local->flags.yvalue);
941  dlt_log(LOG_ERR, str);
942 
943  daemon_local->flags.yvalue[0] = 0;
944  return -1;
945  }
946 
947  if (isatty(fd))
948  {
950 
951  if (daemon_local->flags.bvalue[0])
952  {
953  speed = atoi(daemon_local->flags.bvalue);
954  }
955 
956  daemon_local->baudrate = dlt_convert_serial_speed(speed);
957 
958  if (dlt_setup_serial(fd, daemon_local->baudrate) < 0)
959  {
960  close(fd);
961  daemon_local->flags.yvalue[0] = 0;
962 
963  snprintf(str,
965  "Failed to configure serial device %s (%s) \n",
966  daemon_local->flags.yvalue,
967  strerror(errno));
968  dlt_log(LOG_ERR, str);
969 
970  return -1;
971  }
972 
973  if (daemon_local->flags.vflag)
974  {
975  dlt_log(LOG_DEBUG, "Serial init done\n");
976  }
977  }
978  else
979  {
980  close(fd);
981  fprintf(stderr,
982  "Device is not a serial device, device = %s (%s) \n",
983  daemon_local->flags.yvalue,
984  strerror(errno));
985  daemon_local->flags.yvalue[0] = 0;
986  return -1;
987  }
988 
989  return dlt_connection_create(daemon_local,
990  &daemon_local->pEvent,
991  fd,
992  EPOLLIN,
994 }
995 
996 static int dlt_daemon_init_fifo(DltDaemonLocal *daemon_local)
997 {
998  int ret;
999  int fd = -1;
1000  int fifo_size;
1001  char local_str[DLT_DAEMON_TEXTBUFSIZE];
1002 
1003  /* open named pipe(FIFO) to receive DLT messages from users */
1004  umask(0);
1005 
1006  /* Try to delete existing pipe, ignore result of unlink */
1007  const char *tmpFifo = daemon_local->flags.daemonFifoName;
1008  unlink(tmpFifo);
1009 
1010  ret=mkfifo(tmpFifo, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
1011  if (ret == -1)
1012  {
1013  snprintf(local_str,
1015  "FIFO user %s cannot be created (%s)!\n",
1016  tmpFifo,
1017  strerror(errno));
1018  dlt_log(LOG_WARNING, local_str);
1019  return -1;
1020  } /* if */
1021 
1022  fd = open(tmpFifo, O_RDWR);
1023  if (fd == -1)
1024  {
1025  snprintf(local_str,
1027  "FIFO user %s cannot be opened (%s)!\n",
1028  tmpFifo,
1029  strerror(errno));
1030  dlt_log(LOG_WARNING, local_str);
1031  return -1;
1032  } /* if */
1033 
1034  if (daemon_local->daemonFifoSize != 0)
1035  {
1036  /* Set Daemon FIFO size */
1037  if (fcntl(fd, F_SETPIPE_SZ , daemon_local->daemonFifoSize) == -1)
1038  {
1039  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"set FIFO size error: %s\n",strerror(errno));
1040  dlt_log(LOG_ERR, str);
1041  }
1042  }
1043 
1044  /* Get Daemon FIFO size */
1045  if ((fifo_size = fcntl(fd, F_GETPIPE_SZ , 0)) == -1)
1046  {
1047  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"get FIFO size error: %s\n",strerror(errno));
1048  dlt_log(LOG_ERR, str);
1049  }
1050  else
1051  {
1052  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO size: %d\n",fifo_size);
1053  dlt_log(LOG_INFO, str);
1054  }
1055 
1056  /* Early init, to be able to catch client (app) connections
1057  * as soon as possible. This registration is automatically ignored
1058  * during next execution.
1059  */
1060  return dlt_connection_create(daemon_local,
1061  &daemon_local->pEvent,
1062  fd,
1063  EPOLLIN,
1065 }
1066 
1068  DltDaemonLocal *daemon_local,
1069  int verbose)
1070 {
1071  char local_str[DLT_DAEMON_TEXTBUFSIZE];
1072  int fd = -1;
1073  PRINT_FUNCTION_VERBOSE(verbose);
1074 
1075  if ((daemon == NULL) || (daemon_local == NULL))
1076  {
1077  snprintf(local_str,
1079  "%s: Invalid function parameters\n",
1080  __func__);
1081 
1082  dlt_log(LOG_ERR, local_str);
1083  return -1;
1084  }
1085 
1086  if (dlt_daemon_init_fifo(daemon_local))
1087  {
1088  dlt_log(LOG_ERR, "Unable to initialize fifo.\n");
1089  return -1;
1090  }
1091 
1092  /* create and open socket to receive incoming connections from client */
1093  daemon_local->client_connections = 0;
1094  if(dlt_daemon_socket_open(&fd, daemon_local->flags.port) ||
1095  dlt_connection_create(daemon_local,
1096  &daemon_local->pEvent,
1097  fd,
1098  EPOLLIN,
1100  {
1101  dlt_log(LOG_ERR,"Could not initialize main socket.\n");
1102  return -1;
1103  }
1104 
1105  /* create and open unix socket to receive incoming connections from
1106  * control application */
1107  if (dlt_daemon_unix_socket_open(&fd, daemon_local->flags.ctrlSockPath) ||
1108  dlt_connection_create(daemon_local,
1109  &daemon_local->pEvent,
1110  fd,
1111  EPOLLIN,
1113  {
1114  dlt_log(LOG_ERR, "Could not initialize control socket.\n");
1115  return -1;
1116  }
1117 
1118  /* Init serial */
1119  if (dlt_daemon_init_serial(daemon_local) < 0)
1120  {
1121  dlt_log(LOG_ERR,"Could not initialize daemon data\n");
1122  return -1;
1123  }
1124 
1125  return 0;
1126 }
1127 
1128 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1129 {
1130  char *version = NULL;
1131  FILE *f = NULL;
1132 
1133  PRINT_FUNCTION_VERBOSE(verbose);
1134 
1135  /* By default, version string is null. */
1136  daemon->ECUVersionString = NULL;
1137 
1138  /* Open the file. Bail out if error occurs */
1139  f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
1140  if(f == NULL)
1141  {
1142  /* Error level notice, because this might be deliberate choice */
1143  dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
1144  return -1;
1145  }
1146 
1147  /* Get the file size. Bail out if stat fails. */
1148  int fd = fileno(f);
1149  struct stat s_buf;
1150  if(fstat(fd, &s_buf) < 0)
1151  {
1152  dlt_log(LOG_WARNING, "Failed to stat ECU Software version file.\n");
1153  fclose(f);
1154  return -1;
1155  }
1156 
1157  /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
1158  * Reserve one byte for trailing '\0' */
1159  off_t size = s_buf.st_size;
1160  if(size >= DLT_DAEMON_TEXTBUFSIZE)
1161  {
1162  dlt_log(LOG_WARNING, "Too large file for ECU version.\n");
1163  fclose(f);
1164  return -1;
1165  }
1166 
1167  /* Allocate permanent buffer for version info */
1168  version = malloc(size + 1);
1169  if(version==0)
1170  {
1171  dlt_log(LOG_WARNING, "Cannot allocate memory for ECU version.\n");
1172  fclose(f);
1173  return -1;
1174  }
1175  off_t offset = 0;
1176  while(!feof(f))
1177  {
1178  offset += fread(version + offset, 1, size, f);
1179  if(ferror(f))
1180  {
1181  dlt_log(LOG_WARNING, "Failed to read ECU Software version file.\n");
1182  free(version);
1183  fclose(f);
1184  return -1;
1185  }
1186  if(offset > size)
1187  {
1188  dlt_log(LOG_WARNING, "Too long file for ECU Software version info.\n");
1189  free(version);
1190  fclose(f);
1191  return -1;
1192  }
1193  }
1194  version[offset] = '\0';//append null termination at end of version string
1195  daemon->ECUVersionString = version;
1196  fclose(f);
1197  return 0;
1198 }
1199 
1200 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1201 {
1202  PRINT_FUNCTION_VERBOSE(verbose);
1203 
1204  if ((daemon==0) || (daemon_local==0))
1205  {
1206  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
1207  return;
1208  }
1209 
1210  /* Don't receive event anymore */
1212 
1213  dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
1214 
1215  /* free shared memory */
1216  if(daemon_local->flags.offlineTraceDirectory[0])
1217  dlt_offline_trace_free(&(daemon_local->offlineTrace));
1218 
1219  /* Ignore result */
1220  dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1221 
1222  /* Try to delete existing pipe, ignore result of unlink() */
1223  unlink(daemon_local->flags.daemonFifoName);
1224 
1225 #ifdef DLT_SHM_ENABLE
1226  /* free shared memory */
1227  dlt_shm_free_server(&(daemon_local->dlt_shm));
1228 #endif
1229 
1230  /* Try to delete lock file, ignore result of unlink() */
1231  unlink(DLT_DAEMON_LOCK_FILE);
1232 
1233  if (daemon_local->flags.offlineLogstorageMaxDevices > 0)
1234  {
1235  /* disconnect all logstorage devices */
1237  daemon_local,
1238  daemon_local->flags.vflag);
1239 
1240  free(daemon->storage_handle);
1241  }
1242 
1243  if (daemon->ECUVersionString != NULL)
1244  {
1245  free(daemon->ECUVersionString);
1246  }
1247 
1248  unlink(daemon_local->flags.ctrlSockPath);
1249 
1250 }
1251 
1253 {
1254  switch (sig)
1255  {
1256  case SIGHUP:
1257  case SIGTERM:
1258  case SIGINT:
1259  case SIGQUIT:
1260  {
1261  /* finalize the server */
1262  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Exiting DLT daemon due to signal: %s\n", strsignal(sig) );
1263  dlt_log(LOG_NOTICE, str);
1264 
1265  /* Try to delete existing pipe, ignore result of unlink() */
1266  char tmp[PATH_MAX + 1];
1267  snprintf(tmp, PATH_MAX, "%s/dlt", dltFifoBaseDir);
1268  tmp[PATH_MAX] = 0;
1269  unlink(tmp);
1270 
1271  /* Try to delete lock file, ignore result of unlink() */
1272  snprintf(tmp, PATH_MAX, "%s/%s", dltFifoBaseDir, DLT_DAEMON_LOCK_FILE);
1273  tmp[PATH_MAX] = 0;
1274  unlink(tmp);
1275 
1276  /* stop event loop */
1277  g_exit = -1;
1278  break;
1279  }
1280  default:
1281  {
1282  dlt_log(LOG_CRIT, "This case should never happen!");
1283  break;
1284  }
1285  } /* switch */
1286 } /* dlt_daemon_signal_handler() */
1287 
1288 void dlt_daemon_daemonize(int verbose)
1289 {
1290  int i,lfp;
1291  ssize_t pid_len;
1292 
1293  PRINT_FUNCTION_VERBOSE(verbose);
1294 
1295  dlt_log(LOG_NOTICE, "Daemon mode\n");
1296 
1297  /* Daemonize */
1298  i=fork();
1299  if (i<0)
1300  {
1301  dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1302  exit(-1); /* fork error */
1303  }
1304 
1305  if (i>0)
1306  {
1307  exit(0); /* parent exits */
1308  }
1309  /* child (daemon) continues */
1310 
1311  /* Process independency */
1312 
1313  /* obtain a new process group */
1314  if (setsid()==-1)
1315  {
1316  dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1317  exit(-1); /* fork error */
1318  }
1319 
1320  /* Close descriptors */
1321  for (i=getdtablesize();i>=0;--i)
1322  {
1323  close(i); /* close all descriptors */
1324  }
1325 
1326  /* Open standard descriptors stdin, stdout, stderr */
1327  i=open("/dev/null",O_RDWR); /* open stdin */
1328  if (-1 < i)
1329  {
1330  if(dup(i) < 0)
1331  dlt_log(LOG_WARNING, "Failed to direct stdout to /dev/null.\n");/* stdout */
1332  if(dup(i) < 0)
1333  dlt_log(LOG_WARNING, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1334  }
1335 
1336  /* Set umask */
1337  umask(DLT_DAEMON_UMASK);
1338 
1339  /* Change to known directory */
1340  if(chdir(dltFifoBaseDir) < 0)
1341  {
1342  snprintf(str, DLT_DAEMON_TEXTBUFSIZE, "Failed to chdir to fifo-dir %s\n", dltFifoBaseDir);
1343  dlt_log(LOG_WARNING, str);
1344  }
1345 
1346  /* Ensure single copy of daemon; if started with same directory
1347  run only one instance at a time */
1348  char dlt_daemon_lock_file[PATH_MAX + 1];
1349  snprintf(dlt_daemon_lock_file, PATH_MAX, "%s/%s", dltFifoBaseDir, DLT_DAEMON_LOCK_FILE);
1350  dlt_daemon_lock_file[PATH_MAX] = 0;
1351  lfp=open(dlt_daemon_lock_file,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1352  if (lfp<0)
1353  {
1354  dlt_log(LOG_CRIT, "Can't open lock file, exiting DLT daemon\n");
1355  exit(-1); /* can not open */
1356  }
1357  if (lockf(lfp,F_TLOCK,0)<0)
1358  {
1359  dlt_log(LOG_CRIT, "Can't lock lock file, exiting DLT daemon\n");
1360  exit(-1); /* can not lock */
1361  }
1362  /* only first instance continues */
1363 
1364  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"%d\n",getpid());
1365  pid_len = strlen(str);
1366  if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1367  dlt_log(LOG_WARNING, "Could not write pid to file in dlt_daemon_daemonize.\n");
1368 
1369  /* Catch signals */
1370  signal(SIGCHLD,SIG_IGN); /* ignore child */
1371  signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1372  signal(SIGTTOU,SIG_IGN);
1373  signal(SIGTTIN,SIG_IGN);
1374 
1375 } /* dlt_daemon_daemonize() */
1376 
1377 /* This function logs str to the configured output sink (socket, serial, offline trace).
1378  To avoid recursion this function must be called only from DLT highlevel functions.
1379  E. g. calling it to output a failure when the open of the offline trace file fails
1380  would cause an endless loop because dlt_daemon_log_internal() would itself again try
1381  to open the offline trace file.
1382  This is a dlt-daemon only function. The libdlt has no equivalent function available. */
1383 int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *str, int verbose)
1384 {
1385  DltMessage msg;
1386  static uint8_t uiMsgCount = 0;
1387  DltStandardHeaderExtra *pStandardExtra;
1388  uint32_t uiType;
1389  uint16_t uiSize;
1390  uint32_t uiExtraSize;
1391  int ret;
1392 
1393  PRINT_FUNCTION_VERBOSE(verbose);
1394 
1395  // Set storageheader
1396  msg.storageheader = (DltStorageHeader *)(msg.headerbuffer);
1398 
1399  // Set standardheader
1400  msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
1402  msg.standardheader->mcnt = uiMsgCount++;
1403 
1404  uiExtraSize = DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)+(DLT_IS_HTYP_UEH(msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0);
1405  msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + uiExtraSize;
1406 
1407  // Set extraheader
1408  pStandardExtra = (DltStandardHeaderExtra *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader));
1409  dlt_set_id(pStandardExtra->ecu, daemon->ecuid);
1410  pStandardExtra->tmsp = DLT_HTOBE_32(dlt_uptime());
1411  pStandardExtra->seid = DLT_HTOBE_32(getpid());
1412 
1413  // Set extendedheader
1414  msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
1416  msg.extendedheader->noar = 1;
1417  dlt_set_id(msg.extendedheader->apid, "DLTD");
1418  dlt_set_id(msg.extendedheader->ctid, "INTM");
1419 
1420  // Set payload data...
1421  uiType = DLT_TYPE_INFO_STRG;
1422  uiSize = strlen(str) + 1;
1423  msg.datasize = sizeof(uint32_t) + sizeof(uint16_t) + uiSize;
1424 
1425  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1426  msg.databuffersize = msg.datasize;
1427  if (msg.databuffer==0)
1428  {
1429  dlt_log(LOG_WARNING,"Can't allocate buffer for get log info message\n");
1430  return -1;
1431  }
1432 
1433  msg.datasize = 0;
1434  memcpy((uint8_t *)(msg.databuffer + msg.datasize), (uint8_t *)(&uiType), sizeof(uint32_t));
1435  msg.datasize += sizeof(uint32_t);
1436  memcpy((uint8_t *)(msg.databuffer + msg.datasize), (uint8_t *)(&uiSize), sizeof(uint16_t));
1437  msg.datasize += sizeof(uint16_t);
1438  memcpy((uint8_t *)(msg.databuffer + msg.datasize), str, uiSize);
1439  msg.datasize += uiSize;
1440 
1441  // Calc lengths
1442  msg.standardheader->len = DLT_HTOBE_16(msg.headersize - sizeof(DltStorageHeader) + msg.datasize);
1443 
1444  // Sending data...
1445  {
1446  /* check if overflow occurred */
1447  if(daemon->overflow_counter)
1448  {
1449  if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
1450  {
1451  sprintf(str,"%u messages discarded!\n",daemon->overflow_counter);
1452  dlt_log(LOG_WARNING, str);
1453  daemon->overflow_counter=0;
1454  }
1455  }
1456 
1457  /* look if TCP connection to client is available */
1458  if((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
1459  {
1460 
1461  if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,msg.headerbuffer,sizeof(DltStorageHeader),msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),
1462  msg.databuffer,msg.datasize,verbose)))
1463  {
1464  if(ret == DLT_DAEMON_ERROR_BUFFER_FULL)
1465  {
1466  daemon->overflow_counter++;
1467  }
1468  }
1469  }
1470  }
1471 
1472  free(msg.databuffer);
1473 
1474  return 0;
1475 }
1476 
1478  DltDaemonLocal *daemon_local,
1479  DltReceiver *receiver,
1480  int verbose)
1481 {
1482  socklen_t cli_size;
1483  struct sockaddr cli;
1484 
1485  int in_sock = -1;
1486 
1487  PRINT_FUNCTION_VERBOSE(verbose);
1488 
1489  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1490  {
1491  dlt_log(LOG_ERR,
1492  "Invalid function parameters used for function "
1493  "dlt_daemon_process_client_connect()\n");
1494  return -1;
1495  }
1496 
1497  /* event from TCP server socket, new connection */
1498  cli_size = sizeof(cli);
1499  if ((in_sock = accept(receiver->fd,&cli, &cli_size)) < 0)
1500  {
1501  dlt_log(LOG_ERR, "accept() failed!\n");
1502  return -1 ;
1503  }
1504 
1505  /* check if file file descriptor was already used, and make it invalid if it
1506  * is reused. */
1507  /* This prevents sending messages to wrong file descriptor */
1508  dlt_daemon_applications_invalidate_fd(daemon, in_sock, verbose);
1509  dlt_daemon_contexts_invalidate_fd(daemon, in_sock, verbose);
1510 
1511  /* Set socket timeout in reception */
1512  struct timeval timeout_send;
1513  timeout_send.tv_sec = daemon_local->timeoutOnSend;
1514  timeout_send.tv_usec = 0;
1515  if (setsockopt (in_sock,
1516  SOL_SOCKET,
1517  SO_SNDTIMEO,
1518  (char *)&timeout_send,
1519  sizeof(timeout_send)) < 0)
1520  {
1521  dlt_log(LOG_WARNING, "setsockopt failed\n");
1522  }
1523 
1524  if (dlt_connection_create(daemon_local,
1525  &daemon_local->pEvent,
1526  in_sock,
1527  EPOLLIN,
1529  {
1530  dlt_log(LOG_ERR, "Failed to register new client. \n");
1531  /* TODO: Perform clean-up */
1532  return -1;
1533  }
1534 
1535  if (daemon_local->flags.vflag)
1536  {
1537  snprintf(str,
1539  "New connection to client established, #connections: %d\n",
1540  daemon_local->client_connections);
1541  dlt_log(LOG_INFO, str);
1542  }
1543 
1544  // send connection info about connected
1546  daemon,
1547  daemon_local,
1549  "",
1550  verbose);
1551 
1552  // send ecu version string
1553  if (daemon_local->flags.sendECUSoftwareVersion > 0)
1554  {
1555  if (daemon_local->flags.sendECUSoftwareVersion > 0)
1556  {
1558  daemon,
1559  daemon_local,
1560  daemon_local->flags.vflag);
1561  }
1562 
1563  if (daemon_local->flags.sendTimezone > 0)
1564  {
1566  daemon,
1567  daemon_local,
1568  daemon_local->flags.vflag);
1569  }
1570  }
1571 
1572  if (daemon_local->client_connections == 1)
1573  {
1574  if (daemon_local->flags.vflag)
1575  {
1576  dlt_log(LOG_DEBUG, "Send ring-buffer to client\n");
1577  }
1579  if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1580  {
1581  dlt_log(LOG_WARNING,"Can't send contents of ringbuffer to clients\n");
1582  return -1;
1583  }
1584 
1585  /* send new log state to all applications */
1586  daemon->connectionState = 1;
1587  dlt_daemon_user_send_all_log_state(daemon,verbose);
1588  }
1589 
1590  return 0;
1591 }
1592 
1594  DltDaemonLocal *daemon_local,
1595  DltReceiver *receiver,
1596  int verbose)
1597 {
1598  int bytes_to_be_removed=0;
1599  int must_close_socket = -1;
1600 
1601  PRINT_FUNCTION_VERBOSE(verbose);
1602 
1603  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1604  {
1605  dlt_log(LOG_ERR,
1606  "Invalid function parameters used for function "
1607  "dlt_daemon_process_client_messages()\n");
1608  return -1;
1609  }
1610 
1611  must_close_socket = dlt_receiver_receive_socket(receiver);
1612  if (must_close_socket < 0)
1613  {
1614  dlt_daemon_close_socket(receiver->fd,
1615  daemon,
1616  daemon_local,
1617  verbose);
1618  receiver->fd = -1;
1619  return -1;
1620  }
1621 
1622  /* Process all received messages */
1623  while (dlt_message_read(&(daemon_local->msg),
1624  (uint8_t*)receiver->buf,
1625  receiver->bytesRcvd,
1626  daemon_local->flags.nflag,
1627  daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
1628  {
1629  /* Check for control message */
1630  if (0 < receiver->fd &&
1631  DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1632  {
1634  daemon,
1635  daemon_local,
1636  &(daemon_local->msg),
1637  daemon_local->flags.vflag);
1638  }
1639 
1640  bytes_to_be_removed = daemon_local->msg.headersize +
1641  daemon_local->msg.datasize -
1642  sizeof(DltStorageHeader);
1643  if (daemon_local->msg.found_serialheader)
1644  {
1645  bytes_to_be_removed += sizeof(dltSerialHeader);
1646  }
1647  if (daemon_local->msg.resync_offset)
1648  {
1649  bytes_to_be_removed += daemon_local->msg.resync_offset;
1650  }
1651 
1652  if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
1653  {
1654  dlt_log(LOG_WARNING,
1655  "Can't remove bytes from receiver for sockets\n");
1656  return -1;
1657  }
1658 
1659  } /* while */
1660 
1661  if (dlt_receiver_move_to_begin(receiver) == -1)
1662  {
1663  dlt_log(LOG_WARNING,
1664  "Can't move bytes to beginning of receiver buffer for sockets\n");
1665  return -1;
1666  }
1667 
1668  if (must_close_socket == 0) {
1669  /* FIXME: Why the hell do we need to close the socket
1670  * on control message reception ??
1671  */
1672  dlt_daemon_close_socket(receiver->fd,
1673  daemon,
1674  daemon_local,
1675  verbose);
1676  }
1677 
1678  return 0;
1679 }
1680 
1682  DltDaemonLocal *daemon_local,
1683  DltReceiver *receiver,
1684  int verbose)
1685 {
1686  int bytes_to_be_removed=0;
1687 
1688  PRINT_FUNCTION_VERBOSE(verbose);
1689 
1690  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1691  {
1692  dlt_log(LOG_ERR,
1693  "Invalid function parameters used for function "
1694  "dlt_daemon_process_client_messages_serial()\n");
1695  return -1;
1696  }
1697 
1698  if (dlt_receiver_receive_fd(receiver) <= 0)
1699  {
1700  dlt_log(LOG_WARNING,
1701  "dlt_receiver_receive_fd() for messages from serial interface "
1702  "failed!\n");
1703  return -1;
1704  }
1705 
1706  /* Process all received messages */
1707  while (dlt_message_read(&(daemon_local->msg),
1708  (uint8_t*)receiver->buf,
1709  receiver->bytesRcvd,
1710  daemon_local->flags.mflag,
1711  daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
1712  {
1713  /* Check for control message */
1714  if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1715  {
1716  if (dlt_daemon_client_process_control(receiver->fd,
1717  daemon,
1718  daemon_local,
1719  &(daemon_local->msg),
1720  daemon_local->flags.vflag)
1721  == -1)
1722  {
1723  dlt_log(LOG_WARNING, "Can't process control messages\n");
1724  return -1;
1725  }
1726  }
1727 
1728  bytes_to_be_removed = daemon_local->msg.headersize +
1729  daemon_local->msg.datasize -
1730  sizeof(DltStorageHeader);
1731 
1732  if (daemon_local->msg.found_serialheader)
1733  {
1734  bytes_to_be_removed += sizeof(dltSerialHeader);
1735  }
1736  if (daemon_local->msg.resync_offset)
1737  {
1738  bytes_to_be_removed += daemon_local->msg.resync_offset;
1739  }
1740 
1741  if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
1742  {
1743  dlt_log(LOG_WARNING,
1744  "Can't remove bytes from receiver for serial connection\n");
1745  return -1;
1746  }
1747 
1748  } /* while */
1749 
1750  if (dlt_receiver_move_to_begin(receiver) == -1)
1751  {
1752  dlt_log(LOG_WARNING,
1753  "Can't move bytes to beginning of receiver buffer for serial "
1754  "connection\n");
1755  return -1;
1756  }
1757 
1758  return 0;
1759 }
1760 
1762  DltDaemon *daemon,
1763  DltDaemonLocal *daemon_local,
1764  DltReceiver *receiver,
1765  int verbose)
1766 {
1767  socklen_t ctrl_size;
1768  struct sockaddr_un ctrl;
1769  int in_sock = -1;
1770 
1771  PRINT_FUNCTION_VERBOSE(verbose);
1772 
1773  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1774  {
1775  dlt_log(LOG_ERR,
1776  "Invalid function parameters used for function "
1777  "dlt_daemon_process_control_connect()\n");
1778  return -1;
1779  }
1780 
1781  /* event from UNIX server socket, new connection */
1782  ctrl_size = sizeof(ctrl);
1783  if ((in_sock = accept(receiver->fd, &ctrl, &ctrl_size)) < 0)
1784  {
1785  dlt_log(LOG_ERR, "accept() on UNIX socket failed!\n");
1786  return -1 ;
1787  }
1788 
1789  /* check if file file descriptor was already used, and make it invalid if it
1790  * is reused */
1791  /* This prevents sending messages to wrong file descriptor */
1792  dlt_daemon_applications_invalidate_fd(daemon, in_sock, verbose);
1793  dlt_daemon_contexts_invalidate_fd(daemon, in_sock, verbose);
1794 
1795  if (dlt_connection_create(daemon_local,
1796  &daemon_local->pEvent,
1797  in_sock,
1798  EPOLLIN,
1800  {
1801  dlt_log(LOG_ERR, "Failed to register new client. \n");
1802  /* TODO: Perform clean-up */
1803  return -1;
1804  }
1805 
1806  if (verbose)
1807  {
1808  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,
1809  "New connection to control client established\n");
1810  dlt_log(LOG_INFO, str);
1811  }
1812 
1813  return 0;
1814 }
1815 
1816 // FIXME: More or less copy of dlt_daemon_process_control_messages
1818  DltDaemon *daemon,
1819  DltDaemonLocal *daemon_local,
1820  DltReceiver *receiver,
1821  int verbose)
1822 {
1823  int bytes_to_be_removed=0;
1824 
1825  PRINT_FUNCTION_VERBOSE(verbose);
1826 
1827  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1828  {
1829  dlt_log(LOG_ERR,
1830  "Invalid function parameters used for function "
1831  "dlt_daemon_process_control_messages()\n");
1832  return -1;
1833  }
1834 
1835  if (dlt_receiver_receive_socket(receiver) <= 0)
1836  {
1837  dlt_daemon_close_socket(receiver->fd,
1838  daemon,
1839  daemon_local,
1840  verbose);
1841  receiver->fd = -1;
1842  /* FIXME: Why the hell do we need to close the socket
1843  * on control message reception ??
1844  */
1845  //return 0;
1846  }
1847 
1848  /* Process all received messages */
1849  while (dlt_message_read(
1850  &(daemon_local->msg),
1851  (uint8_t*)receiver->buf,
1852  receiver->bytesRcvd,
1853  daemon_local->flags.nflag,
1854  daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
1855  {
1856  /* Check for control message */
1857  if (receiver->fd > 0 &&
1858  DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1859  {
1861  daemon,daemon_local,
1862  &(daemon_local->msg),
1863  daemon_local->flags.vflag);
1864  }
1865 
1866  bytes_to_be_removed = daemon_local->msg.headersize +
1867  daemon_local->msg.datasize -
1868  sizeof(DltStorageHeader);
1869 
1870  if (daemon_local->msg.found_serialheader)
1871  {
1872  bytes_to_be_removed += sizeof(dltSerialHeader);
1873  }
1874  if (daemon_local->msg.resync_offset)
1875  {
1876  bytes_to_be_removed += daemon_local->msg.resync_offset;
1877  }
1878 
1879  if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
1880  {
1881  dlt_log(LOG_WARNING,
1882  "Can't remove bytes from receiver for sockets\n");
1883  return -1;
1884  }
1885 
1886  } /* while */
1887 
1888  if (dlt_receiver_move_to_begin(receiver) == -1)
1889  {
1890  dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for sockets\n");
1891  return -1;
1892  }
1893 
1894  return 0;
1895 }
1896 
1898  DltDaemonLocal *daemon_local,
1899  DltReceiver *receiver,
1900  int verbose)
1901 {
1902  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
1903  DltUserHeader *userheader = (DltUserHeader*) (receiver->buf);
1904  (void)daemon;
1905  (void)daemon_local;
1906 
1907  PRINT_FUNCTION_VERBOSE(verbose);
1908 
1909  snprintf(local_str,
1911  "Invalid user message type received: %d!\n",
1912  userheader->message);
1913  dlt_log(LOG_ERR, local_str);
1914 
1915  /* remove user header */
1916  if (dlt_receiver_remove(receiver, sizeof(DltUserHeader)) == -1)
1917  {
1918  dlt_log(LOG_WARNING,
1919  "Can't remove bytes from receiver for user messages\n");
1920  }
1921 
1922  return -1;
1923 }
1924 
1936 #ifdef DLT_SHM_ENABLE
1937  dlt_daemon_process_user_message_log_shm,
1938 #else
1940 #endif
1945  dlt_daemon_process_user_message_not_sup
1946 };
1947 
1949  DltDaemonLocal *daemon_local,
1950  DltReceiver *receiver,
1951  int verbose)
1952 {
1953  int offset = 0;
1954  int run_loop = 1;
1955  int32_t min_size = (int32_t)sizeof(DltUserHeader);
1956  DltUserHeader *userheader;
1957 
1958  PRINT_FUNCTION_VERBOSE(verbose);
1959 
1960  if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
1961  {
1962  dlt_log(LOG_ERR,
1963  "Invalid function parameters used for function "
1964  "dlt_daemon_process_user_messages()\n");
1965  return -1;
1966  }
1967 
1968  /* read data from FIFO */
1969  if (dlt_receiver_receive_fd(receiver) < 0)
1970  {
1971  dlt_log(LOG_WARNING,
1972  "dlt_receiver_receive_fd() for user messages failed!\n");
1973  return -1;
1974  }
1975 
1976  /* look through buffer as long as data is in there */
1977  while ((receiver->bytesRcvd >= min_size) && run_loop)
1978  {
1980 
1981  offset = 0;
1982  userheader = (DltUserHeader *)(receiver->buf + offset);
1983 
1984  while (!dlt_user_check_userheader(userheader) &&
1985  (offset + min_size <= receiver->bytesRcvd))
1986  /* resync if necessary */
1987  {
1988  offset++;
1989  userheader = (DltUserHeader *)(receiver->buf + offset);
1990  }
1991 
1992  /* Check for user header pattern */
1993  if (!dlt_user_check_userheader(userheader))
1994  {
1995  break;
1996  }
1997 
1998  /* Set new start offset */
1999  if (offset > 0)
2000  {
2001  dlt_receiver_remove(receiver, offset);
2002  }
2003 
2004 
2005  if (userheader->message >= DLT_USER_MESSAGE_NOT_SUPPORTED)
2006  {
2008  }
2009  else
2010  {
2011  func = process_user_func[userheader->message];
2012  }
2013 
2014  if (func(daemon,
2015  daemon_local,
2016  receiver,
2017  daemon_local->flags.vflag) == -1)
2018  {
2019  run_loop = 0;
2020  }
2021  }
2022 
2023  /* keep not read data in buffer */
2024  if (dlt_receiver_move_to_begin(receiver) == -1)
2025  {
2026  dlt_log(LOG_WARNING,
2027  "Can't move bytes to beginning of receiver buffer for user "
2028  "messages\n");
2029  return -1;
2030  }
2031 
2032  return 0;
2033 }
2034 
2036  DltDaemonLocal *daemon_local,
2037  DltReceiver *rec,
2038  int verbose)
2039 {
2040  uint32_t len = sizeof(DltUserControlMsgBufferOverflow);
2041  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2042  DltUserControlMsgBufferOverflow userpayload;
2043 
2044  PRINT_FUNCTION_VERBOSE(verbose);
2045 
2046  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2047  {
2048  snprintf(local_str,
2050  "Invalid function parameters used for %s\n",
2051  __func__);
2052 
2053  dlt_log(LOG_ERR, local_str);
2054  return -1;
2055  }
2056 
2058  &userpayload,
2059  len,
2061  {
2062  /* Not enough bytes received */
2063  return -1;
2064  }
2065 
2066  /* Store in daemon, that a message buffer overflow has occured */
2067  /* look if TCP connection to client is available or it least message can be put into buffer */
2069  daemon,
2070  daemon_local,
2071  userpayload.overflow_counter,
2072  userpayload.apid,
2073  verbose))
2074  {
2075  /* there was an error when storing message */
2076  /* add the counter of lost messages to the daemon counter */
2077  daemon->overflow_counter += userpayload.overflow_counter;
2078  }
2079 
2080  return 0;
2081 }
2082 
2083 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2084 {
2085  int ret;
2086  PRINT_FUNCTION_VERBOSE(verbose);
2087 
2088  if ((daemon==0) || (daemon_local==0))
2089  {
2090  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
2091  return DLT_DAEMON_ERROR_UNKNOWN;
2092  }
2093 
2094  /* Store in daemon, that a message buffer overflow has occured */
2095  if((ret=dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local,daemon->overflow_counter,"", verbose)))
2096  {
2097  return ret;
2098  }
2099 
2100  return DLT_DAEMON_ERROR_OK;
2101 }
2102 
2104  DltDaemonLocal *daemon_local,
2105  DltReceiver *rec,
2106  int verbose)
2107 {
2108  uint32_t len = sizeof(DltUserControlMsgRegisterApplication);
2109  int to_remove = 0;
2110  DltDaemonApplication *application = NULL;
2111  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2112  char description[DLT_DAEMON_DESCSIZE + 1] = { '\0' };
2113  DltUserControlMsgRegisterApplication userapp;
2114  char *origin;
2115 
2116  PRINT_FUNCTION_VERBOSE(verbose);
2117 
2118  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2119  {
2120  snprintf(local_str,
2122  "Invalid function parameters used for %s\n",
2123  __func__);
2124 
2125  dlt_log(LOG_ERR, local_str);
2126  return -1;
2127  }
2128 
2129  memset(&userapp, 0, sizeof(DltUserControlMsgRegisterApplication));
2130  origin = rec->buf;
2131 
2132  /* We shall not remove data before checking that everything is there. */
2133  to_remove = dlt_receiver_check_and_get(rec,
2134  &userapp,
2135  len,
2137  if (to_remove < 0)
2138  {
2139  /* Not enough bytes received */
2140  return -1;
2141  }
2142 
2143  len = userapp.description_length;
2144  if (len > DLT_DAEMON_DESCSIZE)
2145  {
2146  len = DLT_DAEMON_DESCSIZE;
2147  dlt_log(LOG_WARNING, "Application description exceeds limit\n");
2148  }
2149 
2150  /* adjust buffer pointer */
2151  rec->buf += to_remove + sizeof(DltUserHeader);
2152 
2153  if (dlt_receiver_check_and_get(rec, description, len, DLT_RCV_NONE) < 0)
2154  {
2155  dlt_log(LOG_ERR, "Unable to get application description\n");
2156  /* in case description was not readable, set dummy description */
2157  strncpy(description, "Unknown", sizeof("Unknown"));
2158  /* unknown len of original description, set to 0 to not remove in next
2159  * step. Because message buffer is re-adjusted the corrupted description
2160  * is ignored. */
2161  len = 0;
2162  }
2163 
2164  /* adjust to_remove */
2165  to_remove += sizeof(DltUserHeader) + len;
2166  /* point to begin of message */
2167  rec->buf = origin;
2168 
2169  /* We can now remove data. */
2170  if (dlt_receiver_remove(rec, to_remove) != DLT_RETURN_OK)
2171  {
2172  dlt_log(LOG_WARNING,"Can't remove bytes from receiver\n");
2173  return -1;
2174  }
2175 
2176  application = dlt_daemon_application_add(daemon,
2177  userapp.apid,
2178  userapp.pid,
2179  description,
2180  verbose);
2181 
2182  /* send log state to new application */
2183  dlt_daemon_user_send_log_state(daemon, application, verbose);
2184 
2185  if (application == NULL)
2186  {
2187  snprintf(local_str,
2189  "Can't add ApplicationID '%.4s' for PID %d\n",
2190  userapp.apid,
2191  userapp.pid);
2192  dlt_log(LOG_WARNING,local_str);
2193  return -1;
2194  }
2195  else
2196  {
2197  snprintf(local_str,
2199  "ApplicationID '%.4s' registered for PID %d, Description=%s\n",
2200  application->apid,
2201  application->pid,
2202  application->application_description);
2203  dlt_daemon_log_internal(daemon,
2204  daemon_local,
2205  local_str,
2206  daemon_local->flags.vflag);
2207  dlt_log(LOG_DEBUG, local_str);
2208  }
2209 
2210  return 0;
2211 }
2212 
2214  DltDaemonLocal *daemon_local,
2215  DltReceiver *rec,
2216  int verbose)
2217 {
2218  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2219  int to_remove = 0;
2220  uint32_t len = sizeof(DltUserControlMsgRegisterContext);
2221  DltUserControlMsgRegisterContext userctxt;
2222  char description[DLT_DAEMON_DESCSIZE + 1] = { '\0' };
2223  DltDaemonApplication *application = NULL;
2224  DltDaemonContext *context = NULL;
2225  DltServiceGetLogInfoRequest *req = NULL;
2226  char *origin;
2227 
2228  DltMessage msg;
2229 
2230  PRINT_FUNCTION_VERBOSE(verbose);
2231 
2232  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2233  {
2234  snprintf(local_str,
2236  "Invalid function parameters used for %s\n",
2237  __func__);
2238 
2239  dlt_log(LOG_ERR, local_str);
2240  return -1;
2241  }
2242 
2243  memset(&userctxt, 0, sizeof(DltUserControlMsgRegisterContext));
2244  origin = rec->buf;
2245 
2246  to_remove = dlt_receiver_check_and_get(rec,
2247  &userctxt,
2248  len,
2250 
2251  if (to_remove < 0)
2252  {
2253  /* Not enough bytes received */
2254  return -1;
2255  }
2256 
2257  len = userctxt.description_length;
2258 
2259  if (len > DLT_DAEMON_DESCSIZE)
2260  {
2261  len = DLT_DAEMON_DESCSIZE;
2262  dlt_log(LOG_WARNING, "Context description exceeds limit\n");
2263  }
2264 
2265  /* adjust buffer pointer */
2266  rec->buf += to_remove + sizeof(DltUserHeader);
2267 
2268  if (dlt_receiver_check_and_get(rec, description, len, DLT_RCV_NONE) < 0)
2269  {
2270  dlt_log(LOG_ERR, "Unable to get context description\n");
2271  /* in case description was not readable, set dummy description */
2272  strncpy(description, "Unknown", sizeof("Unknown"));
2273  /* unknown len of original description, set to 0 to not remove in next
2274  * step. Because message buffer is re-adjusted the corrupted description
2275  * is ignored. */
2276  len = 0;
2277  }
2278 
2279  /* adjust to_remove */
2280  to_remove += sizeof(DltUserHeader) + len;
2281  /* point to begin of message */
2282  rec->buf = origin;
2283 
2284  /* We can now remove data. */
2285  if (dlt_receiver_remove(rec, to_remove) != DLT_RETURN_OK)
2286  {
2287  dlt_log(LOG_WARNING,"Can't remove bytes from receiver\n");
2288  return -1;
2289  }
2290 
2291  application = dlt_daemon_application_find(daemon, userctxt.apid, verbose);
2292 
2293  if (application == 0)
2294  {
2295  snprintf(local_str,
2297  "ApID '%.4s' not found for new ContextID '%.4s' in %s\n",
2298  userctxt.apid,
2299  userctxt.ctid,
2300  __func__);
2301  dlt_log(LOG_WARNING, local_str);
2302 
2303  return 0;
2304  }
2305 
2306  /* Set log level */
2307  if (userctxt.log_level == DLT_USER_LOG_LEVEL_NOT_SET)
2308  {
2309  userctxt.log_level = DLT_LOG_DEFAULT;
2310  }
2311  else
2312  {
2313  /* Plausibility check */
2314  if ((userctxt.log_level < DLT_LOG_DEFAULT) ||
2315  (userctxt.log_level > DLT_LOG_VERBOSE))
2316  {
2317  return -1;
2318  }
2319  }
2320 
2321  /* Set trace status */
2322  if (userctxt.trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
2323  {
2324  userctxt.trace_status = DLT_TRACE_STATUS_DEFAULT;
2325  }
2326  else
2327  {
2328  /* Plausibility check */
2329  if ((userctxt.trace_status < DLT_TRACE_STATUS_DEFAULT) ||
2330  (userctxt.trace_status > DLT_TRACE_STATUS_ON))
2331  {
2332  return -1;
2333  }
2334  }
2335 
2336  context = dlt_daemon_context_add(daemon,
2337  userctxt.apid,
2338  userctxt.ctid,
2339  userctxt.log_level,
2340  userctxt.trace_status,
2341  userctxt.log_level_pos,
2342  application->user_handle,
2343  description,
2344  verbose);
2345 
2346  if (context==0)
2347  {
2348  snprintf(local_str,
2350  "Can't add ContextID '%.4s' for ApID '%.4s'\n in %s",
2351  userctxt.ctid,
2352  userctxt.apid,
2353  __func__);
2354  dlt_log(LOG_WARNING, local_str);
2355  return -1;
2356  }
2357  else
2358  {
2359  snprintf(local_str,
2361  "ContextID '%.4s' registered for ApID '%.4s', Description=%s\n",
2362  context->ctid,
2363  context->apid,
2364  context->context_description);
2365  dlt_daemon_log_internal(daemon, daemon_local, local_str, verbose);
2366  dlt_log(LOG_DEBUG, local_str);
2367  }
2368 
2369  if(daemon_local->flags.offlineLogstorageMaxDevices)
2370  {
2371  /* Store log level set for offline logstorage into context structure*/
2372  context->storage_log_level =
2374  daemon_local->flags.offlineLogstorageMaxDevices,
2375  userctxt.apid,
2376  userctxt.ctid);
2377  }
2378  else
2379  {
2381  }
2382  /* Create automatic get log info response for registered context */
2383  if (daemon_local->flags.rflag)
2384  {
2385  /* Prepare request for get log info with one application and one context */
2386  if (dlt_message_init(&msg, verbose)==-1)
2387  {
2388  dlt_log(LOG_WARNING,"Can't initialize message");
2389  return -1;
2390  }
2391 
2392  msg.datasize = sizeof(DltServiceGetLogInfoRequest);
2393  if (msg.databuffer && (msg.databuffersize < msg.datasize))
2394  {
2395  free(msg.databuffer);
2396  msg.databuffer=0;
2397  }
2398  if (msg.databuffer == 0){
2399  msg.databuffer = (uint8_t *) malloc(msg.datasize);
2400  msg.databuffersize = msg.datasize;
2401  }
2402  if (msg.databuffer==0)
2403  {
2404  dlt_log(LOG_WARNING,"Can't allocate buffer for get log info message\n");
2405  return -1;
2406  }
2407 
2408  req = (DltServiceGetLogInfoRequest*) msg.databuffer;
2409 
2410  req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
2411  req->options = daemon_local->flags.autoResponseGetLogInfoOption;
2412  dlt_set_id(req->apid, userctxt.apid);
2413  dlt_set_id(req->ctid, userctxt.ctid);
2414  dlt_set_id(req->com,"remo");
2415 
2416  dlt_daemon_control_get_log_info(DLT_DAEMON_SEND_TO_ALL , daemon,daemon_local, &msg, verbose);
2417 
2418  dlt_message_free(&msg, verbose);
2419  }
2420 
2421  if (context->user_handle >= DLT_FD_MINIMUM)
2422  {
2423  /* This call also replaces the default values with the values defined for default */
2424  if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
2425  {
2426  dlt_vlog(LOG_WARNING, "Can't send current log level as response to %s for (%.4s;%.4s)\n",
2427  __func__,
2428  context->apid,
2429  context->ctid);
2430  }
2431  }
2432 
2433  return 0;
2434 }
2435 
2437  DltDaemonLocal *daemon_local,
2438  DltReceiver *rec,
2439  int verbose)
2440 {
2441  uint32_t len = sizeof(DltUserControlMsgUnregisterApplication);
2442  DltUserControlMsgUnregisterApplication userapp;
2443  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2444  DltDaemonApplication *application = NULL;
2445  DltDaemonContext *context;
2446  int i, offset_base;
2447 
2448  PRINT_FUNCTION_VERBOSE(verbose);
2449 
2450  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2451  {
2452  snprintf(local_str,
2454  "Invalid function parameters used for %s\n",
2455  __func__);
2456 
2457  dlt_log(LOG_ERR, local_str);
2458  return -1;
2459  }
2460 
2462  &userapp,
2463  len,
2465  {
2466  /* Not enough bytes received */
2467  return -1;
2468  }
2469 
2470  if (daemon->num_applications > 0)
2471  {
2472  /* Delete this application and all corresponding contexts
2473  * for this application from internal table.
2474  */
2475  application = dlt_daemon_application_find(daemon,
2476  userapp.apid,
2477  verbose);
2478 
2479  if (application)
2480  {
2481  /* Calculate start offset within contexts[] */
2482  offset_base=0;
2483  for (i=0; i<(application-(daemon->applications)); i++)
2484  {
2485  offset_base+=daemon->applications[i].num_contexts;
2486  }
2487 
2488  for (i=application->num_contexts-1; i>=0; i--)
2489  {
2490  context = &(daemon->contexts[offset_base+i]);
2491  if (context)
2492  {
2493  /* Delete context */
2494  if (dlt_daemon_context_del(daemon, context, verbose) == -1)
2495  {
2496  snprintf(local_str,
2498  "Can't delete CtID '%.4s' for ApID '%.4s' in %s\n",
2499  context->ctid,
2500  context->apid,
2501  __func__);
2502  dlt_log(LOG_WARNING, local_str);
2503  return -1;
2504  }
2505  }
2506  }
2507 
2508  /* Delete this application entry from internal table*/
2509  if (dlt_daemon_application_del(daemon, application, verbose)==-1)
2510  {
2511  snprintf(local_str,
2513  "Can't delete ApID '%.4s' in %s\n",
2514  application->apid,
2515  __func__);
2516  dlt_log(LOG_WARNING, local_str);
2517  return -1;
2518  }
2519  else
2520  {
2521  snprintf(local_str,
2523  "Unregistered ApID '%.4s'\n",
2524  userapp.apid);
2525  dlt_daemon_log_internal(daemon,
2526  daemon_local,
2527  local_str,
2528  verbose);
2529  dlt_log(LOG_DEBUG, local_str);
2530  }
2531  }
2532  }
2533 
2534  return 0;
2535 }
2536 
2538  DltDaemonLocal *daemon_local,
2539  DltReceiver *rec,
2540  int verbose)
2541 {
2542  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2543  uint32_t len = sizeof(DltUserControlMsgUnregisterContext);
2544  DltUserControlMsgUnregisterContext userctxt;
2545  DltDaemonContext *context;
2546 
2547  PRINT_FUNCTION_VERBOSE(verbose);
2548 
2549  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2550  {
2551  snprintf(local_str,
2553  "Invalid function parameters used for %s\n",
2554  __func__);
2555 
2556  dlt_log(LOG_ERR, local_str);
2557  return -1;
2558  }
2559 
2561  &userctxt,
2562  len,
2564  {
2565  /* Not enough bytes received */
2566  return -1;
2567  }
2568 
2569  context = dlt_daemon_context_find(daemon,
2570  userctxt.apid,
2571  userctxt.ctid,
2572  verbose);
2573 
2574  if (context)
2575  {
2576  /* Delete this connection entry from internal table*/
2577  if (dlt_daemon_context_del(daemon, context, verbose)==-1)
2578  {
2579  snprintf(local_str,
2581  "Can't delete CtID '%.4s' for ApID '%.4s' in %s\n",
2582  userctxt.ctid,
2583  userctxt.apid,
2584  __func__);
2585  dlt_log(LOG_WARNING, local_str);
2586  return -1;
2587  }
2588  else
2589  {
2590  snprintf(local_str,
2592  "Unregistered CtID '%.4s' for ApID '%.4s'\n",
2593  userctxt.ctid,
2594  userctxt.apid);
2595  dlt_daemon_log_internal(daemon,
2596  daemon_local,
2597  local_str,
2598  verbose);
2599  dlt_log(LOG_DEBUG, local_str);
2600  }
2601  }
2602 
2603  /* Create automatic unregister context response for unregistered context */
2604  if (daemon_local->flags.rflag)
2605  {
2607  daemon,
2608  daemon_local,
2609  userctxt.apid,
2610  userctxt.ctid,
2611  "remo",
2612  verbose);
2613  }
2614 
2615  return 0;
2616 }
2617 
2619  DltDaemonLocal *daemon_local,
2620  DltReceiver *rec,
2621  int verbose)
2622 {
2623  int ret;
2624  int bytes_to_be_removed;
2625 
2626  static char text[DLT_DAEMON_TEXTSIZE];
2627 
2628  PRINT_FUNCTION_VERBOSE(verbose);
2629 
2630  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2631  {
2632  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2633  return DLT_DAEMON_ERROR_UNKNOWN;
2634  }
2635 
2636  ret = dlt_message_read(&(daemon_local->msg),
2637  (unsigned char*)rec->buf + sizeof(DltUserHeader),
2638  rec->bytesRcvd - sizeof(DltUserHeader),
2639  0,
2640  verbose);
2641  if(ret!=DLT_MESSAGE_ERROR_OK)
2642  {
2643  if(ret!=DLT_MESSAGE_ERROR_SIZE)
2644  {
2645  /* This is a normal usecase: The daemon reads the data in 10kb chunks.
2646  Thus the last trace in this chunk is probably not complete and will be completed
2647  with the next chunk read. This happens always when the FIFO is filled with more than 10kb before
2648  the daemon is able to read from the FIFO.
2649  Thus the loglevel of this message is set to DEBUG.
2650  A cleaner solution would be to check more in detail whether the message is not complete (normal usecase)
2651  or the headers are corrupted (error case). */
2652  dlt_log(LOG_DEBUG,"Can't read messages from receiver\n");
2653  }
2654  return DLT_DAEMON_ERROR_UNKNOWN;
2655  }
2656 
2657  /* set overwrite ecu id */
2658  if ((daemon_local->flags.evalue[0]) && (strncmp(daemon_local->msg.headerextra.ecu,DLT_DAEMON_ECU_ID,4)==0))
2659  {
2660  /* Set header extra parameters */
2661  dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2662  //msg.headerextra.seid = 0;
2663  if (dlt_message_set_extraparameters(&(daemon_local->msg),0) == DLT_RETURN_ERROR)
2664  {
2665  dlt_log(LOG_WARNING,"Can't set message extra parameters in process user message log\n");
2666  return DLT_DAEMON_ERROR_UNKNOWN;
2667  }
2668 
2669  /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2670  daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2671  }
2672 
2673  /* prepare storage header */
2674  if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2675  {
2676  if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu) == DLT_RETURN_ERROR)
2677  {
2678  dlt_log(LOG_WARNING,"Can't set storage header in process user message log\n");
2679  return DLT_DAEMON_ERROR_UNKNOWN;
2680  }
2681  }
2682  else
2683  {
2684  if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid) == DLT_RETURN_ERROR)
2685  {
2686  dlt_log(LOG_WARNING,"Can't set storage header in process user message log\n");
2687  return DLT_DAEMON_ERROR_UNKNOWN;
2688  }
2689  }
2690 
2691  {
2692  /* if no filter set or filter is matching display message */
2693  if (daemon_local->flags.xflag)
2694  {
2695  if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose) == DLT_RETURN_ERROR)
2696  {
2697  dlt_log(LOG_WARNING,"dlt_message_print_hex() failed!\n");
2698  }
2699  } /* if */
2700  else if (daemon_local->flags.aflag)
2701  {
2702  if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose) == DLT_RETURN_ERROR)
2703  {
2704  dlt_log(LOG_WARNING,"dlt_message_print_ascii() failed!\n");
2705  }
2706  } /* if */
2707  else if (daemon_local->flags.sflag)
2708  {
2709  if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose) == DLT_RETURN_ERROR)
2710  {
2711  dlt_log(LOG_WARNING,"dlt_message_print_header() failed!\n");
2712  }
2713  /* print message header only */
2714  } /* if */
2715 
2716 
2717  /* check if overflow occurred */
2718  if(daemon->overflow_counter)
2719  {
2720  if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2721  {
2722  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"%u messages discarded!\n",daemon->overflow_counter);
2723  dlt_log(LOG_WARNING, str);
2724  daemon->overflow_counter=0;
2725  }
2726  }
2727 
2728  /* send message to client or write to log file */
2729  if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,daemon_local->msg.headerbuffer,sizeof(DltStorageHeader),daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2730  daemon_local->msg.databuffer,daemon_local->msg.datasize,verbose)))
2731  {
2732  if(ret == DLT_DAEMON_ERROR_BUFFER_FULL)
2733  {
2734  daemon->overflow_counter++;
2735  }
2736  }
2737 
2738  }
2739  /* keep not read data in buffer */
2740  bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2741  if (daemon_local->msg.found_serialheader)
2742  {
2743  bytes_to_be_removed += sizeof(dltSerialHeader);
2744  }
2745 
2746  if (dlt_receiver_remove(rec, bytes_to_be_removed) == -1)
2747  {
2748  dlt_log(LOG_WARNING,"Can't remove bytes from receiver\n");
2749  return DLT_DAEMON_ERROR_UNKNOWN;
2750  }
2751 
2752  return DLT_DAEMON_ERROR_OK;
2753 }
2754 
2755 #ifdef DLT_SHM_ENABLE
2756 #define DLT_SHM_RCV_BUFFER_SIZE 10000
2757 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon,
2758  DltDaemonLocal *daemon_local,
2759  DltReceiver *rec,
2760  int verbose)
2761 {
2762  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2763  int j,sent,third_value;
2764  ssize_t ret;
2765  uint8_t *rcv_buffer = NULL;
2766  int size;
2767  uint32_t len = sizeof(DltUserHeader);
2768  DltUserHeader userheader;
2769 
2770  static char text[DLT_DAEMON_TEXTSIZE];
2771 
2772  PRINT_FUNCTION_VERBOSE(verbose);
2773 
2774  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2775  {
2776  snprintf(local_str,
2778  "Invalid function parameters used for %s\n",
2779  __func__);
2780 
2781  dlt_log(LOG_ERR, local_str);
2782  return -1;
2783  }
2784 
2785  rcv_buffer = calloc(1, DLT_SHM_RCV_BUFFER_SIZE);
2786 
2787  if (!rcv_buffer)
2788  {
2789  snprintf(local_str,
2791  "No memory to allocate receiver buffer in %s.\n",
2792  __func__);
2793 
2794  dlt_log(LOG_ERR, local_str);
2795 
2796  return -1;
2797  }
2798 
2799  memset(&userheader, 0, len);
2800 
2801  if (dlt_receiver_check_and_get(rec, &userheader, len, DLT_RCV_REMOVE) < 0)
2802  {
2803  /* Not enough bytes received */
2804  return -1;
2805  }
2806 
2807  //dlt_shm_status(&(daemon_local->dlt_shm));
2808  while (1)
2809  {
2810  /* log message in SHM */
2811  size = dlt_shm_copy(&(daemon_local->dlt_shm),
2812  rcv_buffer,
2813  DLT_SHM_RCV_BUFFER_SIZE);
2814  if(size <= 0)
2815  break;
2816 
2817  if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2818  break;
2819  dlt_log(LOG_WARNING,"Can't read messages from shm\n");
2820  return -1;
2821  }
2822 
2823  /* set overwrite ecu id */
2824  if ((daemon_local->flags.evalue[0]) && (strncmp(daemon_local->msg.headerextra.ecu,DLT_DAEMON_ECU_ID,4)==0))
2825  {
2826  /* Set header extra parameters */
2827  dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2828  //msg.headerextra.seid = 0;
2829  if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2830  {
2831  dlt_log(LOG_WARNING,"Can't set message extra parameters in process user message log\n");
2832  dlt_shm_remove(&(daemon_local->dlt_shm));
2833  return -1;
2834  }
2835 
2836  /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2837  daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2838  }
2839 
2840  /* prepare storage header */
2841  if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2842  {
2843  if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2844  {
2845  dlt_log(LOG_WARNING,"Can't set storage header in process user message log\n");
2846  dlt_shm_remove(&(daemon_local->dlt_shm));
2847  return -1;
2848  }
2849  }
2850  else
2851  {
2852  if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2853  {
2854  dlt_log(LOG_WARNING,"Can't set storage header in process user message log\n");
2855  dlt_shm_remove(&(daemon_local->dlt_shm));
2856  return -1;
2857  }
2858  }
2859 
2860  /* display message */
2861  if (daemon_local->flags.xflag)
2862  {
2863  if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2864  {
2865  dlt_log(LOG_WARNING,"dlt_message_print_hex() failed!\n");
2866  }
2867  } /* if */
2868  else if (daemon_local->flags.aflag)
2869  {
2870  if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2871  {
2872  dlt_log(LOG_WARNING,"dlt_message_print_ascii() failed!\n");
2873  }
2874  } /* if */
2875  else if (daemon_local->flags.sflag)
2876  {
2877  if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2878  {
2879  dlt_log(LOG_WARNING,"dlt_message_print_header() failed!\n");
2880  }
2881  /* print message header only */
2882  } /* if */
2883 
2884  sent=0;
2885 
2886  /* write message to offline trace */
2887  if(daemon_local->flags.offlineTraceDirectory[0])
2888  {
2889  dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2890  daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2891  sent = 1;
2892  }
2893 
2894  sent = dlt_daemon_client_send_all(daemon, daemon_local, verbose);
2895 
2896  /* Message was not sent to client, so store it in client ringbuffer */
2897  if (sent == 1)
2898  {
2899  if(userheader.message == DLT_USER_MESSAGE_LOG_SHM) {
2900  /* dlt message was sent, remove from buffer if log message from shm */
2901  dlt_shm_remove(&(daemon_local->dlt_shm));
2902  }
2903  }
2904  else
2905  {
2906  /* dlt message was not sent, keep in buffer */
2907  break;
2908  }
2909  }
2910 
2911  return 0;
2912 }
2913 #undef DLT_SHM_RCV_BUFFER_SIZE
2914 #endif
2915 
2917  DltDaemonLocal *daemon_local,
2918  DltReceiver *rec,
2919  int verbose)
2920 {
2921  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
2922  uint32_t len = sizeof(DltUserControlMsgAppLogLevelTraceStatus);
2923  DltUserControlMsgAppLogLevelTraceStatus userctxt;
2924  DltDaemonApplication *application;
2925  DltDaemonContext *context;
2926  int i, offset_base;
2927  int8_t old_log_level, old_trace_status;
2928 
2929  PRINT_FUNCTION_VERBOSE(verbose);
2930 
2931  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
2932  {
2933  snprintf(local_str,
2935  "Invalid function parameters used for %s\n",
2936  __func__);
2937 
2938  dlt_log(LOG_ERR, local_str);
2939  return -1;
2940  }
2941 
2942  memset(&userctxt, 0, len);
2944  &userctxt,
2945  len,
2947  {
2948  /* Not enough bytes received */
2949  return -1;
2950  }
2951 
2952  if (daemon->num_applications>0)
2953  {
2954  /* Get all contexts with application id matching the received application id */
2955  application = dlt_daemon_application_find(daemon,
2956  userctxt.apid,
2957  verbose);
2958  if (application)
2959  {
2960  /* Calculate start offset within contexts[] */
2961  offset_base=0;
2962  for (i=0; i<(application-(daemon->applications)); i++)
2963  {
2964  offset_base+=daemon->applications[i].num_contexts;
2965  }
2966 
2967  for (i=0; i < application->num_contexts; i++)
2968  {
2969  context = &(daemon->contexts[offset_base+i]);
2970  if (context)
2971  {
2972  old_log_level = context->log_level;
2973  context->log_level = userctxt.log_level; /* No endianess conversion necessary*/
2974 
2975  old_trace_status = context->trace_status;
2976  context->trace_status = userctxt.trace_status; /* No endianess conversion necessary */
2977 
2978  /* The folowing function sends also the trace status */
2979  if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2980  {
2981  context->log_level = old_log_level;
2982  context->trace_status = old_trace_status;
2983  }
2984  }
2985  }
2986  }
2987  }
2988 
2989  return 0;
2990 }
2991 
2993  DltDaemonLocal *daemon_local,
2994  DltReceiver *rec,
2995  int verbose)
2996 {
2997  DltUserControlMsgLogMode userctxt;
2998  uint32_t len = sizeof(DltUserControlMsgLogMode);
2999 
3000  PRINT_FUNCTION_VERBOSE(verbose);
3001 
3002  if ((daemon==0) || (daemon_local==0))
3003  {
3004  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
3005  return -1;
3006  }
3007 
3008  memset(&userctxt, 0, len);
3010  &userctxt,
3011  len,
3013  {
3014  /* Not enough bytes received */
3015  return -1;
3016  }
3017 
3018  /* set the new log mode */
3019  daemon->mode = userctxt.log_mode;
3020 
3021  /* write configuration persistantly */
3022  dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
3023 
3024  return 0;
3025 }
3026 
3028  DltDaemonLocal *daemon_local,
3029  DltReceiver *rec,
3030  int verbose)
3031 {
3032  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
3033  uint32_t len = sizeof(DltUserControlMsgLogMode);
3034  DltUserControlMsgLogMode userctxt;
3035  PRINT_FUNCTION_VERBOSE(verbose);
3036 
3037  if ((daemon == NULL) || (daemon_local == NULL) || (rec == NULL))
3038  {
3039  snprintf(local_str,
3041  "Invalid function parameters used for %s\n",
3042  __func__);
3043 
3044  dlt_log(LOG_ERR, local_str);
3045  return -1;
3046  }
3047 
3048  memset(&userctxt, 0, len);
3049  if (dlt_receiver_check_and_get(rec, &userctxt, len, 1) < 0)
3050  {
3051  /* Not enough bytes received */
3052  return -1;
3053  }
3054 
3055  /* Create automatic unregister context response for unregistered context */
3056  dlt_daemon_control_message_marker(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,verbose);
3057 
3058  return 0;
3059 }
3060 
3061 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
3062 {
3063  int ret;
3064  static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
3065  int length;
3066 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3067  uint32_t curr_time;
3068 #endif
3069 
3070  PRINT_FUNCTION_VERBOSE(verbose);
3071 
3072  if ((daemon==0) || (daemon_local==0))
3073  {
3074  dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
3075  return DLT_DAEMON_ERROR_UNKNOWN;
3076  }
3077 
3078  if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
3079  {
3081  return DLT_DAEMON_ERROR_OK;
3082  }
3083 
3084 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3085  if(sd_notify(0, "WATCHDOG=1") < 0)
3086  {
3087  dlt_log(LOG_WARNING, "Could not reset systemd watchdog\n");
3088  }
3089  curr_time = dlt_uptime();
3090 #endif
3091  while ( (length = dlt_buffer_copy(&(daemon->client_ringbuffer), data, sizeof(data)) ) > 0)
3092  {
3093 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3094  if ((dlt_uptime() - curr_time) / 10000 >= watchdog_trigger_interval)
3095  {
3096  if(sd_notify(0, "WATCHDOG=1") < 0)
3097  {
3098  dlt_log(LOG_WARNING, "Could not reset systemd watchdog\n");
3099  }
3100  curr_time = dlt_uptime();
3101  }
3102 #endif
3103 
3104  if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_FORCE,daemon,daemon_local,0,0,data,length,0,0,verbose)))
3105  {
3106  return ret;
3107  }
3109  if(daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)
3111 
3112  if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
3113  {
3115  return DLT_DAEMON_ERROR_OK;
3116  }
3117  }
3118 
3119  return DLT_DAEMON_ERROR_OK;
3120 }
3121 
3125 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3126  [DLT_TIMER_SYSTEMD] = DLT_CONNECTION_SYSTEMD_TIMER,
3127 #endif
3130 };
3131 
3132 static char dlt_timer_names[DLT_TIMER_UNKNOWN + 1][32] = {
3133  [DLT_TIMER_PACKET] = "Timing packet",
3134  [DLT_TIMER_ECU] = "ECU version",
3135 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3136  [DLT_TIMER_SYSTEMD] = "Systemd watchdog",
3137 #endif
3138  [DLT_TIMER_GATEWAY] = "Gateway",
3139  [DLT_TIMER_UNKNOWN] = "Unknown timer"
3140 };
3141 
3143  int period_sec,
3144  int starts_in,
3145  DltTimers timer_id)
3146 {
3147  int local_fd = -1;
3148  struct itimerspec l_timer_spec;
3149  char *timer_name = NULL;
3150 
3151  if (timer_id >= DLT_TIMER_UNKNOWN) {
3152  dlt_log(DLT_LOG_ERROR, "Unknown timer.");
3153  return -1;
3154  }
3155 
3156  timer_name = dlt_timer_names[timer_id];
3157 
3158  if(daemon_local == NULL)
3159  {
3160  dlt_log(DLT_LOG_ERROR, "Daemaon local structure is NULL");
3161  return -1;
3162  }
3163 
3164  if(period_sec > 0) {
3165 #ifdef linux
3166  local_fd = timerfd_create(CLOCK_MONOTONIC, 0);
3167  if( local_fd < 0)
3168  {
3169  snprintf(str,
3170  sizeof(str),
3171  "<%s> timerfd_create failed: %s\n",
3172  timer_name,
3173  strerror(errno));
3174  dlt_log(LOG_WARNING, str);
3175  }
3176 
3177  l_timer_spec.it_interval.tv_sec = period_sec;
3178  l_timer_spec.it_interval.tv_nsec = 0;
3179  l_timer_spec.it_value.tv_sec = starts_in;
3180  l_timer_spec.it_value.tv_nsec = 0;
3181 
3182  if( timerfd_settime(local_fd, 0, &l_timer_spec, NULL) < 0)
3183  {
3184  snprintf(str,
3185  sizeof(str),
3186  "<%s> timerfd_settime failed: %s\n",
3187  timer_name,
3188  strerror(errno));
3189  dlt_log(LOG_WARNING, str);
3190  local_fd = -1;
3191  }
3192 #endif
3193  }
3194  else {
3195  // timer not activated via the service file
3196  snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name);
3197  dlt_log(LOG_INFO, str);
3198  local_fd = -1;
3199  }
3200 
3201  /* If fully initialized we are done.
3202  * Event handling registration is done later on with other connections.
3203  */
3204  if(local_fd > 0)
3205  {
3206  snprintf(str,
3207  sizeof(str),
3208  "<%s> initialized with %d timer\n",
3209  timer_name,
3210  period_sec);
3211  dlt_log(LOG_INFO, str);
3212  }
3213 
3214  return dlt_connection_create(daemon_local,
3215  &daemon_local->pEvent,
3216  local_fd,
3217  EPOLLIN,
3218  dlt_timer_conn_types[timer_id]);
3219 }
3220 
3221 /* Close connection function */
3222 int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
3223 {
3224  PRINT_FUNCTION_VERBOSE(verbose);
3225 
3226  if((daemon_local == NULL)|| (daemon == NULL))
3227  {
3228  dlt_log(LOG_ERR, "dlt_daemon_close_socket: Invalid input parmeters\n");
3229  return -1;
3230  }
3231 
3232  /* Closure is done while unregistering has for any connection */
3234  daemon_local,
3235  sock);
3236 
3237 
3238  if(daemon_local->client_connections==0)
3239  {
3240  /* send new log state to all applications */
3241  daemon->connectionState = 0;
3242  dlt_daemon_user_send_all_log_state(daemon,verbose);
3243 
3244  // For offline tracing we still can use the same states
3245  // as for socket sending. Using this trick we see the traces
3246  // In the offline trace AND in the socket stream.
3247  if(daemon_local->flags.yvalue[0] == 0)
3249  }
3250 
3251  if (daemon_local->flags.vflag)
3252  {
3253  snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
3254  dlt_log(LOG_INFO, str);
3255  }
3256 
3258 
3259  return 0;
3260 }
3261 
int32_t datasize
Definition: dlt_common.h:423
int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, DltTimers timer_id)
Definition: dlt-daemon.c:3142
static char dlt_timer_conn_types[DLT_TIMER_UNKNOWN+1]
Definition: dlt-daemon.c:3122
int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose)
Definition: dlt_common.c:1091
#define DLT_RCV_SKIP_HEADER
Definition: dlt_common.h:326
int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext *context, int verbose)
int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2035
#define DLT_HTYP_UEH
Definition: dlt_protocol.h:82
int dlt_receiver_receive_socket(DltReceiver *receiver)
Definition: dlt_common.c:2173
#define PRINT_FUNCTION_VERBOSE(_verbose)
Definition: dlt_common.h:220
int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2436
#define DLT_DAEMON_DESCSIZE
DltReturnValue dlt_offline_trace_free(DltOfflineTrace *trace)
int dlt_shm_copy(DltShm *buf, unsigned char *data, int max_size)
Definition: dlt_shm.c:248
int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon, int fd, int verbose)
#define DLT_DAEMON_ERROR_BUFFER_FULL
Definition: dlt-daemon.h:172
int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2618
#define DLT_SHM_SIZE
Definition: dlt_shm.h:69
int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, DltDaemonLocal *daemon_local, int fd)
Unregisters a connection from the event handler and destroys it.
int8_t found_serialheader
Definition: dlt_common.h:416
char * ECUVersionString
DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose)
Definition: dlt_common.c:3297
#define DLT_HTOBE_16(x)
Definition: dlt_common.h:148
DltStorageHeader * storageheader
Definition: dlt_common.h:432
int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:1128
unsigned long RingbufferMaxSize
Definition: dlt-daemon.h:151
int client_connections
Definition: dlt-daemon.h:143
#define DLT_CONNECTION_STATUS_CONNECTED
Definition: dlt_protocol.h:218
int dlt_daemon_process_control_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1761
char ivalue[NAME_MAX+1]
Definition: dlt-daemon.h:101
int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
#define DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH
int sharedMemorySize
Definition: dlt-daemon.h:103
#define DLT_HTYP_PROTOCOL_VERSION1
Definition: dlt_protocol.h:95
void dlt_set_id(char *id, const char *text)
Definition: dlt_common.c:324
DltDaemonApplication * applications
#define DLT_HTYP_WEID
Definition: dlt_protocol.h:84
int contextTraceStatus
Definition: dlt-daemon.h:130
int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2537
#define DLT_BETOH_32(x)
Definition: dlt_common.h:155
void dlt_event_handler_cleanup_connections(DltEventHandler *ev)
Destroy the connection list.
int dlt_receiver_check_and_get(DltReceiver *receiver, void *dest, unsigned int to_get, unsigned int flags)
Definition: dlt_common.c:2277
unsigned int port
Definition: dlt-daemon.h:124
size_t baudrate
Definition: dlt-daemon.h:144
static int dlt_daemon_init_fifo(DltDaemonLocal *daemon_local)
Definition: dlt-daemon.c:996
int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:3061
DltLogStorage * storage_handle
int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon, int max_device, char *apid, char *ctid)
DltDaemonContext * dlt_daemon_context_add(DltDaemon *daemon, char *apid, char *ctid, int8_t log_level, int8_t trace_status, int log_level_pos, int user_handle, char *description, int verbose)
DltReturnValue dlt_shm_free_server(DltShm *buf)
Definition: dlt_shm.c:278
#define DLT_MESSAGE_ERROR_OK
Definition: dlt_common.h:710
char daemonFifoName[NAME_MAX+1]
Definition: dlt-daemon.h:123
#define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp)
Definition: dlt_common.h:213
unsigned long daemonFifoSize
Definition: dlt-daemon.h:153
unsigned int offlineLogstorageMaxCounterIdx
Definition: dlt-daemon.h:120
char bvalue[NAME_MAX+1]
Definition: dlt-daemon.h:99
#define DLT_DAEMON_TEXTSIZE
char offlineLogstorageDelimiter
Definition: dlt-daemon.h:118
#define DLT_DAEMON_LOCK_FILE
DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
Definition: dlt_common.c:2232
char * buf
Definition: dlt_common.h:678
#define DLT_SERVICE_ID_GET_LOG_INFO
Definition: dlt_protocol.h:178
#define DLT_DAEMON_LOCK_FILE_PERM
#define DLT_DAEMON_ERROR_OK
Definition: dlt-daemon.h:170
DltReturnValue dlt_log(int prio, char *s)
Definition: dlt_common.c:2029
char evalue[NAME_MAX+1]
Definition: dlt-daemon.h:98
int dlt_user_check_userheader(DltUserHeader *userheader)
int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
char loggingFilename[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:111
DltFile file
Definition: dlt-daemon.h:139
#define DLT_DAEMON_ERROR_UNKNOWN
Definition: dlt-daemon.h:171
int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1593
int dlt_daemon_process_user_message_marker(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:3027
int dlt_receiver_receive_fd(DltReceiver *receiver)
Definition: dlt_common.c:2203
DltBuffer client_ringbuffer
int sendECUSoftwareVersion
Definition: dlt-daemon.h:112
#define DLT_RCV_REMOVE
Definition: dlt_common.h:327
DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
Definition: dlt_common.c:666
int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:823
int32_t bytesRcvd
Definition: dlt_common.h:675
DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
Definition: dlt_common.c:2257
DltExtendedHeader * extendedheader
Definition: dlt_common.h:435
int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:2083
DltDaemonFlags flags
Definition: dlt-daemon.h:138
DltReturnValue dlt_offline_trace_write(DltOfflineTrace *trace, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3)
DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
Definition: dlt_common.c:3325
void dlt_daemon_signal_handler(int sig)
Definition: dlt-daemon.c:1252
int main(int argc, char *argv[])
Definition: dlt-daemon.c:583
DltEventHandler pEvent
Definition: dlt-daemon.h:140
DltOfflineTrace offlineTrace
Definition: dlt-daemon.h:148
void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
char offlineTraceDirectory[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:105
#define DLT_USER_MESSAGE_NOT_SUPPORTED
DltDaemonContext * contexts
static int dlt_daemon_init_serial(DltDaemonLocal *daemon_local)
Definition: dlt-daemon.c:924
#define DLT_MSIN_MTIN
Definition: dlt_protocol.h:102
int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size)
Definition: dlt_common.c:2889
#define DLT_DAEMON_RINGBUFFER_STEP_SIZE
DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
Definition: dlt_common.c:1273
static char data[kDataSize]
Definition: city-test.cc:40
#define DLT_MSIN_MTIN_SHIFT
Definition: dlt_protocol.h:105
DltDaemonApplication * dlt_daemon_application_add(DltDaemon *daemon, char *apid, pid_t pid, char *description, int verbose)
char ctid[DLT_ID_SIZE]
DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
Definition: dlt_common.c:2315
int dlt_daemon_socket_open(int *sock, unsigned int servPort)
int32_t databuffersize
Definition: dlt_common.h:429
int dlt_daemon_free(DltDaemon *daemon, int verbose)
int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:3222
#define DLT_IS_HTYP_UEH(htyp)
Definition: dlt_protocol.h:89
int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
char cvalue[NAME_MAX+1]
Definition: dlt-daemon.h:102
unsigned long RingbufferStepSize
Definition: dlt-daemon.h:152
int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
#define DLT_HTYP_WTMS
Definition: dlt_protocol.h:86
#define DLT_HTOBE_32(x)
Definition: dlt_common.h:153
void usage()
Definition: dlt-daemon.c:94
int dlt_mkdir_recursive(const char *dir)
Definition: dlt_common.c:3905
int(* dlt_daemon_process_user_message_func)(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.h:196
void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
void dlt_daemon_logstorage_set_logstorage_cache_size(unsigned int size)
uint32_t dlt_uptime(void)
Definition: dlt_common.c:3274
static char dlt_timer_names[DLT_TIMER_UNKNOWN+1][32]
Definition: dlt-daemon.c:3132
int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
char yvalue[NAME_MAX+1]
Definition: dlt-daemon.h:100
int dlt_daemon_client_send_all(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Send out message to all the clients.
void dlt_log_set_filename(const char *filename)
Definition: dlt_common.c:1981
int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1948
#define DLT_CONNECTION_STATUS_DISCONNECTED
Definition: dlt_protocol.h:217
char gatewayConfigFile[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:127
int32_t headersize
Definition: dlt_common.h:422
#define DLT_DAEMON_ECU_ID
int dlt_daemon_control_message_unregister_context(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, char *apid, char *ctid, char *comid, int verbose)
int dlt_daemon_client_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, void *storage_header, int storage_header_size, void *data1, int size1, void *data2, int size2, int verbose)
const char dltSerialHeader[DLT_ID_SIZE]
Definition: dlt_common.c:70
int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1681
int dlt_daemon_init(DltDaemon *daemon, unsigned long RingbufferMinSize, unsigned long RingbufferMaxSize, unsigned long RingbufferStepSize, const char *runtime_directory, int InitialContextLogLevel, int InitialContextTraceStatus, int ForceLLTS, int verbose)
#define DLT_HTYP_WSID
Definition: dlt_protocol.h:85
void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_FD_MINIMUM
Definition: dlt_common.h:199
#define DLT_MSG_IS_CONTROL_REQUEST(MSG)
Definition: dlt_common.h:238
int offlineLogstorageTimestamp
Definition: dlt-daemon.h:117
uint8_t headerbuffer[sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]
Definition: dlt_common.h:427
int enforceContextLLAndTS
Definition: dlt-daemon.h:131
char apid[DLT_ID_SIZE]
int offlineTraceFileSize
Definition: dlt-daemon.h:106
int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2916
DltDaemonApplication * dlt_daemon_application_find(DltDaemon *daemon, char *apid, int verbose)
char userPipesDir[NAME_MAX+1]
Definition: dlt-daemon.h:122
#define DLT_DAEMON_SEND_TO_ALL
#define DLT_IS_HTYP_WEID(htyp)
Definition: dlt_protocol.h:91
int dlt_buffer_remove(DltBuffer *buf)
Definition: dlt_common.c:2894
#define DLT_TYPE_INFO_STRG
Definition: dlt_protocol.h:154
int dlt_buffer_get_message_count(DltBuffer *buf)
Definition: dlt_common.c:2977
DltStandardHeaderExtra headerextra
Definition: dlt_common.h:434
char ctrlSockPath[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:125
DltReturnValue dlt_file_init(DltFile *file, int verbose)
Definition: dlt_common.c:1305
int offlineTraceMaxSize
Definition: dlt-daemon.h:107
int dlt_shm_init_server(DltShm *buf, int key, int size)
Definition: dlt_shm.c:99
#define DLT_TYPE_LOG
Definition: dlt_protocol.h:114
unsigned int overflow_counter
char apid[DLT_ID_SIZE]
#define DLT_GATEWAY_CONFIG_PATH
int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char *comid, int verbose)
DltDaemonState state
char offlineLogstorageDirPath[DLT_MOUNT_PATH_MAX]
Definition: dlt-daemon.h:116
int32_t resync_offset
Definition: dlt_common.h:419
char dltFifoBaseDir[PATH_MAX+1]
Definition: dlt_common.c:72
#define DLT_MSIN_MSTP_SHIFT
Definition: dlt_protocol.h:104
int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose)
Definition: dlt_gateway.c:577
int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2992
DltReturnValue dlt_file_free(DltFile *file, int verbose)
Definition: dlt_common.c:1942
DltReturnValue dlt_setup_serial(int fd, speed_t speed)
Definition: dlt_common.c:2992
int dlt_daemon_process_control_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1817
DltStandardHeader * standardheader
Definition: dlt_common.h:433
int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
Definition: dlt_common.c:691
int autoResponseGetLogInfoOption
Definition: dlt-daemon.h:128
speed_t dlt_convert_serial_speed(int baudrate)
Definition: dlt_common.c:3067
static int dlt_daemon_process_user_message_not_sup(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1897
int offlineLogstorageMaxDevices
Definition: dlt-daemon.h:115
#define DLT_MSIN_VERB
Definition: dlt_protocol.h:100
int option_handling(DltDaemonLocal *daemon_local, int argc, char *argv[])
Definition: dlt-daemon.c:120
int g_exit
Definition: dlt-daemon.c:89
int dlt_daemon_unix_socket_open(int *sock, char *sock_path)
int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2103
sem_t dlt_daemon_mutex
static dlt_daemon_process_user_message_func process_user_func[DLT_USER_MESSAGE_NOT_SUPPORTED]
Definition: dlt-daemon.c:1925
#define DLT_SHM_KEY
Definition: dlt_shm.h:64
int option_file_parser(DltDaemonLocal *daemon_local)
Definition: dlt-daemon.c:209
int offlineTraceFilenameTimestampBased
Definition: dlt-daemon.h:108
void dlt_get_version(char *buf, size_t size)
Definition: dlt_common.c:3239
char pathToECUSoftwareVersion[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:113
#define DLT_DAEMON_RINGBUFFER_MIN_SIZE
#define DLT_DAEMON_RCVBUFSIZE
char runtime_configuration[PATH_MAX+1]
void dlt_log_set_level(int level)
Definition: dlt_common.c:1968
int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *rec, int verbose)
Definition: dlt-daemon.c:2213
#define DLT_DAEMON_UMASK
unsigned int offlineLogstorageMaxCounter
Definition: dlt-daemon.h:119
unsigned int offlineLogstorageCacheSize
Definition: dlt-daemon.h:121
int dlt_daemon_logstorage_setup_internal_storage(DltDaemon *daemon, char *path, int verbose)
int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt-daemon.c:1477
#define DLT_DAEMON_FLAG_MAX
#define DLT_MESSAGE_ERROR_SIZE
Definition: dlt_common.h:712
static char str[DLT_DAEMON_TEXTBUFSIZE]
Definition: dlt-daemon.c:80
int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon, int fd, int verbose)
void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:1200
int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose)
Definition: dlt_common.c:3310
int dlt_shm_remove(DltShm *buf)
Definition: dlt_shm.c:263
uint8_t * databuffer
Definition: dlt_common.h:428
void dlt_daemon_daemonize(int verbose)
Definition: dlt-daemon.c:1288
int dlt_daemon_logstorage_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
#define DLT_DAEMON_TCP_PORT
Definition: dlt_common.h:192
char ecuid[DLT_ID_SIZE]
#define DLT_USER_MESSAGE_LOG_SHM
int dlt_daemon_prepare_event_handling(DltEventHandler *ev)
Prepare the event handler.
#define DLT_USER_TRACE_STATUS_NOT_SET
int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:748
#define DLT_DAEMON_TEXTBUFSIZE
DltMessage msg
Definition: dlt-daemon.h:142
#define DLT_USER_LOG_LEVEL_NOT_SET
int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:1067
DltReturnValue dlt_vlog(int prio, const char *format,...)
Definition: dlt_common.c:2078
DltUserLogMode mode
#define DLT_DAEMON_RINGBUFFER_MAX_SIZE
DltReturnValue dlt_offline_trace_init(DltOfflineTrace *trace, const char *directory, int fileSize, int maxSize, int filenameTimestampBased)
#define DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE
int dlt_connection_create(DltDaemonLocal *daemon_local, DltEventHandler *evh, int fd, int mask, DltConnectionType type)
Creates a connection and registers it to the DltEventHandler.
int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, unsigned int overflow_counter, char *apid, int verbose)
static int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *str, int verbose)
Definition: dlt-daemon.c:1383
DltDaemonContext * dlt_daemon_context_find(DltDaemon *daemon, char *apid, char *ctid, int verbose)
unsigned long RingbufferMinSize
Definition: dlt-daemon.h:150
void dlt_log_init(int mode)
Definition: dlt_common.c:2000
#define DLT_DAEMON_SEND_FORCE
#define NULL
Definition: dlt_common.h:232
#define DLT_RCV_NONE
Definition: dlt_common.h:325
int dlt_daemon_handle_event(DltEventHandler *pEvent, DltDaemon *daemon, DltDaemonLocal *daemon_local)
Catch and process incoming events.
#define DLT_GATEWAY_TIMER_INTERVAL