automotive-dlt
dlt_daemon_client.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 <arpa/inet.h> /* for sockaddr_in and inet_addr() */
35 #include <stdlib.h> /* for atoi() and exit() */
36 #include <string.h> /* for memset() */
37 #include <unistd.h> /* for close() */
38 #include <fcntl.h>
39 #include <signal.h>
40 #include <syslog.h>
41 #include <errno.h>
42 #include <pthread.h>
43 
44 #ifdef linux
45 #include <sys/timerfd.h>
46 #endif
47 #include <sys/stat.h>
48 #include <sys/time.h>
49 #ifdef linux
50 #include <linux/stat.h>
51 #endif
52 
53 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
54 #include <systemd/sd-daemon.h>
55 #endif
56 
57 #include "dlt_types.h"
58 #include "dlt-daemon.h"
59 #include "dlt-daemon_cfg.h"
60 #include "dlt_daemon_common_cfg.h"
61 
62 #include "dlt_daemon_socket.h"
63 #include "dlt_daemon_serial.h"
64 
65 #include "dlt_daemon_client.h"
66 #include "dlt_daemon_connection.h"
67 
69 #include "dlt_gateway.h"
70 
71 /* checks if received size is big enough for expected data */
72 #define DLT_CHECK_RCV_DATA_SIZE(received, required) \
73  ({ \
74  int _ret = DLT_RETURN_OK; \
75  if (((int)received - (int)required) < 0) { \
76  dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__); \
77  _ret = DLT_RETURN_ERROR; \
78  } \
79  _ret; \
80  })
81 
84 
102  DltDaemonLocal *daemon_local,
103  void* data1,
104  int size1,
105  void* data2,
106  int size2,
107  int verbose)
108 {
109  int j, sent = 0;
110  DltConnection* temp = NULL;
111  int type_mask =
113  char local_str[DLT_DAEMON_TEXTBUFSIZE];
114 
115  if ((daemon == NULL) || (daemon_local == NULL))
116  {
117  snprintf(local_str,
119  "%s: Invalid parameters\n",
120  __func__);
121  dlt_log(LOG_ERR, local_str);
122  return 0;
123  }
124 
125  temp = daemon_local->pEvent.connections;
126  temp = dlt_connection_get_next(temp, type_mask);
127 
128  /* FIXME: the lock shall include the for loop as data
129  * can be affect between each iteration, but
130  * dlt_daemon_close_socket may call us too ...
131  */
132  for (j = 0; ((j < daemon_local->client_connections) && (temp != NULL)); j++)
133  {
134  int ret = 0;
136  DltConnection *next = dlt_connection_get_next(temp->next, type_mask);
137 
138  ret = dlt_connection_send_multiple(temp,
139  data1,
140  size1,
141  data2,
142  size2,
143  daemon->sendserialheader);
145 
146  if((ret != DLT_DAEMON_ERROR_OK) &&
148  {
150  daemon,
151  daemon_local,
152  verbose);
153  }
154 
155  if (ret != DLT_DAEMON_ERROR_OK)
156  {
157  snprintf(local_str,
159  "%s: send dlt message failed\n",
160  __func__);
161  dlt_log(LOG_WARNING, local_str);
162  }
163  else
164  {
165  /* If sent to at least one client,
166  * then do not store in ring buffer
167  */
168  sent = 1;
169  }
170 
171  temp = next;
172  } /* for */
173 
174  return sent;
175 }
176 
186  DltDaemonLocal *daemon_local,
187  int verbose)
188 {
189  void *msg1, *msg2;
190  int msg1_sz, msg2_sz;
191  int ret = 0;
192  char local_str[DLT_DAEMON_TEXTBUFSIZE];
193 
194  if ((daemon == NULL) || (daemon_local == NULL))
195  {
196  snprintf(local_str,
198  "%s: Invalid parameters\n",
199  __func__);
200  dlt_log(LOG_ERR, local_str);
201  return 0;
202  }
203 
204  /* FIXME: the lock shall include the for loop but
205  * dlt_daemon_close_socket may call us too ...
206  */
208  msg1 = daemon_local->msg.headerbuffer + sizeof(DltStorageHeader);
209  msg1_sz = daemon_local->msg.headersize - sizeof(DltStorageHeader);
210  msg2 = daemon_local->msg.databuffer;
211  msg2_sz = daemon_local->msg.datasize;
213 
215  daemon_local,
216  msg1,
217  msg1_sz,
218  msg2,
219  msg2_sz,
220  verbose);
221 
222  return ret;
223 }
224 
225 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)
226 {
227  int sent,ret;
228 
230  {
231  /* Send message to specific socket */
232  if (isatty(sock))
233  {
235 
236  if((ret=dlt_daemon_serial_send(sock,data1,size1,data2,size2,daemon->sendserialheader)))
237  {
239  dlt_log(LOG_WARNING,"dlt_daemon_client_send: serial send dlt message failed\n");
240  return ret;
241  }
242 
244  }
245  else
246  {
248 
249  if((ret=dlt_daemon_socket_send(sock,data1,size1,data2,size2,daemon->sendserialheader)))
250  {
252  dlt_log(LOG_WARNING,"dlt_daemon_client_send: socket send dlt message failed\n");
253  return ret;
254  }
255 
257  }
258  return DLT_DAEMON_ERROR_OK;
259  }
260 
261  /* write message to offline trace */
262  // In the SEND_BUFFER state we must skip offline tracing because the offline traces
263  // are going without buffering directly to the offline trace. Thus we have to filter out
264  // the traces that are coming from the buffer.
265  if ((sock!=DLT_DAEMON_SEND_FORCE) && (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER))
266  {
267  if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
268  && daemon_local->flags.offlineTraceDirectory[0])
269  {
270  if(dlt_offline_trace_write(&(daemon_local->offlineTrace),storage_header,storage_header_size,data1,size1,data2,size2))
271  {
272  static int error_dlt_offline_trace_write_failed = 0;
273  if(!error_dlt_offline_trace_write_failed)
274  {
275  dlt_log(LOG_ERR,"dlt_daemon_client_send: dlt_offline_trace_write failed!\n");
276  error_dlt_offline_trace_write_failed = 1;
277  }
278  //return DLT_DAEMON_ERROR_WRITE_FAILED;
279  }
280  }
281  /* write messages to offline logstorage only if there is an extended header set
282  * this need to be checked because the function is dlt_daemon_client_send is called by
283  * newly introduced dlt_daemon_log_internal */
284  if(daemon_local->flags.offlineLogstorageMaxDevices > 0)
285  {
287  &daemon_local->flags,
288  storage_header,
289  storage_header_size,
290  data1,
291  size1,
292  data2,
293  size2);
294  }
295  }
296 
297  /* send messages to daemon socket */
298  if((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
299  {
300  if ((sock==DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
301  {
303  daemon_local,
304  data1,
305  size1,
306  data2,
307  size2,
308  verbose);
309 
310  if((sock==DLT_DAEMON_SEND_FORCE) && !sent)
311  {
313  }
314  }
315  }
316 
317  /* Message was not sent to client, so store it in client ringbuffer */
319  {
320  if(daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)
322 
324  /* Store message in history buffer */
325  if (dlt_buffer_push3(&(daemon->client_ringbuffer),data1,size1,data2,size2,0, 0) < DLT_RETURN_OK)
326  {
328  dlt_log(LOG_DEBUG,"dlt_daemon_client_send: Buffer is full! Message discarded.\n");
331  }
333  }
334 
335  return DLT_DAEMON_ERROR_OK;
336 
337 }
338 
339 int dlt_daemon_client_send_control_message( int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, char* appid, char* ctid, int verbose)
340 {
341  int ret;
342  int32_t len;
343 
344  PRINT_FUNCTION_VERBOSE(verbose);
345 
346  if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
347  {
349  }
350 
351  /* prepare storage header */
352  msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
353 
355  {
357  }
358 
359  /* prepare standard header */
360  msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
362 
363 #if (BYTE_ORDER==BIG_ENDIAN)
364  msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
365 #endif
366 
367  msg->standardheader->mcnt = 0;
368 
369  /* Set header extra parameters */
370  dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
371 
372  //msg->headerextra.seid = 0;
373 
374  msg->headerextra.tmsp = dlt_uptime();
375 
376  dlt_message_set_extraparameters(msg, verbose);
377 
378  /* prepare extended header */
379  msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
381 
382  msg->extendedheader->noar = 1; /* number of arguments */
383  if (strcmp(appid,"")==0)
384  {
385  dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID); /* application id */
386  }
387  else
388  {
389  dlt_set_id(msg->extendedheader->apid, appid);
390  }
391  if (strcmp(ctid,"")==0)
392  {
393  dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID); /* context id */
394  }
395  else
396  {
397  dlt_set_id(msg->extendedheader->ctid, ctid);
398  }
399 
400  /* prepare length information */
401  msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
402 
403  len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
404  if (len>UINT16_MAX)
405  {
406  dlt_log(LOG_WARNING,"Huge control message discarded!\n");
408  }
409 
410  msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
411 
412  if((ret=dlt_daemon_client_send(sock,daemon,daemon_local,msg->headerbuffer,sizeof(DltStorageHeader),msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
413  msg->databuffer,msg->datasize,verbose)))
414  {
415  dlt_log(LOG_DEBUG,"dlt_daemon_control_send_control_message: DLT message send to all failed!.\n");
416  return ret;
417  }
418 
419  return DLT_DAEMON_ERROR_OK;
420 }
421 
422 int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
423 {
424  uint32_t id,id_tmp=0;
425  DltStandardHeaderExtra extra;
426 
427  PRINT_FUNCTION_VERBOSE(verbose);
428 
429  if (daemon == NULL || daemon_local == NULL|| msg == NULL)
430  {
431  return -1;
432  }
433 
434  if (msg->datasize < (int32_t)sizeof(uint32_t))
435  {
436  return -1;
437  }
438 
439  extra = msg->headerextra;
440 
441  /* check if the message needs to be forwarded */
442  if (daemon_local->flags.gatewayMode == 1)
443  {
444  if (strcmp(daemon_local->flags.evalue, extra.ecu) != 0)
445  {
446  return dlt_gateway_forward_control_message(&daemon_local->pGateway,
447  daemon_local,
448  msg,
449  extra.ecu,
450  verbose);
451  }
452  }
453  id_tmp = *((uint32_t*)(msg->databuffer));
454  id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
455 
456  if ((id > 0) && (id < DLT_SERVICE_ID_CALLSW_CINJECTION))
457  {
458  /* Control message handling */
459  switch (id)
460  {
462  {
463  dlt_daemon_control_set_log_level(sock, daemon, daemon_local, msg, verbose);
464  break;
465  }
467  {
468  dlt_daemon_control_set_trace_status(sock, daemon, daemon_local, msg, verbose);
469  break;
470  }
472  {
473  dlt_daemon_control_get_log_info(sock, daemon, daemon_local, msg, verbose);
474  break;
475  }
477  {
478  dlt_daemon_control_get_default_log_level(sock, daemon, daemon_local, verbose);
479  break;
480  }
482  {
483  if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose)==0)
484  {
485  if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose)==0)
486  {
487  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
488  }
489  else
490  {
491  /* Delete saved files */
493  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
494  }
495  }
496  else
497  {
498  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
499  }
500  break;
501  }
503  {
505  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
506  break;
507  }
509  {
510  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
511  break;
512  }
514  {
515  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
516  break;
517  }
519  {
520  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
521  break;
522  }
524  {
525  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
526  break;
527  }
529  {
530  dlt_daemon_control_set_timing_packets(sock, daemon, daemon_local, msg, verbose);
531  break;
532  }
534  {
535  /* Send response with valid timestamp (TMSP) field */
536  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
537  break;
538  }
540  {
541  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
542  break;
543  }
545  {
546  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
547  break;
548  }
550  {
551  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
552  break;
553  }
555  {
556  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
557  break;
558  }
560  {
561  dlt_daemon_control_set_default_log_level(sock, daemon, daemon_local, msg, verbose);
562  break;
563  }
565  {
566  dlt_daemon_control_set_default_trace_status(sock, daemon, daemon_local, msg, verbose);
567  break;
568  }
570  {
571  dlt_daemon_control_get_software_version(sock, daemon, daemon_local, verbose);
572  break;
573  }
575  {
576  dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter,"",verbose);
577  break;
578  }
580  {
581  dlt_daemon_control_set_all_log_level(sock, daemon, daemon_local, msg, verbose);
582  break;
583  }
585  {
586  dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose);
587  break;
588  }
590  {
592  daemon,
593  daemon_local,
594  msg,
595  verbose);
596  break;
597  }
599  {
601  daemon,
602  daemon_local,
603  verbose);
604  break;
605  }
606  default:
607  {
608  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
609  break;
610  }
611  }
612  }
613  else
614  {
615  /* Injection handling */
616  dlt_daemon_control_callsw_cinjection(sock, daemon, daemon_local, msg, verbose);
617  }
618 
619  return 0;
620 }
621 
622 void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
623 {
624  DltMessage msg;
625  uint32_t len;
626  DltServiceGetSoftwareVersionResponse *resp;
627 
628  PRINT_FUNCTION_VERBOSE(verbose);
629 
630  if (daemon==0)
631  {
632  return;
633  }
634 
635  /* initialise new message */
636  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
637  {
639  return;
640  }
641 
642  /* prepare payload of data */
643  len = strlen(daemon->ECUVersionString);
644 
645  msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
646  if (msg.databuffer && (msg.databuffersize < msg.datasize))
647  {
648  free(msg.databuffer);
649  msg.databuffer=0;
650  }
651  if (msg.databuffer == 0){
652  msg.databuffer = (uint8_t *) malloc(msg.datasize);
653  msg.databuffersize = msg.datasize;
654  }
655  if (msg.databuffer==0)
656  {
658  return;
659  }
660 
661  resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
662  resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
663  resp->status = DLT_SERVICE_RESPONSE_OK;
664  resp->length = len;
665  memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),daemon->ECUVersionString,len);
666 
667  /* send message */
668  dlt_daemon_client_send_control_message(sock, daemon,daemon_local, &msg,"","", verbose);
669 
670  /* free message */
671  dlt_message_free(&msg,0);
672 }
673 
674 void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
675 {
676  DltMessage msg;
677  DltServiceGetDefaultLogLevelResponse *resp;
678 
679  PRINT_FUNCTION_VERBOSE(verbose);
680 
681  if (daemon==0)
682  {
683  return;
684  }
685 
686  /* initialise new message */
687  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
688  {
690  return;
691  }
692 
693  msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
694  if (msg.databuffer && (msg.databuffersize<msg.datasize))
695  {
696  free(msg.databuffer);
697  msg.databuffer=0;
698  }
699  if (msg.databuffer == 0){
700  msg.databuffer = (uint8_t *) malloc(msg.datasize);
701  msg.databuffersize = msg.datasize;
702  }
703  if (msg.databuffer==0)
704  {
706  return;
707  }
708 
709  resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
710  resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
711  resp->status = DLT_SERVICE_RESPONSE_OK;
712  resp->log_level = daemon->default_log_level;
713 
714  /* send message */
715  dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose);
716 
717  /* free message */
718  dlt_message_free(&msg,0);
719 }
720 
721 void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
722 {
723  DltServiceGetLogInfoRequest *req;
724  DltMessage resp;
725  DltDaemonContext *context=0;
726  DltDaemonApplication *application=0;
727 
728  int num_applications=0, num_contexts=0;
729  uint16_t count_app_ids=0, count_con_ids=0;
730 
731 #if (DLT_DEBUG_GETLOGINFO==1)
732  char buf[255];
733 #endif
734 
735  int32_t i,j,offset=0;
736  char *apid=0;
737  int8_t ll,ts;
738  uint16_t len;
739  int8_t value;
740  int32_t sizecont=0;
741  int offset_base;
742 
743  uint32_t sid;
744 
745  PRINT_FUNCTION_VERBOSE(verbose);
746 
747  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
748  {
749  return;
750  }
751 
752  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceGetLogInfoRequest)) < 0)
753  {
754  return;
755  }
756 
757  /* prepare pointer to message request */
758  req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
759 
760  /* initialise new message */
761  if (dlt_message_init(&resp,0) == DLT_RETURN_ERROR)
762  {
764  return;
765  }
766 
767  /* check request */
768  if ((req->options < 3 ) || (req->options>7))
769  {
771  return;
772  }
773 
774  if (req->apid[0]!='\0')
775  {
776  application = dlt_daemon_application_find(daemon, req->apid, verbose);
777  if (application)
778  {
779  num_applications = 1;
780  if (req->ctid[0]!='\0')
781  {
782  context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
783 
784  num_contexts = ((context)?1:0);
785  }
786  else
787  {
788  num_contexts = application->num_contexts;
789  }
790  }
791  else
792  {
793  num_applications = 0;
794  num_contexts = 0;
795  }
796  }
797  else
798  {
799  /* Request all applications and contexts */
800  num_applications = daemon->num_applications;
801  num_contexts = daemon->num_contexts;
802  }
803 
804  /* prepare payload of data */
805 
806  /* Calculate maximum size for a response */
807  resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
808 
809  sizecont = sizeof(uint32_t) /* context_id */;
810 
811  /* Add additional size for response of Mode 4, 6, 7 */
812  if ((req->options==4) || (req->options==6) || (req->options==7))
813  {
814  sizecont += sizeof(int8_t); /* log level */
815  }
816 
817  /* Add additional size for response of Mode 5, 6, 7 */
818  if ((req->options==5) || (req->options==6) || (req->options==7))
819  {
820  sizecont+= sizeof(int8_t); /* trace status */
821  }
822 
823  resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
824  (num_contexts * sizecont);
825 
826  resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
827 
828  /* Add additional size for response of Mode 7 */
829  if (req->options==7)
830  {
831  if (req->apid[0]!='\0')
832  {
833  if (req->ctid[0]!='\0')
834  {
835  /* One application, one context */
836  // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
837  if (context)
838  {
839  resp.datasize+=sizeof(uint16_t) /* len_context_description */;
840  if (context->context_description!=0)
841  {
842  resp.datasize+=strlen(context->context_description); /* context_description */
843  }
844  }
845  }
846  else
847  {
848  /* One application, all contexts */
849  if ((daemon->applications) && (application))
850  {
851  /* Calculate start offset within contexts[] */
852  offset_base=0;
853  for (i=0; i<(application-(daemon->applications)); i++)
854  {
855  offset_base+=daemon->applications[i].num_contexts;
856  }
857 
858  /* Iterate over all contexts belonging to this application */
859  for (j=0;j<application->num_contexts;j++)
860  {
861 
862  context = &(daemon->contexts[offset_base+j]);
863  if (context)
864  {
865  resp.datasize+=sizeof(uint16_t) /* len_context_description */;
866  if (context->context_description!=0)
867  {
868  resp.datasize+=strlen(context->context_description); /* context_description */
869  }
870  }
871  }
872  }
873  }
874 
875  /* Space for application description */
876  if (application)
877  {
878  resp.datasize+=sizeof(uint16_t) /* len_app_description */;
879  if (application->application_description!=0)
880  {
881  resp.datasize+=strlen(application->application_description); /* app_description */
882  }
883  }
884  }
885  else
886  {
887  /* All applications, all contexts */
888  for (i=0;i<daemon->num_contexts;i++)
889  {
890  resp.datasize+=sizeof(uint16_t) /* len_context_description */;
891  if (daemon->contexts[i].context_description!=0)
892  {
893  resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
894  }
895  }
896 
897  for (i=0;i<daemon->num_applications;i++)
898  {
899  resp.datasize+=sizeof(uint16_t) /* len_app_description */;
900  if (daemon->applications[i].application_description!=0)
901  {
902  resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
903  }
904  }
905  }
906  }
907 
908  if (verbose)
909  {
910  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
911  dlt_log(LOG_DEBUG, str);
912  }
913 
914  /* Allocate buffer for response message */
915  resp.databuffer = (uint8_t *) malloc(resp.datasize);
916  resp.databuffersize = resp.datasize;
917 
918  if (resp.databuffer==0)
919  {
921  return;
922  }
923  memset(resp.databuffer,0,resp.datasize);
924  /* Preparation finished */
925 
926  /* Prepare response */
928  memcpy(resp.databuffer,&sid,sizeof(uint32_t));
929  offset+=sizeof(uint32_t);
930 
931  value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
932 
933  memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
934  offset+=sizeof(int8_t);
935 
936  count_app_ids = num_applications;
937 
938  if (count_app_ids!=0)
939  {
940  memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
941  offset+=sizeof(uint16_t);
942 
943 #if (DLT_DEBUG_GETLOGINFO==1)
944  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"#apid: %d \n", count_app_ids);
945  dlt_log(LOG_DEBUG, str);
946 #endif
947 
948  for (i=0;i<count_app_ids;i++)
949  {
950  if (req->apid[0]!='\0')
951  {
952  apid = req->apid;
953  }
954  else
955  {
956  if (daemon->applications)
957  {
958  apid = daemon->applications[i].apid;
959  }
960  else
961  {
962  /* This should never occur! */
963  apid=0;
964  }
965  }
966 
967  application = dlt_daemon_application_find(daemon, apid, verbose);
968 
969  if (application)
970  {
971  /* Calculate start offset within contexts[] */
972  offset_base=0;
973  for (j=0; j<(application-(daemon->applications)); j++)
974  {
975  offset_base+=daemon->applications[j].num_contexts;
976  }
977 
978  dlt_set_id((char*)(resp.databuffer+offset),apid);
979  offset+=sizeof(ID4);
980 
981 #if (DLT_DEBUG_GETLOGINFO==1)
982  dlt_print_id(buf, apid);
983  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"apid: %s\n",buf);
984  dlt_log(LOG_DEBUG, str);
985 #endif
986 
987  if (req->apid[0]!='\0')
988  {
989  count_con_ids = num_contexts;
990  }
991  else
992  {
993  count_con_ids = application->num_contexts;
994  }
995 
996  memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
997  offset+=sizeof(uint16_t);
998 
999 #if (DLT_DEBUG_GETLOGINFO==1)
1000  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"#ctid: %d \n", count_con_ids);
1001  dlt_log(LOG_DEBUG, str);
1002 #endif
1003 
1004  for (j=0;j<count_con_ids;j++)
1005  {
1006 #if (DLT_DEBUG_GETLOGINFO==1)
1007  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"j: %d \n",j);
1008  dlt_log(LOG_DEBUG, str);
1009 #endif
1010  if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
1011  {
1012  context = &(daemon->contexts[offset_base+j]);
1013  }
1014  /* else: context was already searched and found
1015  (one application (found) with one context (found))*/
1016 
1017  if ((context) &&
1018  ((req->ctid[0]=='\0') ||
1019  ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
1020  )
1021  {
1022  dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
1023  offset+=sizeof(ID4);
1024 
1025 #if (DLT_DEBUG_GETLOGINFO==1)
1026  dlt_print_id(buf, context->ctid);
1027  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"ctid: %s \n",buf);
1028  dlt_log(LOG_DEBUG, str);
1029 #endif
1030 
1031  /* Mode 4, 6, 7 */
1032  if ((req->options==4) || (req->options==6) || (req->options==7))
1033  {
1034  ll=context->log_level;
1035  memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
1036  offset+=sizeof(int8_t);
1037  }
1038 
1039  /* Mode 5, 6, 7 */
1040  if ((req->options==5) || (req->options==6) || (req->options==7))
1041  {
1042  ts=context->trace_status;
1043  memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
1044  offset+=sizeof(int8_t);
1045  }
1046 
1047  /* Mode 7 */
1048  if (req->options==7)
1049  {
1050  if (context->context_description)
1051  {
1052  len = strlen(context->context_description);
1053  memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1054  offset+=sizeof(uint16_t);
1055  memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
1056  offset+=strlen(context->context_description);
1057  }
1058  else
1059  {
1060  len = 0;
1061  memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1062  offset+=sizeof(uint16_t);
1063  }
1064  }
1065 
1066 #if (DLT_DEBUG_GETLOGINFO==1)
1067  snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
1068  dlt_log(LOG_DEBUG, str);
1069 #endif
1070  }
1071 
1072 #if (DLT_DEBUG_GETLOGINFO==1)
1073  dlt_log(LOG_DEBUG,"\n");
1074 #endif
1075  }
1076 
1077  /* Mode 7 */
1078  if (req->options==7)
1079  {
1080  if (application->application_description)
1081  {
1082  len = strlen(application->application_description);
1083  memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1084  offset+=sizeof(uint16_t);
1085  memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
1086  offset+=strlen(application->application_description);
1087  }
1088  else
1089  {
1090  len = 0;
1091  memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1092  offset+=sizeof(uint16_t);
1093  }
1094  }
1095  } /* if (application) */
1096  } /* for (i=0;i<count_app_ids;i++) */
1097  } /* if (count_app_ids!=0) */
1098 
1099  dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
1100 
1101  /* send message */
1102  dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&resp,"","", verbose);
1103 
1104  /* free message */
1105  dlt_message_free(&resp,0);
1106 }
1107 
1108 int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, unsigned int overflow_counter,char* apid, int verbose)
1109 {
1110  int ret;
1111  DltMessage msg;
1112  DltServiceMessageBufferOverflowResponse *resp;
1113 
1114  PRINT_FUNCTION_VERBOSE(verbose);
1115 
1116  if (daemon==0)
1117  {
1118  return DLT_DAEMON_ERROR_UNKNOWN;
1119  }
1120 
1121  /* initialise new message */
1122  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1123  {
1125  return DLT_DAEMON_ERROR_UNKNOWN;
1126  }
1127 
1128  /* prepare payload of data */
1129  msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
1130  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1131  {
1132  free(msg.databuffer);
1133  msg.databuffer=0;
1134  }
1135  if (msg.databuffer == 0){
1136  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1137  msg.databuffersize = msg.datasize;
1138  }
1139  if (msg.databuffer==0)
1140  {
1141  return DLT_DAEMON_ERROR_UNKNOWN;
1142  }
1143 
1144  resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
1145  resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
1146  resp->status = DLT_SERVICE_RESPONSE_OK;
1147  resp->overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1148  resp->overflow_counter = overflow_counter;
1149 
1150  /* send message */
1151  if((ret=dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,apid,"", verbose)))
1152  {
1153  dlt_message_free(&msg,0);
1154  return ret;
1155  }
1156 
1157  /* free message */
1158  dlt_message_free(&msg,0);
1159 
1160  return DLT_DAEMON_ERROR_OK;
1161 }
1162 
1163 void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint32_t service_id, int8_t status , int verbose)
1164 {
1165  DltMessage msg;
1166  DltServiceResponse *resp;
1167 
1168  PRINT_FUNCTION_VERBOSE(verbose);
1169 
1170  if (daemon==0)
1171  {
1172  return;
1173  }
1174 
1175  /* initialise new message */
1176  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1177  {
1178  return;
1179  }
1180 
1181  /* prepare payload of data */
1182  msg.datasize = sizeof(DltServiceResponse);
1183  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1184  {
1185  free(msg.databuffer);
1186  msg.databuffer=0;
1187  }
1188  if (msg.databuffer == 0){
1189  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1190  msg.databuffersize = msg.datasize;
1191  }
1192  if (msg.databuffer==0)
1193  {
1194  return;
1195  }
1196 
1197  resp = (DltServiceResponse*) msg.databuffer;
1198  resp->service_id = service_id;
1199  resp->status = status;
1200 
1201  /* send message */
1202  dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose);
1203 
1204  /* free message */
1205  dlt_message_free(&msg,0);
1206 }
1207 
1208 int dlt_daemon_control_message_unregister_context(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, char* apid, char* ctid, char* comid, int verbose)
1209 {
1210  DltMessage msg;
1211  DltServiceUnregisterContext *resp;
1212 
1213  PRINT_FUNCTION_VERBOSE(verbose);
1214 
1215  if (daemon==0)
1216  {
1217  return -1;
1218  }
1219 
1220  /* initialise new message */
1221  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1222  {
1223  return -1;
1224  }
1225 
1226  /* prepare payload of data */
1227  msg.datasize = sizeof(DltServiceUnregisterContext);
1228  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1229  {
1230  free(msg.databuffer);
1231  msg.databuffer=0;
1232  }
1233  if (msg.databuffer == 0){
1234  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1235  msg.databuffersize = msg.datasize;
1236  }
1237  if (msg.databuffer==0)
1238  {
1239  return -1;
1240  }
1241 
1242  resp = (DltServiceUnregisterContext*) msg.databuffer;
1243  resp->service_id = DLT_SERVICE_ID_UNREGISTER_CONTEXT;
1244  resp->status = DLT_SERVICE_RESPONSE_OK;
1245  dlt_set_id(resp->apid, apid);
1246  dlt_set_id(resp->ctid, ctid);
1247  dlt_set_id(resp->comid, comid);
1248 
1249  /* send message */
1250  if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose))
1251  {
1252  dlt_message_free(&msg,0);
1253  return -1;
1254  }
1255 
1256  /* free message */
1257  dlt_message_free(&msg,0);
1258 
1259  return 0;
1260 }
1261 
1262 int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char* comid, int verbose)
1263 {
1264  DltMessage msg;
1265  DltServiceConnectionInfo *resp;
1266 
1267  PRINT_FUNCTION_VERBOSE(verbose);
1268 
1269  if (daemon==0)
1270  {
1271  return -1;
1272  }
1273 
1274  /* initialise new message */
1275  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1276  {
1277  return -1;
1278  }
1279 
1280  /* prepare payload of data */
1281  msg.datasize = sizeof(DltServiceConnectionInfo);
1282  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1283  {
1284  free(msg.databuffer);
1285  msg.databuffer=0;
1286  }
1287  if (msg.databuffer == 0){
1288  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1289  msg.databuffersize = msg.datasize;
1290  }
1291  if (msg.databuffer==0)
1292  {
1293  return -1;
1294  }
1295 
1296  resp = (DltServiceConnectionInfo*) msg.databuffer;
1297  resp->service_id = DLT_SERVICE_ID_CONNECTION_INFO;
1298  resp->status = DLT_SERVICE_RESPONSE_OK;
1299  resp->state = state;
1300  dlt_set_id(resp->comid, comid);
1301 
1302  /* send message */
1303  if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose))
1304  {
1305  dlt_message_free(&msg,0);
1306  return -1;
1307  }
1308 
1309  /* free message */
1310  dlt_message_free(&msg,0);
1311 
1312  return 0;
1313 }
1314 
1315 int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1316 {
1317  DltMessage msg;
1318  DltServiceTimezone *resp;
1319 
1320  PRINT_FUNCTION_VERBOSE(verbose);
1321 
1322  if (daemon==0)
1323  {
1324  return -1;
1325  }
1326 
1327  /* initialise new message */
1328  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1329  {
1330  return -1;
1331  }
1332 
1333  /* prepare payload of data */
1334  msg.datasize = sizeof(DltServiceTimezone);
1335  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1336  {
1337  free(msg.databuffer);
1338  msg.databuffer=0;
1339  }
1340  if (msg.databuffer == 0){
1341  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1342  msg.databuffersize = msg.datasize;
1343  }
1344  if (msg.databuffer==0)
1345  {
1346  return -1;
1347  }
1348 
1349  resp = (DltServiceTimezone*) msg.databuffer;
1350  resp->service_id = DLT_SERVICE_ID_TIMEZONE;
1351  resp->status = DLT_SERVICE_RESPONSE_OK;
1352 
1353  time_t t = time(NULL);
1354  struct tm lt;
1355  localtime_r(&t, &lt);
1356 #if !defined(__CYGWIN__)
1357  resp->timezone = (int32_t) lt.tm_gmtoff;
1358 #endif
1359  resp->isdst = (uint8_t) lt.tm_isdst;
1360 
1361  /* send message */
1362  if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose))
1363  {
1364  dlt_message_free(&msg,0);
1365  return -1;
1366  }
1367 
1368  /* free message */
1369  dlt_message_free(&msg,0);
1370 
1371  return 0;
1372 }
1373 
1374 int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1375 {
1376  DltMessage msg;
1377  DltServiceMarker *resp;
1378 
1379  PRINT_FUNCTION_VERBOSE(verbose);
1380 
1381  if (daemon==0)
1382  {
1383  return -1;
1384  }
1385 
1386  /* initialise new message */
1387  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1388  {
1389  return -1;
1390  }
1391 
1392  /* prepare payload of data */
1393  msg.datasize = sizeof(DltServiceMarker);
1394  if (msg.databuffer && (msg.databuffersize < msg.datasize))
1395  {
1396  free(msg.databuffer);
1397  msg.databuffer=0;
1398  }
1399  if (msg.databuffer == 0){
1400  msg.databuffer = (uint8_t *) malloc(msg.datasize);
1401  msg.databuffersize = msg.datasize;
1402  }
1403  if (msg.databuffer==0)
1404  {
1405  return -1;
1406  }
1407 
1408  resp = (DltServiceMarker*) msg.databuffer;
1409  resp->service_id = DLT_SERVICE_ID_MARKER;
1410  resp->status = DLT_SERVICE_RESPONSE_OK;
1411 
1412  /* send message */
1413  if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","", verbose))
1414  {
1415  dlt_message_free(&msg,0);
1416  return -1;
1417  }
1418 
1419  /* free message */
1420  dlt_message_free(&msg,0);
1421 
1422  return 0;
1423 }
1424 
1425 void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1426 {
1427  char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1428  uint32_t id=0,id_tmp=0;
1429  uint8_t *ptr;
1430  DltDaemonContext *context;
1431  int32_t data_length_inject=0;
1432  uint32_t data_length_inject_tmp=0;
1433 
1434  int32_t datalength;
1435 
1436  DltUserHeader userheader;
1437  DltUserControlMsgInjection usercontext;
1438  uint8_t *userbuffer;
1439 
1440  PRINT_FUNCTION_VERBOSE(verbose);
1441 
1442  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1443  {
1444  return;
1445  }
1446 
1447  datalength = msg->datasize;
1448  ptr = msg->databuffer;
1449 
1450  DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
1451  id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1452 
1454  {
1455  /* This a a real SW-C injection call */
1456  data_length_inject=0;
1457  data_length_inject_tmp=0;
1458 
1459  DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
1460  data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1461 
1462  /* Get context handle for apid, ctid (and seid) */
1463  /* Warning: seid is ignored in this implementation! */
1464  if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1465  {
1466  dlt_set_id(apid, msg->extendedheader->apid);
1467  dlt_set_id(ctid, msg->extendedheader->ctid);
1468  }
1469  else
1470  {
1471  /* No extended header, and therefore no apid and ctid available */
1472  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1473  return;
1474  }
1475 
1476  /* At this point, apid and ctid is available */
1477  context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1478 
1479  if (context==0)
1480  {
1481  // dlt_log(LOG_INFO,"No context found!\n");
1482  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1483  return;
1484  }
1485 
1486  /* Send user message to handle, specified in context */
1488  {
1489  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1490  return;
1491  }
1492 
1493  usercontext.log_level_pos = context->log_level_pos;
1494 
1495  if (data_length_inject > msg->databuffersize)
1496  {
1497  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1498  return;
1499  }
1500 
1501  userbuffer = malloc(data_length_inject);
1502 
1503  if (userbuffer==0)
1504  {
1505  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1506  return;
1507  }
1508 
1509  usercontext.data_length_inject = data_length_inject;
1510  usercontext.service_id = id;
1511 
1512  memcpy(userbuffer,ptr,data_length_inject); /* Copy received injection to send buffer */
1513 
1514  /* write to FIFO */
1515  DltReturnValue ret =
1516  dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
1517  &(usercontext), sizeof(DltUserControlMsgInjection),
1518  userbuffer, data_length_inject);
1519  if (ret < DLT_RETURN_OK)
1520  {
1521  if (ret == DLT_RETURN_PIPE_ERROR)
1522  {
1523  /* Close connection */
1524  close(context->user_handle);
1525  context->user_handle=DLT_FD_INIT;
1526  }
1527  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1528  }
1529  else
1530  {
1531  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1532  }
1533 
1534  free(userbuffer);
1535  userbuffer=0;
1536 
1537  }
1538  else
1539  {
1540  /* Invalid ID */
1541  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1542  }
1543 }
1544 
1545 void dlt_daemon_send_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context,int8_t loglevel, int verbose)
1546 {
1547  PRINT_FUNCTION_VERBOSE(verbose);
1548 
1549  int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL;
1550  int8_t old_log_level = 0;
1551 
1552  old_log_level = context->log_level;
1553  context->log_level = loglevel; /* No endianess conversion necessary*/
1554 
1555  if ((context->user_handle >= DLT_FD_MINIMUM) &&
1556  (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1557  {
1558  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1559  }
1560  else
1561  {
1562  dlt_log(LOG_ERR, "Log level could not be sent!\n");
1563  context->log_level = old_log_level;
1564  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1565  }
1566 
1567 }
1568 
1569 void dlt_daemon_find_multiple_context_and_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int8_t app_flag, char *str, int8_t len, int8_t loglevel, int verbose)
1570 {
1571  PRINT_FUNCTION_VERBOSE(verbose);
1572 
1573  int8_t count = 0;
1574  DltDaemonContext *context = NULL;
1575  char src_str[DLT_ID_SIZE +1] = {0};
1576  int8_t ret = 0;
1577 
1578  if (daemon == 0)
1579  {
1580  return;
1581  }
1582 
1583  for (count = 0; count < daemon->num_contexts; count++)
1584  {
1585  context = &(daemon->contexts[count]);
1586 
1587  if (context)
1588  {
1589  if (app_flag == 1)
1590  {
1591  strncpy(src_str, context->apid, DLT_ID_SIZE);
1592  }
1593  else
1594  {
1595  strncpy(src_str, context->ctid, DLT_ID_SIZE);
1596  }
1597  ret = strncmp(src_str, str, len);
1598  if (ret == 0)
1599  {
1600  dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose);
1601  }
1602  else if ((ret > 0) && (app_flag == 1))
1603  {
1604  break;
1605  }
1606  else
1607  {
1608  continue;
1609  }
1610  }
1611  }
1612 }
1613 
1614 void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1615 {
1616  PRINT_FUNCTION_VERBOSE(verbose);
1617 
1618  char apid[DLT_ID_SIZE+1] = {0};
1619  char ctid[DLT_ID_SIZE+1] = {0};
1620  DltServiceSetLogLevel *req = NULL;
1621  DltDaemonContext *context = NULL;
1622  int8_t appid_length = 0;
1623  int8_t ctxtid_length = 0;
1624 
1625  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1626  {
1627  return;
1628  }
1629 
1630  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1631  {
1632  return;
1633  }
1634 
1635  req = (DltServiceSetLogLevel*) (msg->databuffer);
1636 
1637  dlt_set_id(apid, req->apid);
1638  dlt_set_id(ctid, req->ctid);
1639  appid_length = strlen(apid);
1640  ctxtid_length = strlen(ctid);
1641  if ((appid_length != 0) && (apid[appid_length-1] == '*') && (ctid[0] == 0)) /*appid provided having '*' in it and ctid is null*/
1642  {
1643  dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 1, apid, appid_length-1, req->log_level, verbose);
1644  }
1645  else if ((ctxtid_length != 0) && (ctid[ctxtid_length-1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and appid is null*/
1646  {
1647  dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 0, ctid, ctxtid_length-1, req->log_level, verbose);
1648  }
1649  else if ((appid_length != 0) && (apid[appid_length-1] != '*') && (ctid[0] == 0)) /*only app id case*/
1650  {
1651  dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 1, apid, DLT_ID_SIZE, req->log_level, verbose);
1652  }
1653  else if ((ctxtid_length != 0) && (ctid[ctxtid_length-1] != '*') && (apid[0] == 0)) /*only context id case*/
1654  {
1655  dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 0, ctid, DLT_ID_SIZE, req->log_level, verbose);
1656  }
1657  else
1658  {
1659  context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1660 
1661  /* Set log level */
1662  if (context!=0)
1663  {
1664  dlt_daemon_send_log_level(sock, daemon, daemon_local, context, req->log_level, verbose);
1665  }
1666  else
1667  {
1668  dlt_log(LOG_ERR, "Context not found!\n");
1670  }
1671  }
1672 }
1673 
1674 void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1675 {
1676  PRINT_FUNCTION_VERBOSE(verbose);
1677 
1678  char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1679  DltServiceSetLogLevel *req; /* request uses same struct as set log level */
1680  DltDaemonContext *context;
1682 
1683  int8_t old_trace_status;
1684 
1685  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1686  {
1687  return;
1688  }
1689 
1690  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1691  {
1692  return;
1693  }
1694 
1695  req = (DltServiceSetLogLevel*) (msg->databuffer);
1696 
1697  dlt_set_id(apid, req->apid);
1698  dlt_set_id(ctid, req->ctid);
1699 
1700  context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1701 
1702  /* Set log level */
1703  if (context!=0)
1704  {
1705  old_trace_status = context->trace_status;
1706  context->trace_status = req->log_level; /* No endianess conversion necessary */
1707 
1708  if ((context->user_handle >= DLT_FD_MINIMUM ) &&
1709  (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1710  {
1711  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1712  }
1713  else
1714  {
1715  //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
1716  context->trace_status = old_trace_status;
1717  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1718  }
1719  }
1720  else
1721  {
1722  //dlt_log(LOG_ERR, "Context not found!\n");
1723  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1724  }
1725 }
1726 
1727 void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1728 {
1729  PRINT_FUNCTION_VERBOSE(verbose);
1730 
1731  DltServiceSetDefaultLogLevel *req;
1733 
1734  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1735  {
1736  return;
1737  }
1738 
1739  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
1740  {
1741  return;
1742  }
1743 
1744  req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1745 
1746  /* No endianess conversion necessary */
1747  if (/*(req->log_level>=0) &&*/
1748  (req->log_level<=DLT_LOG_VERBOSE))
1749  {
1750  daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
1751 
1752  /* Send Update to all contexts using the default log level */
1753  dlt_daemon_user_send_default_update(daemon, verbose);
1754 
1755  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1756  }
1757  else
1758  {
1759  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1760  }
1761 }
1762 
1763 void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1764 {
1765  PRINT_FUNCTION_VERBOSE(verbose);
1766 
1767  DltServiceSetDefaultLogLevel *req = NULL;
1768  int32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
1769  int8_t loglevel = 0;
1770 
1771  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1772  {
1773  return;
1774  }
1775 
1776  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
1777  {
1778  return;
1779  }
1780 
1781  req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1782 
1783  /* No endianess conversion necessary */
1784  if ((req != NULL) && (req->log_level <= DLT_LOG_VERBOSE))
1785  {
1786  loglevel = req->log_level; /* No endianess conversion necessary */
1787  /* Send Update to all contexts using the new log level */
1788  dlt_daemon_user_send_all_update(daemon, loglevel, verbose);
1789 
1790  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1791  }
1792  else
1793  {
1794  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1795  }
1796 }
1797 
1798 void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1799 {
1800  PRINT_FUNCTION_VERBOSE(verbose);
1801 
1802  /* Payload of request message */
1803  DltServiceSetDefaultLogLevel *req;
1805 
1806  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1807  {
1808  return;
1809  }
1810 
1811  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
1812  {
1813  return;
1814  }
1815 
1816  req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1817 
1818  /* No endianess conversion necessary */
1819  if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
1820  (req->log_level==DLT_TRACE_STATUS_ON))
1821  {
1822  daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
1823 
1824  /* Send Update to all contexts using the default trace status */
1825  dlt_daemon_user_send_default_update(daemon, verbose);
1826 
1827  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1828  }
1829  else
1830  {
1831  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1832  }
1833 }
1834 
1835 void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1836 {
1837  PRINT_FUNCTION_VERBOSE(verbose);
1838 
1839  DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
1841 
1842  if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1843  {
1844  return;
1845  }
1846 
1847  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceSetVerboseMode)) < 0)
1848  {
1849  return;
1850  }
1851 
1852  req = (DltServiceSetVerboseMode*) (msg->databuffer);
1853  if ((req->new_status==0) || (req->new_status==1))
1854  {
1855  daemon->timingpackets = req->new_status;
1856 
1857  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1858  }
1859  else
1860  {
1861  dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1862  }
1863 }
1864 
1865 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1866 {
1867  int ret;
1868  DltMessage msg;
1869  int32_t len;
1870 
1871  PRINT_FUNCTION_VERBOSE(verbose);
1872 
1873  if (daemon==0)
1874  {
1875  return;
1876  }
1877 
1878  /* initialise new message */
1879  if (dlt_message_init(&msg,0) == DLT_RETURN_ERROR)
1880  {
1881  return;
1882  }
1883 
1884  /* send message */
1885 
1886  /* prepare storage header */
1887  msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
1889 
1890  /* prepare standard header */
1891  msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
1893 
1894 #if (BYTE_ORDER==BIG_ENDIAN)
1895  msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
1896 #endif
1897 
1898  msg.standardheader->mcnt = 0;
1899 
1900  /* Set header extra parameters */
1901  dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
1902  msg.headerextra.tmsp = dlt_uptime();
1903 
1904  dlt_message_set_extraparameters(&msg, verbose);
1905 
1906  /* prepare extended header */
1907  msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
1909 
1910  msg.extendedheader->noar = 0; /* number of arguments */
1911  dlt_set_id(msg.extendedheader->apid,""); /* application id */
1912  dlt_set_id(msg.extendedheader->ctid,""); /* context id */
1913 
1914  /* prepare length information */
1915  msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
1916 
1917  len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
1918  if (len>UINT16_MAX)
1919  {
1920  dlt_log(LOG_WARNING,"Huge control message discarded!\n");
1921 
1922  /* free message */
1923  dlt_message_free(&msg,0);
1924 
1925  return;
1926  }
1927 
1928  msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
1929 
1930  /* Send message */
1931  if((ret = dlt_daemon_client_send(sock,daemon,daemon_local,msg.headerbuffer,sizeof(DltStorageHeader),msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),
1932  msg.databuffer,msg.datasize,verbose)))
1933  {
1934 
1935  }
1936 
1937  /* free message */
1938  dlt_message_free(&msg,0);
1939 }
1940 
1942  DltDaemonLocal *daemon_local,
1943  DltReceiver *receiver,
1944  int verbose)
1945 {
1946  uint64_t expir = 0;
1947  ssize_t res = 0;
1948  char local_str[DLT_DAEMON_TEXTBUFSIZE];
1949 
1950  PRINT_FUNCTION_VERBOSE(verbose);
1951 
1952  if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
1953  {
1954  snprintf(local_str,
1956  "%s: invalid parameters",
1957  __func__);
1958  dlt_log(LOG_ERR, local_str);
1959  return -1;
1960  }
1961 
1962  res = read(receiver->fd, &expir, sizeof(expir));
1963 
1964  if(res < 0)
1965  {
1966  snprintf(local_str,
1968  "%s: Fail to read timer (%s)\n", __func__, strerror(errno));
1969  dlt_log(LOG_WARNING, str);
1970  /* Activity received on timer_wd, but unable to read the fd:
1971  let's go on sending notification */
1972  }
1973 
1974  if((daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
1975  (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))
1976  {
1978  daemon_local,
1979  daemon_local->flags.vflag))
1980  {
1981  dlt_log(LOG_DEBUG,
1982  "Can't send contents of ring buffer to clients\n");
1983  }
1984  }
1985 
1986  if((daemon->timingpackets) &&
1987  (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
1988  {
1990  daemon,
1991  daemon_local,
1992  daemon_local->flags.vflag);
1993  }
1994 
1995  dlt_log(LOG_DEBUG, "Timer timingpacket\n");
1996 
1997  return 0;
1998 }
1999 
2001  DltDaemonLocal *daemon_local,
2002  DltReceiver *receiver,
2003  int verbose)
2004 {
2005  uint64_t expir = 0;
2006  ssize_t res = 0;
2007  char local_str[DLT_DAEMON_TEXTBUFSIZE];
2008 
2009  PRINT_FUNCTION_VERBOSE(verbose);
2010 
2011  if((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
2012  {
2013  snprintf(str,
2015  "%s: invalid parameters",
2016  __func__);
2017  dlt_log(LOG_ERR, str);
2018  return -1;
2019  }
2020 
2021  res = read(receiver->fd, &expir, sizeof(expir));
2022 
2023  if(res < 0)
2024  {
2025  snprintf(local_str,
2027  "%s: Fail to read timer (%s)\n", __func__, strerror(errno));
2028  dlt_log(LOG_WARNING, str);
2029  /* Activity received on timer_wd, but unable to read the fd:
2030  let's go on sending notification */
2031  }
2032 
2033  if(daemon_local->flags.sendECUSoftwareVersion > 0)
2034  {
2036  daemon,
2037  daemon_local,
2038  daemon_local->flags.vflag);
2039  }
2040 
2041  if(daemon_local->flags.sendTimezone > 0)
2042  {
2043  // send timezone information
2044  time_t t = time(NULL);
2045  struct tm lt;
2046 
2047  /*Added memset to avoid compiler warning for near initialization */
2048  memset((void*)&lt, 0, sizeof(lt));
2049  localtime_r(&t, &lt);
2050 
2052  daemon,
2053  daemon_local,
2054  daemon_local->flags.vflag);
2055  }
2056 
2057  dlt_log(LOG_DEBUG, "Timer ecuversion\n");
2058 
2059  return 0;
2060 }
2061 
2062 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2064  DltDaemonLocal *daemon_local,
2065  DltReceiver *receiver,
2066  int verbose)
2067 {
2068  uint64_t expir = 0;
2069  ssize_t res = -1;
2070  char local_str[DLT_DAEMON_TEXTBUFSIZE];
2071 
2072  PRINT_FUNCTION_VERBOSE(verbose);
2073 
2074  if((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
2075  {
2076  snprintf(local_str,
2078  "%s: invalid parameters",
2079  __func__);
2080  dlt_log(LOG_ERR, local_str);
2081  return res;
2082  }
2083 
2084  res = read(receiver->fd, &expir, sizeof(expir));
2085 
2086  if(res < 0)
2087  {
2088  snprintf(local_str,
2090  "Failed to read timer_wd; %s\n",
2091  strerror(errno));
2092  dlt_log(LOG_WARNING, local_str);
2093  /* Activity received on timer_wd, but unable to read the fd:
2094  let's go on sending notification */
2095  }
2096 
2097  if(sd_notify(0, "WATCHDOG=1") < 0)
2098  {
2099  dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
2100  }
2101 
2102  dlt_log(LOG_DEBUG, "Timer watchdog\n");
2103 
2104  return 0;
2105 }
2106 #else
2108  DltDaemonLocal *daemon_local,
2109  DltReceiver *receiver,
2110  int verbose)
2111 {
2112  (void)daemon;
2113  (void)daemon_local;
2114  (void)receiver;
2115  (void)verbose;
2116 
2117  dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n");
2118 
2119  return -1;
2120 }
2121 #endif
2122 
2123 void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
2124 {
2125  DltServiceOfflineLogstorage *req;
2126  int ret;
2127 
2128  PRINT_FUNCTION_VERBOSE(verbose);
2129 
2130  if ((daemon == NULL) || (msg == NULL) || (daemon_local == NULL) || (msg->databuffer == NULL))
2131  {
2132  dlt_log(LOG_ERR, "Invalid function parameters used for dlt_daemon_control_service_logstorage\n");
2133  return ;
2134  }
2135 
2136  if(daemon_local->flags.offlineLogstorageMaxDevices <= 0)
2137  {
2139  dlt_log(LOG_INFO, "Offline logstorage functionality not enabled or MAX device set is 0\n");
2140  return;
2141  }
2142 
2143  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServiceOfflineLogstorage)) < 0)
2144  {
2145  return;
2146  }
2147 
2148  req = (DltServiceOfflineLogstorage*) (msg->databuffer);
2149  int device_index=-1;
2150  int i=0;
2151  for(i=0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++)
2152  {
2153  /* Check if the requested device path is already used as log storage device */
2154  if(strcmp(daemon->storage_handle[i].device_mount_point,
2155  req->mount_point) == 0)
2156  {
2157  device_index = i;
2158  break;
2159  }
2160  /* Get first available device index here */
2161  if((daemon->storage_handle[i].connection_type !=
2163  (device_index == -1))
2164  {
2165  device_index = i;
2166  }
2167  }
2168 
2169  if((device_index) == -1)
2170  {
2172  daemon,
2173  daemon_local,
2176  verbose);
2177  dlt_log(LOG_WARNING, "MAX devices already in use \n");
2178  return;
2179  }
2180 
2181 
2182  /* Check for device connection request from log storage ctrl app */
2183  if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
2184  {
2185  ret = dlt_logstorage_device_connected(&(daemon->storage_handle[device_index]), req->mount_point);
2186  if(ret != 0)
2187  {
2189  return;
2190  }
2191 
2192  /* Setup logstorage with config file settings */
2193  ret = dlt_logstorage_load_config(&(daemon->storage_handle[device_index]));
2194  if(ret != 0)
2195  {
2197  return;
2198  }
2199 
2201 
2202  /* Check if log level of running application needs an update */
2203  dlt_daemon_logstorage_update_application_loglevel(daemon, device_index, verbose);
2204 
2205  }
2206  /* Check for device disconnection request from log storage ctrl app */
2207  else if(req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED)
2208  {
2209  /* Check if log level of running application needs to be reset */
2210  dlt_daemon_logstorage_reset_application_loglevel(daemon, device_index, daemon_local->flags.offlineLogstorageMaxDevices, verbose);
2211 
2212  dlt_logstorage_device_disconnected(&(daemon->storage_handle[device_index]),
2214 
2216  }
2217  /* Check for cache synchronization request from log storage ctrl app */
2218  else if(req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES)
2219  {
2220  /* trigger logstorage to sync caches */
2222  daemon_local,
2223  req->mount_point,
2224  verbose) == 0)
2225  {
2227  daemon,
2228  daemon_local,
2231  verbose);
2232  }
2233  else
2234  {
2236  daemon,
2237  daemon_local,
2240  verbose);
2241  }
2242  }
2243  else
2244  {
2246  }
2247 }
2248 
2250  DltDaemon *daemon,
2251  DltDaemonLocal *daemon_local,
2252  DltMessage *msg,
2253  int verbose)
2254 {
2255  PRINT_FUNCTION_VERBOSE(verbose);
2256 
2257  DltServicePassiveNodeConnect *req;
2259 
2260  if (daemon == NULL || daemon_local == NULL || msg == NULL ||
2261  msg->databuffer == NULL)
2262  {
2263  return;
2264  }
2265 
2266  /* return error, if gateway mode not enabled*/
2267  if (daemon_local->flags.gatewayMode == 0)
2268  {
2269  dlt_log(LOG_WARNING,
2270  "Received passive node connection status request, "
2271  "but GatewayMode is disabled\n");
2272 
2274  sock,
2275  daemon,
2276  daemon_local,
2279  verbose);
2280 
2281  return;
2282  }
2283 
2284  if (DLT_CHECK_RCV_DATA_SIZE(msg->datasize, sizeof(DltServicePassiveNodeConnect)) < 0)
2285  {
2286  return;
2287  }
2288 
2289  req = (DltServicePassiveNodeConnect *) msg->databuffer;
2290 
2292  daemon_local,
2293  req->node_id,
2294  req->connection_status,
2295  verbose) < 0)
2296  {
2298  daemon,
2299  daemon_local,
2300  id,
2302  verbose);
2303  }
2304  else
2305  {
2307  daemon,
2308  daemon_local,
2309  id,
2311  verbose);
2312  }
2313 }
2314 
2316  DltDaemon *daemon,
2317  DltDaemonLocal *daemon_local,
2318  int verbose)
2319 {
2320  DltMessage msg;
2321  DltServicePassiveNodeConnectionInfo *resp;
2322  DltGatewayConnection *con = NULL;
2323  unsigned int i = 0;
2324 
2325  PRINT_FUNCTION_VERBOSE(verbose);
2326 
2327  if (daemon == NULL || daemon_local == NULL)
2328  {
2329  return;
2330  }
2331 
2332  if (dlt_message_init(&msg, verbose) == -1)
2333  {
2334  return;
2335  }
2336 
2337  /* return error, if gateway mode not enabled*/
2338  if (daemon_local->flags.gatewayMode == 0)
2339  {
2340  dlt_log(LOG_WARNING,
2341  "Received passive node connection status request, "
2342  "but GatewayMode is disabled\n");
2343 
2345  sock,
2346  daemon,
2347  daemon_local,
2350  verbose);
2351 
2352  return;
2353  }
2354 
2355  /* prepare payload of data */
2356  msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo);
2357  if (msg.databuffer && (msg.databuffersize < msg.datasize))
2358  {
2359  msg.databuffer = NULL;
2360  }
2361  if (msg.databuffer == NULL)
2362  {
2363  msg.databuffer = (uint8_t *) malloc(msg.datasize);
2364  if (msg.databuffer == NULL)
2365  {
2366  dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n");
2367  return;
2368  }
2369  msg.databuffersize = msg.datasize;
2370  }
2371 
2372  resp = (DltServicePassiveNodeConnectionInfo *) msg.databuffer;
2373  memset(resp, 0, msg.datasize);
2375  resp->status = DLT_SERVICE_RESPONSE_OK;
2376  resp->num_connections = daemon_local->pGateway.num_connections;
2377 
2378  for (i = 0; i < resp->num_connections; i++)
2379  {
2380  if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX)
2381  {
2382  dlt_log(LOG_ERR,
2383  "Maximal message size reached. Skip further information\n");
2384  break;
2385  }
2386 
2387  con = &daemon_local->pGateway.connections[i];
2388  if (con == NULL)
2389  {
2390  dlt_log(LOG_CRIT, "Passive node connection structure is NULL\n");
2392  sock,
2393  daemon,
2394  daemon_local,
2397  verbose);
2398 
2399  /* free message */
2400  dlt_message_free(&msg, verbose);
2401 
2402  return;
2403  }
2404 
2405  resp->connection_status[i] = con->status;
2406  memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE);
2407  }
2408 
2410  daemon,
2411  daemon_local,
2412  &msg,
2413  "",
2414  "",
2415  verbose);
2416  /* free message */
2417  dlt_message_free(&msg, verbose);
2418 }
int32_t datasize
Definition: dlt_common.h:423
void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_SERVICE_ID_CALLSW_CINJECTION
Definition: dlt_protocol.h:205
char runtime_application_cfg[PATH_MAX+1]
#define DLT_HTYP_UEH
Definition: dlt_protocol.h:82
#define PRINT_FUNCTION_VERBOSE(_verbose)
Definition: dlt_common.h:220
#define DLT_ENDIAN_GET_32(htyp, x)
Definition: dlt_common.h:165
void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_DAEMON_ERROR_BUFFER_FULL
Definition: dlt-daemon.h:172
int dlt_logstorage_load_config(DltLogStorage *handle)
#define DLT_ID_SIZE
Definition: dlt_common.h:204
char * ECUVersionString
struct DltConnection * next
#define DLT_HTOBE_16(x)
Definition: dlt_common.h:148
#define DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL
Definition: dlt_protocol.h:192
DltStorageHeader * storageheader
Definition: dlt_common.h:432
void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
int client_connections
Definition: dlt-daemon.h:143
DltReturnValue
Definition: dlt_types.h:86
#define DLT_MSIN_CONTROL_RESPONSE
Definition: dlt_protocol.h:142
void dlt_daemon_user_send_all_update(DltDaemon *daemon, int8_t log_level, int verbose)
int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
#define DLT_DAEMON_SEM_LOCK()
#define DLT_HTYP_PROTOCOL_VERSION1
Definition: dlt_protocol.h:95
void dlt_daemon_control_passive_node_connect(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
void dlt_set_id(char *id, const char *text)
Definition: dlt_common.c:324
void dlt_daemon_find_multiple_context_and_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int8_t app_flag, char *str, int8_t len, int8_t loglevel, int verbose)
DltDaemonApplication * applications
#define DLT_USER_MESSAGE_INJECTION
#define DLT_HTYP_WEID
Definition: dlt_protocol.h:84
int contextTraceStatus
Definition: dlt-daemon.h:130
#define DLT_SERVICE_ID_USE_SESSION_ID
Definition: dlt_protocol.h:189
#define DLT_SERVICE_ID_GET_LOCAL_TIME
Definition: dlt_protocol.h:187
unsigned int connection_type
#define DLT_SERVICE_ID_SET_TRACE_STATUS
Definition: dlt_protocol.h:177
int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt-daemon.c:3061
DltLogStorage * storage_handle
#define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp)
Definition: dlt_common.h:213
void dlt_daemon_control_service_response(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint32_t service_id, int8_t status, int verbose)
#define DLT_CHECK_RCV_DATA_SIZE(received, required)
DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3)
int dlt_gateway_process_on_demand_request(DltGateway *gateway, DltDaemonLocal *daemon_local, char *node_id, int connection_status, int verbose)
Definition: dlt_gateway.c:1034
int dlt_logstorage_device_disconnected(DltLogStorage *handle, int reason)
#define DLT_SERVICE_ID_SET_LOG_LEVEL
Definition: dlt_protocol.h:176
#define DLT_SERVICE_ID_GET_LOG_INFO
Definition: dlt_protocol.h:178
#define DLT_SERVICE_ID_OFFLINE_LOGSTORAGE
Definition: dlt_protocol.h:201
#define DLT_DAEMON_ERROR_OK
Definition: dlt-daemon.h:170
#define DLT_MSG_READ_VALUE(dst, src, length, type)
Definition: dlt_common.h:278
DltReturnValue dlt_log(int prio, char *s)
Definition: dlt_common.c:2029
char evalue[NAME_MAX+1]
Definition: dlt-daemon.h:98
int8_t default_trace_status
int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
#define DLT_DAEMON_ERROR_UNKNOWN
Definition: dlt-daemon.h:171
#define DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH
Definition: dlt_protocol.h:183
#define DLT_SERVICE_ID_USE_EXTENDED_HEADER
Definition: dlt_protocol.h:191
#define DLT_SERVICE_ID_MARKER
Definition: dlt_protocol.h:200
#define DLT_MSIN_CONTROL_TIME
Definition: dlt_protocol.h:143
DltBuffer client_ringbuffer
int sendECUSoftwareVersion
Definition: dlt-daemon.h:112
#define DLT_SERVICE_ID_STORE_CONFIG
Definition: dlt_protocol.h:180
#define DLT_DAEMON_REMO_STRING
DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
Definition: dlt_common.c:666
#define DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS
Definition: dlt_protocol.h:193
#define DLT_HTYP_MSBF
Definition: dlt_protocol.h:83
void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon, int dev_num, int max_device, int verbose)
DltExtendedHeader * extendedheader
Definition: dlt_common.h:435
void dlt_daemon_logstorage_write(DltDaemon *daemon, DltDaemonFlags *user_config, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3)
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)
#define DLT_DAEMON_CTRL_CTID
#define DLT_CON_MASK_CLIENT_MSG_SERIAL
char runtime_context_cfg[PATH_MAX+1]
#define DLT_SERVICE_RESPONSE_NOT_SUPPORTED
Definition: dlt_protocol.h:211
DltEventHandler pEvent
Definition: dlt-daemon.h:140
DltOfflineTrace offlineTrace
Definition: dlt-daemon.h:148
char offlineTraceDirectory[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:105
void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
DltDaemonContext * contexts
#define DLT_SERVICE_ID_UNREGISTER_CONTEXT
Definition: dlt_protocol.h:197
void dlt_daemon_send_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context, int8_t loglevel, int verbose)
static char * service_id[]
Definition: dlt_common.c:85
int dlt_daemon_process_one_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
Definition: dlt_common.c:1273
char ctid[DLT_ID_SIZE]
DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
Definition: dlt_common.c:2315
int32_t databuffersize
Definition: dlt_common.h:429
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
#define DLT_SERVICE_RESPONSE_ERROR
Definition: dlt_protocol.h:212
#define DLT_SERVICE_ID_USE_ECU_ID
Definition: dlt_protocol.h:188
#define DLT_DAEMON_ERROR_SEND_FAILED
Definition: dlt-daemon.h:173
#define DLT_DAEMON_SEM_FREE()
void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES
void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon, const char *filename, const char *filename1, int InitialContextLogLevel, int InitialContextTraceStatus, int InitialEnforceLlTsStatus, int verbose)
int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose)
#define DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED
#define DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED
#define DLT_HTYP_WTMS
Definition: dlt_protocol.h:86
void dlt_daemon_control_passive_node_connect_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
#define DLT_SERVICE_ID_SET_VERBOSE_MODE
Definition: dlt_protocol.h:184
uint32_t dlt_uptime(void)
Definition: dlt_common.c:3274
int dlt_daemon_client_send_control_message(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, char *appid, char *ctid, int verbose)
char ID4[DLT_ID_SIZE]
Definition: dlt_common.h:365
#define DLT_SERVICE_ID_USE_TIMESTAMP
Definition: dlt_protocol.h:190
DltGatewayConnection * connections
#define DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT
Definition: dlt_protocol.h:181
static int dlt_daemon_client_send_all_multiple(DltDaemon *daemon, DltDaemonLocal *daemon_local, void *data1, int size1, void *data2, int size2, int verbose)
Sends up to 2 messages to all the clients.
int dlt_daemon_client_send_all(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
Send out message to all the clients.
int dlt_gateway_forward_control_message(DltGateway *gateway, DltDaemonLocal *daemon_local, DltMessage *msg, char *ecu, int verbose)
Definition: dlt_gateway.c:957
int8_t default_log_level
int32_t headersize
Definition: dlt_common.h:422
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)
#define DLT_ENTRY_MAX
Definition: dlt_common.h:337
DltReturnValue dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype)
void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_FD_MINIMUM
Definition: dlt_common.h:199
uint8_t headerbuffer[sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]
Definition: dlt_common.h:427
int dlt_daemon_socket_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader)
int enforceContextLLAndTS
Definition: dlt-daemon.h:131
char apid[DLT_ID_SIZE]
DltDaemonApplication * dlt_daemon_application_find(DltDaemon *daemon, char *apid, int verbose)
#define DLT_DAEMON_INJECTION_MIN
#define DLT_SERVICE_ID_TIMEZONE
Definition: dlt_protocol.h:199
#define DLT_DAEMON_SEND_TO_ALL
DltStandardHeaderExtra headerextra
Definition: dlt_common.h:434
DltConnection * dlt_connection_get_next(DltConnection *current, int type_mask)
Get the next connection filtered with a type mask.
int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
#define DLT_DAEMON_CTRL_APID
connection_status status
#define DLT_DAEMON_INJECTION_MAX
unsigned int overflow_counter
char apid[DLT_ID_SIZE]
int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char *comid, int verbose)
void dlt_print_id(char *text, const char *id)
Definition: dlt_common.c:301
DltDaemonState state
char device_mount_point[DLT_MOUNT_PATH_MAX]
#define DLT_SERVICE_ID_PASSIVE_NODE_CONNECT
Definition: dlt_protocol.h:202
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
DltGateway pGateway
Definition: dlt-daemon.h:141
int offlineLogstorageMaxDevices
Definition: dlt-daemon.h:115
int dlt_connection_send_multiple(DltConnection *con, void *data1, int size1, void *data2, int size2, int sendserialheader)
Send up to two messages through a connection.
#define DLT_SERVICE_ID_SET_ALL_LOG_LEVEL
Definition: dlt_protocol.h:204
#define DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT
int dlt_buffer_push3(DltBuffer *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3)
Definition: dlt_common.c:2691
#define DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL
Definition: dlt_protocol.h:179
#define DLT_MESSAGE_BUFFER_OVERFLOW
Definition: dlt_common.h:265
int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
#define DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS
Definition: dlt_protocol.h:203
void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS
Definition: dlt_protocol.h:182
int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
#define DLT_FD_INIT
Definition: dlt_common.h:196
uint8_t * databuffer
Definition: dlt_common.h:428
void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon, int dev_num, int verbose)
void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
int dlt_logstorage_device_connected(DltLogStorage *handle, char *mount_point)
#define DLT_SERVICE_ID_SET_MESSAGE_FILTERING
Definition: dlt_protocol.h:185
#define DLT_SERVICE_ID_SET_TIMING_PACKETS
Definition: dlt_protocol.h:186
char ecuid[DLT_ID_SIZE]
static char str[DLT_DAEMON_TEXTBUFSIZE]
DltConnectionType type
#define DLT_DAEMON_TEXTBUFSIZE
DltMessage msg
Definition: dlt-daemon.h:142
#define DLT_SERVICE_ID_GET_SOFTWARE_VERSION
Definition: dlt_protocol.h:194
#define DLT_SERVICE_RESPONSE_OK
Definition: dlt_protocol.h:210
DltUserLogMode mode
#define DLT_SERVICE_ID_CONNECTION_INFO
Definition: dlt_protocol.h:198
int dlt_daemon_logstorage_sync_cache(DltDaemon *daemon, DltDaemonLocal *daemon_local, char *mnt_point, int verbose)
#define DLT_CON_MASK_CLIENT_MSG_TCP
#define DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW
Definition: dlt_protocol.h:195
void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, unsigned int overflow_counter, char *apid, int verbose)
DltDaemonContext * dlt_daemon_context_find(DltDaemon *daemon, char *apid, char *ctid, int verbose)
#define DLT_DAEMON_SEND_FORCE
#define NULL
Definition: dlt_common.h:232
int dlt_daemon_serial_send(int sock, void *data1, int size1, void *data2, int size2, char serialheader)
void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)