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 (int8_t)((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 transferred.
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 5885 : 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 5885 : 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 5885 : 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 : (char)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 : (char)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 5869 : if ((sock != DLT_DAEMON_SEND_FORCE) && (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)) {
225 5865 : 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 5865 : if (daemon_local->flags.offlineLogstorageMaxDevices > 0)
244 5839 : 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 5869 : 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 5869 : 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 5869 : if ((sock != DLT_DAEMON_SEND_FORCE) &&
290 5865 : ((daemon->state == DLT_DAEMON_STATE_BUFFER) || (daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
291 : (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))) {
292 5454 : if (daemon->state != DLT_DAEMON_STATE_BUFFER_FULL) {
293 : /* Store message in history buffer */
294 5454 : ret = dlt_buffer_push3(&(daemon->client_ringbuffer), data1, (unsigned int)size1, data2, (unsigned int)size2, 0U, 0U);
295 5454 : if (ret < DLT_RETURN_OK) {
296 0 : dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER_FULL);
297 : }
298 : }
299 5454 : 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 5809 : 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 5809 : PRINT_FUNCTION_VERBOSE(verbose);
339 :
340 5809 : 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 5809 : 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 5809 : if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) {
366 5809 : ecu_ptr = daemon_local->msg.headerextra.ecu;
367 : } else {
368 0 : ecu_ptr = daemon->ecuid;
369 : }
370 :
371 5809 : 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 5809 : 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 5809 : } 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 5809 : } 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 5809 : return dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local,
398 5809 : daemon_local->msg.headerbuffer, sizeof(DltStorageHeader),
399 : daemon_local->msg.headerbuffer + sizeof(DltStorageHeader),
400 5809 : (size_t)(daemon_local->msg.headersize - (int32_t)sizeof(DltStorageHeader)),
401 5809 : daemon_local->msg.databuffer, (size_t)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 = (int32_t)((size_t)sizeof(DltStorageHeader) + (size_t)sizeof(DltStandardHeader) + (size_t)sizeof(DltExtendedHeader) +
466 21 : (size_t)DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
467 :
468 21 : len = (int32_t)((size_t)msg->headersize - (size_t)sizeof(DltStorageHeader) + (size_t)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 : (size_t)(msg->headersize - (int32_t)sizeof(DltStorageHeader)),
481 21 : msg->databuffer, (size_t)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 = (int32_t)((size_t)sizeof(uint32_t) + (size_t)sizeof(uint8_t) + (size_t)sizeof(uint32_t) + (size_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((size_t)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((size_t)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 += (int32_t)(((size_t) num_applications * (sizeof(uint32_t) + sizeof(uint16_t))) +
985 4 : ((size_t) num_contexts * sizecont));
986 :
987 4 : resp.datasize += (int32_t)sizeof(uint16_t);
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 += (int32_t)sizeof(uint16_t);
997 :
998 0 : if (context->context_description != 0)
999 0 : resp.datasize += (int32_t)strlen(context->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 += (int32_t)sizeof(uint16_t);
1018 :
1019 0 : if (context->context_description != 0)
1020 0 : resp.datasize += (int32_t)strlen(context->context_description);
1021 : }
1022 : }
1023 : }
1024 :
1025 : /* Space for application description */
1026 0 : if (application) {
1027 0 : resp.datasize += (int32_t)sizeof(uint16_t);
1028 :
1029 0 : if (application->application_description != 0)
1030 0 : resp.datasize += (int32_t)strlen(application->application_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 += (int32_t)sizeof(uint16_t);
1037 :
1038 0 : if (user_list->contexts[i].context_description != 0)
1039 0 : resp.datasize +=
1040 0 : (int32_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 += (int32_t)sizeof(uint16_t);
1045 :
1046 0 : if (user_list->applications[i].application_description != 0)
1047 0 : resp.datasize += (int32_t)strlen(user_list->applications[i].application_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((size_t)resp.datasize);
1059 4 : resp.databuffersize = (size_t)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, (size_t)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((size_t)msg.datasize);
1272 0 : msg.databuffersize = (size_t)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((size_t)msg.datasize);
1325 3 : msg.databuffersize = (size_t)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((size_t)msg.datasize);
1372 0 : msg.databuffersize = (size_t)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((size_t)msg.datasize);
1426 9 : msg.databuffersize = (size_t)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((size_t)msg.datasize);
1474 0 : msg.databuffersize = (size_t)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(__USE_BSD) || defined(__USE_GNU) || defined(__APPLE__)
1489 0 : resp->timezone = (int32_t)lt.tm_gmtoff;
1490 : #else
1491 : /* Portable fallback: timezone is the difference in seconds between UTC and local time */
1492 : {
1493 : struct tm gmt;
1494 : gmtime_r(&t, &gmt);
1495 : resp->timezone = (int32_t)difftime(mktime(<), mktime(&gmt));
1496 : }
1497 : #endif
1498 0 : resp->isdst = (uint8_t)lt.tm_isdst;
1499 :
1500 : /* send message */
1501 0 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1502 0 : dlt_message_free(&msg, 0);
1503 0 : return -1;
1504 : }
1505 :
1506 : /* free message */
1507 0 : dlt_message_free(&msg, 0);
1508 :
1509 0 : return 0;
1510 : }
1511 :
1512 0 : int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1513 : {
1514 : DltMessage msg;
1515 : DltServiceMarker *resp;
1516 :
1517 0 : PRINT_FUNCTION_VERBOSE(verbose);
1518 :
1519 0 : if (daemon == 0)
1520 : return -1;
1521 :
1522 : /* initialise new message */
1523 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
1524 : return -1;
1525 :
1526 : /* prepare payload of data */
1527 0 : msg.datasize = sizeof(DltServiceMarker);
1528 :
1529 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
1530 0 : free(msg.databuffer);
1531 0 : msg.databuffer = 0;
1532 : }
1533 :
1534 0 : if (msg.databuffer == 0) {
1535 0 : msg.databuffer = (uint8_t *)malloc((size_t)msg.datasize);
1536 0 : msg.databuffersize = (size_t)msg.datasize;
1537 : }
1538 :
1539 0 : if (msg.databuffer == 0)
1540 : return -1;
1541 :
1542 : resp = (DltServiceMarker *)msg.databuffer;
1543 0 : resp->service_id = DLT_SERVICE_ID_MARKER;
1544 0 : resp->status = DLT_SERVICE_RESPONSE_OK;
1545 :
1546 : /* send message */
1547 0 : if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
1548 0 : dlt_message_free(&msg, 0);
1549 0 : return -1;
1550 : }
1551 :
1552 : /* free message */
1553 0 : dlt_message_free(&msg, 0);
1554 :
1555 0 : return 0;
1556 : }
1557 :
1558 0 : void dlt_daemon_control_callsw_cinjection(int sock,
1559 : DltDaemon *daemon,
1560 : DltDaemonLocal *daemon_local,
1561 : DltMessage *msg,
1562 : int verbose)
1563 : {
1564 : char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
1565 : uint32_t id = 0, id_tmp = 0;
1566 : uint8_t *ptr;
1567 : DltDaemonContext *context;
1568 : uint32_t data_length_inject = 0;
1569 : uint32_t data_length_inject_tmp = 0;
1570 :
1571 : int32_t datalength;
1572 :
1573 : DltUserHeader userheader;
1574 : DltUserControlMsgInjection usercontext;
1575 : uint8_t *userbuffer;
1576 :
1577 0 : PRINT_FUNCTION_VERBOSE(verbose);
1578 :
1579 0 : if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1580 0 : return;
1581 :
1582 0 : datalength = (int32_t) msg->datasize;
1583 : ptr = msg->databuffer;
1584 :
1585 0 : DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); /* Get service id */
1586 0 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1587 :
1588 : /* injectionMode is disabled */
1589 0 : if (daemon_local->flags.injectionMode == 0) {
1590 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_PERM_DENIED, verbose);
1591 0 : return;
1592 : }
1593 :
1594 : /* id is always less than DLT_DAEMON_INJECTION_MAX since its type is uinit32_t */
1595 0 : if (id >= DLT_DAEMON_INJECTION_MIN) {
1596 : /* This a a real SW-C injection call */
1597 : data_length_inject = 0;
1598 : data_length_inject_tmp = 0;
1599 :
1600 0 : DLT_MSG_READ_VALUE(data_length_inject_tmp, ptr, datalength, uint32_t); /* Get data length */
1601 0 : data_length_inject = DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1602 :
1603 : /* Get context handle for apid, ctid (and seid) */
1604 : /* Warning: seid is ignored in this implementation! */
1605 0 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
1606 0 : dlt_set_id(apid, msg->extendedheader->apid);
1607 0 : dlt_set_id(ctid, msg->extendedheader->ctid);
1608 : }
1609 : else {
1610 : /* No extended header, and therefore no apid and ctid available */
1611 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1612 0 : return;
1613 : }
1614 :
1615 : /* At this point, apid and ctid is available */
1616 0 : context = dlt_daemon_context_find(daemon,
1617 : apid,
1618 : ctid,
1619 0 : daemon->ecuid,
1620 : verbose);
1621 :
1622 0 : if (context == 0) {
1623 : /* dlt_log(LOG_INFO,"No context found!\n"); */
1624 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1625 0 : return;
1626 : }
1627 :
1628 : /* Send user message to handle, specified in context */
1629 0 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION) < DLT_RETURN_OK) {
1630 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1631 0 : return;
1632 : }
1633 :
1634 0 : usercontext.log_level_pos = context->log_level_pos;
1635 :
1636 0 : if (data_length_inject > (uint32_t) msg->databuffersize) {
1637 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1638 0 : return;
1639 : }
1640 :
1641 0 : userbuffer = malloc(data_length_inject);
1642 :
1643 0 : if (userbuffer == 0) {
1644 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1645 0 : return;
1646 : }
1647 :
1648 0 : usercontext.data_length_inject = (uint32_t) data_length_inject;
1649 0 : usercontext.service_id = id;
1650 :
1651 : memcpy(userbuffer, ptr, (size_t) data_length_inject); /* Copy received injection to send buffer */
1652 :
1653 : /* write to FIFO */
1654 : DltReturnValue ret =
1655 0 : dlt_user_log_out3_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader),
1656 : &(usercontext), sizeof(DltUserControlMsgInjection),
1657 : userbuffer, (size_t) data_length_inject);
1658 :
1659 0 : if (ret < DLT_RETURN_OK) {
1660 0 : if (ret == DLT_RETURN_PIPE_ERROR) {
1661 : /* Close connection */
1662 0 : close(context->user_handle);
1663 0 : context->user_handle = DLT_FD_INIT;
1664 : }
1665 :
1666 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1667 : }
1668 : else {
1669 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
1670 : }
1671 :
1672 0 : free(userbuffer);
1673 : userbuffer = 0;
1674 :
1675 : }
1676 : else {
1677 : /* Invalid ID */
1678 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
1679 : verbose);
1680 : }
1681 : }
1682 :
1683 0 : void dlt_daemon_send_log_level(int sock,
1684 : DltDaemon *daemon,
1685 : DltDaemonLocal *daemon_local,
1686 : DltDaemonContext *context,
1687 : int8_t loglevel,
1688 : int verbose)
1689 : {
1690 0 : PRINT_FUNCTION_VERBOSE(verbose);
1691 :
1692 : int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL;
1693 : int8_t old_log_level = 0;
1694 :
1695 0 : old_log_level = context->log_level;
1696 0 : context->log_level = loglevel; /* No endianess conversion necessary*/
1697 :
1698 0 : if ((context->user_handle >= DLT_FD_MINIMUM) &&
1699 0 : (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
1700 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
1701 : }
1702 : else {
1703 0 : dlt_log(LOG_ERR, "Log level could not be sent!\n");
1704 0 : context->log_level = old_log_level;
1705 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1706 : }
1707 0 : }
1708 :
1709 0 : void dlt_daemon_find_multiple_context_and_send_log_level(int sock,
1710 : DltDaemon *daemon,
1711 : DltDaemonLocal *daemon_local,
1712 : int8_t app_flag,
1713 : char *str,
1714 : int8_t len,
1715 : int8_t loglevel,
1716 : int verbose)
1717 : {
1718 0 : PRINT_FUNCTION_VERBOSE(verbose);
1719 :
1720 : int count = 0;
1721 : DltDaemonContext *context = NULL;
1722 0 : char src_str[DLT_ID_SIZE + 1] = { 0 };
1723 : int ret = 0;
1724 : DltDaemonRegisteredUsers *user_list = NULL;
1725 :
1726 0 : if (daemon == 0) {
1727 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
1728 0 : return;
1729 : }
1730 :
1731 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1732 :
1733 0 : if (user_list == NULL)
1734 : return;
1735 :
1736 0 : for (count = 0; count < user_list->num_contexts; count++) {
1737 0 : context = &(user_list->contexts[count]);
1738 :
1739 0 : if (context) {
1740 0 : if (app_flag == 1)
1741 0 : strncpy(src_str, context->apid, DLT_ID_SIZE);
1742 : else
1743 0 : strncpy(src_str, context->ctid, DLT_ID_SIZE);
1744 :
1745 0 : ret = strncmp(src_str, str, (size_t)len);
1746 :
1747 0 : if (ret == 0)
1748 0 : dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose);
1749 0 : else if ((ret > 0) && (app_flag == 1))
1750 : break;
1751 : else
1752 0 : continue;
1753 : }
1754 : }
1755 : }
1756 :
1757 1 : void dlt_daemon_control_set_log_level(int sock,
1758 : DltDaemon *daemon,
1759 : DltDaemonLocal *daemon_local,
1760 : DltMessage *msg,
1761 : int verbose)
1762 : {
1763 1 : PRINT_FUNCTION_VERBOSE(verbose);
1764 :
1765 1 : char apid[DLT_ID_SIZE + 1] = { 0 };
1766 1 : char ctid[DLT_ID_SIZE + 1] = { 0 };
1767 : DltServiceSetLogLevel *req = NULL;
1768 : DltDaemonContext *context = NULL;
1769 : int8_t apid_length = 0;
1770 : int8_t ctid_length = 0;
1771 :
1772 1 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1773 0 : return;
1774 :
1775 1 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1776 : return;
1777 :
1778 1 : req = (DltServiceSetLogLevel *)(msg->databuffer);
1779 :
1780 1 : if (daemon_local->flags.enforceContextLLAndTS)
1781 0 : req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextLogLevel);
1782 :
1783 1 : dlt_set_id(apid, req->apid);
1784 1 : dlt_set_id(ctid, req->ctid);
1785 1 : apid_length = (int8_t) strlen(apid);
1786 1 : ctid_length = (int8_t) strlen(ctid);
1787 :
1788 1 : if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
1789 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1790 : daemon,
1791 : daemon_local,
1792 : 1,
1793 : apid,
1794 0 : (int8_t) (apid_length - 1),
1795 0 : (int8_t) req->log_level,
1796 : verbose);
1797 : }
1798 1 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
1799 : {
1800 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1801 : daemon,
1802 : daemon_local,
1803 : 0,
1804 : ctid,
1805 0 : (int8_t) (ctid_length - 1),
1806 0 : (int8_t) req->log_level,
1807 : verbose);
1808 : }
1809 1 : else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
1810 : {
1811 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1812 : daemon,
1813 : daemon_local,
1814 : 1,
1815 : apid,
1816 : DLT_ID_SIZE,
1817 0 : (int8_t) req->log_level,
1818 : verbose);
1819 : }
1820 1 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
1821 : {
1822 0 : dlt_daemon_find_multiple_context_and_send_log_level(sock,
1823 : daemon,
1824 : daemon_local,
1825 : 0,
1826 : ctid,
1827 : DLT_ID_SIZE,
1828 0 : (int8_t) req->log_level,
1829 : verbose);
1830 : }
1831 : else {
1832 1 : context = dlt_daemon_context_find(daemon,
1833 : apid,
1834 : ctid,
1835 1 : daemon->ecuid,
1836 : verbose);
1837 :
1838 : /* Set log level */
1839 1 : if (context != 0) {
1840 0 : dlt_daemon_send_log_level(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
1841 : }
1842 : else {
1843 1 : dlt_vlog(LOG_ERR, "Could not set log level: %d. Context [%.4s:%.4s] not found:", req->log_level, apid,
1844 : ctid);
1845 1 : dlt_daemon_control_service_response(sock,
1846 : daemon,
1847 : daemon_local,
1848 : DLT_SERVICE_ID_SET_LOG_LEVEL,
1849 : DLT_SERVICE_RESPONSE_ERROR,
1850 : verbose);
1851 : }
1852 : }
1853 : }
1854 :
1855 :
1856 0 : void dlt_daemon_send_trace_status(int sock,
1857 : DltDaemon *daemon,
1858 : DltDaemonLocal *daemon_local,
1859 : DltDaemonContext *context,
1860 : int8_t tracestatus,
1861 : int verbose)
1862 : {
1863 0 : PRINT_FUNCTION_VERBOSE(verbose);
1864 :
1865 : int32_t id = DLT_SERVICE_ID_SET_TRACE_STATUS;
1866 : int8_t old_trace_status = 0;
1867 :
1868 0 : old_trace_status = context->trace_status;
1869 0 : context->trace_status = tracestatus; /* No endianess conversion necessary*/
1870 :
1871 0 : if ((context->user_handle >= DLT_FD_MINIMUM) &&
1872 0 : (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
1873 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
1874 : }
1875 : else {
1876 0 : dlt_log(LOG_ERR, "Trace status could not be sent!\n");
1877 0 : context->trace_status = old_trace_status;
1878 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1879 : }
1880 0 : }
1881 :
1882 0 : void dlt_daemon_find_multiple_context_and_send_trace_status(int sock,
1883 : DltDaemon *daemon,
1884 : DltDaemonLocal *daemon_local,
1885 : int8_t app_flag,
1886 : char *str,
1887 : int8_t len,
1888 : int8_t tracestatus,
1889 : int verbose)
1890 : {
1891 0 : PRINT_FUNCTION_VERBOSE(verbose);
1892 :
1893 : int count = 0;
1894 : DltDaemonContext *context = NULL;
1895 0 : char src_str[DLT_ID_SIZE + 1] = { 0 };
1896 : int ret = 0;
1897 : DltDaemonRegisteredUsers *user_list = NULL;
1898 :
1899 0 : if (daemon == 0) {
1900 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
1901 0 : return;
1902 : }
1903 :
1904 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1905 :
1906 0 : if (user_list == NULL)
1907 : return;
1908 :
1909 0 : for (count = 0; count < user_list->num_contexts; count++) {
1910 0 : context = &(user_list->contexts[count]);
1911 :
1912 0 : if (context) {
1913 0 : if (app_flag == 1)
1914 0 : strncpy(src_str, context->apid, DLT_ID_SIZE);
1915 : else
1916 0 : strncpy(src_str, context->ctid, DLT_ID_SIZE);
1917 :
1918 0 : ret = strncmp(src_str, str, (size_t)len);
1919 :
1920 0 : if (ret == 0)
1921 0 : dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, tracestatus, verbose);
1922 0 : else if ((ret > 0) && (app_flag == 1))
1923 : break;
1924 : else
1925 0 : continue;
1926 : }
1927 : }
1928 : }
1929 :
1930 0 : void dlt_daemon_control_set_trace_status(int sock,
1931 : DltDaemon *daemon,
1932 : DltDaemonLocal *daemon_local,
1933 : DltMessage *msg,
1934 : int verbose)
1935 : {
1936 0 : PRINT_FUNCTION_VERBOSE(verbose);
1937 :
1938 0 : char apid[DLT_ID_SIZE + 1] = { 0 };
1939 0 : char ctid[DLT_ID_SIZE + 1] = { 0 };
1940 : DltServiceSetLogLevel *req = NULL;
1941 : DltDaemonContext *context = NULL;
1942 : int8_t apid_length = 0;
1943 : int8_t ctid_length = 0;
1944 :
1945 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
1946 0 : return;
1947 :
1948 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
1949 : return;
1950 :
1951 0 : req = (DltServiceSetLogLevel *)(msg->databuffer);
1952 :
1953 0 : if (daemon_local->flags.enforceContextLLAndTS)
1954 0 : req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
1955 :
1956 0 : dlt_set_id(apid, req->apid);
1957 0 : dlt_set_id(ctid, req->ctid);
1958 0 : apid_length = (int8_t) strlen(apid);
1959 0 : ctid_length = (int8_t) strlen(ctid);
1960 :
1961 0 : if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
1962 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1963 : daemon,
1964 : daemon_local,
1965 : 1,
1966 : apid,
1967 0 : (int8_t) (apid_length - 1),
1968 0 : (int8_t) req->log_level,
1969 : verbose);
1970 : }
1971 0 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
1972 :
1973 : {
1974 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1975 : daemon,
1976 : daemon_local,
1977 : 0,
1978 : ctid,
1979 0 : (int8_t) (ctid_length - 1),
1980 0 : (int8_t) req->log_level,
1981 : verbose);
1982 : }
1983 0 : else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
1984 : {
1985 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1986 : daemon,
1987 : daemon_local,
1988 : 1,
1989 : apid,
1990 : DLT_ID_SIZE,
1991 0 : (int8_t) req->log_level,
1992 : verbose);
1993 : }
1994 0 : else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
1995 : {
1996 0 : dlt_daemon_find_multiple_context_and_send_trace_status(sock,
1997 : daemon,
1998 : daemon_local,
1999 : 0,
2000 : ctid,
2001 : DLT_ID_SIZE,
2002 0 : (int8_t) req->log_level,
2003 : verbose);
2004 : }
2005 : else {
2006 0 : context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose);
2007 :
2008 : /* Set trace status */
2009 0 : if (context != 0) {
2010 0 : dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
2011 : }
2012 : else {
2013 0 : dlt_vlog(LOG_ERR,
2014 : "Could not set trace status: %d. Context [%.4s:%.4s] not found:",
2015 0 : req->log_level,
2016 : apid,
2017 : ctid);
2018 0 : dlt_daemon_control_service_response(sock,
2019 : daemon,
2020 : daemon_local,
2021 : DLT_SERVICE_ID_SET_LOG_LEVEL,
2022 : DLT_SERVICE_RESPONSE_ERROR,
2023 : verbose);
2024 : }
2025 : }
2026 : }
2027 :
2028 0 : void dlt_daemon_control_set_default_log_level(int sock,
2029 : DltDaemon *daemon,
2030 : DltDaemonLocal *daemon_local,
2031 : DltMessage *msg,
2032 : int verbose)
2033 : {
2034 0 : PRINT_FUNCTION_VERBOSE(verbose);
2035 :
2036 : DltServiceSetDefaultLogLevel *req;
2037 : uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
2038 :
2039 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2040 : return;
2041 :
2042 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2043 : return;
2044 :
2045 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2046 :
2047 : /* No endianess conversion necessary */
2048 0 : if (/*(req->log_level>=0) &&*/
2049 0 : (req->log_level <= DLT_LOG_VERBOSE)) {
2050 0 : if (daemon_local->flags.enforceContextLLAndTS)
2051 0 : daemon->default_log_level = getStatus(req->log_level, daemon_local->flags.contextLogLevel);
2052 : else
2053 0 : daemon->default_log_level = (int8_t) req->log_level; /* No endianess conversion necessary */
2054 :
2055 : /* Send Update to all contexts using the default log level */
2056 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2057 :
2058 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2059 : }
2060 : else {
2061 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2062 : }
2063 : }
2064 :
2065 0 : void dlt_daemon_control_set_all_log_level(int sock,
2066 : DltDaemon *daemon,
2067 : DltDaemonLocal *daemon_local,
2068 : DltMessage *msg,
2069 : int verbose)
2070 : {
2071 0 : PRINT_FUNCTION_VERBOSE(verbose);
2072 :
2073 : DltServiceSetDefaultLogLevel *req = NULL;
2074 : uint32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
2075 : int8_t loglevel = 0;
2076 :
2077 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
2078 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
2079 0 : return;
2080 : }
2081 :
2082 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2083 : return;
2084 :
2085 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2086 :
2087 : /* No endianess conversion necessary */
2088 0 : if ((req != NULL) && ((req->log_level <= DLT_LOG_VERBOSE) || (req->log_level == (uint8_t)DLT_LOG_DEFAULT))) {
2089 0 : loglevel = (int8_t) req->log_level;
2090 :
2091 : /* Send Update to all contexts using the new log level */
2092 0 : dlt_daemon_user_send_all_log_level_update(
2093 : daemon,
2094 : daemon_local->flags.enforceContextLLAndTS,
2095 0 : (int8_t)daemon_local->flags.contextLogLevel,
2096 : loglevel,
2097 : verbose);
2098 :
2099 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2100 : }
2101 : else {
2102 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2103 : }
2104 : }
2105 :
2106 0 : void dlt_daemon_control_set_default_trace_status(int sock,
2107 : DltDaemon *daemon,
2108 : DltDaemonLocal *daemon_local,
2109 : DltMessage *msg,
2110 : int verbose)
2111 : {
2112 0 : PRINT_FUNCTION_VERBOSE(verbose);
2113 :
2114 : /* Payload of request message */
2115 : DltServiceSetDefaultLogLevel *req;
2116 : uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
2117 :
2118 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2119 : return;
2120 :
2121 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2122 : return;
2123 :
2124 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2125 :
2126 : /* No endianess conversion necessary */
2127 0 : if ((req->log_level == DLT_TRACE_STATUS_OFF) ||
2128 : (req->log_level == DLT_TRACE_STATUS_ON)) {
2129 0 : if (daemon_local->flags.enforceContextLLAndTS)
2130 0 : daemon->default_trace_status = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
2131 : else
2132 0 : daemon->default_trace_status = (int8_t) req->log_level; /* No endianess conversion necessary*/
2133 :
2134 : /* Send Update to all contexts using the default trace status */
2135 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2136 :
2137 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2138 : }
2139 : else {
2140 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2141 : }
2142 : }
2143 :
2144 0 : void dlt_daemon_control_set_all_trace_status(int sock,
2145 : DltDaemon *daemon,
2146 : DltDaemonLocal *daemon_local,
2147 : DltMessage *msg,
2148 : int verbose)
2149 : {
2150 0 : PRINT_FUNCTION_VERBOSE(verbose);
2151 :
2152 : DltServiceSetDefaultLogLevel *req = NULL;
2153 : uint32_t id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS;
2154 : int8_t tracestatus = 0;
2155 :
2156 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
2157 0 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
2158 0 : return;
2159 : }
2160 :
2161 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
2162 : return;
2163 :
2164 0 : req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
2165 :
2166 : /* No endianess conversion necessary */
2167 0 : if ((req != NULL) &&
2168 0 : ((req->log_level <= DLT_TRACE_STATUS_ON) || (req->log_level == (uint8_t)DLT_TRACE_STATUS_DEFAULT))) {
2169 0 : if (daemon_local->flags.enforceContextLLAndTS)
2170 0 : tracestatus = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
2171 : else
2172 0 : tracestatus = (int8_t) req->log_level; /* No endianess conversion necessary */
2173 :
2174 : /* Send Update to all contexts using the new log level */
2175 0 : dlt_daemon_user_send_all_trace_status_update(daemon, tracestatus, verbose);
2176 :
2177 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2178 : }
2179 : else {
2180 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2181 : }
2182 : }
2183 :
2184 0 : void dlt_daemon_control_set_timing_packets(int sock,
2185 : DltDaemon *daemon,
2186 : DltDaemonLocal *daemon_local,
2187 : DltMessage *msg,
2188 : int verbose)
2189 : {
2190 0 : PRINT_FUNCTION_VERBOSE(verbose);
2191 :
2192 : DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
2193 : uint32_t id = DLT_SERVICE_ID_SET_TIMING_PACKETS;
2194 :
2195 0 : if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
2196 : return;
2197 :
2198 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetVerboseMode)) < 0)
2199 : return;
2200 :
2201 0 : req = (DltServiceSetVerboseMode *)(msg->databuffer);
2202 :
2203 0 : if ((req->new_status == 0) || (req->new_status == 1)) {
2204 0 : daemon->timingpackets = req->new_status;
2205 :
2206 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
2207 : }
2208 : else {
2209 0 : dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
2210 : }
2211 : }
2212 :
2213 0 : void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2214 : {
2215 : DltMessage msg;
2216 : int32_t len;
2217 :
2218 0 : PRINT_FUNCTION_VERBOSE(verbose);
2219 :
2220 0 : if (daemon == 0)
2221 0 : return;
2222 :
2223 : /* initialise new message */
2224 0 : if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
2225 : return;
2226 :
2227 : /* send message */
2228 :
2229 : /* prepare storage header */
2230 0 : msg.storageheader = (DltStorageHeader *)msg.headerbuffer;
2231 0 : dlt_set_storageheader(msg.storageheader, daemon->ecuid);
2232 :
2233 : /* prepare standard header */
2234 0 : msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
2235 0 : msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
2236 :
2237 : #if (BYTE_ORDER == BIG_ENDIAN)
2238 : msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2239 : #endif
2240 :
2241 0 : msg.standardheader->mcnt = 0;
2242 :
2243 : /* Set header extra parameters */
2244 0 : dlt_set_id(msg.headerextra.ecu, daemon->ecuid);
2245 0 : msg.headerextra.tmsp = dlt_uptime();
2246 :
2247 0 : dlt_message_set_extraparameters(&msg, verbose);
2248 :
2249 : /* prepare extended header */
2250 0 : msg.extendedheader =
2251 0 : (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
2252 0 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2253 0 : msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
2254 :
2255 0 : msg.extendedheader->noar = 0; /* number of arguments */
2256 0 : dlt_set_id(msg.extendedheader->apid, ""); /* application id */
2257 0 : dlt_set_id(msg.extendedheader->ctid, ""); /* context id */
2258 :
2259 : /* prepare length information */
2260 0 : msg.headersize = (int32_t)((size_t)sizeof(DltStorageHeader) + (size_t)sizeof(DltStandardHeader) + (size_t)sizeof(DltExtendedHeader) +
2261 0 : (size_t)DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2262 :
2263 0 : len = (int32_t)((size_t)msg.headersize - (size_t)sizeof(DltStorageHeader) + (size_t)msg.datasize);
2264 :
2265 0 : if (len > UINT16_MAX) {
2266 0 : dlt_log(LOG_WARNING, "Huge control message discarded!\n");
2267 :
2268 : /* free message */
2269 0 : dlt_message_free(&msg, 0);
2270 :
2271 0 : return;
2272 : }
2273 :
2274 0 : msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2275 :
2276 : /* Send message, ignore return value */
2277 0 : dlt_daemon_client_send(sock, daemon, daemon_local, msg.headerbuffer,
2278 : sizeof(DltStorageHeader),
2279 : msg.headerbuffer + sizeof(DltStorageHeader),
2280 : (int) msg.headersize - (int) sizeof(DltStorageHeader),
2281 0 : msg.databuffer, (int) msg.datasize, verbose);
2282 :
2283 : /* free message */
2284 0 : dlt_message_free(&msg, 0);
2285 : }
2286 :
2287 11 : int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
2288 : DltDaemonLocal *daemon_local,
2289 : DltReceiver *receiver,
2290 : int verbose)
2291 : {
2292 11 : uint64_t expir = 0;
2293 : ssize_t res = 0;
2294 :
2295 11 : PRINT_FUNCTION_VERBOSE(verbose);
2296 :
2297 11 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2298 0 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2299 0 : return -1;
2300 : }
2301 :
2302 11 : res = read(receiver->fd, &expir, sizeof(expir));
2303 :
2304 11 : if (res < 0) {
2305 0 : dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
2306 0 : strerror(errno));
2307 : /* Activity received on timer_wd, but unable to read the fd:
2308 : * let's go on sending notification */
2309 : }
2310 :
2311 11 : if ((daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
2312 : (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)) {
2313 0 : if (dlt_daemon_send_ringbuffer_to_client(daemon,
2314 : daemon_local,
2315 : daemon_local->flags.vflag))
2316 0 : dlt_log(LOG_DEBUG,
2317 : "Can't send contents of ring buffer to clients\n");
2318 : }
2319 :
2320 11 : if ((daemon->timingpackets) &&
2321 0 : (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
2322 0 : dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL,
2323 : daemon,
2324 : daemon_local,
2325 : daemon_local->flags.vflag);
2326 :
2327 11 : dlt_log(LOG_DEBUG, "Timer timingpacket\n");
2328 :
2329 11 : return 0;
2330 : }
2331 :
2332 0 : int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
2333 : DltDaemonLocal *daemon_local,
2334 : DltReceiver *receiver,
2335 : int verbose)
2336 : {
2337 0 : uint64_t expir = 0;
2338 : ssize_t res = 0;
2339 :
2340 0 : PRINT_FUNCTION_VERBOSE(verbose);
2341 :
2342 0 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2343 0 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2344 0 : return -1;
2345 : }
2346 :
2347 0 : res = read(receiver->fd, &expir, sizeof(expir));
2348 :
2349 0 : if (res < 0) {
2350 0 : dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
2351 0 : strerror(errno));
2352 : /* Activity received on timer_wd, but unable to read the fd:
2353 : * let's go on sending notification */
2354 : }
2355 :
2356 0 : if (daemon_local->flags.sendECUSoftwareVersion > 0)
2357 0 : dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL,
2358 : daemon,
2359 : daemon_local,
2360 : daemon_local->flags.vflag);
2361 :
2362 0 : if (daemon_local->flags.sendTimezone > 0) {
2363 : /* send timezone information */
2364 0 : time_t t = time(NULL);
2365 : struct tm lt;
2366 :
2367 : /*Added memset to avoid compiler warning for near initialization */
2368 : memset((void *)<, 0, sizeof(lt));
2369 0 : tzset();
2370 0 : localtime_r(&t, <);
2371 :
2372 0 : dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,
2373 : daemon,
2374 : daemon_local,
2375 : daemon_local->flags.vflag);
2376 : }
2377 :
2378 0 : dlt_log(LOG_DEBUG, "Timer ecuversion\n");
2379 :
2380 0 : return 0;
2381 : }
2382 :
2383 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2384 : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
2385 : DltDaemonLocal *daemon_local,
2386 : DltReceiver *receiver,
2387 : int verbose)
2388 : {
2389 : uint64_t expir = 0;
2390 : ssize_t res = -1;
2391 :
2392 : PRINT_FUNCTION_VERBOSE(verbose);
2393 :
2394 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
2395 : dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
2396 : return res;
2397 : }
2398 :
2399 : res = read(receiver->fd, &expir, sizeof(expir));
2400 :
2401 : if (res < 0) {
2402 : dlt_vlog(LOG_WARNING, "Failed to read timer_wd; %s\n", strerror(errno));
2403 : /* Activity received on timer_wd, but unable to read the fd:
2404 : * let's go on sending notification */
2405 : }
2406 :
2407 : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
2408 : if (!daemon->received_message_since_last_watchdog_interval) {
2409 : dlt_log(LOG_WARNING, "No new messages received since last watchdog timer run\n");
2410 : return 0;
2411 : }
2412 : daemon->received_message_since_last_watchdog_interval = 0;
2413 : #endif
2414 :
2415 : dlt_daemon_trigger_systemd_watchdog_if_necessary(daemon);
2416 :
2417 : dlt_log(LOG_DEBUG, "Timer watchdog\n");
2418 :
2419 : return 0;
2420 : }
2421 : #else
2422 0 : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
2423 : DltDaemonLocal *daemon_local,
2424 : DltReceiver *receiver,
2425 : int verbose)
2426 : {
2427 : (void)daemon;
2428 : (void)daemon_local;
2429 : (void)receiver;
2430 : (void)verbose;
2431 :
2432 0 : dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n");
2433 :
2434 0 : return -1;
2435 : }
2436 : #endif
2437 :
2438 2 : void dlt_daemon_control_service_logstorage(int sock,
2439 : DltDaemon *daemon,
2440 : DltDaemonLocal *daemon_local,
2441 : DltMessage *msg,
2442 : int verbose)
2443 : {
2444 : DltServiceOfflineLogstorage *req = NULL;
2445 : int ret = 0;
2446 : unsigned int connection_type = 0;
2447 : DltLogStorage *device = NULL;
2448 : int device_index = -1;
2449 : uint32_t i = 0;
2450 :
2451 : int tmp_errno = 0;
2452 :
2453 2 : struct stat daemon_mpoint_st = {0};
2454 : int daemon_st_status = 0;
2455 :
2456 2 : struct stat req_mpoint_st = {0};
2457 : int req_st_status = 0;
2458 :
2459 2 : PRINT_FUNCTION_VERBOSE(verbose);
2460 :
2461 2 : if ((daemon == NULL) || (msg == NULL) || (daemon_local == NULL)) {
2462 0 : dlt_vlog(LOG_ERR,
2463 : "%s: Invalid function parameters\n",
2464 : __func__);
2465 0 : return;
2466 : }
2467 :
2468 2 : if ((daemon_local->flags.offlineLogstorageMaxDevices <= 0) || (msg->databuffer == NULL)) {
2469 0 : dlt_daemon_control_service_response(sock,
2470 : daemon,
2471 : daemon_local,
2472 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2473 : DLT_SERVICE_RESPONSE_ERROR,
2474 : verbose);
2475 :
2476 0 : dlt_log(LOG_INFO,
2477 : "Logstorage functionality not enabled or MAX device set is 0\n");
2478 0 : return;
2479 : }
2480 :
2481 2 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceOfflineLogstorage)) < 0)
2482 : return;
2483 :
2484 2 : req = (DltServiceOfflineLogstorage *)(msg->databuffer);
2485 :
2486 2 : if(req->connection_type != DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) {
2487 0 : req_st_status = stat(req->mount_point, &req_mpoint_st);
2488 0 : tmp_errno = errno;
2489 0 : if (req_st_status < 0) {
2490 0 : dlt_daemon_control_service_response(sock,
2491 : daemon,
2492 : daemon_local,
2493 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2494 : DLT_SERVICE_RESPONSE_ERROR,
2495 : verbose);
2496 :
2497 0 : dlt_vlog(LOG_WARNING,
2498 : "%s: Failed to stat requested mount point [%s] with error [%s]\n",
2499 : __func__, req->mount_point, strerror(tmp_errno));
2500 0 : return;
2501 : }
2502 : }
2503 :
2504 4 : for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++) {
2505 2 : connection_type = daemon->storage_handle[i].connection_type;
2506 :
2507 : memset(&daemon_mpoint_st, 0, sizeof(struct stat));
2508 2 : if (strlen(daemon->storage_handle[i].device_mount_point) > 1) {
2509 0 : daemon_st_status = stat(daemon->storage_handle[i].device_mount_point,
2510 : &daemon_mpoint_st);
2511 0 : tmp_errno = errno;
2512 :
2513 0 : if (daemon_st_status < 0) {
2514 0 : dlt_daemon_control_service_response(sock,
2515 : daemon,
2516 : daemon_local,
2517 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2518 : DLT_SERVICE_RESPONSE_ERROR,
2519 : verbose);
2520 0 : dlt_vlog(LOG_WARNING,
2521 : "%s: Failed to stat daemon mount point [%s] with error [%s]\n",
2522 0 : __func__, daemon->storage_handle[i].device_mount_point,
2523 : strerror(tmp_errno));
2524 0 : return;
2525 : }
2526 :
2527 : /* Check if the requested device path is already used as log storage device */
2528 0 : if (req_mpoint_st.st_dev == daemon_mpoint_st.st_dev &&
2529 0 : req_mpoint_st.st_ino == daemon_mpoint_st.st_ino) {
2530 0 : device_index = (int) i;
2531 0 : break;
2532 : }
2533 : }
2534 :
2535 : /* Get first available device index here */
2536 2 : if ((connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) &&
2537 2 : (device_index == -1))
2538 0 : device_index = (int) i;
2539 : }
2540 :
2541 : /* It might be possible to sync all caches of all devices */
2542 2 : if ((req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) &&
2543 2 : (strlen(req->mount_point) == 0)) {
2544 : /* It is expected to receive an empty mount point to sync all Logstorage
2545 : * devices in this case. */
2546 : }
2547 0 : else if (device_index == -1) {
2548 0 : dlt_daemon_control_service_response(sock,
2549 : daemon,
2550 : daemon_local,
2551 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2552 : DLT_SERVICE_RESPONSE_ERROR,
2553 : verbose);
2554 0 : dlt_log(LOG_WARNING, "MAX devices already in use \n");
2555 0 : return;
2556 : }
2557 :
2558 : /* Check for device connection request from log storage ctrl app */
2559 2 : device = &daemon->storage_handle[device_index];
2560 :
2561 2 : if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
2562 0 : ret = dlt_logstorage_device_connected(device, req->mount_point);
2563 :
2564 0 : if (ret == 1) {
2565 0 : dlt_daemon_control_service_response(sock,
2566 : daemon,
2567 : daemon_local,
2568 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2569 : DLT_SERVICE_RESPONSE_WARNING,
2570 : verbose);
2571 0 : return;
2572 : }
2573 0 : else if (ret != 0)
2574 : {
2575 0 : dlt_daemon_control_service_response(sock,
2576 : daemon,
2577 : daemon_local,
2578 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2579 : DLT_SERVICE_RESPONSE_ERROR,
2580 : verbose);
2581 0 : return;
2582 : }
2583 :
2584 0 : dlt_daemon_control_service_response(sock,
2585 : daemon,
2586 : daemon_local,
2587 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2588 : DLT_SERVICE_RESPONSE_OK,
2589 : verbose);
2590 :
2591 : /* Update maintain logstorage loglevel if necessary */
2592 0 : if (daemon->storage_handle[device_index].maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF)
2593 : {
2594 0 : daemon->maintain_logstorage_loglevel = daemon->storage_handle[device_index].maintain_logstorage_loglevel;
2595 : }
2596 :
2597 : /* Check if log level of running application needs an update */
2598 0 : dlt_daemon_logstorage_update_application_loglevel(daemon,
2599 : daemon_local,
2600 : device_index,
2601 : verbose);
2602 :
2603 : }
2604 : /* Check for device disconnection request from log storage ctrl app */
2605 2 : else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED)
2606 : {
2607 : /* Check if log level of running application needs to be reset */
2608 0 : dlt_daemon_logstorage_reset_application_loglevel(
2609 : daemon,
2610 : daemon_local,
2611 : device_index,
2612 : (int) daemon_local->flags.offlineLogstorageMaxDevices,
2613 : verbose);
2614 :
2615 0 : dlt_logstorage_device_disconnected(&(daemon->storage_handle[device_index]),
2616 : DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
2617 :
2618 0 : dlt_daemon_control_service_response(sock,
2619 : daemon,
2620 : daemon_local,
2621 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2622 : DLT_SERVICE_RESPONSE_OK,
2623 : verbose);
2624 :
2625 : }
2626 : /* Check for cache synchronization request from log storage ctrl app */
2627 2 : else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES)
2628 : {
2629 : ret = 0;
2630 :
2631 2 : if (device_index == -1) { /* sync all Logstorage devices */
2632 :
2633 4 : for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++)
2634 2 : if (daemon->storage_handle[i].connection_type ==
2635 : DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
2636 2 : ret = dlt_daemon_logstorage_sync_cache(
2637 : daemon,
2638 : daemon_local,
2639 2 : daemon->storage_handle[i].device_mount_point,
2640 : verbose);
2641 : }
2642 : else {
2643 : /* trigger logstorage to sync caches */
2644 0 : ret = dlt_daemon_logstorage_sync_cache(daemon,
2645 : daemon_local,
2646 0 : req->mount_point,
2647 : verbose);
2648 : }
2649 :
2650 2 : if (ret == 0)
2651 2 : dlt_daemon_control_service_response(sock,
2652 : daemon,
2653 : daemon_local,
2654 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2655 : DLT_SERVICE_RESPONSE_OK,
2656 : verbose);
2657 : else
2658 0 : dlt_daemon_control_service_response(sock,
2659 : daemon,
2660 : daemon_local,
2661 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2662 : DLT_SERVICE_RESPONSE_ERROR,
2663 : verbose);
2664 : }
2665 : else {
2666 0 : dlt_daemon_control_service_response(sock,
2667 : daemon,
2668 : daemon_local,
2669 : DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
2670 : DLT_SERVICE_RESPONSE_ERROR,
2671 : verbose);
2672 : }
2673 : }
2674 :
2675 0 : void dlt_daemon_control_passive_node_connect(int sock,
2676 : DltDaemon *daemon,
2677 : DltDaemonLocal *daemon_local,
2678 : DltMessage *msg,
2679 : int verbose)
2680 : {
2681 0 : PRINT_FUNCTION_VERBOSE(verbose);
2682 :
2683 : DltServicePassiveNodeConnect *req;
2684 : uint32_t id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
2685 :
2686 0 : if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) ||
2687 0 : (msg->databuffer == NULL))
2688 : return;
2689 :
2690 : /* return error, if gateway mode not enabled*/
2691 0 : if (daemon_local->flags.gatewayMode == 0) {
2692 0 : dlt_log(LOG_WARNING,
2693 : "Received passive node connection status request, "
2694 : "but GatewayMode is disabled\n");
2695 :
2696 0 : dlt_daemon_control_service_response(
2697 : sock,
2698 : daemon,
2699 : daemon_local,
2700 : DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
2701 : DLT_SERVICE_RESPONSE_ERROR,
2702 : verbose);
2703 :
2704 0 : return;
2705 : }
2706 :
2707 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServicePassiveNodeConnect)) < 0)
2708 : return;
2709 :
2710 0 : req = (DltServicePassiveNodeConnect *)msg->databuffer;
2711 :
2712 0 : if (dlt_gateway_process_on_demand_request(&daemon_local->pGateway,
2713 : daemon_local,
2714 0 : req->node_id,
2715 0 : (int) req->connection_status,
2716 : verbose) < 0)
2717 0 : dlt_daemon_control_service_response(sock,
2718 : daemon,
2719 : daemon_local,
2720 : id,
2721 : DLT_SERVICE_RESPONSE_ERROR,
2722 : verbose);
2723 : else
2724 0 : dlt_daemon_control_service_response(sock,
2725 : daemon,
2726 : daemon_local,
2727 : id,
2728 : DLT_SERVICE_RESPONSE_OK,
2729 : verbose);
2730 : }
2731 :
2732 0 : void dlt_daemon_control_passive_node_connect_status(int sock,
2733 : DltDaemon *daemon,
2734 : DltDaemonLocal *daemon_local,
2735 : int verbose)
2736 : {
2737 : DltMessage msg;
2738 : DltServicePassiveNodeConnectionInfo *resp;
2739 : DltGatewayConnection *con = NULL;
2740 : unsigned int i = 0;
2741 :
2742 0 : PRINT_FUNCTION_VERBOSE(verbose);
2743 :
2744 0 : if ((daemon == NULL) || (daemon_local == NULL))
2745 0 : return;
2746 :
2747 0 : if (dlt_message_init(&msg, verbose) == -1)
2748 : return;
2749 :
2750 : /* return error, if gateway mode not enabled*/
2751 0 : if (daemon_local->flags.gatewayMode == 0) {
2752 0 : dlt_log(LOG_WARNING,
2753 : "Received passive node connection status request, "
2754 : "but GatewayMode is disabled\n");
2755 :
2756 0 : dlt_daemon_control_service_response(
2757 : sock,
2758 : daemon,
2759 : daemon_local,
2760 : DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
2761 : DLT_SERVICE_RESPONSE_ERROR,
2762 : verbose);
2763 :
2764 0 : return;
2765 : }
2766 :
2767 : /* prepare payload of data */
2768 0 : msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo);
2769 :
2770 0 : if (msg.databuffer && (msg.databuffersize < msg.datasize))
2771 0 : msg.databuffer = NULL;
2772 :
2773 0 : if (msg.databuffer == NULL) {
2774 0 : msg.databuffer = (uint8_t *)malloc((size_t)msg.datasize);
2775 :
2776 0 : if (msg.databuffer == NULL) {
2777 0 : dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n");
2778 0 : return;
2779 : }
2780 :
2781 0 : msg.databuffersize = msg.datasize;
2782 : }
2783 :
2784 0 : resp = (DltServicePassiveNodeConnectionInfo *)msg.databuffer;
2785 : memset(resp, 0, (size_t)msg.datasize);
2786 0 : resp->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS;
2787 : resp->status = DLT_SERVICE_RESPONSE_OK;
2788 0 : resp->num_connections = (uint32_t) daemon_local->pGateway.num_connections;
2789 :
2790 0 : for (i = 0; i < resp->num_connections; i++) {
2791 0 : if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX) {
2792 0 : dlt_log(LOG_ERR,
2793 : "Maximal message size reached. Skip further information\n");
2794 0 : break;
2795 : }
2796 :
2797 0 : con = &daemon_local->pGateway.connections[i];
2798 :
2799 0 : resp->connection_status[i] = con->status;
2800 0 : memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE);
2801 : }
2802 :
2803 0 : dlt_daemon_client_send_control_message(sock,
2804 : daemon,
2805 : daemon_local,
2806 : &msg,
2807 : "",
2808 : "",
2809 : verbose);
2810 : /* free message */
2811 0 : dlt_message_free(&msg, verbose);
2812 : }
|