Line data Source code
1 : /*
2 : * SPDX license identifier: MPL-2.0
3 : *
4 : * Copyright (C) 2011-2015, BMW AG
5 : *
6 : * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
7 : *
8 : * This Source Code Form is subject to the terms of the
9 : * Mozilla Public License (MPL), v. 2.0.
10 : * If a copy of the MPL was not distributed with this file,
11 : * You can obtain one at http://mozilla.org/MPL/2.0/.
12 : *
13 : * For further information see http://www.covesa.org/.
14 : */
15 :
16 : /*!
17 : * \author
18 : * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
19 : * Markus Klein <Markus.Klein@esk.fraunhofer.de>
20 : * Mikko Rapeli <mikko.rapeli@bmw.de>
21 : *
22 : * \copyright Copyright © 2011-2015 BMW AG. \n
23 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
24 : *
25 : * \file dlt_daemon_client.c
26 : */
27 :
28 : #include <netdb.h>
29 : #include <ctype.h>
30 : #include <stdio.h> /* for printf() and fprintf() */
31 : #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
32 : #include <sys/stat.h> /* for stat() */
33 : #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
34 : #include <stdlib.h> /* for atoi() and exit() */
35 : #include <string.h> /* for memset() */
36 : #include <unistd.h> /* for close() */
37 : #include <signal.h>
38 : #include <syslog.h>
39 : #include <errno.h>
40 : #include <pthread.h>
41 :
42 : #ifdef linux
43 : # include <sys/timerfd.h>
44 : #endif
45 : #include <sys/time.h>
46 : #if defined(linux) && defined(__NR_statx)
47 : # include <linux/stat.h>
48 : #endif
49 :
50 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
51 : # include <systemd/sd-daemon.h>
52 : #endif
53 :
54 : #include "dlt_types.h"
55 : #include "dlt_log.h"
56 : #include "dlt-daemon.h"
57 : #include "dlt-daemon_cfg.h"
58 : #include "dlt_daemon_common_cfg.h"
59 :
60 : #include "dlt_daemon_socket.h"
61 : #include "dlt_daemon_serial.h"
62 :
63 : #include "dlt_daemon_client.h"
64 : #include "dlt_daemon_connection.h"
65 : #include "dlt_daemon_event_handler.h"
66 :
67 : #include "dlt_daemon_offline_logstorage.h"
68 : #include "dlt_gateway.h"
69 :
70 : /** Inline function to calculate/set the requested log level or traces status
71 : * with default log level or trace status when "ForceContextLogLevelAndTraceStatus"
72 : * is enabled and set to 1 in dlt.conf file.
73 : *
74 : * @param request_log The requested log level (or) trace status
75 : * @param context_log The default log level (or) trace status
76 : *
77 : * @return The log level if requested log level is lower or equal to ContextLogLevel
78 : */
79 : static inline int8_t getStatus(uint8_t request_log, int context_log)
80 : {
81 0 : return (request_log <= context_log) ? request_log : context_log;
82 : }
83 :
84 : #ifdef UDP_CONNECTION_SUPPORT
85 : # include "dlt_daemon_udp_socket.h"
86 : #endif
87 :
88 : /** @brief Sends up to 2 messages to all the clients.
89 : *
90 : * Runs through the client list and sends the messages to them. If the message
91 : * transfer fails and the connection is a socket connection, the socket is closed.
92 : * Takes and release dlt_daemon_mutex.
93 : *
94 : * @param daemon Daemon structure needed for socket closure.
95 : * @param daemon_local Daemon local structure
96 : * @param data1 The first message to be sent.
97 : * @param size1 The size of the first message.
98 : * @param data2 The second message to be send.
99 : * @param size2 The second message size.
100 : * @param verbose Needed for socket closure.
101 : *
102 : * @return The amount of data transfered.
103 : */
104 214 : static int dlt_daemon_client_send_all_multiple(DltDaemon *daemon,
105 : DltDaemonLocal *daemon_local,
106 : void *data1,
107 : int size1,
108 : void *data2,
109 : int size2,
110 : int verbose)
111 : {
112 : int sent = 0;
113 : unsigned int i = 0;
114 : int ret = 0;
115 : DltConnection *temp = NULL;
116 : int type_mask =
117 : (DLT_CON_MASK_CLIENT_MSG_TCP | DLT_CON_MASK_CLIENT_MSG_SERIAL);
118 :
119 214 : PRINT_FUNCTION_VERBOSE(verbose);
120 :
121 214 : if ((daemon == NULL) || (daemon_local == NULL)) {
122 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
123 0 : return 0;
124 : }
125 :
126 1286 : for (i = 0; i < daemon_local->pEvent.nfds; i++)
127 : {
128 1072 : temp = dlt_event_handler_find_connection(&(daemon_local->pEvent),
129 1072 : daemon_local->pEvent.pfd[i].fd);
130 :
131 1072 : if ((temp == NULL) || (temp->receiver == NULL) ||
132 1072 : !((1 << temp->type) & type_mask)) {
133 856 : dlt_log(LOG_DEBUG, "The connection not found or the connection type not TCP/Serial.\n");
134 856 : continue;
135 : }
136 :
137 216 : ret = dlt_connection_send_multiple(temp,
138 : data1,
139 : size1,
140 : data2,
141 : size2,
142 : daemon->sendserialheader);
143 :
144 216 : if ((ret != DLT_DAEMON_ERROR_OK) &&
145 0 : (DLT_CONNECTION_CLIENT_MSG_TCP == temp->type)) {
146 0 : dlt_daemon_close_socket(temp->receiver->fd,
147 : daemon,
148 : daemon_local,
149 : verbose);
150 : }
151 :
152 216 : if (ret != DLT_DAEMON_ERROR_OK)
153 0 : dlt_vlog(LOG_WARNING, "%s: send dlt message failed\n", __func__);
154 : else
155 : /* If sent to at least one client,
156 : * then do not store in ring buffer
157 : */
158 : sent = 1;
159 : } /* for */
160 :
161 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
162 : if (sent)
163 : {
164 : const uint32_t serial_header = daemon->sendserialheader ? sizeof(dltSerialHeader) : 0;
165 : daemon->bytes_sent += size1 + size2 + serial_header;
166 : }
167 : #endif
168 :
169 : return sent;
170 : }
171 :
172 5885 : int dlt_daemon_client_send(int sock,
173 : DltDaemon *daemon,
174 : DltDaemonLocal *daemon_local,
175 : void *storage_header,
176 : int storage_header_size,
177 : void *data1,
178 : int size1,
179 : void *data2,
180 : int size2,
181 : int verbose)
182 : {
183 : int sent, ret;
184 : int ret_logstorage = 0;
185 : static int sent_message_overflow_cnt = 0;
186 :
187 5885 : if ((daemon == NULL) || (daemon_local == NULL)) {
188 0 : dlt_vlog(LOG_ERR, "%s: Invalid arguments\n", __func__);
189 0 : return DLT_DAEMON_ERROR_UNKNOWN;
190 : }
191 :
192 5885 : if ((sock != DLT_DAEMON_SEND_TO_ALL) && (sock != DLT_DAEMON_SEND_FORCE)) {
193 : /* Send message to specific socket */
194 16 : if (isatty(sock)) {
195 0 : if ((ret =
196 0 : dlt_daemon_serial_send(sock, data1, size1, data2, size2,
197 0 : daemon->sendserialheader))) {
198 0 : dlt_vlog(LOG_WARNING, "%s: serial send dlt message failed\n", __func__);
199 0 : return ret;
200 : }
201 : } else {
202 16 : if ((ret =
203 16 : dlt_daemon_socket_send(sock, data1, size1, data2, size2,
204 16 : daemon->sendserialheader))) {
205 1 : dlt_vlog(LOG_WARNING, "%s: socket send dlt message failed\n", __func__);
206 1 : return ret;
207 : }
208 : }
209 :
210 15 : return DLT_DAEMON_ERROR_OK;
211 : }
212 :
213 : /* write message to offline trace */
214 : /* In the SEND_BUFFER state we must skip offline tracing because the offline traces */
215 : /* are going without buffering directly to the offline trace. Thus we have to filter out */
216 : /* the traces that are coming from the buffer. */
217 5869 : if ((sock != DLT_DAEMON_SEND_FORCE) && (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)) {
218 5865 : if (((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
219 0 : && daemon_local->flags.offlineTraceDirectory[0]) {
220 0 : if (dlt_offline_trace_write(&(daemon_local->offlineTrace), storage_header, storage_header_size, data1,
221 : size1, data2, size2)) {
222 : static int error_dlt_offline_trace_write_failed = 0;
223 :
224 0 : if (!error_dlt_offline_trace_write_failed) {
225 0 : dlt_vlog(LOG_ERR, "%s: dlt_offline_trace_write failed!\n", __func__);
226 0 : error_dlt_offline_trace_write_failed = 1;
227 : }
228 :
229 : /*return DLT_DAEMON_ERROR_WRITE_FAILED; */
230 : }
231 : }
232 :
233 : /* write messages to offline logstorage only if there is an extended header set
234 : * this need to be checked because the function is dlt_daemon_client_send is called by
235 : * newly introduced dlt_daemon_log_internal */
236 5865 : if (daemon_local->flags.offlineLogstorageMaxDevices > 0)
237 5839 : ret_logstorage = dlt_daemon_logstorage_write(daemon,
238 : &daemon_local->flags,
239 : storage_header,
240 : storage_header_size,
241 : data1,
242 : size1,
243 : data2,
244 : size2);
245 : }
246 :
247 : /* send messages to daemon socket */
248 5869 : if ((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) {
249 : #ifdef UDP_CONNECTION_SUPPORT
250 : if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED) {
251 : /* Forward message to network client if network routing is not disabled */
252 : if (ret_logstorage != 1) {
253 : dlt_daemon_udp_dltmsg_multicast(data1,
254 : size1,
255 : data2,
256 : size2,
257 : verbose);
258 : }
259 : }
260 :
261 : #endif
262 :
263 5869 : if ((sock == DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT)) {
264 : /* Forward message to network client if network routing is not disabled */
265 415 : if (ret_logstorage != 1) {
266 214 : sent = dlt_daemon_client_send_all_multiple(daemon,
267 : daemon_local,
268 : data1,
269 : size1,
270 : data2,
271 : size2,
272 : verbose);
273 :
274 214 : if ((sock == DLT_DAEMON_SEND_FORCE) && !sent) {
275 : return DLT_DAEMON_ERROR_SEND_FAILED;
276 : }
277 : }
278 : }
279 : }
280 :
281 : /* Message was not sent to client, so store it in client ringbuffer */
282 5869 : if ((sock != DLT_DAEMON_SEND_FORCE) &&
283 5865 : ((daemon->state == DLT_DAEMON_STATE_BUFFER) || (daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
284 : (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))) {
285 5454 : if (daemon->state != DLT_DAEMON_STATE_BUFFER_FULL) {
286 : /* Store message in history buffer */
287 5454 : ret = dlt_buffer_push3(&(daemon->client_ringbuffer), data1, size1, data2, size2, 0, 0);
288 5454 : if (ret < DLT_RETURN_OK) {
289 0 : dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER_FULL);
290 : }
291 : }
292 5454 : if (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL) {
293 0 : daemon->overflow_counter += 1;
294 0 : if (daemon->overflow_counter == 1)
295 0 : dlt_vlog(LOG_INFO, "%s: Buffer is full! Messages will be discarded.\n", __func__);
296 :
297 0 : return DLT_DAEMON_ERROR_BUFFER_FULL;
298 : }
299 : } else {
300 415 : if ((daemon->overflow_counter > 0) &&
301 0 : (daemon_local->client_connections > 0)) {
302 0 : sent_message_overflow_cnt++;
303 0 : if (sent_message_overflow_cnt >= 2) {
304 0 : sent_message_overflow_cnt--;
305 : }
306 : else {
307 0 : if (dlt_daemon_send_message_overflow(daemon, daemon_local,
308 : verbose) == DLT_DAEMON_ERROR_OK) {
309 0 : dlt_vlog(LOG_WARNING,
310 : "%s: %u messages discarded! Now able to send messages to the client.\n",
311 : __func__,
312 : daemon->overflow_counter);
313 0 : daemon->overflow_counter = 0;
314 0 : sent_message_overflow_cnt--;
315 : }
316 : }
317 : }
318 : }
319 :
320 : return DLT_DAEMON_ERROR_OK;
321 :
322 : }
323 :
324 5809 : int dlt_daemon_client_send_message_to_all_client(DltDaemon *daemon,
325 : DltDaemonLocal *daemon_local,
326 : int verbose)
327 : {
328 : static char text[DLT_DAEMON_TEXTSIZE];
329 : char * ecu_ptr = NULL;
330 :
331 5809 : PRINT_FUNCTION_VERBOSE(verbose);
332 :
333 5809 : if ((daemon == NULL) || (daemon_local == NULL)) {
334 0 : dlt_vlog(LOG_ERR, "%s: invalid arguments\n", __func__);
335 0 : return DLT_DAEMON_ERROR_UNKNOWN;
336 : }
337 :
338 : /* set overwrite ecu id */
339 5809 : if ((daemon_local->flags.evalue[0]) &&
340 0 : (strncmp(daemon_local->msg.headerextra.ecu,
341 : DLT_DAEMON_ECU_ID, DLT_ID_SIZE) == 0)) {
342 : /* Set header extra parameters */
343 0 : dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid);
344 :
345 : /*msg.headerextra.seid = 0; */
346 0 : if (dlt_message_set_extraparameters(&(daemon_local->msg), 0)) {
347 0 : dlt_vlog(LOG_WARNING,
348 : "%s: failed to set message extra parameters.\n", __func__);
349 0 : return DLT_DAEMON_ERROR_UNKNOWN;
350 : }
351 :
352 : /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
353 0 : daemon_local->msg.headerextra.tmsp =
354 0 : DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
355 : }
356 :
357 : /* prepare storage header */
358 5809 : if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) {
359 5809 : ecu_ptr = daemon_local->msg.headerextra.ecu;
360 : } else {
361 0 : ecu_ptr = daemon->ecuid;
362 : }
363 :
364 5809 : if (dlt_set_storageheader(daemon_local->msg.storageheader, ecu_ptr)) {
365 0 : dlt_vlog(LOG_WARNING,
366 : "%s: failed to set storage header with header type: 0x%x\n",
367 0 : __func__, daemon_local->msg.standardheader->htyp);
368 0 : return DLT_DAEMON_ERROR_UNKNOWN;
369 : }
370 :
371 : /* if no filter set or filter is matching display message */
372 5809 : if (daemon_local->flags.xflag) {
373 0 : if (DLT_RETURN_OK !=
374 0 : dlt_message_print_hex(&(daemon_local->msg), text,
375 : DLT_DAEMON_TEXTSIZE, verbose))
376 0 : dlt_log(LOG_WARNING, "dlt_message_print_hex() failed!\n");
377 5809 : } else if (daemon_local->flags.aflag) {
378 0 : if (DLT_RETURN_OK !=
379 0 : dlt_message_print_ascii(&(daemon_local->msg), text,
380 : DLT_DAEMON_TEXTSIZE, verbose))
381 0 : dlt_log(LOG_WARNING, "dlt_message_print_ascii() failed!\n");
382 5809 : } else if (daemon_local->flags.sflag) {
383 0 : if (DLT_RETURN_OK !=
384 0 : dlt_message_print_header(&(daemon_local->msg), text,
385 : DLT_DAEMON_TEXTSIZE, verbose))
386 0 : dlt_log(LOG_WARNING, "dlt_message_print_header() failed!\n");
387 : }
388 :
389 : /* send message to client or write to log file */
390 5809 : return dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local,
391 5809 : daemon_local->msg.headerbuffer, sizeof(DltStorageHeader),
392 : daemon_local->msg.headerbuffer + sizeof(DltStorageHeader),
393 5809 : (int) (daemon_local->msg.headersize - sizeof(DltStorageHeader)),
394 5809 : daemon_local->msg.databuffer, (int) daemon_local->msg.datasize, verbose);
395 :
396 : }
397 :
398 21 : int dlt_daemon_client_send_control_message(int sock,
399 : DltDaemon *daemon,
400 : DltDaemonLocal *daemon_local,
401 : DltMessage *msg,
402 : char *apid,
403 : char *ctid,
404 : int verbose)
405 : {
406 : int ret;
407 : int32_t len;
408 :
409 21 : PRINT_FUNCTION_VERBOSE(verbose);
410 :
411 21 : if ((daemon == 0) || (msg == 0) || (apid == 0) || (ctid == 0))
412 : return DLT_DAEMON_ERROR_UNKNOWN;
413 :
414 : /* prepare storage header */
415 21 : msg->storageheader = (DltStorageHeader *)msg->headerbuffer;
416 :
417 21 : if (dlt_set_storageheader(msg->storageheader, daemon->ecuid) == DLT_RETURN_ERROR)
418 : return DLT_DAEMON_ERROR_UNKNOWN;
419 :
420 : /* prepare standard header */
421 21 : msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader));
422 21 : msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
423 :
424 : #if (BYTE_ORDER == BIG_ENDIAN)
425 : msg->standardheader->htyp = (msg->standardheader->htyp | DLT_HTYP_MSBF);
426 : #endif
427 :
428 21 : msg->standardheader->mcnt = 0;
429 :
430 : /* Set header extra parameters */
431 21 : dlt_set_id(msg->headerextra.ecu, daemon->ecuid);
432 :
433 : /*msg->headerextra.seid = 0; */
434 :
435 21 : msg->headerextra.tmsp = dlt_uptime();
436 :
437 21 : dlt_message_set_extraparameters(msg, verbose);
438 :
439 : /* prepare extended header */
440 21 : msg->extendedheader =
441 21 : (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
442 21 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
443 21 : msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
444 :
445 21 : msg->extendedheader->noar = 1; /* number of arguments */
446 :
447 21 : if (strcmp(apid, "") == 0)
448 21 : dlt_set_id(msg->extendedheader->apid, DLT_DAEMON_CTRL_APID); /* application id */
449 : else
450 0 : dlt_set_id(msg->extendedheader->apid, apid);
451 :
452 21 : if (strcmp(ctid, "") == 0)
453 21 : dlt_set_id(msg->extendedheader->ctid, DLT_DAEMON_CTRL_CTID); /* context id */
454 : else
455 0 : dlt_set_id(msg->extendedheader->ctid, ctid);
456 :
457 : /* prepare length information */
458 21 : msg->headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) +
459 21 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
460 :
461 21 : len = (int32_t) (msg->headersize - sizeof(DltStorageHeader) + msg->datasize);
462 :
463 21 : if (len > UINT16_MAX) {
464 0 : dlt_log(LOG_WARNING, "Huge control message discarded!\n");
465 0 : return DLT_DAEMON_ERROR_UNKNOWN;
466 : }
467 :
468 21 : msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
469 :
470 21 : if ((ret =
471 21 : dlt_daemon_client_send(sock, daemon, daemon_local, msg->headerbuffer, sizeof(DltStorageHeader),
472 : msg->headerbuffer + sizeof(DltStorageHeader),
473 21 : (int) (msg->headersize - sizeof(DltStorageHeader)),
474 21 : msg->databuffer, (int) msg->datasize, verbose))) {
475 1 : dlt_log(LOG_DEBUG, "dlt_daemon_control_send_control_message: DLT message send to all failed!.\n");
476 1 : return ret;
477 : }
478 :
479 : return DLT_DAEMON_ERROR_OK;
480 : }
481 :
482 12 : int dlt_daemon_client_process_control(int sock,
483 : DltDaemon *daemon,
484 : DltDaemonLocal *daemon_local,
485 : DltMessage *msg,
486 : int verbose)
487 : {
488 : uint32_t id, id_tmp = 0;
489 : DltStandardHeaderExtra extra;
490 :
491 12 : PRINT_FUNCTION_VERBOSE(verbose);
492 :
493 12 : if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL))
494 : return -1;
495 :
496 12 : if (msg->datasize < (int32_t)sizeof(uint32_t))
497 : return -1;
498 :
499 12 : extra = msg->headerextra;
500 :
501 : /* check if the message needs to be forwarded */
502 12 : if (daemon_local->flags.gatewayMode == 1) {
503 0 : if (strncmp(daemon_local->flags.evalue, extra.ecu, DLT_ID_SIZE) != 0)
504 0 : return dlt_gateway_forward_control_message(&daemon_local->pGateway,
505 : daemon_local,
506 : msg,
507 : extra.ecu,
508 : verbose);
509 : }
510 :
511 12 : id_tmp = *((uint32_t *)(msg->databuffer));
512 12 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
513 :
514 12 : if ((id > DLT_SERVICE_ID) && (id < DLT_SERVICE_ID_CALLSW_CINJECTION)) {
515 : /* Control message handling */
516 12 : switch (id) {
517 1 : case DLT_SERVICE_ID_SET_LOG_LEVEL:
518 : {
519 1 : dlt_daemon_control_set_log_level(sock, daemon, daemon_local, msg, verbose);
520 1 : break;
521 : }
522 0 : case DLT_SERVICE_ID_SET_TRACE_STATUS:
523 : {
524 0 : dlt_daemon_control_set_trace_status(sock, daemon, daemon_local, msg, verbose);
525 0 : break;
526 : }
527 4 : case DLT_SERVICE_ID_GET_LOG_INFO:
528 : {
529 4 : dlt_daemon_control_get_log_info(sock, daemon, daemon_local, msg, verbose);
530 4 : break;
531 : }
532 1 : case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
533 : {
534 1 : dlt_daemon_control_get_default_log_level(sock, daemon, daemon_local, verbose);
535 1 : break;
536 : }
537 0 : case DLT_SERVICE_ID_STORE_CONFIG:
538 : {
539 0 : if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose) == 0) {
540 0 : if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose) == 0) {
541 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,
542 : verbose);
543 : }
544 : else {
545 : /* Delete saved files */
546 0 : dlt_daemon_control_reset_to_factory_default(daemon,
547 : daemon->runtime_application_cfg,
548 : daemon->runtime_context_cfg,
549 : daemon_local->flags.contextLogLevel,
550 : daemon_local->flags.contextTraceStatus,
551 : daemon_local->flags.enforceContextLLAndTS,
552 : verbose);
553 0 : dlt_daemon_control_service_response(sock,
554 : daemon,
555 : daemon_local,
556 : id,
557 : DLT_SERVICE_RESPONSE_ERROR,
558 : verbose);
559 : }
560 : }
561 : else {
562 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,
563 : verbose);
564 : }
565 :
566 : break;
567 : }
568 0 : case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
569 : {
570 0 : dlt_daemon_control_reset_to_factory_default(daemon,
571 0 : daemon->runtime_application_cfg,
572 0 : daemon->runtime_context_cfg,
573 : daemon_local->flags.contextLogLevel,
574 : daemon_local->flags.contextTraceStatus,
575 : daemon_local->flags.enforceContextLLAndTS,
576 : verbose);
577 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
578 0 : break;
579 : }
580 0 : case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
581 : {
582 0 : dlt_daemon_control_service_response(sock,
583 : daemon,
584 : daemon_local,
585 : id,
586 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
587 : verbose);
588 0 : break;
589 : }
590 0 : case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
591 : {
592 0 : dlt_daemon_control_service_response(sock,
593 : daemon,
594 : daemon_local,
595 : id,
596 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
597 : verbose);
598 0 : break;
599 : }
600 0 : case DLT_SERVICE_ID_SET_VERBOSE_MODE:
601 : {
602 0 : dlt_daemon_control_service_response(sock,
603 : daemon,
604 : daemon_local,
605 : id,
606 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
607 : verbose);
608 0 : break;
609 : }
610 0 : case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
611 : {
612 0 : dlt_daemon_control_service_response(sock,
613 : daemon,
614 : daemon_local,
615 : id,
616 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
617 : verbose);
618 0 : break;
619 : }
620 0 : case DLT_SERVICE_ID_SET_TIMING_PACKETS:
621 : {
622 0 : dlt_daemon_control_set_timing_packets(sock, daemon, daemon_local, msg, verbose);
623 0 : break;
624 : }
625 0 : case DLT_SERVICE_ID_GET_LOCAL_TIME:
626 : {
627 : /* Send response with valid timestamp (TMSP) field */
628 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
629 0 : break;
630 : }
631 0 : case DLT_SERVICE_ID_USE_ECU_ID:
632 : {
633 0 : dlt_daemon_control_service_response(sock,
634 : daemon,
635 : daemon_local,
636 : id,
637 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
638 : verbose);
639 0 : break;
640 : }
641 0 : case DLT_SERVICE_ID_USE_SESSION_ID:
642 : {
643 0 : dlt_daemon_control_service_response(sock,
644 : daemon,
645 : daemon_local,
646 : id,
647 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
648 : verbose);
649 0 : break;
650 : }
651 0 : case DLT_SERVICE_ID_USE_TIMESTAMP:
652 : {
653 0 : dlt_daemon_control_service_response(sock,
654 : daemon,
655 : daemon_local,
656 : id,
657 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
658 : verbose);
659 0 : break;
660 : }
661 0 : case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
662 : {
663 0 : dlt_daemon_control_service_response(sock,
664 : daemon,
665 : daemon_local,
666 : id,
667 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
668 : verbose);
669 0 : break;
670 : }
671 0 : case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
672 : {
673 0 : dlt_daemon_control_set_default_log_level(sock, daemon, daemon_local, msg, verbose);
674 0 : break;
675 : }
676 0 : case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
677 : {
678 0 : dlt_daemon_control_set_default_trace_status(sock, daemon, daemon_local, msg, verbose);
679 0 : break;
680 : }
681 4 : case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
682 : {
683 4 : dlt_daemon_control_get_software_version(sock, daemon, daemon_local, verbose);
684 4 : break;
685 : }
686 0 : case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
687 : {
688 0 : dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter, "",
689 : verbose);
690 0 : break;
691 : }
692 2 : case DLT_SERVICE_ID_OFFLINE_LOGSTORAGE:
693 : {
694 2 : dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose);
695 2 : break;
696 : }
697 0 : case DLT_SERVICE_ID_PASSIVE_NODE_CONNECT:
698 : {
699 0 : dlt_daemon_control_passive_node_connect(sock,
700 : daemon,
701 : daemon_local,
702 : msg,
703 : verbose);
704 0 : break;
705 : }
706 0 : case DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS:
707 : {
708 0 : dlt_daemon_control_passive_node_connect_status(sock,
709 : daemon,
710 : daemon_local,
711 : verbose);
712 0 : break;
713 : }
714 0 : case DLT_SERVICE_ID_SET_ALL_LOG_LEVEL:
715 : {
716 0 : dlt_daemon_control_set_all_log_level(sock, daemon, daemon_local, msg, verbose);
717 0 : break;
718 : }
719 0 : case DLT_SERVICE_ID_SET_ALL_TRACE_STATUS:
720 : {
721 0 : dlt_daemon_control_set_all_trace_status(sock, daemon, daemon_local, msg, verbose);
722 0 : break;
723 : }
724 0 : default:
725 : {
726 0 : dlt_daemon_control_service_response(sock,
727 : daemon,
728 : daemon_local,
729 : id,
730 : DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
731 : verbose);
732 0 : break;
733 : }
734 : }
735 : }
736 : else {
737 : /* Injection handling */
738 0 : dlt_daemon_control_callsw_cinjection(sock, daemon, daemon_local, msg, verbose);
739 : }
740 :
741 : return 0;
742 : }
743 :
744 4 : void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
745 : {
746 : DltMessage msg;
747 : uint32_t len;
748 : DltServiceGetSoftwareVersionResponse *resp;
749 :
750 4 : PRINT_FUNCTION_VERBOSE(verbose);
751 :
752 4 : if (daemon == 0)
753 0 : return;
754 :
755 : /* initialise new message */
756 4 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
757 0 : dlt_daemon_control_service_response(sock,
758 : daemon,
759 : daemon_local,
760 : DLT_SERVICE_ID_GET_SOFTWARE_VERSION,
761 : DLT_SERVICE_RESPONSE_ERROR,
762 : verbose);
763 0 : return;
764 : }
765 :
766 : /* prepare payload of data */
767 4 : len = (uint32_t) strlen(daemon->ECUVersionString);
768 :
769 : /* msg.datasize = sizeof(serviceID) + sizeof(status) + sizeof(length) + len */
770 4 : msg.datasize = (uint32_t) (sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) + len);
771 :
772 4 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
773 0 : free(msg.databuffer);
774 0 : msg.databuffer = 0;
775 : }
776 :
777 4 : if (msg.databuffer == 0) {
778 4 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
779 4 : msg.databuffersize = msg.datasize;
780 : }
781 :
782 4 : if (msg.databuffer == 0) {
783 0 : dlt_daemon_control_service_response(sock,
784 : daemon,
785 : daemon_local,
786 : DLT_SERVICE_ID_GET_SOFTWARE_VERSION,
787 : DLT_SERVICE_RESPONSE_ERROR,
788 : verbose);
789 0 : return;
790 : }
791 :
792 : resp = (DltServiceGetSoftwareVersionResponse *)msg.databuffer;
793 4 : resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
794 4 : resp->status = DLT_SERVICE_RESPONSE_OK;
795 4 : resp->length = len;
796 4 : memcpy(msg.databuffer + msg.datasize - len, daemon->ECUVersionString, len);
797 :
798 : /* send message */
799 4 : dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
800 :
801 : /* free message */
802 4 : dlt_message_free(&msg, 0);
803 : }
804 :
805 1 : void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
806 : {
807 : DltMessage msg;
808 : DltServiceGetDefaultLogLevelResponse *resp;
809 :
810 1 : PRINT_FUNCTION_VERBOSE(verbose);
811 :
812 1 : if (daemon == 0)
813 0 : return;
814 :
815 : /* initialise new message */
816 1 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
817 0 : dlt_daemon_control_service_response(sock,
818 : daemon,
819 : daemon_local,
820 : DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL,
821 : DLT_SERVICE_RESPONSE_ERROR,
822 : verbose);
823 0 : return;
824 : }
825 :
826 1 : msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
827 :
828 1 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
829 0 : free(msg.databuffer);
830 0 : msg.databuffer = 0;
831 : }
832 :
833 1 : if (msg.databuffer == 0) {
834 1 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
835 1 : msg.databuffersize = msg.datasize;
836 : }
837 :
838 1 : if (msg.databuffer == 0) {
839 0 : dlt_daemon_control_service_response(sock,
840 : daemon,
841 : daemon_local,
842 : DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL,
843 : DLT_SERVICE_RESPONSE_ERROR,
844 : verbose);
845 0 : return;
846 : }
847 :
848 : resp = (DltServiceGetDefaultLogLevelResponse *)msg.databuffer;
849 1 : resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
850 1 : resp->status = DLT_SERVICE_RESPONSE_OK;
851 1 : resp->log_level = (uint8_t) daemon->default_log_level;
852 :
853 : /* send message */
854 1 : dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
855 :
856 : /* free message */
857 1 : dlt_message_free(&msg, 0);
858 : }
859 :
860 4 : void dlt_daemon_control_get_log_info(int sock,
861 : DltDaemon *daemon,
862 : DltDaemonLocal *daemon_local,
863 : DltMessage *msg,
864 : int verbose)
865 : {
866 : DltServiceGetLogInfoRequest *req;
867 : DltMessage resp;
868 : DltDaemonContext *context = 0;
869 : DltDaemonApplication *application = 0;
870 :
871 : int num_applications = 0, num_contexts = 0;
872 4 : uint16_t count_app_ids = 0, count_con_ids = 0;
873 :
874 : #if (DLT_DEBUG_GETLOGINFO == 1)
875 : char buf[255];
876 : #endif
877 :
878 : int32_t i, j;
879 : size_t offset = 0;
880 : char *apid = 0;
881 : int8_t ll, ts;
882 : uint16_t len;
883 : int8_t value;
884 : size_t sizecont = 0;
885 : int offset_base;
886 :
887 : uint32_t sid;
888 :
889 : DltDaemonRegisteredUsers *user_list = NULL;
890 :
891 4 : PRINT_FUNCTION_VERBOSE(verbose);
892 :
893 4 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
894 0 : return;
895 :
896 4 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceGetLogInfoRequest)) < 0)
897 : return;
898 :
899 4 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
900 :
901 4 : if (user_list == NULL)
902 : return;
903 :
904 : /* prepare pointer to message request */
905 4 : req = (DltServiceGetLogInfoRequest *)(msg->databuffer);
906 :
907 : /* initialise new message */
908 4 : if (dlt_message_init(&resp, 0) == DLT_RETURN_ERROR) {
909 0 : dlt_daemon_control_service_response(sock,
910 : daemon,
911 : daemon_local,
912 : DLT_SERVICE_ID_GET_LOG_INFO,
913 : DLT_SERVICE_RESPONSE_ERROR,
914 : verbose);
915 0 : return;
916 : }
917 :
918 : /* check request */
919 4 : if ((req->options < 3) || (req->options > 7)) {
920 0 : dlt_daemon_control_service_response(sock,
921 : daemon,
922 : daemon_local,
923 : DLT_SERVICE_ID_GET_LOG_INFO,
924 : DLT_SERVICE_RESPONSE_ERROR,
925 : verbose);
926 0 : return;
927 : }
928 :
929 4 : if (req->apid[0] != '\0') {
930 0 : application = dlt_daemon_application_find(daemon,
931 0 : req->apid,
932 : daemon->ecuid,
933 : verbose);
934 :
935 0 : if (application) {
936 : num_applications = 1;
937 :
938 0 : if (req->ctid[0] != '\0') {
939 0 : context = dlt_daemon_context_find(daemon,
940 : req->apid,
941 0 : req->ctid,
942 : daemon->ecuid,
943 : verbose);
944 :
945 0 : num_contexts = ((context) ? 1 : 0);
946 : }
947 : else {
948 0 : num_contexts = application->num_contexts;
949 : }
950 : }
951 : else {
952 : num_applications = 0;
953 : num_contexts = 0;
954 : }
955 : }
956 : else {
957 : /* Request all applications and contexts */
958 4 : num_applications = user_list->num_applications;
959 4 : num_contexts = user_list->num_contexts;
960 : }
961 :
962 : /* prepare payload of data */
963 :
964 : /* Calculate maximum size for a response */
965 : resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
966 :
967 : sizecont = sizeof(uint32_t) /* context_id */;
968 :
969 : /* Add additional size for response of Mode 4, 6, 7 */
970 4 : if ((req->options == 4) || (req->options == 6) || (req->options == 7))
971 : sizecont += sizeof(int8_t); /* log level */
972 :
973 : /* Add additional size for response of Mode 5, 6, 7 */
974 4 : if ((req->options == 5) || (req->options == 6) || (req->options == 7))
975 4 : sizecont += sizeof(int8_t); /* trace status */
976 :
977 4 : resp.datasize += (uint32_t) (((uint32_t) num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
978 4 : ((size_t) num_contexts * sizecont));
979 :
980 4 : resp.datasize += (uint32_t) sizeof(uint16_t) /* count_app_ids */;
981 :
982 : /* Add additional size for response of Mode 7 */
983 4 : if (req->options == 7) {
984 4 : if (req->apid[0] != '\0') {
985 0 : if (req->ctid[0] != '\0') {
986 : /* One application, one context */
987 : /* context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose); */
988 0 : if (context) {
989 0 : resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
990 :
991 0 : if (context->context_description != 0)
992 0 : resp.datasize += (uint32_t) strlen(context->context_description); /* context_description */
993 : }
994 : }
995 : else
996 : /* One application, all contexts */
997 0 : if ((user_list->applications) && (application)) {
998 : /* Calculate start offset within contexts[] */
999 : offset_base = 0;
1000 :
1001 0 : for (i = 0; i < (application - (user_list->applications)); i++)
1002 0 : offset_base += user_list->applications[i].num_contexts;
1003 :
1004 : /* Iterate over all contexts belonging to this application */
1005 0 : for (j = 0; j < application->num_contexts; j++) {
1006 :
1007 0 : context = &(user_list->contexts[offset_base + j]);
1008 :
1009 0 : if (context) {
1010 0 : resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
1011 :
1012 0 : if (context->context_description != 0)
1013 0 : resp.datasize += (uint32_t) strlen(context->context_description); /* context_description */
1014 : }
1015 : }
1016 : }
1017 :
1018 : /* Space for application description */
1019 0 : if (application) {
1020 0 : resp.datasize += (uint32_t) sizeof(uint16_t) /* len_app_description */;
1021 :
1022 0 : if (application->application_description != 0)
1023 0 : resp.datasize += (uint32_t) strlen(application->application_description); /* app_description */
1024 : }
1025 : }
1026 : else {
1027 : /* All applications, all contexts */
1028 4 : for (i = 0; i < user_list->num_contexts; i++) {
1029 0 : resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
1030 :
1031 0 : if (user_list->contexts[i].context_description != 0)
1032 0 : resp.datasize +=
1033 0 : (uint32_t) strlen(user_list->contexts[i].context_description);
1034 : }
1035 :
1036 4 : for (i = 0; i < user_list->num_applications; i++) {
1037 0 : resp.datasize += (uint32_t) sizeof(uint16_t) /* len_app_description */;
1038 :
1039 0 : if (user_list->applications[i].application_description != 0)
1040 0 : resp.datasize += (uint32_t) strlen(user_list->applications[i].application_description); /* app_description */
1041 : }
1042 : }
1043 : }
1044 :
1045 4 : if (verbose)
1046 0 : dlt_vlog(LOG_DEBUG,
1047 : "Allocate %u bytes for response msg databuffer\n",
1048 : resp.datasize);
1049 :
1050 : /* Allocate buffer for response message */
1051 4 : resp.databuffer = (uint8_t *)malloc(resp.datasize);
1052 4 : resp.databuffersize = resp.datasize;
1053 :
1054 4 : if (resp.databuffer == 0) {
1055 0 : dlt_daemon_control_service_response(sock,
1056 : daemon,
1057 : daemon_local,
1058 : DLT_SERVICE_ID_GET_LOG_INFO,
1059 : DLT_SERVICE_RESPONSE_ERROR,
1060 : verbose);
1061 0 : return;
1062 : }
1063 :
1064 : memset(resp.databuffer, 0, resp.datasize);
1065 : /* Preparation finished */
1066 :
1067 : /* Prepare response */
1068 4 : sid = DLT_SERVICE_ID_GET_LOG_INFO;
1069 : memcpy(resp.databuffer, &sid, sizeof(uint32_t));
1070 : offset += sizeof(uint32_t);
1071 :
1072 4 : value = (int8_t) (((num_applications != 0) && (num_contexts != 0)) ? req->options : 8); /* 8 = no matching context found */
1073 :
1074 4 : memcpy(resp.databuffer + offset, &value, sizeof(int8_t));
1075 : offset += sizeof(int8_t);
1076 :
1077 4 : count_app_ids = (uint16_t) num_applications;
1078 :
1079 4 : if (count_app_ids != 0) {
1080 0 : memcpy(resp.databuffer + offset, &count_app_ids, sizeof(uint16_t));
1081 : offset += sizeof(uint16_t);
1082 :
1083 : #if (DLT_DEBUG_GETLOGINFO == 1)
1084 : dlt_vlog(LOG_DEBUG, "#apid: %d \n", count_app_ids);
1085 : #endif
1086 :
1087 0 : for (i = 0; i < count_app_ids; i++) {
1088 0 : if (req->apid[0] != '\0') {
1089 0 : apid = req->apid;
1090 : }
1091 : else {
1092 0 : if (user_list->applications)
1093 0 : apid = user_list->applications[i].apid;
1094 : else
1095 : /* This should never occur! */
1096 : apid = 0;
1097 : }
1098 :
1099 0 : application = dlt_daemon_application_find(daemon,
1100 : apid,
1101 : daemon->ecuid,
1102 : verbose);
1103 :
1104 0 : if ((user_list->applications) && (application)) {
1105 : /* Calculate start offset within contexts[] */
1106 : offset_base = 0;
1107 :
1108 0 : for (j = 0; j < (application - (user_list->applications)); j++)
1109 0 : offset_base += user_list->applications[j].num_contexts;
1110 :
1111 0 : dlt_set_id((char *)(resp.databuffer + offset), apid);
1112 0 : offset += sizeof(ID4);
1113 :
1114 : #if (DLT_DEBUG_GETLOGINFO == 1)
1115 : dlt_print_id(buf, apid);
1116 : dlt_vlog(LOG_DEBUG, "apid: %s\n", buf);
1117 : #endif
1118 :
1119 0 : if (req->apid[0] != '\0')
1120 0 : count_con_ids = (uint16_t) num_contexts;
1121 : else
1122 0 : count_con_ids = (uint16_t) application->num_contexts;
1123 :
1124 0 : memcpy(resp.databuffer + offset, &count_con_ids, sizeof(uint16_t));
1125 0 : offset += sizeof(uint16_t);
1126 :
1127 : #if (DLT_DEBUG_GETLOGINFO == 1)
1128 : dlt_vlog(LOG_DEBUG, "#ctid: %d \n", count_con_ids);
1129 : #endif
1130 :
1131 0 : for (j = 0; j < count_con_ids; j++) {
1132 : #if (DLT_DEBUG_GETLOGINFO == 1)
1133 : dlt_vlog(LOG_DEBUG, "j: %d \n", j);
1134 : #endif
1135 :
1136 0 : if (!((count_con_ids == 1) && (req->apid[0] != '\0') &&
1137 0 : (req->ctid[0] != '\0')))
1138 0 : context = &(user_list->contexts[offset_base + j]);
1139 :
1140 : /* else: context was already searched and found
1141 : * (one application (found) with one context (found))*/
1142 :
1143 0 : if ((context) &&
1144 0 : ((req->ctid[0] == '\0') || ((req->ctid[0] != '\0') &&
1145 0 : (memcmp(context->ctid, req->ctid, DLT_ID_SIZE) == 0)))
1146 : ) {
1147 0 : dlt_set_id((char *)(resp.databuffer + offset), context->ctid);
1148 0 : offset += sizeof(ID4);
1149 :
1150 : #if (DLT_DEBUG_GETLOGINFO == 1)
1151 : dlt_print_id(buf, context->ctid);
1152 : dlt_vlog(LOG_DEBUG, "ctid: %s \n", buf);
1153 : #endif
1154 :
1155 : /* Mode 4, 6, 7 */
1156 0 : if ((req->options == 4) || (req->options == 6) || (req->options == 7)) {
1157 0 : ll = context->log_level;
1158 0 : memcpy(resp.databuffer + offset, &ll, sizeof(int8_t));
1159 0 : offset += sizeof(int8_t);
1160 : }
1161 :
1162 : /* Mode 5, 6, 7 */
1163 0 : if ((req->options == 5) || (req->options == 6) || (req->options == 7)) {
1164 0 : ts = context->trace_status;
1165 0 : memcpy(resp.databuffer + offset, &ts, sizeof(int8_t));
1166 0 : offset += sizeof(int8_t);
1167 : }
1168 :
1169 : /* Mode 7 */
1170 0 : if (req->options == 7) {
1171 0 : if (context->context_description) {
1172 0 : len = (uint16_t) strlen(context->context_description);
1173 0 : memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
1174 0 : offset += sizeof(uint16_t);
1175 0 : memcpy(resp.databuffer + offset, context->context_description,
1176 0 : strlen(context->context_description));
1177 0 : offset += strlen(context->context_description);
1178 : }
1179 : else {
1180 0 : len = 0;
1181 0 : memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
1182 0 : offset += sizeof(uint16_t);
1183 : }
1184 : }
1185 :
1186 : #if (DLT_DEBUG_GETLOGINFO == 1)
1187 : dlt_vlog(LOG_DEBUG, "ll=%d ts=%d \n", (int32_t)ll,
1188 : (int32_t)ts);
1189 : #endif
1190 : }
1191 :
1192 : #if (DLT_DEBUG_GETLOGINFO == 1)
1193 : dlt_log(LOG_DEBUG, "\n");
1194 : #endif
1195 : }
1196 :
1197 : /* Mode 7 */
1198 0 : if (req->options == 7) {
1199 0 : if (application->application_description) {
1200 0 : len = (uint16_t) strlen(application->application_description);
1201 0 : memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
1202 0 : offset += sizeof(uint16_t);
1203 0 : memcpy(resp.databuffer + offset, application->application_description,
1204 0 : strlen(application->application_description));
1205 0 : offset += strlen(application->application_description);
1206 : }
1207 : else {
1208 0 : len = 0;
1209 0 : memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
1210 0 : offset += sizeof(uint16_t);
1211 : }
1212 : }
1213 : } /* if (application) */
1214 :
1215 : } /* for (i=0;i<count_app_ids;i++) */
1216 :
1217 : } /* if (count_app_ids!=0) */
1218 :
1219 4 : dlt_set_id((char *)(resp.databuffer + offset), DLT_DAEMON_REMO_STRING);
1220 :
1221 : /* send message */
1222 4 : dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &resp, "", "", verbose);
1223 :
1224 : /* free message */
1225 4 : dlt_message_free(&resp, 0);
1226 : }
1227 :
1228 0 : int dlt_daemon_control_message_buffer_overflow(int sock,
1229 : DltDaemon *daemon,
1230 : DltDaemonLocal *daemon_local,
1231 : unsigned int overflow_counter,
1232 : char *apid,
1233 : int verbose)
1234 : {
1235 : int ret;
1236 : DltMessage msg;
1237 : DltServiceMessageBufferOverflowResponse *resp;
1238 :
1239 0 : PRINT_FUNCTION_VERBOSE(verbose);
1240 :
1241 0 : if (daemon == 0)
1242 : return DLT_DAEMON_ERROR_UNKNOWN;
1243 :
1244 : /* initialise new message */
1245 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
1246 0 : dlt_daemon_control_service_response(sock,
1247 : daemon,
1248 : daemon_local,
1249 : DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW,
1250 : DLT_SERVICE_RESPONSE_ERROR,
1251 : verbose);
1252 0 : return DLT_DAEMON_ERROR_UNKNOWN;
1253 : }
1254 :
1255 : /* prepare payload of data */
1256 0 : msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
1257 :
1258 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1259 0 : free(msg.databuffer);
1260 0 : msg.databuffer = 0;
1261 : }
1262 :
1263 0 : if (msg.databuffer == 0) {
1264 0 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1265 0 : msg.databuffersize = msg.datasize;
1266 : }
1267 :
1268 0 : if (msg.databuffer == 0)
1269 : return DLT_DAEMON_ERROR_UNKNOWN;
1270 :
1271 : resp = (DltServiceMessageBufferOverflowResponse *)msg.databuffer;
1272 0 : resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
1273 0 : resp->status = DLT_SERVICE_RESPONSE_OK;
1274 0 : resp->overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1275 0 : resp->overflow_counter = overflow_counter;
1276 :
1277 : /* send message */
1278 0 : if ((ret = dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, apid, "", verbose))) {
1279 0 : dlt_message_free(&msg, 0);
1280 0 : return ret;
1281 : }
1282 :
1283 : /* free message */
1284 0 : dlt_message_free(&msg, 0);
1285 :
1286 0 : return DLT_DAEMON_ERROR_OK;
1287 : }
1288 :
1289 3 : void dlt_daemon_control_service_response(int sock,
1290 : DltDaemon *daemon,
1291 : DltDaemonLocal *daemon_local,
1292 : uint32_t service_id,
1293 : int8_t status,
1294 : int verbose)
1295 : {
1296 : DltMessage msg;
1297 : DltServiceResponse *resp;
1298 :
1299 3 : PRINT_FUNCTION_VERBOSE(verbose);
1300 :
1301 3 : if (daemon == 0)
1302 0 : return;
1303 :
1304 : /* initialise new message */
1305 3 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1306 : return;
1307 :
1308 : /* prepare payload of data */
1309 3 : msg.datasize = sizeof(DltServiceResponse);
1310 :
1311 3 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1312 0 : free(msg.databuffer);
1313 0 : msg.databuffer = 0;
1314 : }
1315 :
1316 3 : if (msg.databuffer == 0) {
1317 3 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1318 3 : msg.databuffersize = msg.datasize;
1319 : }
1320 :
1321 3 : if (msg.databuffer == 0)
1322 : return;
1323 :
1324 : resp = (DltServiceResponse *)msg.databuffer;
1325 3 : resp->service_id = service_id;
1326 3 : resp->status = (uint8_t) status;
1327 :
1328 : /* send message */
1329 3 : dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
1330 :
1331 : /* free message */
1332 3 : dlt_message_free(&msg, 0);
1333 : }
1334 :
1335 0 : int dlt_daemon_control_message_unregister_context(int sock,
1336 : DltDaemon *daemon,
1337 : DltDaemonLocal *daemon_local,
1338 : char *apid,
1339 : char *ctid,
1340 : char *comid,
1341 : int verbose)
1342 : {
1343 : DltMessage msg;
1344 : DltServiceUnregisterContext *resp;
1345 :
1346 0 : PRINT_FUNCTION_VERBOSE(verbose);
1347 :
1348 0 : if (daemon == 0)
1349 : return -1;
1350 :
1351 : /* initialise new message */
1352 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1353 : return -1;
1354 :
1355 : /* prepare payload of data */
1356 0 : msg.datasize = sizeof(DltServiceUnregisterContext);
1357 :
1358 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1359 0 : free(msg.databuffer);
1360 0 : msg.databuffer = 0;
1361 : }
1362 :
1363 0 : if (msg.databuffer == 0) {
1364 0 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1365 0 : msg.databuffersize = msg.datasize;
1366 : }
1367 :
1368 0 : if (msg.databuffer == 0)
1369 : return -1;
1370 :
1371 : resp = (DltServiceUnregisterContext *)msg.databuffer;
1372 0 : resp->service_id = DLT_SERVICE_ID_UNREGISTER_CONTEXT;
1373 0 : resp->status = DLT_SERVICE_RESPONSE_OK;
1374 0 : dlt_set_id(resp->apid, apid);
1375 0 : dlt_set_id(resp->ctid, ctid);
1376 0 : dlt_set_id(resp->comid, comid);
1377 :
1378 : /* send message */
1379 0 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1380 0 : dlt_message_free(&msg, 0);
1381 0 : return -1;
1382 : }
1383 :
1384 : /* free message */
1385 0 : dlt_message_free(&msg, 0);
1386 :
1387 0 : return 0;
1388 : }
1389 :
1390 9 : int dlt_daemon_control_message_connection_info(int sock,
1391 : DltDaemon *daemon,
1392 : DltDaemonLocal *daemon_local,
1393 : uint8_t state,
1394 : char *comid,
1395 : int verbose)
1396 : {
1397 : DltMessage msg;
1398 : DltServiceConnectionInfo *resp;
1399 :
1400 9 : PRINT_FUNCTION_VERBOSE(verbose);
1401 :
1402 9 : if (daemon == 0)
1403 : return -1;
1404 :
1405 : /* initialise new message */
1406 9 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1407 : return -1;
1408 :
1409 : /* prepare payload of data */
1410 9 : msg.datasize = sizeof(DltServiceConnectionInfo);
1411 :
1412 9 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1413 0 : free(msg.databuffer);
1414 0 : msg.databuffer = 0;
1415 : }
1416 :
1417 9 : if (msg.databuffer == 0) {
1418 9 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1419 9 : msg.databuffersize = msg.datasize;
1420 : }
1421 :
1422 9 : if (msg.databuffer == 0)
1423 : return -1;
1424 :
1425 : resp = (DltServiceConnectionInfo *)msg.databuffer;
1426 9 : resp->service_id = DLT_SERVICE_ID_CONNECTION_INFO;
1427 9 : resp->status = DLT_SERVICE_RESPONSE_OK;
1428 9 : resp->state = state;
1429 9 : dlt_set_id(resp->comid, comid);
1430 :
1431 : /* send message */
1432 9 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1433 0 : dlt_message_free(&msg, 0);
1434 0 : return -1;
1435 : }
1436 :
1437 : /* free message */
1438 9 : dlt_message_free(&msg, 0);
1439 :
1440 9 : return 0;
1441 : }
1442 :
1443 0 : int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1444 : {
1445 : DltMessage msg;
1446 : DltServiceTimezone *resp;
1447 :
1448 0 : PRINT_FUNCTION_VERBOSE(verbose);
1449 :
1450 0 : if (daemon == 0)
1451 : return -1;
1452 :
1453 : /* initialise new message */
1454 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1455 : return -1;
1456 :
1457 : /* prepare payload of data */
1458 0 : msg.datasize = sizeof(DltServiceTimezone);
1459 :
1460 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1461 0 : free(msg.databuffer);
1462 0 : msg.databuffer = 0;
1463 : }
1464 :
1465 0 : if (msg.databuffer == 0) {
1466 0 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1467 0 : msg.databuffersize = msg.datasize;
1468 : }
1469 :
1470 0 : if (msg.databuffer == 0)
1471 : return -1;
1472 :
1473 : resp = (DltServiceTimezone *)msg.databuffer;
1474 0 : resp->service_id = DLT_SERVICE_ID_TIMEZONE;
1475 0 : resp->status = DLT_SERVICE_RESPONSE_OK;
1476 :
1477 0 : time_t t = time(NULL);
1478 : struct tm lt;
1479 0 : tzset();
1480 0 : localtime_r(&t, <);
1481 : #if !defined(__CYGWIN__)
1482 0 : resp->timezone = (int32_t)lt.tm_gmtoff;
1483 : #endif
1484 0 : resp->isdst = (uint8_t)lt.tm_isdst;
1485 :
1486 : /* send message */
1487 0 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1488 0 : dlt_message_free(&msg, 0);
1489 0 : return -1;
1490 : }
1491 :
1492 : /* free message */
1493 0 : dlt_message_free(&msg, 0);
1494 :
1495 0 : return 0;
1496 : }
1497 :
1498 0 : int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1499 : {
1500 : DltMessage msg;
1501 : DltServiceMarker *resp;
1502 :
1503 0 : PRINT_FUNCTION_VERBOSE(verbose);
1504 :
1505 0 : if (daemon == 0)
1506 : return -1;
1507 :
1508 : /* initialise new message */
1509 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1510 : return -1;
1511 :
1512 : /* prepare payload of data */
1513 0 : msg.datasize = sizeof(DltServiceMarker);
1514 :
1515 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1516 0 : free(msg.databuffer);
1517 0 : msg.databuffer = 0;
1518 : }
1519 :
1520 0 : if (msg.databuffer == 0) {
1521 0 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
1522 0 : msg.databuffersize = msg.datasize;
1523 : }
1524 :
1525 0 : if (msg.databuffer == 0)
1526 : return -1;
1527 :
1528 : resp = (DltServiceMarker *)msg.databuffer;
1529 0 : resp->service_id = DLT_SERVICE_ID_MARKER;
1530 0 : resp->status = DLT_SERVICE_RESPONSE_OK;
1531 :
1532 : /* send message */
1533 0 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1534 0 : dlt_message_free(&msg, 0);
1535 0 : return -1;
1536 : }
1537 :
1538 : /* free message */
1539 0 : dlt_message_free(&msg, 0);
1540 :
1541 0 : return 0;
1542 : }
1543 :
1544 0 : void dlt_daemon_control_callsw_cinjection(int sock,
1545 : DltDaemon *daemon,
1546 : DltDaemonLocal *daemon_local,
1547 : DltMessage *msg,
1548 : int verbose)
1549 : {
1550 : char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
1551 : uint32_t id = 0, id_tmp = 0;
1552 : uint8_t *ptr;
1553 : DltDaemonContext *context;
1554 : uint32_t data_length_inject = 0;
1555 : uint32_t data_length_inject_tmp = 0;
1556 :
1557 : int32_t datalength;
1558 :
1559 : DltUserHeader userheader;
1560 : DltUserControlMsgInjection usercontext;
1561 : uint8_t *userbuffer;
1562 :
1563 0 : PRINT_FUNCTION_VERBOSE(verbose);
1564 :
1565 0 : if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1566 0 : return;
1567 :
1568 0 : datalength = (int32_t) msg->datasize;
1569 : ptr = msg->databuffer;
1570 :
1571 0 : DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); /* Get service id */
1572 0 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1573 :
1574 : /* injectionMode is disabled */
1575 0 : if (daemon_local->flags.injectionMode == 0) {
1576 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_PERM_DENIED, verbose);
1577 0 : return;
1578 : }
1579 :
1580 : /* id is always less than DLT_DAEMON_INJECTION_MAX since its type is uinit32_t */
1581 0 : if (id >= DLT_DAEMON_INJECTION_MIN) {
1582 : /* This a a real SW-C injection call */
1583 : data_length_inject = 0;
1584 : data_length_inject_tmp = 0;
1585 :
1586 0 : DLT_MSG_READ_VALUE(data_length_inject_tmp, ptr, datalength, uint32_t); /* Get data length */
1587 0 : data_length_inject = DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1588 :
1589 : /* Get context handle for apid, ctid (and seid) */
1590 : /* Warning: seid is ignored in this implementation! */
1591 0 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
1592 0 : dlt_set_id(apid, msg->extendedheader->apid);
1593 0 : dlt_set_id(ctid, msg->extendedheader->ctid);
1594 : }
1595 : else {
1596 : /* No extended header, and therefore no apid and ctid available */
1597 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1598 0 : return;
1599 : }
1600 :
1601 : /* At this point, apid and ctid is available */
1602 0 : context = dlt_daemon_context_find(daemon,
1603 : apid,
1604 : ctid,
1605 0 : daemon->ecuid,
1606 : verbose);
1607 :
1608 0 : if (context == 0) {
1609 : /* dlt_log(LOG_INFO,"No context found!\n"); */
1610 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1611 0 : return;
1612 : }
1613 :
1614 : /* Send user message to handle, specified in context */
1615 0 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION) < DLT_RETURN_OK) {
1616 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1617 0 : return;
1618 : }
1619 :
1620 0 : usercontext.log_level_pos = context->log_level_pos;
1621 :
1622 0 : if (data_length_inject > (uint32_t) msg->databuffersize) {
1623 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1624 0 : return;
1625 : }
1626 :
1627 0 : userbuffer = malloc(data_length_inject);
1628 :
1629 0 : if (userbuffer == 0) {
1630 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1631 0 : return;
1632 : }
1633 :
1634 0 : usercontext.data_length_inject = (uint32_t) data_length_inject;
1635 0 : usercontext.service_id = id;
1636 :
1637 : memcpy(userbuffer, ptr, (size_t) data_length_inject); /* Copy received injection to send buffer */
1638 :
1639 : /* write to FIFO */
1640 : DltReturnValue ret =
1641 0 : dlt_user_log_out3_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader),
1642 : &(usercontext), sizeof(DltUserControlMsgInjection),
1643 : userbuffer, (size_t) data_length_inject);
1644 :
1645 0 : if (ret < DLT_RETURN_OK) {
1646 0 : if (ret == DLT_RETURN_PIPE_ERROR) {
1647 : /* Close connection */
1648 0 : close(context->user_handle);
1649 0 : context->user_handle = DLT_FD_INIT;
1650 : }
1651 :
1652 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1653 : }
1654 : else {
1655 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1656 : }
1657 :
1658 0 : free(userbuffer);
1659 : userbuffer = 0;
1660 :
1661 : }
1662 : else {
1663 : /* Invalid ID */
1664 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
1665 : verbose);
1666 : }
1667 : }
1668 :
1669 0 : void dlt_daemon_send_log_level(int sock,
1670 : DltDaemon *daemon,
1671 : DltDaemonLocal *daemon_local,
1672 : DltDaemonContext *context,
1673 : int8_t loglevel,
1674 : int verbose)
1675 : {
1676 0 : PRINT_FUNCTION_VERBOSE(verbose);
1677 :
1678 : int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL;
1679 : int8_t old_log_level = 0;
1680 :
1681 0 : old_log_level = context->log_level;
1682 0 : context->log_level = loglevel; /* No endianess conversion necessary*/
1683 :
1684 0 : if ((context->user_handle >= DLT_FD_MINIMUM) &&
1685 0 : (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
1686 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
1687 : }
1688 : else {
1689 0 : dlt_log(LOG_ERR, "Log level could not be sent!\n");
1690 0 : context->log_level = old_log_level;
1691 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1692 : }
1693 0 : }
1694 :
1695 0 : void dlt_daemon_find_multiple_context_and_send_log_level(int sock,
1696 : DltDaemon *daemon,
1697 : DltDaemonLocal *daemon_local,
1698 : int8_t app_flag,
1699 : char *str,
1700 : int8_t len,
1701 : int8_t loglevel,
1702 : int verbose)
1703 : {
1704 0 : PRINT_FUNCTION_VERBOSE(verbose);
1705 :
1706 : int count = 0;
1707 : DltDaemonContext *context = NULL;
1708 0 : char src_str[DLT_ID_SIZE + 1] = { 0 };
1709 : int ret = 0;
1710 : DltDaemonRegisteredUsers *user_list = NULL;
1711 :
1712 0 : if (daemon == 0) {
1713 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
1714 0 : return;
1715 : }
1716 :
1717 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1718 :
1719 0 : if (user_list == NULL)
1720 : return;
1721 :
1722 0 : for (count = 0; count < user_list->num_contexts; count++) {
1723 0 : context = &(user_list->contexts[count]);
1724 :
1725 0 : if (context) {
1726 0 : if (app_flag == 1)
1727 0 : strncpy(src_str, context->apid, DLT_ID_SIZE);
1728 : else
1729 0 : strncpy(src_str, context->ctid, DLT_ID_SIZE);
1730 :
1731 0 : ret = strncmp(src_str, str, len);
1732 :
1733 0 : if (ret == 0)
1734 0 : dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose);
1735 0 : else if ((ret > 0) && (app_flag == 1))
1736 : break;
1737 : else
1738 0 : continue;
1739 : }
1740 : }
1741 : }
1742 :
1743 1 : void dlt_daemon_control_set_log_level(int sock,
1744 : DltDaemon *daemon,
1745 : DltDaemonLocal *daemon_local,
1746 : DltMessage *msg,
1747 : int verbose)
1748 : {
1749 1 : PRINT_FUNCTION_VERBOSE(verbose);
1750 :
1751 1 : char apid[DLT_ID_SIZE + 1] = { 0 };
1752 1 : char ctid[DLT_ID_SIZE + 1] = { 0 };
1753 : DltServiceSetLogLevel *req = NULL;
1754 : DltDaemonContext *context = NULL;
1755 : int8_t apid_length = 0;
1756 : int8_t ctid_length = 0;
1757 :
1758 1 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1759 0 : return;
1760 :
1761 1 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1762 : return;
1763 :
1764 1 : req = (DltServiceSetLogLevel *)(msg->databuffer);
1765 :
1766 1 : if (daemon_local->flags.enforceContextLLAndTS)
1767 0 : req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextLogLevel);
1768 :
1769 1 : dlt_set_id(apid, req->apid);
1770 1 : dlt_set_id(ctid, req->ctid);
1771 1 : apid_length = (int8_t) strlen(apid);
1772 1 : ctid_length = (int8_t) strlen(ctid);
1773 :
1774 1 : if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
1775 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1776 : daemon,
1777 : daemon_local,
1778 : 1,
1779 : apid,
1780 0 : (int8_t) (apid_length - 1),
1781 0 : (int8_t) req->log_level,
1782 : verbose);
1783 : }
1784 1 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
1785 : {
1786 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1787 : daemon,
1788 : daemon_local,
1789 : 0,
1790 : ctid,
1791 0 : (int8_t) (ctid_length - 1),
1792 0 : (int8_t) req->log_level,
1793 : verbose);
1794 : }
1795 1 : else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
1796 : {
1797 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1798 : daemon,
1799 : daemon_local,
1800 : 1,
1801 : apid,
1802 : DLT_ID_SIZE,
1803 0 : (int8_t) req->log_level,
1804 : verbose);
1805 : }
1806 1 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
1807 : {
1808 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1809 : daemon,
1810 : daemon_local,
1811 : 0,
1812 : ctid,
1813 : DLT_ID_SIZE,
1814 0 : (int8_t) req->log_level,
1815 : verbose);
1816 : }
1817 : else {
1818 1 : context = dlt_daemon_context_find(daemon,
1819 : apid,
1820 : ctid,
1821 1 : daemon->ecuid,
1822 : verbose);
1823 :
1824 : /* Set log level */
1825 1 : if (context != 0) {
1826 0 : dlt_daemon_send_log_level(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
1827 : }
1828 : else {
1829 1 : dlt_vlog(LOG_ERR, "Could not set log level: %d. Context [%.4s:%.4s] not found:", req->log_level, apid,
1830 : ctid);
1831 1 : dlt_daemon_control_service_response(sock,
1832 : daemon,
1833 : daemon_local,
1834 : DLT_SERVICE_ID_SET_LOG_LEVEL,
1835 : DLT_SERVICE_RESPONSE_ERROR,
1836 : verbose);
1837 : }
1838 : }
1839 : }
1840 :
1841 :
1842 0 : void dlt_daemon_send_trace_status(int sock,
1843 : DltDaemon *daemon,
1844 : DltDaemonLocal *daemon_local,
1845 : DltDaemonContext *context,
1846 : int8_t tracestatus,
1847 : int verbose)
1848 : {
1849 0 : PRINT_FUNCTION_VERBOSE(verbose);
1850 :
1851 : int32_t id = DLT_SERVICE_ID_SET_TRACE_STATUS;
1852 : int8_t old_trace_status = 0;
1853 :
1854 0 : old_trace_status = context->trace_status;
1855 0 : context->trace_status = tracestatus; /* No endianess conversion necessary*/
1856 :
1857 0 : if ((context->user_handle >= DLT_FD_MINIMUM) &&
1858 0 : (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
1859 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
1860 : }
1861 : else {
1862 0 : dlt_log(LOG_ERR, "Trace status could not be sent!\n");
1863 0 : context->trace_status = old_trace_status;
1864 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1865 : }
1866 0 : }
1867 :
1868 0 : void dlt_daemon_find_multiple_context_and_send_trace_status(int sock,
1869 : DltDaemon *daemon,
1870 : DltDaemonLocal *daemon_local,
1871 : int8_t app_flag,
1872 : char *str,
1873 : int8_t len,
1874 : int8_t tracestatus,
1875 : int verbose)
1876 : {
1877 0 : PRINT_FUNCTION_VERBOSE(verbose);
1878 :
1879 : int count = 0;
1880 : DltDaemonContext *context = NULL;
1881 0 : char src_str[DLT_ID_SIZE + 1] = { 0 };
1882 : int ret = 0;
1883 : DltDaemonRegisteredUsers *user_list = NULL;
1884 :
1885 0 : if (daemon == 0) {
1886 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
1887 0 : return;
1888 : }
1889 :
1890 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1891 :
1892 0 : if (user_list == NULL)
1893 : return;
1894 :
1895 0 : for (count = 0; count < user_list->num_contexts; count++) {
1896 0 : context = &(user_list->contexts[count]);
1897 :
1898 0 : if (context) {
1899 0 : if (app_flag == 1)
1900 0 : strncpy(src_str, context->apid, DLT_ID_SIZE);
1901 : else
1902 0 : strncpy(src_str, context->ctid, DLT_ID_SIZE);
1903 :
1904 0 : ret = strncmp(src_str, str, len);
1905 :
1906 0 : if (ret == 0)
1907 0 : dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, tracestatus, verbose);
1908 0 : else if ((ret > 0) && (app_flag == 1))
1909 : break;
1910 : else
1911 0 : continue;
1912 : }
1913 : }
1914 : }
1915 :
1916 0 : void dlt_daemon_control_set_trace_status(int sock,
1917 : DltDaemon *daemon,
1918 : DltDaemonLocal *daemon_local,
1919 : DltMessage *msg,
1920 : int verbose)
1921 : {
1922 0 : PRINT_FUNCTION_VERBOSE(verbose);
1923 :
1924 0 : char apid[DLT_ID_SIZE + 1] = { 0 };
1925 0 : char ctid[DLT_ID_SIZE + 1] = { 0 };
1926 : DltServiceSetLogLevel *req = NULL;
1927 : DltDaemonContext *context = NULL;
1928 : int8_t apid_length = 0;
1929 : int8_t ctid_length = 0;
1930 :
1931 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1932 0 : return;
1933 :
1934 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1935 : return;
1936 :
1937 0 : req = (DltServiceSetLogLevel *)(msg->databuffer);
1938 :
1939 0 : if (daemon_local->flags.enforceContextLLAndTS)
1940 0 : req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
1941 :
1942 0 : dlt_set_id(apid, req->apid);
1943 0 : dlt_set_id(ctid, req->ctid);
1944 0 : apid_length = (int8_t) strlen(apid);
1945 0 : ctid_length = (int8_t) strlen(ctid);
1946 :
1947 0 : if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
1948 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1949 : daemon,
1950 : daemon_local,
1951 : 1,
1952 : apid,
1953 0 : (int8_t) (apid_length - 1),
1954 0 : (int8_t) req->log_level,
1955 : verbose);
1956 : }
1957 0 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
1958 :
1959 : {
1960 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1961 : daemon,
1962 : daemon_local,
1963 : 0,
1964 : ctid,
1965 0 : (int8_t) (ctid_length - 1),
1966 0 : (int8_t) req->log_level,
1967 : verbose);
1968 : }
1969 0 : else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
1970 : {
1971 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1972 : daemon,
1973 : daemon_local,
1974 : 1,
1975 : apid,
1976 : DLT_ID_SIZE,
1977 0 : (int8_t) req->log_level,
1978 : verbose);
1979 : }
1980 0 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
1981 : {
1982 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1983 : daemon,
1984 : daemon_local,
1985 : 0,
1986 : ctid,
1987 : DLT_ID_SIZE,
1988 0 : (int8_t) req->log_level,
1989 : verbose);
1990 : }
1991 : else {
1992 0 : context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose);
1993 :
1994 : /* Set trace status */
1995 0 : if (context != 0) {
1996 0 : dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
1997 : }
1998 : else {
1999 0 : dlt_vlog(LOG_ERR,
2000 : "Could not set trace status: %d. Context [%.4s:%.4s] not found:",
2001 0 : req->log_level,
2002 : apid,
2003 : ctid);
2004 0 : dlt_daemon_control_service_response(sock,
2005 : daemon,
2006 : daemon_local,
2007 : DLT_SERVICE_ID_SET_LOG_LEVEL,
2008 : DLT_SERVICE_RESPONSE_ERROR,
2009 : verbose);
2010 : }
2011 : }
2012 : }
2013 :
2014 0 : void dlt_daemon_control_set_default_log_level(int sock,
2015 : DltDaemon *daemon,
2016 : DltDaemonLocal *daemon_local,
2017 : DltMessage *msg,
2018 : int verbose)
2019 : {
2020 0 : PRINT_FUNCTION_VERBOSE(verbose);
2021 :
2022 : DltServiceSetDefaultLogLevel *req;
2023 : uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
2024 :
2025 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2026 : return;
2027 :
2028 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2029 : return;
2030 :
2031 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2032 :
2033 : /* No endianess conversion necessary */
2034 0 : if (/*(req->log_level>=0) &&*/
2035 0 : (req->log_level <= DLT_LOG_VERBOSE)) {
2036 0 : if (daemon_local->flags.enforceContextLLAndTS)
2037 0 : daemon->default_log_level = getStatus(req->log_level, daemon_local->flags.contextLogLevel);
2038 : else
2039 0 : daemon->default_log_level = (int8_t) req->log_level; /* No endianess conversion necessary */
2040 :
2041 : /* Send Update to all contexts using the default log level */
2042 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2043 :
2044 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2045 : }
2046 : else {
2047 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2048 : }
2049 : }
2050 :
2051 0 : void dlt_daemon_control_set_all_log_level(int sock,
2052 : DltDaemon *daemon,
2053 : DltDaemonLocal *daemon_local,
2054 : DltMessage *msg,
2055 : int verbose)
2056 : {
2057 0 : PRINT_FUNCTION_VERBOSE(verbose);
2058 :
2059 : DltServiceSetDefaultLogLevel *req = NULL;
2060 : uint32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
2061 : int8_t loglevel = 0;
2062 :
2063 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
2064 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
2065 0 : return;
2066 : }
2067 :
2068 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2069 : return;
2070 :
2071 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2072 :
2073 : /* No endianess conversion necessary */
2074 0 : if ((req != NULL) && ((req->log_level <= DLT_LOG_VERBOSE) || (req->log_level == (uint8_t)DLT_LOG_DEFAULT))) {
2075 0 : loglevel = (int8_t) req->log_level;
2076 :
2077 : /* Send Update to all contexts using the new log level */
2078 0 : dlt_daemon_user_send_all_log_level_update(
2079 : daemon,
2080 : daemon_local->flags.enforceContextLLAndTS,
2081 0 : (int8_t)daemon_local->flags.contextLogLevel,
2082 : loglevel,
2083 : verbose);
2084 :
2085 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2086 : }
2087 : else {
2088 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2089 : }
2090 : }
2091 :
2092 0 : void dlt_daemon_control_set_default_trace_status(int sock,
2093 : DltDaemon *daemon,
2094 : DltDaemonLocal *daemon_local,
2095 : DltMessage *msg,
2096 : int verbose)
2097 : {
2098 0 : PRINT_FUNCTION_VERBOSE(verbose);
2099 :
2100 : /* Payload of request message */
2101 : DltServiceSetDefaultLogLevel *req;
2102 : uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
2103 :
2104 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2105 : return;
2106 :
2107 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2108 : return;
2109 :
2110 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2111 :
2112 : /* No endianess conversion necessary */
2113 0 : if ((req->log_level == DLT_TRACE_STATUS_OFF) ||
2114 : (req->log_level == DLT_TRACE_STATUS_ON)) {
2115 0 : if (daemon_local->flags.enforceContextLLAndTS)
2116 0 : daemon->default_trace_status = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
2117 : else
2118 0 : daemon->default_trace_status = (int8_t) req->log_level; /* No endianess conversion necessary*/
2119 :
2120 : /* Send Update to all contexts using the default trace status */
2121 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2122 :
2123 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2124 : }
2125 : else {
2126 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2127 : }
2128 : }
2129 :
2130 0 : void dlt_daemon_control_set_all_trace_status(int sock,
2131 : DltDaemon *daemon,
2132 : DltDaemonLocal *daemon_local,
2133 : DltMessage *msg,
2134 : int verbose)
2135 : {
2136 0 : PRINT_FUNCTION_VERBOSE(verbose);
2137 :
2138 : DltServiceSetDefaultLogLevel *req = NULL;
2139 : uint32_t id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS;
2140 : int8_t tracestatus = 0;
2141 :
2142 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
2143 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
2144 0 : return;
2145 : }
2146 :
2147 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2148 : return;
2149 :
2150 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2151 :
2152 : /* No endianess conversion necessary */
2153 0 : if ((req != NULL) &&
2154 0 : ((req->log_level <= DLT_TRACE_STATUS_ON) || (req->log_level == (uint8_t)DLT_TRACE_STATUS_DEFAULT))) {
2155 0 : if (daemon_local->flags.enforceContextLLAndTS)
2156 0 : tracestatus = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
2157 : else
2158 0 : tracestatus = (int8_t) req->log_level; /* No endianess conversion necessary */
2159 :
2160 : /* Send Update to all contexts using the new log level */
2161 0 : dlt_daemon_user_send_all_trace_status_update(daemon, tracestatus, verbose);
2162 :
2163 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2164 : }
2165 : else {
2166 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2167 : }
2168 : }
2169 :
2170 0 : void dlt_daemon_control_set_timing_packets(int sock,
2171 : DltDaemon *daemon,
2172 : DltDaemonLocal *daemon_local,
2173 : DltMessage *msg,
2174 : int verbose)
2175 : {
2176 0 : PRINT_FUNCTION_VERBOSE(verbose);
2177 :
2178 : DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
2179 : uint32_t id = DLT_SERVICE_ID_SET_TIMING_PACKETS;
2180 :
2181 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2182 : return;
2183 :
2184 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetVerboseMode)) < 0)
2185 : return;
2186 :
2187 0 : req = (DltServiceSetVerboseMode *)(msg->databuffer);
2188 :
2189 0 : if ((req->new_status == 0) || (req->new_status == 1)) {
2190 0 : daemon->timingpackets = req->new_status;
2191 :
2192 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2193 : }
2194 : else {
2195 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2196 : }
2197 : }
2198 :
2199 0 : void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2200 : {
2201 : DltMessage msg;
2202 : int32_t len;
2203 :
2204 0 : PRINT_FUNCTION_VERBOSE(verbose);
2205 :
2206 0 : if (daemon == 0)
2207 0 : return;
2208 :
2209 : /* initialise new message */
2210 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
2211 : return;
2212 :
2213 : /* send message */
2214 :
2215 : /* prepare storage header */
2216 0 : msg.storageheader = (DltStorageHeader *)msg.headerbuffer;
2217 0 : dlt_set_storageheader(msg.storageheader, daemon->ecuid);
2218 :
2219 : /* prepare standard header */
2220 0 : msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
2221 0 : msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
2222 :
2223 : #if (BYTE_ORDER == BIG_ENDIAN)
2224 : msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2225 : #endif
2226 :
2227 0 : msg.standardheader->mcnt = 0;
2228 :
2229 : /* Set header extra parameters */
2230 0 : dlt_set_id(msg.headerextra.ecu, daemon->ecuid);
2231 0 : msg.headerextra.tmsp = dlt_uptime();
2232 :
2233 0 : dlt_message_set_extraparameters(&msg, verbose);
2234 :
2235 : /* prepare extended header */
2236 0 : msg.extendedheader =
2237 0 : (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
2238 0 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2239 0 : msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
2240 :
2241 0 : msg.extendedheader->noar = 0; /* number of arguments */
2242 0 : dlt_set_id(msg.extendedheader->apid, ""); /* application id */
2243 0 : dlt_set_id(msg.extendedheader->ctid, ""); /* context id */
2244 :
2245 : /* prepare length information */
2246 0 : msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) +
2247 0 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2248 :
2249 0 : len = (int32_t) (msg.headersize - sizeof(DltStorageHeader) + msg.datasize);
2250 :
2251 0 : if (len > UINT16_MAX) {
2252 0 : dlt_log(LOG_WARNING, "Huge control message discarded!\n");
2253 :
2254 : /* free message */
2255 0 : dlt_message_free(&msg, 0);
2256 :
2257 0 : return;
2258 : }
2259 :
2260 0 : msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2261 :
2262 : /* Send message, ignore return value */
2263 0 : dlt_daemon_client_send(sock, daemon, daemon_local, msg.headerbuffer,
2264 : sizeof(DltStorageHeader),
2265 : msg.headerbuffer + sizeof(DltStorageHeader),
2266 : (int) msg.headersize - (int) sizeof(DltStorageHeader),
2267 0 : msg.databuffer, (int) msg.datasize, verbose);
2268 :
2269 : /* free message */
2270 0 : dlt_message_free(&msg, 0);
2271 : }
2272 :
2273 11 : int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
2274 : DltDaemonLocal *daemon_local,
2275 : DltReceiver *receiver,
2276 : int verbose)
2277 : {
2278 11 : uint64_t expir = 0;
2279 : ssize_t res = 0;
2280 :
2281 11 : PRINT_FUNCTION_VERBOSE(verbose);
2282 :
2283 11 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2284 0 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2285 0 : return -1;
2286 : }
2287 :
2288 11 : res = read(receiver->fd, &expir, sizeof(expir));
2289 :
2290 11 : if (res < 0) {
2291 0 : dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
2292 0 : strerror(errno));
2293 : /* Activity received on timer_wd, but unable to read the fd:
2294 : * let's go on sending notification */
2295 : }
2296 :
2297 11 : if ((daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
2298 : (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)) {
2299 0 : if (dlt_daemon_send_ringbuffer_to_client(daemon,
2300 : daemon_local,
2301 : daemon_local->flags.vflag))
2302 0 : dlt_log(LOG_DEBUG,
2303 : "Can't send contents of ring buffer to clients\n");
2304 : }
2305 :
2306 11 : if ((daemon->timingpackets) &&
2307 0 : (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
2308 0 : dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL,
2309 : daemon,
2310 : daemon_local,
2311 : daemon_local->flags.vflag);
2312 :
2313 11 : dlt_log(LOG_DEBUG, "Timer timingpacket\n");
2314 :
2315 11 : return 0;
2316 : }
2317 :
2318 0 : int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
2319 : DltDaemonLocal *daemon_local,
2320 : DltReceiver *receiver,
2321 : int verbose)
2322 : {
2323 0 : uint64_t expir = 0;
2324 : ssize_t res = 0;
2325 :
2326 0 : PRINT_FUNCTION_VERBOSE(verbose);
2327 :
2328 0 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2329 0 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2330 0 : return -1;
2331 : }
2332 :
2333 0 : res = read(receiver->fd, &expir, sizeof(expir));
2334 :
2335 0 : if (res < 0) {
2336 0 : dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
2337 0 : strerror(errno));
2338 : /* Activity received on timer_wd, but unable to read the fd:
2339 : * let's go on sending notification */
2340 : }
2341 :
2342 0 : if (daemon_local->flags.sendECUSoftwareVersion > 0)
2343 0 : dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL,
2344 : daemon,
2345 : daemon_local,
2346 : daemon_local->flags.vflag);
2347 :
2348 0 : if (daemon_local->flags.sendTimezone > 0) {
2349 : /* send timezone information */
2350 0 : time_t t = time(NULL);
2351 : struct tm lt;
2352 :
2353 : /*Added memset to avoid compiler warning for near initialization */
2354 : memset((void *)<, 0, sizeof(lt));
2355 0 : tzset();
2356 0 : localtime_r(&t, <);
2357 :
2358 0 : dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,
2359 : daemon,
2360 : daemon_local,
2361 : daemon_local->flags.vflag);
2362 : }
2363 :
2364 0 : dlt_log(LOG_DEBUG, "Timer ecuversion\n");
2365 :
2366 0 : return 0;
2367 : }
2368 :
2369 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2370 : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
2371 : DltDaemonLocal *daemon_local,
2372 : DltReceiver *receiver,
2373 : int verbose)
2374 : {
2375 : uint64_t expir = 0;
2376 : ssize_t res = -1;
2377 :
2378 : PRINT_FUNCTION_VERBOSE(verbose);
2379 :
2380 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2381 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2382 : return res;
2383 : }
2384 :
2385 : res = read(receiver->fd, &expir, sizeof(expir));
2386 :
2387 : if (res < 0) {
2388 : dlt_vlog(LOG_WARNING, "Failed to read timer_wd; %s\n", strerror(errno));
2389 : /* Activity received on timer_wd, but unable to read the fd:
2390 : * let's go on sending notification */
2391 : }
2392 :
2393 : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
2394 : if (!daemon->received_message_since_last_watchdog_interval) {
2395 : dlt_log(LOG_WARNING, "No new messages received since last watchdog timer run\n");
2396 : return 0;
2397 : }
2398 : daemon->received_message_since_last_watchdog_interval = 0;
2399 : #endif
2400 :
2401 : if (sd_notify(0, "WATCHDOG=1") < 0)
2402 : dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
2403 :
2404 : dlt_log(LOG_DEBUG, "Timer watchdog\n");
2405 :
2406 : return 0;
2407 : }
2408 : #else
2409 0 : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
2410 : DltDaemonLocal *daemon_local,
2411 : DltReceiver *receiver,
2412 : int verbose)
2413 : {
2414 : (void)daemon;
2415 : (void)daemon_local;
2416 : (void)receiver;
2417 : (void)verbose;
2418 :
2419 0 : dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n");
2420 :
2421 0 : return -1;
2422 : }
2423 : #endif
2424 :
2425 2 : void dlt_daemon_control_service_logstorage(int sock,
2426 : DltDaemon *daemon,
2427 : DltDaemonLocal *daemon_local,
2428 : DltMessage *msg,
2429 : int verbose)
2430 : {
2431 : DltServiceOfflineLogstorage *req = NULL;
2432 : int ret = 0;
2433 : unsigned int connection_type = 0;
2434 : DltLogStorage *device = NULL;
2435 : int device_index = -1;
2436 : uint32_t i = 0;
2437 :
2438 : int tmp_errno = 0;
2439 :
2440 2 : struct stat daemon_mpoint_st = {0};
2441 : int daemon_st_status = 0;
2442 :
2443 2 : struct stat req_mpoint_st = {0};
2444 : int req_st_status = 0;
2445 :
2446 2 : PRINT_FUNCTION_VERBOSE(verbose);
2447 :
2448 2 : if ((daemon == NULL) || (msg == NULL) || (daemon_local == NULL)) {
2449 0 : dlt_vlog(LOG_ERR,
2450 : "%s: Invalid function parameters\n",
2451 : __func__);
2452 0 : return;
2453 : }
2454 :
2455 2 : if ((daemon_local->flags.offlineLogstorageMaxDevices <= 0) || (msg->databuffer == NULL)) {
2456 0 : dlt_daemon_control_service_response(sock,
2457 : daemon,
2458 : daemon_local,
2459 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2460 : DLT_SERVICE_RESPONSE_ERROR,
2461 : verbose);
2462 :
2463 0 : dlt_log(LOG_INFO,
2464 : "Logstorage functionality not enabled or MAX device set is 0\n");
2465 0 : return;
2466 : }
2467 :
2468 2 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceOfflineLogstorage)) < 0)
2469 : return;
2470 :
2471 2 : req = (DltServiceOfflineLogstorage *)(msg->databuffer);
2472 :
2473 2 : if(req->connection_type != DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) {
2474 0 : req_st_status = stat(req->mount_point, &req_mpoint_st);
2475 0 : tmp_errno = errno;
2476 0 : if (req_st_status < 0) {
2477 0 : dlt_daemon_control_service_response(sock,
2478 : daemon,
2479 : daemon_local,
2480 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2481 : DLT_SERVICE_RESPONSE_ERROR,
2482 : verbose);
2483 :
2484 0 : dlt_vlog(LOG_WARNING,
2485 : "%s: Failed to stat requested mount point [%s] with error [%s]\n",
2486 : __func__, req->mount_point, strerror(tmp_errno));
2487 0 : return;
2488 : }
2489 : }
2490 :
2491 4 : for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++) {
2492 2 : connection_type = daemon->storage_handle[i].connection_type;
2493 :
2494 : memset(&daemon_mpoint_st, 0, sizeof(struct stat));
2495 2 : if (strlen(daemon->storage_handle[i].device_mount_point) > 1) {
2496 0 : daemon_st_status = stat(daemon->storage_handle[i].device_mount_point,
2497 : &daemon_mpoint_st);
2498 0 : tmp_errno = errno;
2499 :
2500 0 : if (daemon_st_status < 0) {
2501 0 : dlt_daemon_control_service_response(sock,
2502 : daemon,
2503 : daemon_local,
2504 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2505 : DLT_SERVICE_RESPONSE_ERROR,
2506 : verbose);
2507 0 : dlt_vlog(LOG_WARNING,
2508 : "%s: Failed to stat daemon mount point [%s] with error [%s]\n",
2509 0 : __func__, daemon->storage_handle[i].device_mount_point,
2510 : strerror(tmp_errno));
2511 0 : return;
2512 : }
2513 :
2514 : /* Check if the requested device path is already used as log storage device */
2515 0 : if (req_mpoint_st.st_dev == daemon_mpoint_st.st_dev &&
2516 0 : req_mpoint_st.st_ino == daemon_mpoint_st.st_ino) {
2517 0 : device_index = (int) i;
2518 0 : break;
2519 : }
2520 : }
2521 :
2522 : /* Get first available device index here */
2523 2 : if ((connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) &&
2524 2 : (device_index == -1))
2525 0 : device_index = (int) i;
2526 : }
2527 :
2528 : /* It might be possible to sync all caches of all devices */
2529 2 : if ((req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) &&
2530 2 : (strlen(req->mount_point) == 0)) {
2531 : /* It is expected to receive an empty mount point to sync all Logstorage
2532 : * devices in this case. */
2533 : }
2534 0 : else if (device_index == -1) {
2535 0 : dlt_daemon_control_service_response(sock,
2536 : daemon,
2537 : daemon_local,
2538 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2539 : DLT_SERVICE_RESPONSE_ERROR,
2540 : verbose);
2541 0 : dlt_log(LOG_WARNING, "MAX devices already in use \n");
2542 0 : return;
2543 : }
2544 :
2545 : /* Check for device connection request from log storage ctrl app */
2546 2 : device = &daemon->storage_handle[device_index];
2547 :
2548 2 : if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
2549 0 : ret = dlt_logstorage_device_connected(device, req->mount_point);
2550 :
2551 0 : if (ret == 1) {
2552 0 : dlt_daemon_control_service_response(sock,
2553 : daemon,
2554 : daemon_local,
2555 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2556 : DLT_SERVICE_RESPONSE_WARNING,
2557 : verbose);
2558 0 : return;
2559 : }
2560 0 : else if (ret != 0)
2561 : {
2562 0 : dlt_daemon_control_service_response(sock,
2563 : daemon,
2564 : daemon_local,
2565 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2566 : DLT_SERVICE_RESPONSE_ERROR,
2567 : verbose);
2568 0 : return;
2569 : }
2570 :
2571 0 : dlt_daemon_control_service_response(sock,
2572 : daemon,
2573 : daemon_local,
2574 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2575 : DLT_SERVICE_RESPONSE_OK,
2576 : verbose);
2577 :
2578 : /* Update maintain logstorage loglevel if necessary */
2579 0 : if (daemon->storage_handle[device_index].maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF)
2580 : {
2581 0 : daemon->maintain_logstorage_loglevel = daemon->storage_handle[device_index].maintain_logstorage_loglevel;
2582 : }
2583 :
2584 : /* Check if log level of running application needs an update */
2585 0 : dlt_daemon_logstorage_update_application_loglevel(daemon,
2586 : daemon_local,
2587 : device_index,
2588 : verbose);
2589 :
2590 : }
2591 : /* Check for device disconnection request from log storage ctrl app */
2592 2 : else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED)
2593 : {
2594 : /* Check if log level of running application needs to be reset */
2595 0 : dlt_daemon_logstorage_reset_application_loglevel(
2596 : daemon,
2597 : daemon_local,
2598 : device_index,
2599 : (int) daemon_local->flags.offlineLogstorageMaxDevices,
2600 : verbose);
2601 :
2602 0 : dlt_logstorage_device_disconnected(&(daemon->storage_handle[device_index]),
2603 : DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
2604 :
2605 0 : dlt_daemon_control_service_response(sock,
2606 : daemon,
2607 : daemon_local,
2608 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2609 : DLT_SERVICE_RESPONSE_OK,
2610 : verbose);
2611 :
2612 : }
2613 : /* Check for cache synchronization request from log storage ctrl app */
2614 2 : else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES)
2615 : {
2616 : ret = 0;
2617 :
2618 2 : if (device_index == -1) { /* sync all Logstorage devices */
2619 :
2620 4 : for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++)
2621 2 : if (daemon->storage_handle[i].connection_type ==
2622 : DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
2623 2 : ret = dlt_daemon_logstorage_sync_cache(
2624 : daemon,
2625 : daemon_local,
2626 2 : daemon->storage_handle[i].device_mount_point,
2627 : verbose);
2628 : }
2629 : else {
2630 : /* trigger logstorage to sync caches */
2631 0 : ret = dlt_daemon_logstorage_sync_cache(daemon,
2632 : daemon_local,
2633 0 : req->mount_point,
2634 : verbose);
2635 : }
2636 :
2637 2 : if (ret == 0)
2638 2 : dlt_daemon_control_service_response(sock,
2639 : daemon,
2640 : daemon_local,
2641 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2642 : DLT_SERVICE_RESPONSE_OK,
2643 : verbose);
2644 : else
2645 0 : dlt_daemon_control_service_response(sock,
2646 : daemon,
2647 : daemon_local,
2648 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2649 : DLT_SERVICE_RESPONSE_ERROR,
2650 : verbose);
2651 : }
2652 : else {
2653 0 : dlt_daemon_control_service_response(sock,
2654 : daemon,
2655 : daemon_local,
2656 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2657 : DLT_SERVICE_RESPONSE_ERROR,
2658 : verbose);
2659 : }
2660 : }
2661 :
2662 0 : void dlt_daemon_control_passive_node_connect(int sock,
2663 : DltDaemon *daemon,
2664 : DltDaemonLocal *daemon_local,
2665 : DltMessage *msg,
2666 : int verbose)
2667 : {
2668 0 : PRINT_FUNCTION_VERBOSE(verbose);
2669 :
2670 : DltServicePassiveNodeConnect *req;
2671 : uint32_t id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
2672 :
2673 0 : if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) ||
2674 0 : (msg->databuffer == NULL))
2675 : return;
2676 :
2677 : /* return error, if gateway mode not enabled*/
2678 0 : if (daemon_local->flags.gatewayMode == 0) {
2679 0 : dlt_log(LOG_WARNING,
2680 : "Received passive node connection status request, "
2681 : "but GatewayMode is disabled\n");
2682 :
2683 0 : dlt_daemon_control_service_response(
2684 : sock,
2685 : daemon,
2686 : daemon_local,
2687 : DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
2688 : DLT_SERVICE_RESPONSE_ERROR,
2689 : verbose);
2690 :
2691 0 : return;
2692 : }
2693 :
2694 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServicePassiveNodeConnect)) < 0)
2695 : return;
2696 :
2697 0 : req = (DltServicePassiveNodeConnect *)msg->databuffer;
2698 :
2699 0 : if (dlt_gateway_process_on_demand_request(&daemon_local->pGateway,
2700 : daemon_local,
2701 0 : req->node_id,
2702 0 : (int) req->connection_status,
2703 : verbose) < 0)
2704 0 : dlt_daemon_control_service_response(sock,
2705 : daemon,
2706 : daemon_local,
2707 : id,
2708 : DLT_SERVICE_RESPONSE_ERROR,
2709 : verbose);
2710 : else
2711 0 : dlt_daemon_control_service_response(sock,
2712 : daemon,
2713 : daemon_local,
2714 : id,
2715 : DLT_SERVICE_RESPONSE_OK,
2716 : verbose);
2717 : }
2718 :
2719 0 : void dlt_daemon_control_passive_node_connect_status(int sock,
2720 : DltDaemon *daemon,
2721 : DltDaemonLocal *daemon_local,
2722 : int verbose)
2723 : {
2724 : DltMessage msg;
2725 : DltServicePassiveNodeConnectionInfo *resp;
2726 : DltGatewayConnection *con = NULL;
2727 : unsigned int i = 0;
2728 :
2729 0 : PRINT_FUNCTION_VERBOSE(verbose);
2730 :
2731 0 : if ((daemon == NULL) || (daemon_local == NULL))
2732 0 : return;
2733 :
2734 0 : if (dlt_message_init(&msg, verbose) == -1)
2735 : return;
2736 :
2737 : /* return error, if gateway mode not enabled*/
2738 0 : if (daemon_local->flags.gatewayMode == 0) {
2739 0 : dlt_log(LOG_WARNING,
2740 : "Received passive node connection status request, "
2741 : "but GatewayMode is disabled\n");
2742 :
2743 0 : dlt_daemon_control_service_response(
2744 : sock,
2745 : daemon,
2746 : daemon_local,
2747 : DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
2748 : DLT_SERVICE_RESPONSE_ERROR,
2749 : verbose);
2750 :
2751 0 : return;
2752 : }
2753 :
2754 : /* prepare payload of data */
2755 0 : msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo);
2756 :
2757 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize))
2758 0 : msg.databuffer = NULL;
2759 :
2760 0 : if (msg.databuffer == NULL) {
2761 0 : msg.databuffer = (uint8_t *)malloc(msg.datasize);
2762 :
2763 0 : if (msg.databuffer == NULL) {
2764 0 : dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n");
2765 0 : return;
2766 : }
2767 :
2768 0 : msg.databuffersize = msg.datasize;
2769 : }
2770 :
2771 0 : resp = (DltServicePassiveNodeConnectionInfo *)msg.databuffer;
2772 : memset(resp, 0, msg.datasize);
2773 0 : resp->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS;
2774 : resp->status = DLT_SERVICE_RESPONSE_OK;
2775 0 : resp->num_connections = (uint32_t) daemon_local->pGateway.num_connections;
2776 :
2777 0 : for (i = 0; i < resp->num_connections; i++) {
2778 0 : if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX) {
2779 0 : dlt_log(LOG_ERR,
2780 : "Maximal message size reached. Skip further information\n");
2781 0 : break;
2782 : }
2783 :
2784 0 : con = &daemon_local->pGateway.connections[i];
2785 :
2786 0 : resp->connection_status[i] = con->status;
2787 0 : memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE);
2788 : }
2789 :
2790 0 : dlt_daemon_client_send_control_message(sock,
2791 : daemon,
2792 : daemon_local,
2793 : &msg,
2794 : "",
2795 : "",
2796 : verbose);
2797 : /* free message */
2798 0 : dlt_message_free(&msg, verbose);
2799 : }
|