Updated authors information.
[profile/ivi/dlt-daemon.git] / src / daemon / dlt_daemon_client.c
1 /**
2  * @licence app begin@
3  * Copyright (C) 2012-2014  BMW AG
4  *
5  * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
6  *
7  * Contributions are licensed to the GENIVI Alliance under one or more
8  * Contribution License Agreements.
9  *
10  * \copyright
11  * This Source Code Form is subject to the terms of the
12  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
13  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
14  *
15  * \author
16  * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
17  * Markus Klein <Markus.Klein@esk.fraunhofer.de>
18  * Mikko Rapeli <mikko.rapeli@bmw.de>
19  *
20  * \file dlt_daemon_client.c
21  * For further information see http://www.genivi.org/.
22  * @licence end@
23  */
24
25 #include <netdb.h>
26 #include <ctype.h>
27 #include <stdio.h>      /* for printf() and fprintf() */
28 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
29 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
30 #include <stdlib.h>     /* for atoi() and exit() */
31 #include <string.h>     /* for memset() */
32 #include <unistd.h>     /* for close() */
33 #include <fcntl.h>
34 #include <signal.h>
35 #include <syslog.h>
36 #include <errno.h>
37 #include <pthread.h>
38
39 #ifdef linux
40 #include <sys/timerfd.h>
41 #endif
42 #include <sys/stat.h>
43 #include <sys/time.h>
44 #ifdef linux
45 #include <linux/stat.h>
46 #endif
47
48 #include "dlt_types.h"
49 #include "dlt-daemon.h"
50 #include "dlt-daemon_cfg.h"
51 #include "dlt_daemon_common_cfg.h"
52
53 #include "dlt_daemon_socket.h"
54 #include "dlt_daemon_serial.h"
55
56 #include "dlt_daemon_client.h"
57
58 /** Global text output buffer, mainly used for creation of error/warning strings */
59 static char str[DLT_DAEMON_TEXTBUFSIZE];
60
61 int dlt_daemon_client_send(int sock,DltDaemon *daemon,DltDaemonLocal *daemon_local,void* data1,int size1,void* data2,int size2,int verbose)
62 {
63         int ret;
64         int j;
65
66     if (sock!=DLT_DAEMON_SEND_TO_ALL && sock!=DLT_DAEMON_SEND_FORCE)
67     {
68         /* Send message to specific socket */
69         if (isatty(sock))
70         {
71             DLT_DAEMON_SEM_LOCK();
72
73             if((ret=dlt_daemon_serial_send(sock,data1,size1,data2,size2,daemon->sendserialheader)))
74             {
75                 DLT_DAEMON_SEM_FREE();
76                 dlt_log(LOG_WARNING,"dlt_daemon_client_send: serial send dlt message failed\n");
77                 return ret;
78            }
79
80             DLT_DAEMON_SEM_FREE();
81         }
82         else
83         {
84             DLT_DAEMON_SEM_LOCK();
85
86             if((ret=dlt_daemon_socket_send(sock,data1,size1,data2,size2,daemon->sendserialheader)))
87             {
88                 DLT_DAEMON_SEM_FREE();
89                 dlt_log(LOG_WARNING,"dlt_daemon_client_send: socket send dlt message failed\n");
90                 return ret;
91             }
92
93             DLT_DAEMON_SEM_FREE();
94         }
95         return DLT_DAEMON_ERROR_OK;
96     }
97
98         /* write message to offline trace */
99         if ((sock!=DLT_DAEMON_SEND_FORCE) && (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
100         {
101                 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
102                                                         && daemon_local->flags.offlineTraceDirectory[0])
103                 {
104                         if(dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
105                                                                         daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0))
106                         {
107                                 static int error_dlt_offline_trace_write_failed = 0;
108                 if(!error_dlt_offline_trace_write_failed)
109                 {
110                         dlt_log(LOG_ERR,"dlt_daemon_client_send: dlt_offline_trace_write failed!\n");
111                         error_dlt_offline_trace_write_failed = 1;
112                 }
113                                 //return DLT_DAEMON_ERROR_WRITE_FAILED;
114                         }
115                 }
116         }
117
118         /* send messages to daemon socket */
119         if((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
120         {
121                 if ((sock==DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
122                 {
123                         int sent = 0;
124                         /* look if TCP connection to client is available */
125                         for (j = 0; j <= daemon_local->fdmax; j++)
126                         {
127                                 /* send to everyone! */
128                                 if (FD_ISSET(j, &(daemon_local->master)))
129                                 {
130                                         if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != daemon_local->sock)
131                 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
132                                                                 && (j!=daemon_local->timer_wd)
133                 #endif
134                                         && (j!=daemon_local->timer_one_s) && (j!=daemon_local->timer_sixty_s))
135                                         {
136                                                 /* Send message */
137                                                 if (isatty(j))
138                                                 {
139                                                         DLT_DAEMON_SEM_LOCK();
140
141                                                         if((ret=dlt_daemon_serial_send(j,data1,size1,data2,size2,daemon->sendserialheader)))
142                                                         {
143                                                                 DLT_DAEMON_SEM_FREE();
144                                                                 dlt_log(LOG_WARNING,"dlt_daemon_client_send: serial send dlt message failed\n");
145                                                                 return ret;
146                                                         }
147
148                                                         DLT_DAEMON_SEM_FREE();
149                                                 }
150                                                 else
151                                                 {
152                                                         DLT_DAEMON_SEM_LOCK();
153
154                                                         if((ret=dlt_daemon_socket_send(j,data1,size1,data2,size2,daemon->sendserialheader)))
155                                                         {
156                                                                 DLT_DAEMON_SEM_FREE();
157                                                                 dlt_log(LOG_WARNING,"dlt_daemon_client_send: socket send dlt message failed\n");
158                                                                 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
159                                                                 return ret;
160                                                         }
161
162                                                         DLT_DAEMON_SEM_FREE();
163                                                 }
164                                                 sent=1;
165
166                                         }
167                                 }
168                         }
169                         if((sock==DLT_DAEMON_SEND_FORCE) && !sent)
170                         {
171                                 return DLT_DAEMON_ERROR_SEND_FAILED;
172                         }
173                 }
174         }
175
176     /* Message was not sent to client, so store it in client ringbuffer */
177     if ((sock!=DLT_DAEMON_SEND_FORCE) && (daemon->state == DLT_DAEMON_STATE_BUFFER || daemon->state == DLT_DAEMON_STATE_SEND_BUFFER || daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))
178     {
179         if(daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)
180                 return DLT_DAEMON_ERROR_BUFFER_FULL;
181
182         DLT_DAEMON_SEM_LOCK();
183         /* Store message in history buffer */
184         if (dlt_buffer_push3(&(daemon->client_ringbuffer),data1,size1,data2,size2,0, 0)<0)
185                 {
186                 DLT_DAEMON_SEM_FREE();
187                         dlt_log(LOG_DEBUG,"dlt_daemon_client_send: Buffer is full! Message discarded.\n");
188                         dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_BUFFER_FULL);
189                         return DLT_DAEMON_ERROR_BUFFER_FULL;
190                 }
191         DLT_DAEMON_SEM_FREE();
192     }
193
194     return DLT_DAEMON_ERROR_OK;
195
196 }
197
198 int dlt_daemon_client_send_control_message( int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, char* appid, char* ctid, int verbose)
199 {
200         int ret;
201     int32_t len;
202
203     PRINT_FUNCTION_VERBOSE(verbose);
204
205     if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
206     {
207         return DLT_DAEMON_ERROR_UNKNOWN;
208     }
209
210     /* prepare storage header */
211     msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
212
213     if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1)
214     {
215                 return DLT_DAEMON_ERROR_UNKNOWN;
216     }
217
218     /* prepare standard header */
219     msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
220     msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
221
222 #if (BYTE_ORDER==BIG_ENDIAN)
223     msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
224 #endif
225
226     msg->standardheader->mcnt = 0;
227
228     /* Set header extra parameters */
229     dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
230
231     //msg->headerextra.seid = 0;
232
233     msg->headerextra.tmsp = dlt_uptime();
234
235     dlt_message_set_extraparameters(msg, verbose);
236
237     /* prepare extended header */
238     msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
239     msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
240
241     msg->extendedheader->noar = 1; /* number of arguments */
242     if (strcmp(appid,"")==0)
243     {
244         dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID);       /* application id */
245     }
246     else
247     {
248         dlt_set_id(msg->extendedheader->apid, appid);
249     }
250     if (strcmp(ctid,"")==0)
251     {
252         dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID);       /* context id */
253     }
254     else
255     {
256         dlt_set_id(msg->extendedheader->ctid, ctid);
257     }
258
259     /* prepare length information */
260     msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
261
262     len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
263     if (len>UINT16_MAX)
264     {
265         dlt_log(LOG_CRIT,"Huge control message discarded!\n");
266         return DLT_DAEMON_ERROR_UNKNOWN;
267     }
268
269     msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
270
271         if((ret=dlt_daemon_client_send(sock,daemon,daemon_local,msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
272                                                 msg->databuffer,msg->datasize,verbose)))
273         {
274                 dlt_log(LOG_DEBUG,"dlt_daemon_control_send_control_message: DLT message send to all failed!.\n");
275                 return ret;
276         }
277
278     return DLT_DAEMON_ERROR_OK;
279 }
280
281 int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
282 {
283     uint32_t id,id_tmp=0;
284
285     PRINT_FUNCTION_VERBOSE(verbose);
286
287     if ((daemon==0) || (msg==0))
288     {
289         return -1;
290     }
291
292     if (msg->datasize < (int32_t)sizeof(uint32_t))
293     {
294         return -1;
295     }
296
297     id_tmp = *((uint32_t*)(msg->databuffer));
298     id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
299
300     if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW))
301     {
302         /* Control message handling */
303         switch (id)
304         {
305         case DLT_SERVICE_ID_SET_LOG_LEVEL:
306         {
307             dlt_daemon_control_set_log_level(sock, daemon, daemon_local, msg,  verbose);
308             break;
309         }
310         case DLT_SERVICE_ID_SET_TRACE_STATUS:
311         {
312             dlt_daemon_control_set_trace_status(sock, daemon, daemon_local, msg,  verbose);
313             break;
314         }
315         case DLT_SERVICE_ID_GET_LOG_INFO:
316         {
317             dlt_daemon_control_get_log_info(sock, daemon, daemon_local, msg, verbose);
318             break;
319         }
320         case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
321         {
322             dlt_daemon_control_get_default_log_level(sock, daemon, daemon_local, verbose);
323             break;
324         }
325         case DLT_SERVICE_ID_STORE_CONFIG:
326         {
327             if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose)==0)
328             {
329                                 if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose)==0)
330                                 {
331                                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
332                                 }
333                                 else
334                                 {
335                                         /* Delete saved files */
336                                         dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
337                                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
338                                 }
339             }
340             else
341             {
342                 dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
343             }
344             break;
345         }
346         case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
347         {
348             dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
349             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
350             break;
351         }
352         case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
353         {
354             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
355             break;
356         }
357         case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
358         {
359             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
360             break;
361         }
362         case DLT_SERVICE_ID_SET_VERBOSE_MODE:
363         {
364             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
365             break;
366         }
367         case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
368         {
369             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
370             break;
371         }
372         case DLT_SERVICE_ID_SET_TIMING_PACKETS:
373         {
374             dlt_daemon_control_set_timing_packets(sock, daemon, daemon_local, msg,  verbose);
375             break;
376         }
377         case DLT_SERVICE_ID_GET_LOCAL_TIME:
378         {
379             /* Send response with valid timestamp (TMSP) field */
380             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
381             break;
382         }
383         case DLT_SERVICE_ID_USE_ECU_ID:
384         {
385             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
386             break;
387         }
388         case DLT_SERVICE_ID_USE_SESSION_ID:
389         {
390             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
391             break;
392         }
393         case DLT_SERVICE_ID_USE_TIMESTAMP:
394         {
395             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
396             break;
397         }
398         case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
399         {
400             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
401             break;
402         }
403         case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
404         {
405             dlt_daemon_control_set_default_log_level(sock, daemon, daemon_local, msg,  verbose);
406             break;
407         }
408         case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
409         {
410             dlt_daemon_control_set_default_trace_status(sock, daemon, daemon_local, msg,  verbose);
411             break;
412         }
413         case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
414         {
415             dlt_daemon_control_get_software_version(sock, daemon, daemon_local,  verbose);
416             break;
417         }
418         case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
419         {
420             dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter,"",verbose);
421             break;
422         }
423         default:
424         {
425             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
426             break;
427         }
428         }
429     }
430     else
431     {
432         /* Injection handling */
433         dlt_daemon_control_callsw_cinjection(sock, daemon, daemon_local, msg,  verbose);
434     }
435
436     return 0;
437 }
438
439 void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
440 {
441     DltMessage msg;
442     uint32_t len;
443         DltServiceGetSoftwareVersionResponse *resp;
444
445     PRINT_FUNCTION_VERBOSE(verbose);
446
447     if (daemon==0)
448     {
449         return;
450     }
451
452     /* initialise new message */
453     if (dlt_message_init(&msg,0)==-1)
454     {
455         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR,  verbose);
456                 return;
457     }
458
459     /* prepare payload of data */
460     len = strlen(daemon->ECUVersionString);
461
462     msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
463     if (msg.databuffer && (msg.databuffersize < msg.datasize))
464     {
465         free(msg.databuffer);
466         msg.databuffer=0;
467     }
468     if (msg.databuffer == 0){
469         msg.databuffer = (uint8_t *) malloc(msg.datasize);
470         msg.databuffersize = msg.datasize;
471     }
472     if (msg.databuffer==0)
473     {
474         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR,  verbose);
475         return;
476     }
477
478     resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
479     resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
480     resp->status = DLT_SERVICE_RESPONSE_OK;
481     resp->length = len;
482     memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),daemon->ECUVersionString,len);
483
484     /* send message */
485     dlt_daemon_client_send_control_message(sock, daemon,daemon_local, &msg,"","",  verbose);
486
487     /* free message */
488     dlt_message_free(&msg,0);
489 }
490
491 void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
492 {
493     DltMessage msg;
494         DltServiceGetDefaultLogLevelResponse *resp;
495
496     PRINT_FUNCTION_VERBOSE(verbose);
497
498     if (daemon==0)
499     {
500         return;
501     }
502
503     /* initialise new message */
504     if (dlt_message_init(&msg,0)==-1)
505     {
506         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR,  verbose);
507         return;
508     }
509
510     msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
511     if (msg.databuffer && (msg.databuffersize<msg.datasize))
512     {
513         free(msg.databuffer);
514         msg.databuffer=0;
515     }
516     if (msg.databuffer == 0){
517         msg.databuffer = (uint8_t *) malloc(msg.datasize);
518         msg.databuffersize = msg.datasize;
519     }
520     if (msg.databuffer==0)
521     {
522         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR,  verbose);
523         return;
524     }
525
526     resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
527     resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
528     resp->status = DLT_SERVICE_RESPONSE_OK;
529     resp->log_level = daemon->default_log_level;
530
531     /* send message */
532     dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","",  verbose);
533
534     /* free message */
535     dlt_message_free(&msg,0);
536 }
537
538 void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
539 {
540     DltServiceGetLogInfoRequest *req;
541     DltMessage resp;
542     DltDaemonContext *context=0;
543     DltDaemonApplication *application=0;
544
545     int num_applications=0, num_contexts=0;
546     uint16_t count_app_ids=0, count_con_ids=0;
547
548 #if (DLT_DEBUG_GETLOGINFO==1)
549     char buf[255];
550 #endif
551
552     int32_t i,j,offset=0;
553     char *apid=0;
554     int8_t ll,ts;
555     uint16_t len;
556     int8_t value;
557     int32_t sizecont=0;
558     int offset_base;
559
560     uint32_t sid;
561
562     PRINT_FUNCTION_VERBOSE(verbose);
563
564     if ((daemon==0) || (msg==0))
565     {
566         return;
567     }
568
569     /* prepare pointer to message request */
570     req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
571
572     /* initialise new message */
573     if (dlt_message_init(&resp,0)==-1)
574     {
575                 dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
576         return;
577     }
578
579     /* check request */
580     if ((req->options < 3 ) || (req->options>7))
581     {
582         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
583         return;
584     }
585
586     if (req->apid[0]!='\0')
587     {
588         application = dlt_daemon_application_find(daemon, req->apid, verbose);
589         if (application)
590         {
591             num_applications = 1;
592             if (req->ctid[0]!='\0')
593             {
594                 context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
595
596                 num_contexts = ((context)?1:0);
597             }
598             else
599             {
600                 num_contexts = application->num_contexts;
601             }
602         }
603         else
604         {
605             num_applications = 0;
606             num_contexts = 0;
607         }
608     }
609     else
610     {
611         /* Request all applications and contexts */
612         num_applications = daemon->num_applications;
613         num_contexts = daemon->num_contexts;
614     }
615
616     /* prepare payload of data */
617
618     /* Calculate maximum size for a response */
619     resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
620
621     sizecont = sizeof(uint32_t) /* context_id */;
622
623     /* Add additional size for response of Mode 4, 6, 7 */
624     if ((req->options==4) || (req->options==6) || (req->options==7))
625     {
626         sizecont += sizeof(int8_t); /* log level */
627     }
628
629     /* Add additional size for response of Mode 5, 6, 7 */
630     if ((req->options==5) || (req->options==6) || (req->options==7))
631     {
632         sizecont+= sizeof(int8_t); /* trace status */
633     }
634
635     resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */  + sizeof(uint16_t) /* count_con_ids */)) +
636                     (num_contexts * sizecont);
637
638     resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
639
640     /* Add additional size for response of Mode 7 */
641     if (req->options==7)
642     {
643         if (req->apid[0]!='\0')
644         {
645             if (req->ctid[0]!='\0')
646             {
647                 /* One application, one context */
648                 // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
649                 if (context)
650                 {
651                     resp.datasize+=sizeof(uint16_t) /* len_context_description */;
652                     if (context->context_description!=0)
653                     {
654                         resp.datasize+=strlen(context->context_description); /* context_description */
655                     }
656                 }
657             }
658             else
659             {
660                 /* One application, all contexts */
661                 if ((daemon->applications) && (application))
662                 {
663                     /* Calculate start offset within contexts[] */
664                     offset_base=0;
665                     for (i=0; i<(application-(daemon->applications)); i++)
666                     {
667                         offset_base+=daemon->applications[i].num_contexts;
668                     }
669
670                     /* Iterate over all contexts belonging to this application */
671                     for (j=0;j<application->num_contexts;j++)
672                     {
673
674                         context = &(daemon->contexts[offset_base+j]);
675                         if (context)
676                         {
677                             resp.datasize+=sizeof(uint16_t) /* len_context_description */;
678                             if (context->context_description!=0)
679                             {
680                                 resp.datasize+=strlen(context->context_description); /* context_description */
681                             }
682                         }
683                     }
684                 }
685             }
686
687             /* Space for application description */
688             if (application)
689             {
690                 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
691                 if (application->application_description!=0)
692                 {
693                     resp.datasize+=strlen(application->application_description); /* app_description */
694                 }
695             }
696         }
697         else
698         {
699             /* All applications, all contexts */
700             for (i=0;i<daemon->num_contexts;i++)
701             {
702                 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
703                 if (daemon->contexts[i].context_description!=0)
704                 {
705                     resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
706                 }
707             }
708
709             for (i=0;i<daemon->num_applications;i++)
710             {
711                 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
712                 if (daemon->applications[i].application_description!=0)
713                 {
714                     resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
715                 }
716             }
717         }
718     }
719
720     if (verbose)
721     {
722         sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
723         dlt_log(LOG_INFO, str);
724     }
725
726     /* Allocate buffer for response message */
727     resp.databuffer = (uint8_t *) malloc(resp.datasize);
728     resp.databuffersize = resp.datasize;
729
730     if (resp.databuffer==0)
731     {
732         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
733         return;
734     }
735     memset(resp.databuffer,0,resp.datasize);
736     /* Preparation finished */
737
738     /* Prepare response */
739     sid = DLT_SERVICE_ID_GET_LOG_INFO;
740     memcpy(resp.databuffer,&sid,sizeof(uint32_t));
741     offset+=sizeof(uint32_t);
742
743     value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
744
745     memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
746     offset+=sizeof(int8_t);
747
748     count_app_ids = num_applications;
749
750     if (count_app_ids!=0)
751     {
752         memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
753         offset+=sizeof(uint16_t);
754
755 #if (DLT_DEBUG_GETLOGINFO==1)
756         sprintf(str,"#apid: %d \n", count_app_ids);
757         dlt_log(LOG_DEBUG, str);
758 #endif
759
760         for (i=0;i<count_app_ids;i++)
761         {
762             if (req->apid[0]!='\0')
763             {
764                 apid = req->apid;
765             }
766             else
767             {
768                 if (daemon->applications)
769                 {
770                     apid = daemon->applications[i].apid;
771                 }
772                 else
773                 {
774                     /* This should never occur! */
775                     apid=0;
776                 }
777             }
778
779             application = dlt_daemon_application_find(daemon, apid, verbose);
780
781             if (application)
782             {
783                 /* Calculate start offset within contexts[] */
784                 offset_base=0;
785                 for (j=0; j<(application-(daemon->applications)); j++)
786                 {
787                     offset_base+=daemon->applications[j].num_contexts;
788                 }
789
790                 dlt_set_id((char*)(resp.databuffer+offset),apid);
791                 offset+=sizeof(ID4);
792
793 #if (DLT_DEBUG_GETLOGINFO==1)
794                 dlt_print_id(buf, apid);
795                 sprintf(str,"apid: %s\n",buf);
796                 dlt_log(LOG_DEBUG, str);
797 #endif
798
799                 if (req->apid[0]!='\0')
800                 {
801                     count_con_ids = num_contexts;
802                 }
803                 else
804                 {
805                     count_con_ids = application->num_contexts;
806                 }
807
808                 memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
809                 offset+=sizeof(uint16_t);
810
811 #if (DLT_DEBUG_GETLOGINFO==1)
812                 sprintf(str,"#ctid: %d \n", count_con_ids);
813                 dlt_log(LOG_DEBUG, str);
814 #endif
815
816                 for (j=0;j<count_con_ids;j++)
817                 {
818 #if (DLT_DEBUG_GETLOGINFO==1)
819                     sprintf(str,"j: %d \n",j);
820                     dlt_log(LOG_DEBUG, str);
821 #endif
822                     if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
823                     {
824                         context = &(daemon->contexts[offset_base+j]);
825                     }
826                     /* else: context was already searched and found
827                              (one application (found) with one context (found))*/
828
829                     if ((context) &&
830                             ((req->ctid[0]=='\0') ||
831                              ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
832                        )
833                     {
834                         dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
835                         offset+=sizeof(ID4);
836
837 #if (DLT_DEBUG_GETLOGINFO==1)
838                         dlt_print_id(buf, context->ctid);
839                         sprintf(str,"ctid: %s \n",buf);
840                         dlt_log(LOG_DEBUG, str);
841 #endif
842
843                         /* Mode 4, 6, 7 */
844                         if ((req->options==4) || (req->options==6) || (req->options==7))
845                         {
846                             ll=context->log_level;
847                             memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
848                             offset+=sizeof(int8_t);
849                         }
850
851                         /* Mode 5, 6, 7 */
852                         if ((req->options==5) || (req->options==6) || (req->options==7))
853                         {
854                             ts=context->trace_status;
855                             memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
856                             offset+=sizeof(int8_t);
857                         }
858
859                         /* Mode 7 */
860                         if (req->options==7)
861                         {
862                             if (context->context_description)
863                             {
864                                 len = strlen(context->context_description);
865                                 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
866                                 offset+=sizeof(uint16_t);
867                                 memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
868                                 offset+=strlen(context->context_description);
869                             }
870                             else
871                             {
872                                 len = 0;
873                                 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
874                                 offset+=sizeof(uint16_t);
875                             }
876                         }
877
878 #if (DLT_DEBUG_GETLOGINFO==1)
879                         sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
880                         dlt_log(LOG_DEBUG, str);
881 #endif
882                     }
883
884 #if (DLT_DEBUG_GETLOGINFO==1)
885                     dlt_log(LOG_DEBUG,"\n");
886 #endif
887                 }
888
889                 /* Mode 7 */
890                 if (req->options==7)
891                 {
892                     if (application->application_description)
893                     {
894                         len = strlen(application->application_description);
895                         memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
896                         offset+=sizeof(uint16_t);
897                         memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
898                         offset+=strlen(application->application_description);
899                     }
900                     else
901                     {
902                         len = 0;
903                         memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
904                         offset+=sizeof(uint16_t);
905                     }
906                 }
907             } /* if (application) */
908         } /* for (i=0;i<count_app_ids;i++) */
909     } /* if (count_app_ids!=0) */
910
911     dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
912
913     /* send message */
914     dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&resp,"","",  verbose);
915
916     /* free message */
917     dlt_message_free(&resp,0);
918 }
919
920 int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, unsigned int overflow_counter,char* apid, int verbose)
921 {
922         int ret;
923     DltMessage msg;
924         DltServiceMessageBufferOverflowResponse *resp;
925
926     PRINT_FUNCTION_VERBOSE(verbose);
927
928     if (daemon==0)
929     {
930         return DLT_DAEMON_ERROR_UNKNOWN;
931     }
932
933     /* initialise new message */
934     if (dlt_message_init(&msg,0)==-1)
935     {
936         dlt_daemon_control_service_response(sock, daemon,daemon_local, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR,  verbose);
937         return DLT_DAEMON_ERROR_UNKNOWN;
938     }
939
940     /* prepare payload of data */
941     msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
942     if (msg.databuffer && (msg.databuffersize < msg.datasize))
943     {
944         free(msg.databuffer);
945         msg.databuffer=0;
946     }
947     if (msg.databuffer == 0){
948         msg.databuffer = (uint8_t *) malloc(msg.datasize);
949         msg.databuffersize = msg.datasize;
950     }
951     if (msg.databuffer==0)
952     {
953         return DLT_DAEMON_ERROR_UNKNOWN;
954     }
955
956     resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
957     resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
958     resp->status = DLT_SERVICE_RESPONSE_OK;
959     resp->overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
960         resp->overflow_counter = overflow_counter;
961
962     /* send message */
963     if((ret=dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,apid,"",  verbose)))
964     {
965         dlt_message_free(&msg,0);
966         return ret;
967     }
968
969     /* free message */
970     dlt_message_free(&msg,0);
971
972     return DLT_DAEMON_ERROR_OK;
973 }
974
975 void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint32_t service_id, int8_t status , int verbose)
976 {
977     DltMessage msg;
978     DltServiceResponse *resp;
979
980     PRINT_FUNCTION_VERBOSE(verbose);
981
982     if (daemon==0)
983     {
984         return;
985     }
986
987     /* initialise new message */
988     if (dlt_message_init(&msg,0)==-1)
989     {
990                 return;
991     }
992
993     /* prepare payload of data */
994     msg.datasize = sizeof(DltServiceResponse);
995     if (msg.databuffer && (msg.databuffersize < msg.datasize))
996     {
997         free(msg.databuffer);
998         msg.databuffer=0;
999     }
1000     if (msg.databuffer == 0){
1001         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1002         msg.databuffersize = msg.datasize;
1003     }
1004     if (msg.databuffer==0)
1005     {
1006         return;
1007     }
1008
1009     resp = (DltServiceResponse*) msg.databuffer;
1010     resp->service_id = service_id;
1011     resp->status = status;
1012
1013     /* send message */
1014     dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","",  verbose);
1015
1016     /* free message */
1017     dlt_message_free(&msg,0);
1018 }
1019
1020 int dlt_daemon_control_message_unregister_context(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, char* apid, char* ctid, char* comid, int verbose)
1021 {
1022     DltMessage msg;
1023     DltServiceUnregisterContext *resp;
1024
1025     PRINT_FUNCTION_VERBOSE(verbose);
1026
1027     if (daemon==0)
1028     {
1029         return -1;
1030     }
1031
1032     /* initialise new message */
1033     if (dlt_message_init(&msg,0)==-1)
1034     {
1035         return -1;
1036     }
1037
1038     /* prepare payload of data */
1039     msg.datasize = sizeof(DltServiceUnregisterContext);
1040     if (msg.databuffer && (msg.databuffersize < msg.datasize))
1041     {
1042         free(msg.databuffer);
1043         msg.databuffer=0;
1044     }
1045     if (msg.databuffer == 0){
1046         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1047         msg.databuffersize = msg.datasize;
1048     }
1049     if (msg.databuffer==0)
1050     {
1051         return -1;
1052     }
1053
1054     resp = (DltServiceUnregisterContext*) msg.databuffer;
1055     resp->service_id = DLT_SERVICE_ID_UNREGISTER_CONTEXT;
1056     resp->status = DLT_SERVICE_RESPONSE_OK;
1057         dlt_set_id(resp->apid, apid);
1058         dlt_set_id(resp->ctid, ctid);
1059         dlt_set_id(resp->comid, comid);
1060
1061     /* send message */
1062     if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","",  verbose))
1063     {
1064         dlt_message_free(&msg,0);
1065         return -1;
1066     }
1067
1068     /* free message */
1069     dlt_message_free(&msg,0);
1070
1071     return 0;
1072 }
1073
1074 int dlt_daemon_control_message_connection_info(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, uint8_t state, char* comid, int verbose)
1075 {
1076     DltMessage msg;
1077     DltServiceConnectionInfo *resp;
1078
1079     PRINT_FUNCTION_VERBOSE(verbose);
1080
1081     if (daemon==0)
1082     {
1083         return -1;
1084     }
1085
1086     /* initialise new message */
1087     if (dlt_message_init(&msg,0)==-1)
1088     {
1089         return -1;
1090     }
1091
1092     /* prepare payload of data */
1093     msg.datasize = sizeof(DltServiceConnectionInfo);
1094     if (msg.databuffer && (msg.databuffersize < msg.datasize))
1095     {
1096         free(msg.databuffer);
1097         msg.databuffer=0;
1098     }
1099     if (msg.databuffer == 0){
1100         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1101         msg.databuffersize = msg.datasize;
1102     }
1103     if (msg.databuffer==0)
1104     {
1105         return -1;
1106     }
1107
1108     resp = (DltServiceConnectionInfo*) msg.databuffer;
1109     resp->service_id = DLT_SERVICE_ID_CONNECTION_INFO;
1110     resp->status = DLT_SERVICE_RESPONSE_OK;
1111     resp->state = state;
1112     dlt_set_id(resp->comid, comid);
1113
1114     /* send message */
1115     if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","",  verbose))
1116     {
1117         dlt_message_free(&msg,0);
1118         return -1;
1119     }
1120
1121     /* free message */
1122     dlt_message_free(&msg,0);
1123
1124     return 0;
1125 }
1126
1127 int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1128 {
1129     DltMessage msg;
1130     DltServiceTimezone *resp;
1131
1132     PRINT_FUNCTION_VERBOSE(verbose);
1133
1134     if (daemon==0)
1135     {
1136         return -1;
1137     }
1138
1139     /* initialise new message */
1140     if (dlt_message_init(&msg,0)==-1)
1141     {
1142         return -1;
1143     }
1144
1145     /* prepare payload of data */
1146     msg.datasize = sizeof(DltServiceTimezone);
1147     if (msg.databuffer && (msg.databuffersize < msg.datasize))
1148     {
1149         free(msg.databuffer);
1150         msg.databuffer=0;
1151     }
1152     if (msg.databuffer == 0){
1153         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1154         msg.databuffersize = msg.datasize;
1155     }
1156     if (msg.databuffer==0)
1157     {
1158         return -1;
1159     }
1160
1161     resp = (DltServiceTimezone*) msg.databuffer;
1162     resp->service_id = DLT_SERVICE_ID_TIMEZONE;
1163     resp->status = DLT_SERVICE_RESPONSE_OK;
1164
1165         time_t t = time(NULL);
1166         struct tm lt = {0};
1167         localtime_r(&t, &lt);
1168 #if !defined(__CYGWIN__)
1169     resp->timezone = (int32_t) lt.tm_gmtoff;
1170 #endif
1171     resp->isdst = (uint8_t) lt.tm_isdst;
1172
1173     /* send message */
1174     if(dlt_daemon_client_send_control_message(sock,daemon,daemon_local,&msg,"","",  verbose))
1175     {
1176         dlt_message_free(&msg,0);
1177         return -1;
1178     }
1179
1180     /* free message */
1181     dlt_message_free(&msg,0);
1182
1183     return 0;
1184 }
1185
1186 void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1187 {
1188     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1189     uint32_t id=0,id_tmp=0;
1190     uint8_t *ptr;
1191     DltDaemonContext *context;
1192         int32_t data_length_inject=0;
1193         uint32_t data_length_inject_tmp=0;
1194
1195         int32_t datalength;
1196
1197         DltUserHeader userheader;
1198         DltUserControlMsgInjection usercontext;
1199         uint8_t *userbuffer;
1200
1201     PRINT_FUNCTION_VERBOSE(verbose);
1202
1203     if ((daemon==0) || (msg==0))
1204     {
1205         return;
1206     }
1207
1208     datalength = msg->datasize;
1209     ptr = msg->databuffer;
1210
1211     if (ptr==0)
1212     {
1213         return;
1214     }
1215
1216     DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
1217     id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1218
1219     if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX))
1220     {
1221         /* This a a real SW-C injection call */
1222         data_length_inject=0;
1223         data_length_inject_tmp=0;
1224
1225         DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
1226         data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1227
1228         /* Get context handle for apid, ctid (and seid) */
1229         /* Warning: seid is ignored in this implementation! */
1230         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1231         {
1232             dlt_set_id(apid, msg->extendedheader->apid);
1233             dlt_set_id(ctid, msg->extendedheader->ctid);
1234         }
1235         else
1236         {
1237             /* No extended header, and therefore no apid and ctid available */
1238             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1239             return;
1240         }
1241
1242         /* At this point, apid and ctid is available */
1243         context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1244
1245         if (context==0)
1246         {
1247             // dlt_log(LOG_INFO,"No context found!\n");
1248             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1249             return;
1250         }
1251
1252         /* Send user message to handle, specified in context */
1253                 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1)
1254                 {
1255                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1256                         return;
1257                 }
1258
1259                 usercontext.log_level_pos = context->log_level_pos;
1260
1261                 if(data_length_inject > msg->databuffersize)
1262                 {
1263                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1264                         return;
1265                 }
1266
1267                 userbuffer = malloc(data_length_inject);
1268
1269                 if (userbuffer==0)
1270                 {
1271                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1272                         return;
1273                 }
1274
1275                 usercontext.data_length_inject = data_length_inject;
1276                 usercontext.service_id = id;
1277
1278                 memcpy(userbuffer,ptr,data_length_inject);  /* Copy received injection to send buffer */
1279
1280                 /* write to FIFO */
1281                 DltReturnValue ret =
1282                                 dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
1283                                   &(usercontext), sizeof(DltUserControlMsgInjection),
1284                                   userbuffer, data_length_inject);
1285                 if (ret != DLT_RETURN_OK)
1286                 {
1287                         if (ret == DLT_RETURN_PIPE_ERROR)
1288                         {
1289                                 /* Close connection */
1290                                 close(context->user_handle);
1291                                 context->user_handle=DLT_FD_INIT;
1292                         }
1293                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1294                 }
1295                 else
1296                 {
1297                         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1298                 }
1299
1300                 free(userbuffer);
1301                 userbuffer=0;
1302
1303     }
1304     else
1305     {
1306         /* Invalid ID */
1307         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1308     }
1309 }
1310
1311 void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1312 {
1313     PRINT_FUNCTION_VERBOSE(verbose);
1314
1315     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1316     DltServiceSetLogLevel *req;
1317     DltDaemonContext *context;
1318     int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL;
1319
1320         int8_t old_log_level;
1321
1322     if ((daemon==0) || (msg==0))
1323     {
1324         return;
1325     }
1326
1327     req = (DltServiceSetLogLevel*) (msg->databuffer);
1328
1329     dlt_set_id(apid, req->apid);
1330     dlt_set_id(ctid, req->ctid);
1331
1332     context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1333
1334     /* Set log level */
1335     if (context!=0)
1336     {
1337         old_log_level = context->log_level;
1338         context->log_level = req->log_level; /* No endianess conversion necessary*/
1339
1340         if ((context->user_handle >= DLT_FD_MINIMUM) &&
1341                 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1342         {
1343             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1344         }
1345         else
1346         {
1347             //dlt_log(LOG_ERR, "Log level could not be sent!\n");
1348             context->log_level = old_log_level;
1349             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1350         }
1351     }
1352     else
1353     {
1354         //dlt_log(LOG_ERR, "Context not found!\n");
1355         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1356     }
1357 }
1358
1359 void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1360 {
1361     PRINT_FUNCTION_VERBOSE(verbose);
1362
1363     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1364     DltServiceSetLogLevel *req;             /* request uses same struct as set log level */
1365     DltDaemonContext *context;
1366     int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS;
1367
1368         int8_t old_trace_status;
1369
1370     if ((daemon==0) || (msg==0))
1371     {
1372         return;
1373     }
1374
1375     req = (DltServiceSetLogLevel*) (msg->databuffer);
1376
1377     dlt_set_id(apid, req->apid);
1378     dlt_set_id(ctid, req->ctid);
1379
1380     context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1381
1382     /* Set log level */
1383     if (context!=0)
1384     {
1385         old_trace_status = context->trace_status;
1386         context->trace_status = req->log_level;   /* No endianess conversion necessary */
1387
1388         if ((context->user_handle >= DLT_FD_MINIMUM ) &&
1389                 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1390         {
1391             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1392         }
1393         else
1394         {
1395             //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
1396             context->trace_status = old_trace_status;
1397             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1398         }
1399     }
1400     else
1401     {
1402         //dlt_log(LOG_ERR, "Context not found!\n");
1403         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1404     }
1405 }
1406
1407 void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1408 {
1409     PRINT_FUNCTION_VERBOSE(verbose);
1410
1411     DltServiceSetDefaultLogLevel *req;
1412     int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
1413
1414     if ((daemon==0) || (msg==0))
1415     {
1416         return;
1417     }
1418
1419     req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1420
1421     /* No endianess conversion necessary */
1422     if (/*(req->log_level>=0) &&*/
1423             (req->log_level<=DLT_LOG_VERBOSE))
1424     {
1425         daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
1426
1427         /* Send Update to all contexts using the default log level */
1428         dlt_daemon_user_send_default_update(daemon, verbose);
1429
1430         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1431     }
1432     else
1433     {
1434         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1435     }
1436 }
1437
1438 void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1439 {
1440     PRINT_FUNCTION_VERBOSE(verbose);
1441
1442     /* Payload of request message */
1443     DltServiceSetDefaultLogLevel *req;
1444     int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
1445
1446     if ((daemon==0) || (msg==0))
1447     {
1448         return;
1449     }
1450
1451     req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1452
1453     /* No endianess conversion necessary */
1454     if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
1455             (req->log_level==DLT_TRACE_STATUS_ON))
1456     {
1457         daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
1458
1459         /* Send Update to all contexts using the default trace status */
1460         dlt_daemon_user_send_default_update(daemon, verbose);
1461
1462         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1463     }
1464     else
1465     {
1466         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1467     }
1468 }
1469
1470 void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
1471 {
1472     PRINT_FUNCTION_VERBOSE(verbose);
1473
1474     DltServiceSetVerboseMode *req;  /* request uses same struct as set verbose mode */
1475     int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS;
1476
1477     if ((daemon==0) || (msg==0))
1478     {
1479         return;
1480     }
1481
1482     req = (DltServiceSetVerboseMode*) (msg->databuffer);
1483     if ((req->new_status==0) || (req->new_status==1))
1484     {
1485         daemon->timingpackets = req->new_status;
1486
1487         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1488     }
1489     else
1490     {
1491         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1492     }
1493 }
1494
1495 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1496 {
1497         int ret;
1498     DltMessage msg;
1499     int32_t len;
1500
1501     PRINT_FUNCTION_VERBOSE(verbose);
1502
1503     if (daemon==0)
1504     {
1505         return;
1506     }
1507
1508     /* initialise new message */
1509     if (dlt_message_init(&msg,0)==-1)
1510     {
1511         return;
1512     }
1513
1514     /* send message */
1515
1516     /* prepare storage header */
1517     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
1518     dlt_set_storageheader(msg.storageheader,daemon->ecuid);
1519
1520     /* prepare standard header */
1521     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
1522     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
1523
1524 #if (BYTE_ORDER==BIG_ENDIAN)
1525     msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
1526 #endif
1527
1528     msg.standardheader->mcnt = 0;
1529
1530     /* Set header extra parameters */
1531     dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
1532     msg.headerextra.tmsp = dlt_uptime();
1533
1534     dlt_message_set_extraparameters(&msg, verbose);
1535
1536     /* prepare extended header */
1537     msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
1538     msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
1539
1540     msg.extendedheader->noar = 0;                  /* number of arguments */
1541     dlt_set_id(msg.extendedheader->apid,"");       /* application id */
1542     dlt_set_id(msg.extendedheader->ctid,"");       /* context id */
1543
1544     /* prepare length information */
1545     msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
1546
1547     len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
1548     if (len>UINT16_MAX)
1549     {
1550         dlt_log(LOG_CRIT,"Huge control message discarded!\n");
1551
1552         /* free message */
1553         dlt_message_free(&msg,0);
1554
1555         return;
1556     }
1557
1558     msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
1559
1560     /* Send message */
1561     if((ret = dlt_daemon_client_send(sock,daemon,daemon_local,msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),
1562                            msg.databuffer,msg.datasize,verbose)))
1563     {
1564
1565     }
1566
1567     /* free message */
1568     dlt_message_free(&msg,0);
1569 }
1570
1571