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