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 Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 : *
19 : * \copyright Copyright © 2011-2015 BMW AG. \n
20 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
21 : *
22 : * \file dlt_daemon_common.c
23 : */
24 :
25 : /*******************************************************************************
26 : ** **
27 : ** SRC-MODULE: dlt_daemon_common.c **
28 : ** **
29 : ** TARGET : linux **
30 : ** **
31 : ** PROJECT : DLT **
32 : ** **
33 : ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
34 : ** Markus Klein **
35 : ** **
36 : ** PURPOSE : **
37 : ** **
38 : ** REMARKS : **
39 : ** **
40 : ** PLATFORM DEPENDANT [yes/no]: yes **
41 : ** **
42 : ** TO BE CHANGED BY USER [yes/no]: no **
43 : ** **
44 : *******************************************************************************/
45 :
46 : /*******************************************************************************
47 : ** Author Identity **
48 : ********************************************************************************
49 : ** **
50 : ** Initials Name Company **
51 : ** -------- ------------------------- ---------------------------------- **
52 : ** aw Alexander Wenzel BMW **
53 : ** mk Markus Klein Fraunhofer ESK **
54 : *******************************************************************************/
55 :
56 : /*******************************************************************************
57 : ** Revision Control History **
58 : *******************************************************************************/
59 :
60 : /*
61 : * $LastChangedRevision: 1670 $
62 : * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
63 : * $LastChangedBy$
64 : * Initials Date Comment
65 : * aw 13.01.2010 initial
66 : */
67 :
68 : #include <stdbool.h>
69 : #include <stdio.h>
70 : #include <stdlib.h>
71 : #include <string.h>
72 : #include <syslog.h>
73 : #include <errno.h>
74 : #include <unistd.h>
75 : #include <fcntl.h>
76 :
77 : #include <sys/socket.h> /* send() */
78 :
79 : #include "dlt_types.h"
80 : #include "dlt_log.h"
81 : #include "dlt_daemon_common.h"
82 : #include "dlt_daemon_common_cfg.h"
83 : #include "dlt_user_shared.h"
84 : #include "dlt_user_shared_cfg.h"
85 : #include "dlt-daemon.h"
86 :
87 : #include "dlt_daemon_socket.h"
88 : #include "dlt_daemon_serial.h"
89 :
90 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
91 : # include <systemd/sd-daemon.h>
92 : #endif
93 :
94 : char *app_recv_buffer = NULL; /* pointer to receiver buffer for application msges */
95 :
96 0 : static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
97 : {
98 132 : if ((m1 == NULL) || (m2 == NULL))
99 : return -1;
100 :
101 : const DltDaemonApplication *mi1 = (const DltDaemonApplication *)m1;
102 : const DltDaemonApplication *mi2 = (const DltDaemonApplication *)m2;
103 :
104 132 : return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
105 : }
106 :
107 471 : static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
108 : {
109 471 : if ((m1 == NULL) || (m2 == NULL))
110 : return -1;
111 :
112 : int ret, cmp;
113 : const DltDaemonContext *mi1 = (const DltDaemonContext *)m1;
114 : const DltDaemonContext *mi2 = (const DltDaemonContext *)m2;
115 :
116 471 : cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
117 :
118 471 : if (cmp < 0)
119 : ret = -1;
120 471 : else if (cmp == 0)
121 471 : ret = memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
122 : else
123 : ret = 1;
124 :
125 : return ret;
126 : }
127 :
128 474 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon,
129 : char *ecu,
130 : int verbose)
131 : {
132 474 : PRINT_FUNCTION_VERBOSE(verbose);
133 :
134 : int i = 0;
135 :
136 474 : if ((daemon == NULL) || (ecu == NULL)) {
137 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
138 0 : return (DltDaemonRegisteredUsers *)NULL;
139 : }
140 :
141 476 : for (i = 0; i < daemon->num_user_lists; i++)
142 444 : if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
143 442 : return &daemon->user_list[i];
144 :
145 32 : dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %4s\n", ecu);
146 32 : return (DltDaemonRegisteredUsers *)NULL;
147 : }
148 :
149 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
150 :
151 : static int dlt_daemon_cmp_log_settings(const void *lhs, const void *rhs) {
152 : if ((lhs == NULL) || (rhs == NULL))
153 : return -1;
154 :
155 : DltDaemonContextLogSettings *settings1 = (DltDaemonContextLogSettings *)lhs;
156 : DltDaemonContextLogSettings *settings2 = (DltDaemonContextLogSettings *)rhs;
157 :
158 : int cmp = memcmp(settings1->apid, settings2->apid, DLT_ID_SIZE);
159 :
160 : if (cmp < 0)
161 : return -1;
162 : else if (cmp == 0)
163 : return memcmp(settings1->ctid, settings2->ctid, DLT_ID_SIZE);
164 : else
165 : return 1;
166 : }
167 :
168 : /**
169 : * Find configuration for app/ctx id specific log settings configuration
170 : * @param daemon pointer to dlt daemon struct
171 : * @param apid application id to use
172 : * @param ctid context id to use, can be NULL
173 : * @return pointer to log settings if found, otherwise NULL
174 : */
175 : DltDaemonContextLogSettings *dlt_daemon_find_configured_app_id_ctx_id_settings(
176 : const DltDaemon *daemon, const char *apid, const char *ctid) {
177 : DltDaemonContextLogSettings *app_id_settings = NULL;
178 : for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
179 : DltDaemonContextLogSettings *settings = &daemon->app_id_log_level_settings[i];
180 :
181 : if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
182 : if (app_id_settings != NULL)
183 : return app_id_settings;
184 : continue;
185 : }
186 :
187 : if (strlen(settings->ctid) == 0) {
188 : app_id_settings = settings;
189 : }
190 :
191 : if (ctid == NULL || strlen(ctid) == 0) {
192 : if (app_id_settings != NULL) {
193 : return app_id_settings;
194 : }
195 : } else {
196 : if (strncmp(ctid, settings->ctid, DLT_ID_SIZE) == 0) {
197 : return settings;
198 : }
199 : }
200 : }
201 :
202 : return app_id_settings;
203 : }
204 :
205 : /**
206 : * Find configured log levels in a given DltDaemonApplication for the passed context id.
207 : * @param app The application settings which contain the previously loaded ap id settings
208 : * @param ctid The context id to find.
209 : * @return Pointer to DltDaemonApplicationLogSettings containing the log level
210 : * for the requested application or NULL if none found.
211 : */
212 : DltDaemonContextLogSettings *dlt_daemon_find_app_log_level_config(
213 : const DltDaemonApplication *const app, const char *const ctid) {
214 :
215 : if (NULL == ctid)
216 : return NULL;
217 :
218 : DltDaemonContextLogSettings settings;
219 : memcpy(settings.apid, app->apid, DLT_ID_SIZE);
220 : memcpy(settings.ctid, ctid, DLT_ID_SIZE);
221 :
222 : DltDaemonContextLogSettings* log_settings = NULL;
223 : log_settings =
224 : (DltDaemonContextLogSettings *)bsearch(
225 : &settings, app->context_log_level_settings,
226 : (size_t)app->num_context_log_level_settings,
227 : sizeof(DltDaemonContextLogSettings),
228 : dlt_daemon_cmp_log_settings);
229 : return log_settings;
230 : }
231 :
232 : #endif
233 :
234 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
235 : int dlt_daemon_compare_trace_load_settings(const void *a, const void *b) {
236 : const DltTraceLoadSettings *s1 = (const DltTraceLoadSettings *)a;
237 : const DltTraceLoadSettings *s2 = (const DltTraceLoadSettings *)b;
238 :
239 : int cmp = strncmp(s1->apid, s2->apid, DLT_ID_SIZE);
240 : if (cmp != 0) {
241 : return cmp;
242 : }
243 :
244 : return strncmp(s1->ctid, s2->ctid, DLT_ID_SIZE);
245 : }
246 :
247 : DltReturnValue dlt_daemon_find_preconfigured_trace_load_settings(
248 : DltDaemon *const daemon, const char *apid, const char *ctid, DltTraceLoadSettings **settings, int *num_settings, int verbose)
249 : {
250 : PRINT_FUNCTION_VERBOSE(verbose);
251 : int i;
252 : *num_settings = 0;
253 : *settings = NULL;
254 :
255 : if ((daemon == NULL) || (apid == NULL)) {
256 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
257 : return DLT_RETURN_WRONG_PARAMETER;
258 : }
259 :
260 : if (NULL == daemon->preconfigured_trace_load_settings || daemon->preconfigured_trace_load_settings_count == 0) {
261 : return DLT_RETURN_OK;
262 : }
263 :
264 : for (i = 0; i < daemon->preconfigured_trace_load_settings_count; ++i) {
265 : // check if we can exit already, the trace load settings are sorted
266 : // and if the apid does not match anymore, but we already have settings
267 : // means we collected all settings
268 : if (strncmp(apid, daemon->preconfigured_trace_load_settings[i].apid, DLT_ID_SIZE) != 0) {
269 : if ((*num_settings) != 0)
270 : break;
271 : continue;
272 : }
273 :
274 : // If a ctid is passed, we only want to return entries where both match
275 : if (ctid != NULL && strlen(ctid) > 0) {
276 : if (strncmp(ctid, daemon->preconfigured_trace_load_settings[i].ctid, DLT_ID_SIZE) != 0) {
277 : continue;
278 : }
279 : }
280 :
281 : // Reallocate memory for the settings array with an additional slot for the new setting
282 : DltTraceLoadSettings *temp = realloc(*settings, (*num_settings + 1) * sizeof(DltTraceLoadSettings));
283 : if (temp == NULL) {
284 : dlt_vlog(LOG_ERR, "Failed to allocate memory for trace load settings\n");
285 : free(*settings); // Free any previously allocated memory
286 : *settings = NULL;
287 : *num_settings = 0;
288 : return DLT_RETURN_ERROR;
289 : }
290 : *settings = temp;
291 : // Copy preconfigured trace load settings into the app settings
292 : (*settings)[*num_settings] = daemon->preconfigured_trace_load_settings[i];
293 : (*num_settings)++;
294 : }
295 :
296 : qsort(*settings, (size_t)*num_settings, sizeof(DltTraceLoadSettings),
297 : dlt_daemon_compare_trace_load_settings);
298 : return DLT_RETURN_OK;
299 : }
300 : #endif
301 :
302 9 : int dlt_daemon_init_runtime_configuration(DltDaemon *daemon, const char *runtime_directory, int verbose)
303 : {
304 9 : PRINT_FUNCTION_VERBOSE(verbose);
305 : size_t append_length = 0;
306 :
307 9 : if (daemon == NULL)
308 : return DLT_RETURN_ERROR;
309 :
310 : /* Default */
311 9 : daemon->mode = DLT_USER_MODE_EXTERNAL;
312 :
313 9 : if (runtime_directory == NULL)
314 : return DLT_RETURN_ERROR;
315 :
316 : /* prepare filenames for configuration */
317 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
318 :
319 9 : if (runtime_directory[0]) {
320 0 : strncpy(daemon->runtime_application_cfg, runtime_directory, append_length);
321 0 : daemon->runtime_application_cfg[append_length] = 0;
322 : }
323 : else {
324 9 : strncpy(daemon->runtime_application_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
325 9 : daemon->runtime_application_cfg[append_length] = 0;
326 : }
327 :
328 9 : strcat(daemon->runtime_application_cfg, DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */
329 :
330 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
331 :
332 9 : if (runtime_directory[0]) {
333 0 : strncpy(daemon->runtime_context_cfg, runtime_directory, append_length);
334 0 : daemon->runtime_context_cfg[append_length] = 0;
335 : }
336 : else {
337 9 : strncpy(daemon->runtime_context_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
338 9 : daemon->runtime_context_cfg[append_length] = 0;
339 : }
340 :
341 9 : strcat(daemon->runtime_context_cfg, DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */
342 :
343 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
344 :
345 9 : if (runtime_directory[0]) {
346 0 : strncpy(daemon->runtime_configuration, runtime_directory, append_length);
347 0 : daemon->runtime_configuration[append_length] = 0;
348 : }
349 : else {
350 9 : strncpy(daemon->runtime_configuration, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
351 9 : daemon->runtime_configuration[append_length] = 0;
352 : }
353 :
354 9 : strcat(daemon->runtime_configuration, DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */
355 :
356 9 : return DLT_RETURN_OK;
357 : }
358 :
359 17 : int dlt_daemon_init(DltDaemon *daemon,
360 : unsigned long RingbufferMinSize,
361 : unsigned long RingbufferMaxSize,
362 : unsigned long RingbufferStepSize,
363 : const char *runtime_directory,
364 : int InitialContextLogLevel,
365 : int InitialContextTraceStatus,
366 : int ForceLLTS,
367 : int verbose)
368 : {
369 17 : PRINT_FUNCTION_VERBOSE(verbose);
370 :
371 17 : if ((daemon == NULL) || (runtime_directory == NULL))
372 : return -1;
373 :
374 17 : daemon->user_list = NULL;
375 17 : daemon->num_user_lists = 0;
376 :
377 17 : daemon->default_log_level = (int8_t) InitialContextLogLevel;
378 17 : daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
379 17 : daemon->force_ll_ts = (int8_t) ForceLLTS;
380 :
381 17 : daemon->overflow_counter = 0;
382 :
383 17 : daemon->runtime_context_cfg_loaded = 0;
384 :
385 17 : daemon->connectionState = 0; /* no logger connected */
386 :
387 17 : daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */
388 :
389 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
390 : daemon->preconfigured_trace_load_settings = NULL;
391 : daemon->bytes_sent = 0;
392 : daemon->bytes_recv = 0;
393 : #endif
394 :
395 17 : daemon->sendserialheader = 0;
396 17 : daemon->timingpackets = 0;
397 :
398 17 : dlt_set_id(daemon->ecuid, "");
399 :
400 : /* initialize ring buffer for client connection */
401 17 : dlt_vlog(LOG_INFO, "Ringbuffer configuration: %lu/%lu/%lu\n",
402 : RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize);
403 :
404 17 : if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer),
405 : (uint32_t) RingbufferMinSize,
406 : (uint32_t) RingbufferMaxSize,
407 : (uint32_t) RingbufferStepSize) < DLT_RETURN_OK)
408 : return -1;
409 :
410 17 : daemon->storage_handle = NULL;
411 : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
412 : daemon->received_message_since_last_watchdog_interval = 0;
413 : #endif
414 17 : return 0;
415 : }
416 :
417 9 : int dlt_daemon_free(DltDaemon *daemon, int verbose)
418 : {
419 : int i = 0;
420 : DltDaemonRegisteredUsers *user_list = NULL;
421 :
422 9 : PRINT_FUNCTION_VERBOSE(verbose);
423 :
424 9 : if ((daemon == NULL) || (daemon->user_list == NULL))
425 : return -1;
426 :
427 : /* free all registered user information */
428 19 : for (i = 0; i < daemon->num_user_lists; i++) {
429 10 : user_list = &daemon->user_list[i];
430 :
431 10 : if (user_list != NULL) {
432 : /* ignore return values */
433 10 : dlt_daemon_contexts_clear(daemon, user_list->ecu, verbose);
434 10 : dlt_daemon_applications_clear(daemon, user_list->ecu, verbose);
435 : }
436 : }
437 :
438 9 : free(daemon->user_list);
439 :
440 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
441 : if (daemon->app_id_log_level_settings != NULL) {
442 : free(daemon->app_id_log_level_settings);
443 : }
444 : #endif
445 :
446 9 : if (app_recv_buffer)
447 9 : free(app_recv_buffer);
448 :
449 : /* free ringbuffer */
450 9 : dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
451 :
452 9 : return 0;
453 : }
454 :
455 18 : int dlt_daemon_init_user_information(DltDaemon *daemon,
456 : DltGateway *gateway,
457 : int gateway_mode,
458 : int verbose)
459 : {
460 : int nodes = 1;
461 : int i = 1;
462 :
463 18 : PRINT_FUNCTION_VERBOSE(verbose);
464 :
465 18 : if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL)))
466 : return DLT_RETURN_ERROR;
467 :
468 18 : if (gateway_mode == 0) {
469 : /* initialize application list */
470 17 : daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
471 :
472 17 : if (daemon->user_list == NULL) {
473 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
474 0 : return DLT_RETURN_ERROR;
475 : }
476 :
477 17 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
478 17 : daemon->num_user_lists = 1;
479 : }
480 : else { /* gateway is active */
481 1 : nodes += gateway->num_connections;
482 :
483 : /* initialize application list */
484 1 : daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
485 :
486 1 : if (daemon->user_list == NULL) {
487 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
488 0 : return DLT_RETURN_ERROR;
489 : }
490 :
491 1 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
492 1 : daemon->num_user_lists = nodes;
493 :
494 2 : for (i = 1; i < nodes; i++)
495 1 : dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid);
496 : }
497 :
498 : return DLT_RETURN_OK;
499 : }
500 :
501 15 : int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,
502 : char *ecu,
503 : int fd,
504 : int verbose)
505 : {
506 : int i;
507 : DltDaemonRegisteredUsers *user_list = NULL;
508 :
509 15 : PRINT_FUNCTION_VERBOSE(verbose);
510 :
511 15 : if ((daemon == NULL) || (ecu == NULL))
512 : return DLT_RETURN_ERROR;
513 :
514 15 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
515 :
516 15 : if (user_list != NULL) {
517 26 : for (i = 0; i < user_list->num_applications; i++)
518 11 : if (user_list->applications[i].user_handle == fd)
519 0 : user_list->applications[i].user_handle = DLT_FD_INIT;
520 :
521 : return DLT_RETURN_OK;
522 : }
523 :
524 : return DLT_RETURN_ERROR;
525 : }
526 :
527 10 : int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose)
528 : {
529 : int i;
530 : DltDaemonRegisteredUsers *user_list = NULL;
531 :
532 10 : PRINT_FUNCTION_VERBOSE(verbose);
533 :
534 10 : if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
535 : return DLT_RETURN_WRONG_PARAMETER;
536 :
537 10 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
538 :
539 10 : if (user_list == NULL)
540 : return DLT_RETURN_ERROR;
541 :
542 11 : for (i = 0; i < user_list->num_applications; i++)
543 1 : if (user_list->applications[i].application_description != NULL) {
544 :
545 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
546 : if (user_list->applications[i].context_log_level_settings)
547 : free(user_list->applications[i].context_log_level_settings);
548 : #endif
549 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
550 : if (user_list->applications[i].trace_load_settings) {
551 : free(user_list->applications[i].trace_load_settings);
552 : user_list->applications[i].trace_load_settings = NULL;
553 : user_list->applications[i].trace_load_settings_count = 0;
554 : }
555 : #endif
556 1 : free(user_list->applications[i].application_description);
557 1 : user_list->applications[i].application_description = NULL;
558 : }
559 :
560 10 : if (user_list->applications != NULL)
561 7 : free(user_list->applications);
562 :
563 10 : user_list->applications = NULL;
564 10 : user_list->num_applications = 0;
565 :
566 10 : return 0;
567 : }
568 :
569 15 : static void dlt_daemon_application_reset_user_handle(DltDaemon *daemon,
570 : DltDaemonApplication *application,
571 : int verbose)
572 : {
573 : DltDaemonRegisteredUsers *user_list;
574 : DltDaemonContext *context;
575 : int i;
576 :
577 15 : if (application->user_handle == DLT_FD_INIT)
578 : return;
579 :
580 6 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
581 6 : if (user_list != NULL) {
582 6 : for (i = 0; i < user_list->num_contexts; i++) {
583 0 : context = &user_list->contexts[i];
584 0 : if (context->user_handle == application->user_handle)
585 0 : context->user_handle = DLT_FD_INIT;
586 : }
587 : }
588 :
589 6 : if (application->owns_user_handle)
590 6 : close(application->user_handle);
591 :
592 6 : application->user_handle = DLT_FD_INIT;
593 6 : application->owns_user_handle = false;
594 : }
595 :
596 10 : DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon,
597 : char *apid,
598 : pid_t pid,
599 : char *description,
600 : int fd,
601 : char *ecu,
602 : int verbose)
603 : {
604 : DltDaemonApplication *application;
605 : DltDaemonApplication *old;
606 : int new_application;
607 : int dlt_user_handle;
608 : bool owns_user_handle;
609 : DltDaemonRegisteredUsers *user_list = NULL;
610 : #ifdef DLT_DAEMON_USE_FIFO_IPC
611 : (void)fd; /* To avoid compiler warning : unused variable */
612 : char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
613 : #endif
614 :
615 10 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
616 : return (DltDaemonApplication *)NULL;
617 :
618 10 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
619 :
620 10 : if (user_list == NULL)
621 : return (DltDaemonApplication *)NULL;
622 :
623 10 : if (user_list->applications == NULL) {
624 10 : user_list->applications = (DltDaemonApplication *)
625 10 : malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
626 :
627 10 : if (user_list->applications == NULL)
628 : return (DltDaemonApplication *)NULL;
629 : }
630 :
631 : new_application = 0;
632 :
633 : /* Check if application [apid] is already available */
634 10 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
635 :
636 10 : if (application == NULL) {
637 10 : user_list->num_applications += 1;
638 :
639 10 : if (user_list->num_applications != 0) {
640 10 : if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
641 : /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
642 0 : old = user_list->applications;
643 0 : user_list->applications = (DltDaemonApplication *)
644 0 : malloc((size_t)sizeof(DltDaemonApplication) *
645 0 : ((size_t)(user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) *
646 : (size_t)DLT_DAEMON_APPL_ALLOC_SIZE);
647 :
648 0 : if (user_list->applications == NULL) {
649 0 : user_list->applications = old;
650 0 : user_list->num_applications -= 1;
651 0 : return (DltDaemonApplication *)NULL;
652 : }
653 :
654 0 : memcpy(user_list->applications,
655 : old,
656 0 : (size_t)sizeof(DltDaemonApplication) * (size_t)user_list->num_applications);
657 0 : free(old);
658 : }
659 : }
660 :
661 10 : application = &(user_list->applications[(size_t)(user_list->num_applications - 1)]);
662 :
663 10 : dlt_set_id(application->apid, apid);
664 10 : application->pid = 0;
665 10 : application->application_description = NULL;
666 10 : application->num_contexts = 0;
667 10 : application->user_handle = DLT_FD_INIT;
668 10 : application->owns_user_handle = false;
669 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
670 : application->trace_load_settings = NULL;
671 : application->trace_load_settings_count = 0;
672 : #endif
673 :
674 : new_application = 1;
675 :
676 : }
677 0 : else if ((pid != application->pid) && (application->pid != 0))
678 : {
679 :
680 0 : dlt_vlog(LOG_WARNING,
681 : "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n",
682 : apid,
683 : pid,
684 : application->pid);
685 : }
686 :
687 : /* Store application description and pid of application */
688 10 : if (application->application_description) {
689 0 : free(application->application_description);
690 0 : application->application_description = NULL;
691 : }
692 :
693 10 : if (description != NULL) {
694 10 : application->application_description = malloc(strlen(description) + 1);
695 :
696 10 : if (application->application_description) {
697 10 : memcpy(application->application_description, description, strlen(description) + 1);
698 : } else {
699 0 : dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
700 0 : free(application);
701 0 : return (DltDaemonApplication *)NULL;
702 : }
703 : }
704 :
705 10 : if (application->pid != pid) {
706 9 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
707 9 : application->pid = 0;
708 : }
709 :
710 : /* open user pipe only if it is not yet opened */
711 10 : if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
712 : dlt_user_handle = DLT_FD_INIT;
713 : owns_user_handle = false;
714 :
715 : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
716 : if (fd >= DLT_FD_MINIMUM) {
717 : dlt_user_handle = fd;
718 : owns_user_handle = false;
719 : }
720 : #endif
721 : #ifdef DLT_DAEMON_USE_FIFO_IPC
722 : if (dlt_user_handle < DLT_FD_MINIMUM) {
723 : int ret = snprintf(filename,
724 : DLT_DAEMON_COMMON_TEXTBUFSIZE,
725 : "%s/dltpipes/dlt%d",
726 : dltFifoBaseDir,
727 : (int)pid);
728 9 : if (ret < 0 || ret >= DLT_DAEMON_COMMON_TEXTBUFSIZE) {
729 0 : filename[0] = '\0';
730 : }
731 :
732 : dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
733 :
734 9 : if (dlt_user_handle < 0) {
735 0 : int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
736 0 : dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
737 : } else {
738 : owns_user_handle = true;
739 : }
740 : }
741 : #endif
742 : /* check if file descriptor was already used, and make it invalid if it
743 : * is reused. This prevents sending messages to wrong file descriptor */
744 9 : dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
745 9 : dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
746 :
747 9 : application->user_handle = dlt_user_handle;
748 9 : application->owns_user_handle = owns_user_handle;
749 9 : application->pid = pid;
750 : }
751 :
752 : /* Sort */
753 10 : if (new_application) {
754 10 : qsort(user_list->applications,
755 10 : (size_t) user_list->num_applications,
756 : sizeof(DltDaemonApplication),
757 : dlt_daemon_cmp_apid);
758 :
759 : /* Find new position of application with apid*/
760 10 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
761 : }
762 :
763 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
764 : application->num_context_log_level_settings = 0;
765 : application->context_log_level_settings = NULL;
766 : #endif
767 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
768 : if (application->trace_load_settings == NULL) {
769 : DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
770 : int num_settings = 0;
771 : DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
772 : daemon,
773 : application->apid,
774 : NULL /*load settings for all contexts*/,
775 : &pre_configured_trace_load_settings,
776 : &num_settings,
777 : verbose);
778 :
779 : DltTraceLoadSettings *app_level = NULL;
780 : if ((find_trace_settings_return_value == DLT_RETURN_OK) &&
781 : (pre_configured_trace_load_settings != NULL) &&
782 : (num_settings != 0)) {
783 : application->trace_load_settings = pre_configured_trace_load_settings;
784 : application->trace_load_settings_count = num_settings;
785 : app_level = dlt_find_runtime_trace_load_settings(
786 : application->trace_load_settings,
787 : application->trace_load_settings_count, application->apid,
788 : NULL);
789 : }
790 :
791 : // app is not configured, set daemon defaults
792 : if (app_level == NULL) {
793 : DltTraceLoadSettings *temp = realloc(application->trace_load_settings,
794 : (application->trace_load_settings_count + 1) *
795 : sizeof(DltTraceLoadSettings));
796 :
797 : if (temp != NULL) {
798 : application->trace_load_settings = temp;
799 : ++application->trace_load_settings_count;
800 :
801 : app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
802 : memset(app_level, 0, sizeof(DltTraceLoadSettings));
803 : app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
804 : app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
805 : memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
806 : memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
807 : } else {
808 : dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
809 : }
810 :
811 : // We inserted the application id at the end, to make sure
812 : // Lookups are working properly later on, we have to sort the list again.
813 : qsort(application->trace_load_settings,
814 : (size_t)application->trace_load_settings_count,
815 : sizeof(DltTraceLoadSettings),
816 : dlt_daemon_compare_trace_load_settings);
817 : }
818 : }
819 :
820 : #endif
821 :
822 : return application;
823 : }
824 :
825 6 : int dlt_daemon_application_del(DltDaemon *daemon,
826 : DltDaemonApplication *application,
827 : char *ecu,
828 : int verbose)
829 : {
830 : int pos;
831 : DltDaemonRegisteredUsers *user_list = NULL;
832 :
833 6 : PRINT_FUNCTION_VERBOSE(verbose);
834 :
835 6 : if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
836 : return -1;
837 :
838 6 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
839 :
840 6 : if (user_list == NULL)
841 : return -1;
842 :
843 6 : if (user_list->num_applications > 0) {
844 6 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
845 :
846 : /* Free description of application to be deleted */
847 6 : if (application->application_description) {
848 6 : free(application->application_description);
849 6 : application->application_description = NULL;
850 : }
851 :
852 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
853 : if (application->trace_load_settings != NULL) {
854 : free(application->trace_load_settings);
855 : application->trace_load_settings = NULL;
856 : application->trace_load_settings_count = 0;
857 : }
858 : #endif
859 6 : pos = (int) (application - (user_list->applications));
860 :
861 : /* move all applications above pos to pos */
862 6 : memmove(&(user_list->applications[pos]),
863 6 : &(user_list->applications[pos + 1]),
864 6 : (size_t)sizeof(DltDaemonApplication) * (size_t)((user_list->num_applications - 1) - pos));
865 :
866 : /* Clear last application */
867 6 : memset(&(user_list->applications[(size_t)(user_list->num_applications - 1)]),
868 : 0,
869 : (size_t)sizeof(DltDaemonApplication));
870 :
871 6 : user_list->num_applications--;
872 : }
873 :
874 : return 0;
875 : }
876 :
877 149 : DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon,
878 : char *apid,
879 : char *ecu,
880 : int verbose)
881 : {
882 : DltDaemonApplication application;
883 : DltDaemonRegisteredUsers *user_list = NULL;
884 :
885 149 : PRINT_FUNCTION_VERBOSE(verbose);
886 :
887 149 : if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
888 149 : (apid[0] == '\0') || (ecu == NULL))
889 : return (DltDaemonApplication *)NULL;
890 :
891 149 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
892 :
893 149 : if ((user_list == NULL) || (user_list->num_applications == 0))
894 : return (DltDaemonApplication *)NULL;
895 :
896 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
897 132 : if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
898 132 : (memcmp(apid,
899 132 : user_list->applications[user_list->num_applications - 1].apid,
900 : DLT_ID_SIZE) > 0))
901 : return (DltDaemonApplication *)NULL;
902 :
903 132 : dlt_set_id(application.apid, apid);
904 132 : return (DltDaemonApplication *)bsearch(&application,
905 132 : user_list->applications,
906 132 : (size_t) user_list->num_applications,
907 : sizeof(DltDaemonApplication),
908 : dlt_daemon_cmp_apid);
909 : }
910 :
911 9 : int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose)
912 : {
913 : FILE *fd;
914 : ID4 apid;
915 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
916 : char *ret;
917 : char *pb;
918 :
919 9 : PRINT_FUNCTION_VERBOSE(verbose);
920 :
921 9 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
922 : return -1;
923 :
924 9 : fd = fopen(filename, "r");
925 :
926 9 : if (fd == NULL) {
927 9 : dlt_vlog(LOG_WARNING,
928 : "%s: cannot open file %s: %s\n",
929 : __func__,
930 : filename,
931 9 : strerror(errno));
932 :
933 9 : return -1;
934 : }
935 :
936 0 : while (!feof(fd)) {
937 : /* Clear buf */
938 : memset(buf, 0, sizeof(buf));
939 :
940 : /* Get line */
941 : ret = fgets(buf, sizeof(buf), fd);
942 :
943 0 : if (NULL == ret) {
944 : /* fgets always null pointer if the last byte of the file is a new line
945 : * We need to check here if there was an error or was it feof.*/
946 0 : if (ferror(fd)) {
947 0 : dlt_vlog(LOG_WARNING,
948 : "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
949 : __func__,
950 0 : strerror(errno));
951 0 : fclose(fd);
952 0 : return -1;
953 : }
954 0 : else if (feof(fd))
955 : {
956 0 : fclose(fd);
957 0 : return 0;
958 : }
959 : else {
960 0 : dlt_vlog(LOG_WARNING,
961 : "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
962 : __func__);
963 0 : fclose(fd);
964 0 : return -1;
965 : }
966 : }
967 :
968 0 : if (strcmp(buf, "") != 0) {
969 : /* Split line */
970 0 : pb = strtok(buf, ":");
971 :
972 0 : if (pb != NULL) {
973 0 : dlt_set_id(apid, pb);
974 0 : pb = strtok(NULL, ":");
975 :
976 0 : if (pb != NULL) {
977 : /* pb contains now the description */
978 : /* pid is unknown at loading time */
979 0 : if (dlt_daemon_application_add(daemon,
980 : apid,
981 : 0,
982 : pb,
983 : -1,
984 0 : daemon->ecuid,
985 : verbose) == 0) {
986 0 : dlt_vlog(LOG_WARNING,
987 : "%s: dlt_daemon_application_add failed for %4s\n",
988 : __func__,
989 : apid);
990 0 : fclose(fd);
991 0 : return -1;
992 : }
993 : }
994 : }
995 : }
996 : }
997 :
998 0 : fclose(fd);
999 :
1000 0 : return 0;
1001 : }
1002 :
1003 0 : int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose)
1004 : {
1005 : FILE *fd;
1006 : int i;
1007 :
1008 : char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
1009 : DltDaemonRegisteredUsers *user_list = NULL;
1010 :
1011 0 : PRINT_FUNCTION_VERBOSE(verbose);
1012 :
1013 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1014 : return -1;
1015 :
1016 : memset(apid, 0, sizeof(apid));
1017 :
1018 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1019 :
1020 0 : if (user_list == NULL)
1021 : return -1;
1022 :
1023 0 : if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
1024 0 : fd = fopen(filename, "w");
1025 :
1026 0 : if (fd != NULL) {
1027 0 : for (i = 0; i < user_list->num_applications; i++) {
1028 0 : dlt_set_id(apid, user_list->applications[i].apid);
1029 :
1030 0 : if ((user_list->applications[i].application_description) &&
1031 0 : (user_list->applications[i].application_description[0] != '\0'))
1032 : fprintf(fd,
1033 : "%s:%s:\n",
1034 : apid,
1035 : user_list->applications[i].application_description);
1036 : else
1037 : fprintf(fd, "%s::\n", apid);
1038 : }
1039 :
1040 0 : fclose(fd);
1041 : }
1042 : else {
1043 0 : dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n",
1044 : __func__,
1045 : filename);
1046 : }
1047 : }
1048 :
1049 : return 0;
1050 : }
1051 :
1052 41 : DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon,
1053 : char *apid,
1054 : char *ctid,
1055 : int8_t log_level,
1056 : int8_t trace_status,
1057 : int log_level_pos,
1058 : int user_handle,
1059 : char *description,
1060 : char *ecu,
1061 : int verbose)
1062 : {
1063 : DltDaemonApplication *application;
1064 : DltDaemonContext *context;
1065 : DltDaemonContext *old;
1066 : int new_context = 0;
1067 : DltDaemonRegisteredUsers *user_list = NULL;
1068 :
1069 41 : PRINT_FUNCTION_VERBOSE(verbose);
1070 :
1071 41 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
1072 41 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1073 : return (DltDaemonContext *)NULL;
1074 :
1075 41 : if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
1076 : return (DltDaemonContext *)NULL;
1077 :
1078 41 : if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
1079 : return (DltDaemonContext *)NULL;
1080 :
1081 41 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1082 :
1083 41 : if (user_list == NULL)
1084 : return (DltDaemonContext *)NULL;
1085 :
1086 41 : if (user_list->contexts == NULL) {
1087 10 : user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1088 :
1089 10 : if (user_list->contexts == NULL)
1090 : return (DltDaemonContext *)NULL;
1091 : }
1092 :
1093 : /* Check if application [apid] is available */
1094 41 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
1095 :
1096 41 : if (application == NULL)
1097 : return (DltDaemonContext *)NULL;
1098 :
1099 : /* Check if context [apid, ctid] is already available */
1100 41 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1101 :
1102 41 : if (context == NULL) {
1103 41 : user_list->num_contexts += 1;
1104 :
1105 41 : if (user_list->num_contexts != 0) {
1106 41 : if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
1107 : /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
1108 0 : old = user_list->contexts;
1109 0 : user_list->contexts = (DltDaemonContext *)calloc(1, (size_t) sizeof(DltDaemonContext) *
1110 0 : ((size_t)(user_list->num_contexts /
1111 : DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) *
1112 : (size_t)DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1113 :
1114 0 : if (user_list->contexts == NULL) {
1115 0 : user_list->contexts = old;
1116 0 : user_list->num_contexts -= 1;
1117 0 : return (DltDaemonContext *)NULL;
1118 : }
1119 :
1120 0 : memcpy(user_list->contexts,
1121 : old,
1122 0 : (size_t) sizeof(DltDaemonContext) * (size_t)user_list->num_contexts);
1123 0 : free(old);
1124 : }
1125 : }
1126 :
1127 41 : context = &(user_list->contexts[(size_t)(user_list->num_contexts - 1)]);
1128 : memset(context, 0, sizeof(DltDaemonContext));
1129 :
1130 41 : dlt_set_id(context->apid, apid);
1131 41 : dlt_set_id(context->ctid, ctid);
1132 :
1133 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1134 : context->trace_load_settings = NULL;
1135 : #endif
1136 :
1137 41 : application->num_contexts++;
1138 : new_context = 1;
1139 : }
1140 :
1141 : /* Set context description */
1142 41 : if (context->context_description) {
1143 0 : free(context->context_description);
1144 0 : context->context_description = NULL;
1145 : }
1146 :
1147 41 : if (description != NULL) {
1148 41 : context->context_description = malloc(strlen(description) + 1);
1149 :
1150 41 : if (context->context_description) {
1151 41 : memcpy(context->context_description, description, strlen(description) + 1);
1152 : }
1153 : }
1154 :
1155 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1156 : /* configure initial log level */
1157 : DltDaemonContextLogSettings *settings = NULL;
1158 : settings = dlt_daemon_find_configured_app_id_ctx_id_settings(
1159 : daemon, context->apid, ctid);
1160 :
1161 : if (settings != NULL) {
1162 : /* set log level */
1163 : log_level = settings->log_level;
1164 :
1165 : DltDaemonContextLogSettings *ct_settings = NULL;
1166 : ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
1167 :
1168 : /* ct_settings != null: context and app id combination already exists */
1169 : if (ct_settings == NULL) {
1170 : /* copy the configuration into the DltDaemonApplication for faster access later */
1171 : DltDaemonContextLogSettings *tmp =
1172 : realloc(application->context_log_level_settings,
1173 : (++application->num_context_log_level_settings) *
1174 : sizeof(DltDaemonContextLogSettings));
1175 : application->context_log_level_settings = tmp;
1176 :
1177 : ct_settings =
1178 : &application->context_log_level_settings[application->num_context_log_level_settings - 1];
1179 : memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
1180 : memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
1181 : }
1182 : }
1183 : #endif
1184 :
1185 41 : if ((strncmp(daemon->ecuid, ecu, DLT_ID_SIZE) == 0) && (daemon->force_ll_ts)) {
1186 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1187 : if (log_level > daemon->default_log_level && settings == NULL)
1188 : #else
1189 0 : if (log_level > daemon->default_log_level)
1190 : #endif
1191 : log_level = daemon->default_log_level;
1192 :
1193 0 : if (trace_status > daemon->default_trace_status)
1194 : trace_status = daemon->default_trace_status;
1195 :
1196 0 : dlt_vlog(LOG_NOTICE,
1197 : "Adapting ll_ts for context: %.4s:%.4s with %i %i\n",
1198 : apid,
1199 : ctid,
1200 : log_level,
1201 : trace_status);
1202 : }
1203 :
1204 : /* Store log level and trace status,
1205 : * if this is a new context, or
1206 : * if this is an old context and the runtime cfg was not loaded */
1207 41 : if ((new_context == 1) ||
1208 0 : ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
1209 41 : context->log_level = log_level;
1210 41 : context->trace_status = trace_status;
1211 : }
1212 :
1213 41 : context->log_level_pos = log_level_pos;
1214 41 : context->user_handle = user_handle;
1215 :
1216 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1217 : DltTraceLoadSettings* tl_settings = dlt_find_runtime_trace_load_settings(
1218 : application->trace_load_settings,
1219 : application->trace_load_settings_count,
1220 : application->apid,
1221 : context->ctid);
1222 : if (tl_settings == NULL) {
1223 : dlt_vlog(LOG_WARNING, "failed to find trace load settings for application %s context %s\n",
1224 : application->apid, context->ctid);
1225 : } else {
1226 : context->trace_load_settings = tl_settings;
1227 : }
1228 : #endif
1229 :
1230 :
1231 : /* In case a context is loaded from runtime config file,
1232 : * the user_handle is 0 and we mark that context as predefined.
1233 : */
1234 41 : if (context->user_handle == 0)
1235 0 : context->predefined = true;
1236 : else
1237 41 : context->predefined = false;
1238 :
1239 : /* Sort */
1240 41 : if (new_context) {
1241 41 : qsort(user_list->contexts,
1242 41 : (size_t) user_list->num_contexts,
1243 : sizeof(DltDaemonContext),
1244 : dlt_daemon_cmp_apid_ctid);
1245 :
1246 : /* Find new position of context with apid, ctid */
1247 41 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1248 : }
1249 :
1250 : return context;
1251 : }
1252 :
1253 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1254 : static void dlt_daemon_free_context_log_settings(
1255 : DltDaemonApplication *application,
1256 : DltDaemonContext *context)
1257 : {
1258 : DltDaemonContextLogSettings *ct_settings;
1259 : int i;
1260 : int skipped = 0;
1261 :
1262 : ct_settings = dlt_daemon_find_app_log_level_config(application, context->ctid);
1263 : if (ct_settings == NULL) {
1264 : return;
1265 : }
1266 :
1267 : /* move all data forward */
1268 : for (i = 0; i < application->num_context_log_level_settings; ++i) {
1269 : /* skip given context to delete it */
1270 : if (i + skipped < application->num_context_log_level_settings &&
1271 : strncmp(application->context_log_level_settings[i+skipped].ctid, context->ctid, DLT_ID_SIZE) == 0) {
1272 : ++skipped;
1273 : continue;
1274 : }
1275 :
1276 : memcpy(&application->context_log_level_settings[i-skipped],
1277 : &application->context_log_level_settings[i],
1278 : sizeof(DltDaemonContextLogSettings));
1279 : }
1280 :
1281 : application->num_context_log_level_settings -= skipped;
1282 :
1283 : /* if size is equal to zero, and ptr is not NULL, then realloc is equivalent to free(ptr) */
1284 : application->context_log_level_settings = realloc(application->context_log_level_settings,
1285 : sizeof(DltDaemonContextLogSettings) * (application->num_context_log_level_settings));
1286 :
1287 : }
1288 : #endif
1289 :
1290 37 : int dlt_daemon_context_del(DltDaemon *daemon,
1291 : DltDaemonContext *context,
1292 : char *ecu,
1293 : int verbose)
1294 : {
1295 : int pos;
1296 : DltDaemonApplication *application;
1297 : DltDaemonRegisteredUsers *user_list = NULL;
1298 :
1299 37 : PRINT_FUNCTION_VERBOSE(verbose);
1300 :
1301 37 : if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
1302 : return -1;
1303 :
1304 37 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1305 :
1306 37 : if (user_list == NULL)
1307 : return -1;
1308 :
1309 37 : if (user_list->num_contexts > 0) {
1310 37 : application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose);
1311 :
1312 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1313 : dlt_daemon_free_context_log_settings(application, context);
1314 : #endif
1315 : /* Free description of context to be deleted */
1316 37 : if (context->context_description) {
1317 37 : free(context->context_description);
1318 37 : context->context_description = NULL;
1319 : }
1320 :
1321 37 : pos = (int) (context - (user_list->contexts));
1322 :
1323 : /* move all contexts above pos to pos */
1324 37 : memmove(&(user_list->contexts[pos]),
1325 37 : &(user_list->contexts[pos + 1]),
1326 37 : (size_t)sizeof(DltDaemonContext) * (size_t)((user_list->num_contexts - 1) - pos));
1327 :
1328 : /* Clear last context */
1329 37 : memset(&(user_list->contexts[(size_t)(user_list->num_contexts - 1)]),
1330 : 0,
1331 : (size_t)sizeof(DltDaemonContext));
1332 :
1333 37 : user_list->num_contexts--;
1334 :
1335 : /* Check if application [apid] is available */
1336 37 : if (application != NULL)
1337 37 : application->num_contexts--;
1338 : }
1339 :
1340 : return 0;
1341 : }
1342 :
1343 157 : DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon,
1344 : char *apid,
1345 : char *ctid,
1346 : char *ecu,
1347 : int verbose)
1348 : {
1349 : DltDaemonContext context;
1350 : DltDaemonRegisteredUsers *user_list = NULL;
1351 :
1352 157 : PRINT_FUNCTION_VERBOSE(verbose);
1353 :
1354 157 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
1355 157 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1356 : return (DltDaemonContext *)NULL;
1357 :
1358 157 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1359 :
1360 157 : if ((user_list == NULL) || (user_list->num_contexts == 0))
1361 : return (DltDaemonContext *)NULL;
1362 :
1363 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
1364 112 : if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
1365 112 : (memcmp(apid,
1366 112 : user_list->contexts[user_list->num_contexts - 1].apid,
1367 : DLT_ID_SIZE) > 0))
1368 : return (DltDaemonContext *)NULL;
1369 :
1370 112 : dlt_set_id(context.apid, apid);
1371 112 : dlt_set_id(context.ctid, ctid);
1372 :
1373 112 : return (DltDaemonContext *)bsearch(&context,
1374 112 : user_list->contexts,
1375 112 : (size_t) user_list->num_contexts,
1376 : sizeof(DltDaemonContext),
1377 : dlt_daemon_cmp_apid_ctid);
1378 : }
1379 :
1380 15 : int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,
1381 : char *ecu,
1382 : int fd,
1383 : int verbose)
1384 : {
1385 : int i;
1386 : DltDaemonRegisteredUsers *user_list = NULL;
1387 :
1388 15 : PRINT_FUNCTION_VERBOSE(verbose);
1389 :
1390 15 : if ((daemon == NULL) || (ecu == NULL))
1391 : return -1;
1392 :
1393 15 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1394 :
1395 15 : if (user_list != NULL) {
1396 39 : for (i = 0; i < user_list->num_contexts; i++)
1397 24 : if (user_list->contexts[i].user_handle == fd)
1398 0 : user_list->contexts[i].user_handle = DLT_FD_INIT;
1399 :
1400 : return 0;
1401 : }
1402 :
1403 : return -1;
1404 : }
1405 :
1406 10 : int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose)
1407 : {
1408 : int i;
1409 : DltDaemonRegisteredUsers *users = NULL;
1410 :
1411 10 : PRINT_FUNCTION_VERBOSE(verbose);
1412 :
1413 10 : if ((daemon == NULL) || (ecu == NULL))
1414 : return DLT_RETURN_WRONG_PARAMETER;
1415 :
1416 10 : users = dlt_daemon_find_users_list(daemon, ecu, verbose);
1417 :
1418 10 : if (users == NULL)
1419 : return DLT_RETURN_ERROR;
1420 :
1421 11 : for (i = 0; i < users->num_contexts; i++)
1422 1 : if (users->contexts[i].context_description != NULL) {
1423 1 : free(users->contexts[i].context_description);
1424 1 : users->contexts[i].context_description = NULL;
1425 : }
1426 :
1427 10 : if (users->contexts) {
1428 7 : free(users->contexts);
1429 7 : users->contexts = NULL;
1430 : }
1431 :
1432 11 : for (i = 0; i < users->num_applications; i++)
1433 1 : users->applications[i].num_contexts = 0;
1434 :
1435 10 : users->num_contexts = 0;
1436 :
1437 10 : return 0;
1438 : }
1439 :
1440 0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
1441 : {
1442 : FILE *fd;
1443 : ID4 apid, ctid;
1444 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
1445 : char *ret;
1446 : char *pb;
1447 : int ll, ts;
1448 :
1449 0 : PRINT_FUNCTION_VERBOSE(verbose);
1450 :
1451 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1452 : return -1;
1453 :
1454 0 : fd = fopen(filename, "r");
1455 :
1456 0 : if (fd == NULL) {
1457 0 : dlt_vlog(LOG_WARNING,
1458 : "DLT runtime-context load, cannot open file %s: %s\n",
1459 : filename,
1460 0 : strerror(errno));
1461 :
1462 0 : return -1;
1463 : }
1464 :
1465 0 : while (!feof(fd)) {
1466 : /* Clear buf */
1467 : memset(buf, 0, sizeof(buf));
1468 :
1469 : /* Get line */
1470 : ret = fgets(buf, sizeof(buf), fd);
1471 :
1472 0 : if (NULL == ret) {
1473 : /* fgets always returns null pointer if the last byte of the file is a new line.
1474 : * We need to check here if there was an error or was it feof.*/
1475 0 : if (ferror(fd)) {
1476 0 : dlt_vlog(LOG_WARNING,
1477 : "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
1478 : __func__,
1479 0 : strerror(errno));
1480 0 : fclose(fd);
1481 0 : return -1;
1482 : }
1483 0 : else if (feof(fd))
1484 : {
1485 0 : fclose(fd);
1486 0 : return 0;
1487 : }
1488 : else {
1489 0 : dlt_vlog(LOG_WARNING,
1490 : "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
1491 : __func__);
1492 0 : fclose(fd);
1493 0 : return -1;
1494 : }
1495 : }
1496 :
1497 0 : if (strcmp(buf, "") != 0) {
1498 : /* Split line */
1499 0 : pb = strtok(buf, ":");
1500 :
1501 0 : if (pb != NULL) {
1502 0 : dlt_set_id(apid, pb);
1503 0 : pb = strtok(NULL, ":");
1504 :
1505 0 : if (pb != NULL) {
1506 0 : dlt_set_id(ctid, pb);
1507 0 : pb = strtok(NULL, ":");
1508 :
1509 0 : if (pb != NULL) {
1510 0 : sscanf(pb, "%d", &ll);
1511 0 : pb = strtok(NULL, ":");
1512 :
1513 0 : if (pb != NULL) {
1514 0 : sscanf(pb, "%d", &ts);
1515 0 : pb = strtok(NULL, ":");
1516 :
1517 0 : if (pb != NULL) {
1518 : /* pb contains now the description */
1519 :
1520 : /* log_level_pos, and user_handle are unknown at loading time */
1521 0 : if (dlt_daemon_context_add(daemon,
1522 : apid,
1523 : ctid,
1524 0 : (int8_t)ll,
1525 0 : (int8_t)ts,
1526 : 0,
1527 : 0,
1528 : pb,
1529 0 : daemon->ecuid,
1530 : verbose) == NULL) {
1531 0 : dlt_vlog(LOG_WARNING,
1532 : "%s dlt_daemon_context_add failed\n",
1533 : __func__);
1534 0 : fclose(fd);
1535 0 : return -1;
1536 : }
1537 : }
1538 : }
1539 : }
1540 : }
1541 : }
1542 : }
1543 : }
1544 :
1545 0 : fclose(fd);
1546 :
1547 0 : return 0;
1548 : }
1549 :
1550 0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
1551 : {
1552 : FILE *fd;
1553 : int i;
1554 :
1555 : char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
1556 : DltDaemonRegisteredUsers *user_list = NULL;
1557 :
1558 0 : PRINT_FUNCTION_VERBOSE(verbose);
1559 :
1560 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1561 : return -1;
1562 :
1563 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1564 :
1565 0 : if (user_list == NULL)
1566 : return -1;
1567 :
1568 : memset(apid, 0, sizeof(apid));
1569 : memset(ctid, 0, sizeof(ctid));
1570 :
1571 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
1572 0 : fd = fopen(filename, "w");
1573 :
1574 0 : if (fd != NULL) {
1575 0 : for (i = 0; i < user_list->num_contexts; i++) {
1576 0 : dlt_set_id(apid, user_list->contexts[i].apid);
1577 0 : dlt_set_id(ctid, user_list->contexts[i].ctid);
1578 :
1579 0 : if ((user_list->contexts[i].context_description) &&
1580 0 : (user_list->contexts[i].context_description[0] != '\0'))
1581 0 : fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
1582 0 : (int)(user_list->contexts[i].log_level),
1583 0 : (int)(user_list->contexts[i].trace_status),
1584 : user_list->contexts[i].context_description);
1585 : else
1586 0 : fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
1587 0 : (int)(user_list->contexts[i].log_level),
1588 0 : (int)(user_list->contexts[i].trace_status));
1589 : }
1590 :
1591 0 : fclose(fd);
1592 : }
1593 : else {
1594 0 : dlt_vlog(LOG_ERR,
1595 : "%s: Cannot open %s. No context information stored\n",
1596 : __func__,
1597 : filename);
1598 : }
1599 : }
1600 :
1601 : return 0;
1602 : }
1603 :
1604 0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
1605 : {
1606 : FILE *fd;
1607 :
1608 0 : PRINT_FUNCTION_VERBOSE(verbose);
1609 :
1610 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1611 : return -1;
1612 :
1613 0 : fd = fopen(filename, "w");
1614 :
1615 0 : if (fd != NULL) {
1616 : fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
1617 0 : fprintf(fd, "LoggingMode = %d\n", daemon->mode);
1618 :
1619 0 : fclose(fd);
1620 : }
1621 :
1622 : return 0;
1623 : }
1624 :
1625 9 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
1626 : {
1627 9 : if ((daemon == NULL) || (filename == NULL))
1628 : return -1;
1629 :
1630 : FILE *pFile;
1631 : char line[1024];
1632 : char token[1024];
1633 : char value[1024];
1634 : char *pch;
1635 :
1636 9 : PRINT_FUNCTION_VERBOSE(verbose);
1637 :
1638 9 : pFile = fopen (filename, "r");
1639 :
1640 9 : if (pFile != NULL) {
1641 : while (1) {
1642 : /* fetch line from configuration file */
1643 18 : if (fgets (line, 1024, pFile) != NULL) {
1644 9 : pch = strtok (line, " =\r\n");
1645 9 : token[0] = 0;
1646 9 : value[0] = 0;
1647 :
1648 18 : while (pch != NULL) {
1649 9 : if (strcmp(pch, "#") == 0)
1650 : break;
1651 :
1652 9 : if (token[0] == 0) {
1653 : strncpy(token, pch, sizeof(token) - 1);
1654 9 : token[sizeof(token) - 1] = 0;
1655 : }
1656 : else {
1657 : strncpy(value, pch, sizeof(value) - 1);
1658 0 : value[sizeof(value) - 1] = 0;
1659 0 : break;
1660 : }
1661 :
1662 9 : pch = strtok (NULL, " =\r\n");
1663 : }
1664 :
1665 9 : if (token[0] && value[0]) {
1666 : /* parse arguments here */
1667 0 : if (strcmp(token, "LoggingMode") == 0) {
1668 0 : daemon->mode = atoi(value);
1669 0 : dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
1670 : daemon->mode);
1671 : }
1672 : else {
1673 0 : dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
1674 : value);
1675 : }
1676 : }
1677 : }
1678 : else {
1679 : break;
1680 : }
1681 : }
1682 :
1683 9 : fclose (pFile);
1684 : }
1685 : else {
1686 0 : dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
1687 : }
1688 :
1689 : return 0;
1690 : }
1691 :
1692 41 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
1693 : {
1694 : DltUserHeader userheader;
1695 : DltUserControlMsgLogLevel usercontext;
1696 : DltReturnValue ret;
1697 : DltDaemonApplication *app;
1698 :
1699 41 : PRINT_FUNCTION_VERBOSE(verbose);
1700 :
1701 41 : if ((daemon == NULL) || (context == NULL)) {
1702 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
1703 0 : return -1;
1704 : }
1705 :
1706 41 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
1707 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
1708 0 : return -1;
1709 : }
1710 :
1711 41 : if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
1712 34 : (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
1713 32 : usercontext.log_level = (uint8_t) (context->log_level >
1714 : context->storage_log_level ? context->log_level : context->storage_log_level);
1715 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
1716 9 : usercontext.log_level =
1717 9 : (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
1718 :
1719 41 : usercontext.trace_status =
1720 41 : (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
1721 :
1722 41 : usercontext.log_level_pos = context->log_level_pos;
1723 :
1724 41 : dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
1725 41 : context->apid,
1726 41 : context->ctid,
1727 41 : context->log_level,
1728 41 : usercontext.log_level,
1729 : context->trace_status,
1730 : usercontext.trace_status);
1731 :
1732 : /* log to FIFO */
1733 41 : errno = 0;
1734 41 : ret = dlt_user_log_out2_with_timeout(context->user_handle,
1735 : &(userheader), sizeof(DltUserHeader),
1736 : &(usercontext), sizeof(DltUserControlMsgLogLevel));
1737 :
1738 41 : if (ret < DLT_RETURN_OK) {
1739 0 : dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
1740 : __func__,
1741 0 : errno != 0 ? strerror(errno) : "Unknown error");
1742 :
1743 0 : if (errno == EPIPE || errno == EBADF) {
1744 0 : app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
1745 0 : if (app != NULL)
1746 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
1747 : }
1748 : }
1749 :
1750 41 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
1751 : }
1752 :
1753 9 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
1754 : {
1755 : DltUserHeader userheader;
1756 : DltUserControlMsgLogState logstate;
1757 : DltReturnValue ret;
1758 :
1759 9 : PRINT_FUNCTION_VERBOSE(verbose);
1760 :
1761 9 : if ((daemon == NULL) || (app == NULL))
1762 : return -1;
1763 :
1764 9 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
1765 : return -1;
1766 :
1767 9 : logstate.log_state = daemon->connectionState;
1768 :
1769 : /* log to FIFO */
1770 9 : ret = dlt_user_log_out2_with_timeout(app->user_handle,
1771 : &(userheader), sizeof(DltUserHeader),
1772 : &(logstate), sizeof(DltUserControlMsgLogState));
1773 :
1774 9 : if (ret < DLT_RETURN_OK) {
1775 0 : if (errno == EPIPE || errno == EBADF)
1776 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
1777 : }
1778 :
1779 9 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
1780 : }
1781 :
1782 0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
1783 : const char *filename,
1784 : const char *filename1,
1785 : int InitialContextLogLevel,
1786 : int InitialContextTraceStatus,
1787 : int InitialEnforceLlTsStatus,
1788 : int verbose)
1789 : {
1790 : FILE *fd;
1791 :
1792 0 : PRINT_FUNCTION_VERBOSE(verbose);
1793 :
1794 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
1795 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1796 0 : return;
1797 : }
1798 :
1799 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
1800 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
1801 0 : return;
1802 : }
1803 :
1804 : /* Check for runtime cfg file and delete it, if available */
1805 0 : fd = fopen(filename, "r");
1806 :
1807 0 : if (fd != NULL) {
1808 : /* Close and delete file */
1809 0 : fclose(fd);
1810 0 : if (unlink(filename) != 0) {
1811 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
1812 0 : __func__, strerror(errno));
1813 : }
1814 : }
1815 :
1816 0 : fd = fopen(filename1, "r");
1817 :
1818 0 : if (fd != NULL) {
1819 : /* Close and delete file */
1820 0 : fclose(fd);
1821 0 : if (unlink(filename1) != 0) {
1822 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
1823 0 : __func__, strerror(errno));
1824 : }
1825 : }
1826 :
1827 0 : daemon->default_log_level = (int8_t) InitialContextLogLevel;
1828 0 : daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
1829 0 : daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
1830 :
1831 : /* Reset all other things (log level, trace status, etc.
1832 : * to default values */
1833 :
1834 : /* Inform user libraries about changed default log level/trace status */
1835 0 : dlt_daemon_user_send_default_update(daemon, verbose);
1836 : }
1837 :
1838 0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
1839 : {
1840 : int32_t count;
1841 : DltDaemonContext *context;
1842 : DltDaemonRegisteredUsers *user_list = NULL;
1843 :
1844 0 : PRINT_FUNCTION_VERBOSE(verbose);
1845 :
1846 0 : if (daemon == NULL) {
1847 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1848 0 : return;
1849 : }
1850 :
1851 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1852 :
1853 0 : if (user_list == NULL)
1854 : return;
1855 :
1856 0 : for (count = 0; count < user_list->num_contexts; count++) {
1857 0 : context = &(user_list->contexts[count]);
1858 :
1859 0 : if (context != NULL) {
1860 0 : if ((context->log_level == DLT_LOG_DEFAULT) ||
1861 0 : (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
1862 0 : if (context->user_handle >= DLT_FD_MINIMUM)
1863 0 : if (dlt_daemon_user_send_log_level(daemon,
1864 : context,
1865 : verbose) == -1)
1866 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
1867 : }
1868 : }
1869 : }
1870 : }
1871 :
1872 0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
1873 : int enforce_context_ll_and_ts,
1874 : int8_t context_log_level,
1875 : int8_t log_level,
1876 : int verbose)
1877 : {
1878 : int32_t count = 0;
1879 : DltDaemonContext *context = NULL;
1880 : DltDaemonRegisteredUsers *user_list = NULL;
1881 :
1882 0 : PRINT_FUNCTION_VERBOSE(verbose);
1883 :
1884 0 : if (daemon == NULL)
1885 : return;
1886 :
1887 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1888 :
1889 0 : if (user_list == NULL)
1890 : return;
1891 :
1892 0 : for (count = 0; count < user_list->num_contexts; count++) {
1893 0 : context = &(user_list->contexts[count]);
1894 :
1895 0 : if (context) {
1896 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
1897 0 : context->log_level = log_level;
1898 :
1899 0 : if (enforce_context_ll_and_ts) {
1900 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1901 : DltDaemonContextLogSettings *settings =
1902 : dlt_daemon_find_configured_app_id_ctx_id_settings(
1903 : daemon, context->apid, context->ctid);
1904 : if (settings != NULL) {
1905 : if (log_level > settings->log_level) {
1906 : context->log_level = settings->log_level;
1907 : }
1908 : } else
1909 : #endif
1910 0 : if (log_level > context_log_level) {
1911 0 : context->log_level = (int8_t)context_log_level;
1912 : }
1913 : }
1914 :
1915 0 : if (dlt_daemon_user_send_log_level(daemon,
1916 : context,
1917 : verbose) == -1)
1918 0 : dlt_vlog(LOG_WARNING,
1919 : "Cannot send log level %.4s:%.4s -> %i\n",
1920 0 : context->apid,
1921 0 : context->ctid,
1922 0 : context->log_level);
1923 : }
1924 : }
1925 : }
1926 : }
1927 :
1928 0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
1929 : {
1930 : int32_t count = 0;
1931 : DltDaemonContext *context = NULL;
1932 : DltDaemonRegisteredUsers *user_list = NULL;
1933 :
1934 0 : PRINT_FUNCTION_VERBOSE(verbose);
1935 :
1936 0 : if (daemon == NULL)
1937 : return;
1938 :
1939 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1940 :
1941 0 : if (user_list == NULL)
1942 : return;
1943 :
1944 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
1945 :
1946 0 : for (count = 0; count < user_list->num_contexts; count++) {
1947 0 : context = &(user_list->contexts[count]);
1948 :
1949 0 : if (context) {
1950 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
1951 0 : context->trace_status = trace_status;
1952 :
1953 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
1954 0 : dlt_vlog(LOG_WARNING,
1955 : "Cannot send trace status %.4s:%.4s -> %i\n",
1956 0 : context->apid,
1957 0 : context->ctid,
1958 0 : context->trace_status);
1959 : }
1960 : }
1961 : }
1962 : }
1963 :
1964 5 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
1965 : {
1966 : int32_t count;
1967 : DltDaemonApplication *app;
1968 : DltDaemonRegisteredUsers *user_list = NULL;
1969 :
1970 5 : PRINT_FUNCTION_VERBOSE(verbose);
1971 :
1972 5 : if (daemon == NULL) {
1973 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1974 0 : return;
1975 : }
1976 :
1977 5 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1978 :
1979 5 : if (user_list == NULL)
1980 : return;
1981 :
1982 7 : for (count = 0; count < user_list->num_applications; count++) {
1983 2 : app = &(user_list->applications[count]);
1984 :
1985 2 : if (app != NULL) {
1986 2 : if (app->user_handle >= DLT_FD_MINIMUM)
1987 2 : if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
1988 0 : dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d\n", app->apid, app->pid);
1989 : }
1990 : }
1991 : }
1992 :
1993 16 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
1994 : {
1995 16 : switch (newState) {
1996 0 : case DLT_DAEMON_STATE_INIT:
1997 0 : dlt_log(LOG_INFO, "Switched to init state.\n");
1998 0 : daemon->state = DLT_DAEMON_STATE_INIT;
1999 0 : break;
2000 12 : case DLT_DAEMON_STATE_BUFFER:
2001 12 : dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
2002 12 : daemon->state = DLT_DAEMON_STATE_BUFFER;
2003 12 : break;
2004 0 : case DLT_DAEMON_STATE_BUFFER_FULL:
2005 0 : dlt_log(LOG_INFO, "Switched to buffer full state.\n");
2006 0 : daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
2007 0 : break;
2008 2 : case DLT_DAEMON_STATE_SEND_BUFFER:
2009 2 : dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
2010 2 : daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
2011 2 : break;
2012 2 : case DLT_DAEMON_STATE_SEND_DIRECT:
2013 2 : dlt_log(LOG_INFO, "Switched to send direct state.\n");
2014 2 : daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
2015 2 : break;
2016 : }
2017 16 : }
2018 :
2019 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2020 : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon *daemon) {
2021 : if (daemon->watchdog_trigger_interval == 0) {
2022 : return false;
2023 : }
2024 :
2025 : const unsigned int uptime_seconds = dlt_uptime() / 10000;
2026 : const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
2027 : if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
2028 : return false;
2029 : }
2030 : if (sd_notify(0, "WATCHDOG=1") < 0) {
2031 : dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
2032 : return false;
2033 : }
2034 : else
2035 : daemon->watchdog_last_trigger_time = uptime_seconds;
2036 :
2037 : return true;
2038 : }
2039 :
2040 : #endif
2041 :
2042 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
2043 : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
2044 : {
2045 : DltUserHeader userheader;
2046 : DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
2047 : uint32_t trace_load_settings_count;
2048 : DltReturnValue ret;
2049 :
2050 :
2051 : PRINT_FUNCTION_VERBOSE(verbose);
2052 :
2053 : if ((daemon == NULL) || (app == NULL)) return -1;
2054 :
2055 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
2056 :
2057 : DltTraceLoadSettings* app_settings = app->trace_load_settings;
2058 :
2059 : if (app_settings != NULL) {
2060 : trace_load_settings_count = app->trace_load_settings_count;
2061 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
2062 : for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
2063 : // App id is not transmitted as the user library only
2064 : // has one application ID
2065 : memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
2066 : trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
2067 : trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
2068 :
2069 : if (app_settings[i].ctid[0] == '\0') {
2070 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
2071 : app->apid,
2072 : app_settings[i].soft_limit,
2073 : app_settings[i].hard_limit);
2074 : } else {
2075 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
2076 : app->apid,
2077 : app_settings[i].ctid,
2078 : app_settings[i].soft_limit,
2079 : app_settings[i].hard_limit);
2080 : }
2081 :
2082 : }
2083 : }
2084 : else {
2085 : dlt_vlog(LOG_INFO,
2086 : "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
2087 :
2088 : trace_load_settings_count = 1;
2089 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
2090 :
2091 : memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
2092 : trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
2093 : trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
2094 : }
2095 :
2096 : /* log to FIFO */
2097 : ret = dlt_user_log_out3_with_timeout(app->user_handle,
2098 : &(userheader), sizeof(DltUserHeader),
2099 : &(trace_load_settings_count), sizeof(uint32_t),
2100 : trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
2101 :
2102 : if (ret < DLT_RETURN_OK) {
2103 : if (errno == EPIPE || errno == EBADF)
2104 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2105 : }
2106 :
2107 : free(trace_load_settings_user_msg);
2108 :
2109 : return ret;
2110 : }
2111 : #endif
|