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 : DltDaemonApplication *mi1 = (DltDaemonApplication *)m1;
102 : DltDaemonApplication *mi2 = (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 : DltDaemonContext *mi1 = (DltDaemonContext *)m1;
114 : DltDaemonContext *mi2 = (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 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
446 : if (daemon->preconfigured_trace_load_settings != NULL) {
447 : free(daemon->preconfigured_trace_load_settings);
448 : daemon->preconfigured_trace_load_settings = NULL;
449 : }
450 : pthread_rwlock_destroy(&trace_load_rw_lock);
451 : #endif
452 :
453 9 : if (app_recv_buffer)
454 9 : free(app_recv_buffer);
455 :
456 : /* free ringbuffer */
457 9 : dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
458 :
459 9 : return 0;
460 : }
461 :
462 18 : int dlt_daemon_init_user_information(DltDaemon *daemon,
463 : DltGateway *gateway,
464 : int gateway_mode,
465 : int verbose)
466 : {
467 : int nodes = 1;
468 : int i = 1;
469 :
470 18 : PRINT_FUNCTION_VERBOSE(verbose);
471 :
472 18 : if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL)))
473 : return DLT_RETURN_ERROR;
474 :
475 18 : if (gateway_mode == 0) {
476 : /* initialize application list */
477 17 : daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
478 :
479 17 : if (daemon->user_list == NULL) {
480 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
481 0 : return DLT_RETURN_ERROR;
482 : }
483 :
484 17 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
485 17 : daemon->num_user_lists = 1;
486 : }
487 : else { /* gateway is active */
488 1 : nodes += gateway->num_connections;
489 :
490 : /* initialize application list */
491 1 : daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
492 :
493 1 : if (daemon->user_list == NULL) {
494 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
495 0 : return DLT_RETURN_ERROR;
496 : }
497 :
498 1 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
499 1 : daemon->num_user_lists = nodes;
500 :
501 2 : for (i = 1; i < nodes; i++)
502 1 : dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid);
503 : }
504 :
505 : return DLT_RETURN_OK;
506 : }
507 :
508 15 : int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,
509 : char *ecu,
510 : int fd,
511 : int verbose)
512 : {
513 : int i;
514 : DltDaemonRegisteredUsers *user_list = NULL;
515 :
516 15 : PRINT_FUNCTION_VERBOSE(verbose);
517 :
518 15 : if ((daemon == NULL) || (ecu == NULL))
519 : return DLT_RETURN_ERROR;
520 :
521 15 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
522 :
523 15 : if (user_list != NULL) {
524 26 : for (i = 0; i < user_list->num_applications; i++)
525 11 : if (user_list->applications[i].user_handle == fd)
526 0 : user_list->applications[i].user_handle = DLT_FD_INIT;
527 :
528 : return DLT_RETURN_OK;
529 : }
530 :
531 : return DLT_RETURN_ERROR;
532 : }
533 :
534 10 : int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose)
535 : {
536 : int i;
537 : DltDaemonRegisteredUsers *user_list = NULL;
538 :
539 10 : PRINT_FUNCTION_VERBOSE(verbose);
540 :
541 10 : if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
542 : return DLT_RETURN_WRONG_PARAMETER;
543 :
544 10 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
545 :
546 10 : if (user_list == NULL)
547 : return DLT_RETURN_ERROR;
548 :
549 11 : for (i = 0; i < user_list->num_applications; i++)
550 1 : if (user_list->applications[i].application_description != NULL) {
551 :
552 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
553 : if (user_list->applications[i].context_log_level_settings)
554 : free(user_list->applications[i].context_log_level_settings);
555 : #endif
556 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
557 : if (user_list->applications[i].trace_load_settings) {
558 : free(user_list->applications[i].trace_load_settings);
559 : user_list->applications[i].trace_load_settings = NULL;
560 : user_list->applications[i].trace_load_settings_count = 0;
561 : }
562 : #endif
563 1 : free(user_list->applications[i].application_description);
564 1 : user_list->applications[i].application_description = NULL;
565 : }
566 :
567 10 : if (user_list->applications != NULL)
568 7 : free(user_list->applications);
569 :
570 10 : user_list->applications = NULL;
571 10 : user_list->num_applications = 0;
572 :
573 10 : return 0;
574 : }
575 :
576 15 : static void dlt_daemon_application_reset_user_handle(DltDaemon *daemon,
577 : DltDaemonApplication *application,
578 : int verbose)
579 : {
580 : DltDaemonRegisteredUsers *user_list;
581 : DltDaemonContext *context;
582 : int i;
583 :
584 15 : if (application->user_handle == DLT_FD_INIT)
585 : return;
586 :
587 6 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
588 6 : if (user_list != NULL) {
589 6 : for (i = 0; i < user_list->num_contexts; i++) {
590 0 : context = &user_list->contexts[i];
591 0 : if (context->user_handle == application->user_handle)
592 0 : context->user_handle = DLT_FD_INIT;
593 : }
594 : }
595 :
596 6 : if (application->owns_user_handle)
597 6 : close(application->user_handle);
598 :
599 6 : application->user_handle = DLT_FD_INIT;
600 6 : application->owns_user_handle = false;
601 : }
602 :
603 10 : DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon,
604 : char *apid,
605 : pid_t pid,
606 : char *description,
607 : int fd,
608 : char *ecu,
609 : int verbose)
610 : {
611 : DltDaemonApplication *application;
612 : DltDaemonApplication *old;
613 : int new_application;
614 : int dlt_user_handle;
615 : bool owns_user_handle;
616 : DltDaemonRegisteredUsers *user_list = NULL;
617 : #ifdef DLT_DAEMON_USE_FIFO_IPC
618 : (void)fd; /* To avoid compiler warning : unused variable */
619 : char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
620 : #endif
621 :
622 10 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
623 : return (DltDaemonApplication *)NULL;
624 :
625 10 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
626 :
627 10 : if (user_list == NULL)
628 : return (DltDaemonApplication *)NULL;
629 :
630 10 : if (user_list->applications == NULL) {
631 10 : user_list->applications = (DltDaemonApplication *)
632 10 : malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
633 :
634 10 : if (user_list->applications == NULL)
635 : return (DltDaemonApplication *)NULL;
636 : }
637 :
638 : new_application = 0;
639 :
640 : /* Check if application [apid] is already available */
641 10 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
642 :
643 10 : if (application == NULL) {
644 10 : user_list->num_applications += 1;
645 :
646 10 : if (user_list->num_applications != 0) {
647 10 : if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
648 : /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
649 0 : old = user_list->applications;
650 0 : user_list->applications = (DltDaemonApplication *)
651 0 : malloc(sizeof(DltDaemonApplication) *
652 0 : ((user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) *
653 : DLT_DAEMON_APPL_ALLOC_SIZE);
654 :
655 0 : if (user_list->applications == NULL) {
656 0 : user_list->applications = old;
657 0 : user_list->num_applications -= 1;
658 0 : return (DltDaemonApplication *)NULL;
659 : }
660 :
661 0 : memcpy(user_list->applications,
662 : old,
663 0 : sizeof(DltDaemonApplication) * user_list->num_applications);
664 0 : free(old);
665 : }
666 : }
667 :
668 10 : application = &(user_list->applications[user_list->num_applications - 1]);
669 :
670 10 : dlt_set_id(application->apid, apid);
671 10 : application->pid = 0;
672 10 : application->application_description = NULL;
673 10 : application->num_contexts = 0;
674 10 : application->user_handle = DLT_FD_INIT;
675 10 : application->owns_user_handle = false;
676 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
677 : application->trace_load_settings = NULL;
678 : application->trace_load_settings_count = 0;
679 : #endif
680 :
681 : new_application = 1;
682 :
683 : }
684 0 : else if ((pid != application->pid) && (application->pid != 0))
685 : {
686 :
687 0 : dlt_vlog(LOG_WARNING,
688 : "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n",
689 : apid,
690 : pid,
691 : application->pid);
692 : }
693 :
694 : /* Store application description and pid of application */
695 10 : if (application->application_description) {
696 0 : free(application->application_description);
697 0 : application->application_description = NULL;
698 : }
699 :
700 10 : if (description != NULL) {
701 10 : application->application_description = malloc(strlen(description) + 1);
702 :
703 10 : if (application->application_description) {
704 10 : memcpy(application->application_description, description, strlen(description) + 1);
705 : } else {
706 0 : dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
707 0 : free(application);
708 0 : return (DltDaemonApplication *)NULL;
709 : }
710 : }
711 :
712 10 : if (application->pid != pid) {
713 9 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
714 9 : application->pid = 0;
715 : }
716 :
717 : /* open user pipe only if it is not yet opened */
718 10 : if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
719 : dlt_user_handle = DLT_FD_INIT;
720 : owns_user_handle = false;
721 :
722 : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
723 : if (fd >= DLT_FD_MINIMUM) {
724 : dlt_user_handle = fd;
725 : owns_user_handle = false;
726 : }
727 : #endif
728 : #ifdef DLT_DAEMON_USE_FIFO_IPC
729 : if (dlt_user_handle < DLT_FD_MINIMUM) {
730 : snprintf(filename,
731 : DLT_DAEMON_COMMON_TEXTBUFSIZE,
732 : "%s/dltpipes/dlt%d",
733 : dltFifoBaseDir,
734 : pid);
735 :
736 : dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
737 :
738 9 : if (dlt_user_handle < 0) {
739 0 : int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
740 0 : dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
741 : } else {
742 : owns_user_handle = true;
743 : }
744 : }
745 : #endif
746 : /* check if file descriptor was already used, and make it invalid if it
747 : * is reused. This prevents sending messages to wrong file descriptor */
748 9 : dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
749 9 : dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
750 :
751 9 : application->user_handle = dlt_user_handle;
752 9 : application->owns_user_handle = owns_user_handle;
753 9 : application->pid = pid;
754 : }
755 :
756 : /* Sort */
757 10 : if (new_application) {
758 10 : qsort(user_list->applications,
759 10 : (size_t) user_list->num_applications,
760 : sizeof(DltDaemonApplication),
761 : dlt_daemon_cmp_apid);
762 :
763 : /* Find new position of application with apid*/
764 10 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
765 : }
766 :
767 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
768 : application->num_context_log_level_settings = 0;
769 : application->context_log_level_settings = NULL;
770 : #endif
771 : #if DLT_TRACE_LOAD_CTRL_ENABLE
772 : if (application->trace_load_settings == NULL) {
773 : DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
774 : int num_settings = 0;
775 : DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
776 : daemon,
777 : application->apid,
778 : NULL /*load settings for all contexts*/,
779 : &pre_configured_trace_load_settings,
780 : &num_settings,
781 : verbose);
782 :
783 : DltTraceLoadSettings *app_level = NULL;
784 : if ((find_trace_settings_return_value == DLT_RETURN_OK) &&
785 : (pre_configured_trace_load_settings != NULL) &&
786 : (num_settings != 0)) {
787 : application->trace_load_settings = pre_configured_trace_load_settings;
788 : application->trace_load_settings_count = num_settings;
789 : app_level = dlt_find_runtime_trace_load_settings(
790 : application->trace_load_settings,
791 : application->trace_load_settings_count, application->apid,
792 : NULL);
793 : }
794 :
795 : // app is not configured, set daemon defaults
796 : if (app_level == NULL) {
797 : DltTraceLoadSettings *temp = realloc(application->trace_load_settings,
798 : (application->trace_load_settings_count + 1) *
799 : sizeof(DltTraceLoadSettings));
800 :
801 : if (temp != NULL) {
802 : application->trace_load_settings = temp;
803 : ++application->trace_load_settings_count;
804 :
805 : app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
806 : memset(app_level, 0, sizeof(DltTraceLoadSettings));
807 : app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
808 : app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
809 : memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
810 : memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
811 : } else {
812 : dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
813 : }
814 :
815 : // We inserted the application id at the end, to make sure
816 : // Lookups are working properly later on, we have to sort the list again.
817 : qsort(application->trace_load_settings,
818 : (size_t)application->trace_load_settings_count,
819 : sizeof(DltTraceLoadSettings),
820 : dlt_daemon_compare_trace_load_settings);
821 : }
822 : }
823 :
824 : #endif
825 :
826 : return application;
827 : }
828 :
829 6 : int dlt_daemon_application_del(DltDaemon *daemon,
830 : DltDaemonApplication *application,
831 : char *ecu,
832 : int verbose)
833 : {
834 : int pos;
835 : DltDaemonRegisteredUsers *user_list = NULL;
836 :
837 6 : PRINT_FUNCTION_VERBOSE(verbose);
838 :
839 6 : if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
840 : return -1;
841 :
842 6 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
843 :
844 6 : if (user_list == NULL)
845 : return -1;
846 :
847 6 : if (user_list->num_applications > 0) {
848 6 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
849 :
850 : /* Free description of application to be deleted */
851 6 : if (application->application_description) {
852 6 : free(application->application_description);
853 6 : application->application_description = NULL;
854 : }
855 :
856 : #if DLT_TRACE_LOAD_CTRL_ENABLE
857 : if (application->trace_load_settings != NULL) {
858 : free(application->trace_load_settings);
859 : application->trace_load_settings = NULL;
860 : application->trace_load_settings_count = 0;
861 : }
862 : #endif
863 6 : pos = (int) (application - (user_list->applications));
864 :
865 : /* move all applications above pos to pos */
866 6 : memmove(&(user_list->applications[pos]),
867 6 : &(user_list->applications[pos + 1]),
868 6 : sizeof(DltDaemonApplication) * ((user_list->num_applications - 1) - pos));
869 :
870 : /* Clear last application */
871 6 : memset(&(user_list->applications[user_list->num_applications - 1]),
872 : 0,
873 : sizeof(DltDaemonApplication));
874 :
875 6 : user_list->num_applications--;
876 : }
877 :
878 : return 0;
879 : }
880 :
881 149 : DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon,
882 : char *apid,
883 : char *ecu,
884 : int verbose)
885 : {
886 : DltDaemonApplication application;
887 : DltDaemonRegisteredUsers *user_list = NULL;
888 :
889 149 : PRINT_FUNCTION_VERBOSE(verbose);
890 :
891 149 : if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
892 149 : (apid[0] == '\0') || (ecu == NULL))
893 : return (DltDaemonApplication *)NULL;
894 :
895 149 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
896 :
897 149 : if ((user_list == NULL) || (user_list->num_applications == 0))
898 : return (DltDaemonApplication *)NULL;
899 :
900 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
901 132 : if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
902 132 : (memcmp(apid,
903 132 : user_list->applications[user_list->num_applications - 1].apid,
904 : DLT_ID_SIZE) > 0))
905 : return (DltDaemonApplication *)NULL;
906 :
907 132 : dlt_set_id(application.apid, apid);
908 132 : return (DltDaemonApplication *)bsearch(&application,
909 132 : user_list->applications,
910 132 : (size_t) user_list->num_applications,
911 : sizeof(DltDaemonApplication),
912 : dlt_daemon_cmp_apid);
913 : }
914 :
915 9 : int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose)
916 : {
917 : FILE *fd;
918 : ID4 apid;
919 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
920 : char *ret;
921 : char *pb;
922 :
923 9 : PRINT_FUNCTION_VERBOSE(verbose);
924 :
925 9 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
926 : return -1;
927 :
928 9 : fd = fopen(filename, "r");
929 :
930 9 : if (fd == NULL) {
931 9 : dlt_vlog(LOG_WARNING,
932 : "%s: cannot open file %s: %s\n",
933 : __func__,
934 : filename,
935 9 : strerror(errno));
936 :
937 9 : return -1;
938 : }
939 :
940 0 : while (!feof(fd)) {
941 : /* Clear buf */
942 : memset(buf, 0, sizeof(buf));
943 :
944 : /* Get line */
945 : ret = fgets(buf, sizeof(buf), fd);
946 :
947 0 : if (NULL == ret) {
948 : /* fgets always null pointer if the last byte of the file is a new line
949 : * We need to check here if there was an error or was it feof.*/
950 0 : if (ferror(fd)) {
951 0 : dlt_vlog(LOG_WARNING,
952 : "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
953 : __func__,
954 0 : strerror(errno));
955 0 : fclose(fd);
956 0 : return -1;
957 : }
958 0 : else if (feof(fd))
959 : {
960 0 : fclose(fd);
961 0 : return 0;
962 : }
963 : else {
964 0 : dlt_vlog(LOG_WARNING,
965 : "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
966 : __func__);
967 0 : fclose(fd);
968 0 : return -1;
969 : }
970 : }
971 :
972 0 : if (strcmp(buf, "") != 0) {
973 : /* Split line */
974 0 : pb = strtok(buf, ":");
975 :
976 0 : if (pb != NULL) {
977 0 : dlt_set_id(apid, pb);
978 0 : pb = strtok(NULL, ":");
979 :
980 0 : if (pb != NULL) {
981 : /* pb contains now the description */
982 : /* pid is unknown at loading time */
983 0 : if (dlt_daemon_application_add(daemon,
984 : apid,
985 : 0,
986 : pb,
987 : -1,
988 0 : daemon->ecuid,
989 : verbose) == 0) {
990 0 : dlt_vlog(LOG_WARNING,
991 : "%s: dlt_daemon_application_add failed for %4s\n",
992 : __func__,
993 : apid);
994 0 : fclose(fd);
995 0 : return -1;
996 : }
997 : }
998 : }
999 : }
1000 : }
1001 :
1002 0 : fclose(fd);
1003 :
1004 0 : return 0;
1005 : }
1006 :
1007 0 : int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose)
1008 : {
1009 : FILE *fd;
1010 : int i;
1011 :
1012 : char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
1013 : DltDaemonRegisteredUsers *user_list = NULL;
1014 :
1015 0 : PRINT_FUNCTION_VERBOSE(verbose);
1016 :
1017 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1018 : return -1;
1019 :
1020 : memset(apid, 0, sizeof(apid));
1021 :
1022 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1023 :
1024 0 : if (user_list == NULL)
1025 : return -1;
1026 :
1027 0 : if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
1028 0 : fd = fopen(filename, "w");
1029 :
1030 0 : if (fd != NULL) {
1031 0 : for (i = 0; i < user_list->num_applications; i++) {
1032 0 : dlt_set_id(apid, user_list->applications[i].apid);
1033 :
1034 0 : if ((user_list->applications[i].application_description) &&
1035 0 : (user_list->applications[i].application_description[0] != '\0'))
1036 : fprintf(fd,
1037 : "%s:%s:\n",
1038 : apid,
1039 : user_list->applications[i].application_description);
1040 : else
1041 : fprintf(fd, "%s::\n", apid);
1042 : }
1043 :
1044 0 : fclose(fd);
1045 : }
1046 : else {
1047 0 : dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n",
1048 : __func__,
1049 : filename);
1050 : }
1051 : }
1052 :
1053 : return 0;
1054 : }
1055 :
1056 41 : DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon,
1057 : char *apid,
1058 : char *ctid,
1059 : int8_t log_level,
1060 : int8_t trace_status,
1061 : int log_level_pos,
1062 : int user_handle,
1063 : char *description,
1064 : char *ecu,
1065 : int verbose)
1066 : {
1067 : DltDaemonApplication *application;
1068 : DltDaemonContext *context;
1069 : DltDaemonContext *old;
1070 : int new_context = 0;
1071 : DltDaemonRegisteredUsers *user_list = NULL;
1072 :
1073 41 : PRINT_FUNCTION_VERBOSE(verbose);
1074 :
1075 41 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
1076 41 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1077 : return (DltDaemonContext *)NULL;
1078 :
1079 41 : if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
1080 : return (DltDaemonContext *)NULL;
1081 :
1082 41 : if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
1083 : return (DltDaemonContext *)NULL;
1084 :
1085 41 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1086 :
1087 41 : if (user_list == NULL)
1088 : return (DltDaemonContext *)NULL;
1089 :
1090 41 : if (user_list->contexts == NULL) {
1091 10 : user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1092 :
1093 10 : if (user_list->contexts == NULL)
1094 : return (DltDaemonContext *)NULL;
1095 : }
1096 :
1097 : /* Check if application [apid] is available */
1098 41 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
1099 :
1100 41 : if (application == NULL)
1101 : return (DltDaemonContext *)NULL;
1102 :
1103 : /* Check if context [apid, ctid] is already available */
1104 41 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1105 :
1106 41 : if (context == NULL) {
1107 41 : user_list->num_contexts += 1;
1108 :
1109 41 : if (user_list->num_contexts != 0) {
1110 41 : if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
1111 : /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
1112 0 : old = user_list->contexts;
1113 0 : user_list->contexts = (DltDaemonContext *)calloc(1, (size_t) sizeof(DltDaemonContext) *
1114 0 : ((user_list->num_contexts /
1115 0 : DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) *
1116 : DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1117 :
1118 0 : if (user_list->contexts == NULL) {
1119 0 : user_list->contexts = old;
1120 0 : user_list->num_contexts -= 1;
1121 0 : return (DltDaemonContext *)NULL;
1122 : }
1123 :
1124 0 : memcpy(user_list->contexts,
1125 : old,
1126 0 : (size_t) sizeof(DltDaemonContext) * user_list->num_contexts);
1127 0 : free(old);
1128 : }
1129 : }
1130 :
1131 41 : context = &(user_list->contexts[user_list->num_contexts - 1]);
1132 : memset(context, 0, sizeof(DltDaemonContext));
1133 :
1134 41 : dlt_set_id(context->apid, apid);
1135 41 : dlt_set_id(context->ctid, ctid);
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 : /* In case a context is loaded from runtime config file,
1217 : * the user_handle is 0 and we mark that context as predefined.
1218 : */
1219 41 : if (context->user_handle == 0)
1220 0 : context->predefined = true;
1221 : else
1222 41 : context->predefined = false;
1223 :
1224 : /* Sort */
1225 41 : if (new_context) {
1226 41 : qsort(user_list->contexts,
1227 41 : (size_t) user_list->num_contexts,
1228 : sizeof(DltDaemonContext),
1229 : dlt_daemon_cmp_apid_ctid);
1230 :
1231 : /* Find new position of context with apid, ctid */
1232 41 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1233 : }
1234 :
1235 : return context;
1236 : }
1237 :
1238 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1239 : static void dlt_daemon_free_context_log_settings(
1240 : DltDaemonApplication *application,
1241 : DltDaemonContext *context)
1242 : {
1243 : DltDaemonContextLogSettings *ct_settings;
1244 : int i;
1245 : int skipped = 0;
1246 :
1247 : ct_settings = dlt_daemon_find_app_log_level_config(application, context->ctid);
1248 : if (ct_settings == NULL) {
1249 : return;
1250 : }
1251 :
1252 : /* move all data forward */
1253 : for (i = 0; i < application->num_context_log_level_settings; ++i) {
1254 : /* skip given context to delete it */
1255 : if (i + skipped < application->num_context_log_level_settings &&
1256 : strncmp(application->context_log_level_settings[i+skipped].ctid, context->ctid, DLT_ID_SIZE) == 0) {
1257 : ++skipped;
1258 : continue;
1259 : }
1260 :
1261 : memcpy(&application->context_log_level_settings[i-skipped],
1262 : &application->context_log_level_settings[i],
1263 : sizeof(DltDaemonContextLogSettings));
1264 : }
1265 :
1266 : application->num_context_log_level_settings -= skipped;
1267 :
1268 : /* if size is equal to zero, and ptr is not NULL, then realloc is equivalent to free(ptr) */
1269 : application->context_log_level_settings = realloc(application->context_log_level_settings,
1270 : sizeof(DltDaemonContextLogSettings) * (application->num_context_log_level_settings));
1271 :
1272 : }
1273 : #endif
1274 :
1275 37 : int dlt_daemon_context_del(DltDaemon *daemon,
1276 : DltDaemonContext *context,
1277 : char *ecu,
1278 : int verbose)
1279 : {
1280 : int pos;
1281 : DltDaemonApplication *application;
1282 : DltDaemonRegisteredUsers *user_list = NULL;
1283 :
1284 37 : PRINT_FUNCTION_VERBOSE(verbose);
1285 :
1286 37 : if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
1287 : return -1;
1288 :
1289 37 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1290 :
1291 37 : if (user_list == NULL)
1292 : return -1;
1293 :
1294 37 : if (user_list->num_contexts > 0) {
1295 37 : application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose);
1296 :
1297 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1298 : dlt_daemon_free_context_log_settings(application, context);
1299 : #endif
1300 : /* Free description of context to be deleted */
1301 37 : if (context->context_description) {
1302 37 : free(context->context_description);
1303 37 : context->context_description = NULL;
1304 : }
1305 :
1306 37 : pos = (int) (context - (user_list->contexts));
1307 :
1308 : /* move all contexts above pos to pos */
1309 37 : memmove(&(user_list->contexts[pos]),
1310 37 : &(user_list->contexts[pos + 1]),
1311 37 : sizeof(DltDaemonContext) * ((user_list->num_contexts - 1) - pos));
1312 :
1313 : /* Clear last context */
1314 37 : memset(&(user_list->contexts[user_list->num_contexts - 1]),
1315 : 0,
1316 : sizeof(DltDaemonContext));
1317 :
1318 37 : user_list->num_contexts--;
1319 :
1320 : /* Check if application [apid] is available */
1321 37 : if (application != NULL)
1322 37 : application->num_contexts--;
1323 : }
1324 :
1325 : return 0;
1326 : }
1327 :
1328 157 : DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon,
1329 : char *apid,
1330 : char *ctid,
1331 : char *ecu,
1332 : int verbose)
1333 : {
1334 : DltDaemonContext context;
1335 : DltDaemonRegisteredUsers *user_list = NULL;
1336 :
1337 157 : PRINT_FUNCTION_VERBOSE(verbose);
1338 :
1339 157 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
1340 157 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1341 : return (DltDaemonContext *)NULL;
1342 :
1343 157 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1344 :
1345 157 : if ((user_list == NULL) || (user_list->num_contexts == 0))
1346 : return (DltDaemonContext *)NULL;
1347 :
1348 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
1349 112 : if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
1350 112 : (memcmp(apid,
1351 112 : user_list->contexts[user_list->num_contexts - 1].apid,
1352 : DLT_ID_SIZE) > 0))
1353 : return (DltDaemonContext *)NULL;
1354 :
1355 112 : dlt_set_id(context.apid, apid);
1356 112 : dlt_set_id(context.ctid, ctid);
1357 :
1358 112 : return (DltDaemonContext *)bsearch(&context,
1359 112 : user_list->contexts,
1360 112 : (size_t) user_list->num_contexts,
1361 : sizeof(DltDaemonContext),
1362 : dlt_daemon_cmp_apid_ctid);
1363 : }
1364 :
1365 15 : int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,
1366 : char *ecu,
1367 : int fd,
1368 : int verbose)
1369 : {
1370 : int i;
1371 : DltDaemonRegisteredUsers *user_list = NULL;
1372 :
1373 15 : PRINT_FUNCTION_VERBOSE(verbose);
1374 :
1375 15 : if ((daemon == NULL) || (ecu == NULL))
1376 : return -1;
1377 :
1378 15 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1379 :
1380 15 : if (user_list != NULL) {
1381 39 : for (i = 0; i < user_list->num_contexts; i++)
1382 24 : if (user_list->contexts[i].user_handle == fd)
1383 0 : user_list->contexts[i].user_handle = DLT_FD_INIT;
1384 :
1385 : return 0;
1386 : }
1387 :
1388 : return -1;
1389 : }
1390 :
1391 10 : int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose)
1392 : {
1393 : int i;
1394 : DltDaemonRegisteredUsers *users = NULL;
1395 :
1396 10 : PRINT_FUNCTION_VERBOSE(verbose);
1397 :
1398 10 : if ((daemon == NULL) || (ecu == NULL))
1399 : return DLT_RETURN_WRONG_PARAMETER;
1400 :
1401 10 : users = dlt_daemon_find_users_list(daemon, ecu, verbose);
1402 :
1403 10 : if (users == NULL)
1404 : return DLT_RETURN_ERROR;
1405 :
1406 11 : for (i = 0; i < users->num_contexts; i++)
1407 1 : if (users->contexts[i].context_description != NULL) {
1408 1 : free(users->contexts[i].context_description);
1409 1 : users->contexts[i].context_description = NULL;
1410 : }
1411 :
1412 10 : if (users->contexts) {
1413 7 : free(users->contexts);
1414 7 : users->contexts = NULL;
1415 : }
1416 :
1417 11 : for (i = 0; i < users->num_applications; i++)
1418 1 : users->applications[i].num_contexts = 0;
1419 :
1420 10 : users->num_contexts = 0;
1421 :
1422 10 : return 0;
1423 : }
1424 :
1425 0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
1426 : {
1427 : FILE *fd;
1428 : ID4 apid, ctid;
1429 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
1430 : char *ret;
1431 : char *pb;
1432 : int ll, ts;
1433 :
1434 0 : PRINT_FUNCTION_VERBOSE(verbose);
1435 :
1436 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1437 : return -1;
1438 :
1439 0 : fd = fopen(filename, "r");
1440 :
1441 0 : if (fd == NULL) {
1442 0 : dlt_vlog(LOG_WARNING,
1443 : "DLT runtime-context load, cannot open file %s: %s\n",
1444 : filename,
1445 0 : strerror(errno));
1446 :
1447 0 : return -1;
1448 : }
1449 :
1450 0 : while (!feof(fd)) {
1451 : /* Clear buf */
1452 : memset(buf, 0, sizeof(buf));
1453 :
1454 : /* Get line */
1455 : ret = fgets(buf, sizeof(buf), fd);
1456 :
1457 0 : if (NULL == ret) {
1458 : /* fgets always returns null pointer if the last byte of the file is a new line.
1459 : * We need to check here if there was an error or was it feof.*/
1460 0 : if (ferror(fd)) {
1461 0 : dlt_vlog(LOG_WARNING,
1462 : "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
1463 : __func__,
1464 0 : strerror(errno));
1465 0 : fclose(fd);
1466 0 : return -1;
1467 : }
1468 0 : else if (feof(fd))
1469 : {
1470 0 : fclose(fd);
1471 0 : return 0;
1472 : }
1473 : else {
1474 0 : dlt_vlog(LOG_WARNING,
1475 : "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
1476 : __func__);
1477 0 : fclose(fd);
1478 0 : return -1;
1479 : }
1480 : }
1481 :
1482 0 : if (strcmp(buf, "") != 0) {
1483 : /* Split line */
1484 0 : pb = strtok(buf, ":");
1485 :
1486 0 : if (pb != NULL) {
1487 0 : dlt_set_id(apid, pb);
1488 0 : pb = strtok(NULL, ":");
1489 :
1490 0 : if (pb != NULL) {
1491 0 : dlt_set_id(ctid, pb);
1492 0 : pb = strtok(NULL, ":");
1493 :
1494 0 : if (pb != NULL) {
1495 0 : sscanf(pb, "%d", &ll);
1496 0 : pb = strtok(NULL, ":");
1497 :
1498 0 : if (pb != NULL) {
1499 0 : sscanf(pb, "%d", &ts);
1500 0 : pb = strtok(NULL, ":");
1501 :
1502 0 : if (pb != NULL) {
1503 : /* pb contains now the description */
1504 :
1505 : /* log_level_pos, and user_handle are unknown at loading time */
1506 0 : if (dlt_daemon_context_add(daemon,
1507 : apid,
1508 : ctid,
1509 0 : (int8_t)ll,
1510 0 : (int8_t)ts,
1511 : 0,
1512 : 0,
1513 : pb,
1514 0 : daemon->ecuid,
1515 : verbose) == NULL) {
1516 0 : dlt_vlog(LOG_WARNING,
1517 : "%s dlt_daemon_context_add failed\n",
1518 : __func__);
1519 0 : fclose(fd);
1520 0 : return -1;
1521 : }
1522 : }
1523 : }
1524 : }
1525 : }
1526 : }
1527 : }
1528 : }
1529 :
1530 0 : fclose(fd);
1531 :
1532 0 : return 0;
1533 : }
1534 :
1535 0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
1536 : {
1537 : FILE *fd;
1538 : int i;
1539 :
1540 : char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
1541 : DltDaemonRegisteredUsers *user_list = NULL;
1542 :
1543 0 : PRINT_FUNCTION_VERBOSE(verbose);
1544 :
1545 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1546 : return -1;
1547 :
1548 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1549 :
1550 0 : if (user_list == NULL)
1551 : return -1;
1552 :
1553 : memset(apid, 0, sizeof(apid));
1554 : memset(ctid, 0, sizeof(ctid));
1555 :
1556 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
1557 0 : fd = fopen(filename, "w");
1558 :
1559 0 : if (fd != NULL) {
1560 0 : for (i = 0; i < user_list->num_contexts; i++) {
1561 0 : dlt_set_id(apid, user_list->contexts[i].apid);
1562 0 : dlt_set_id(ctid, user_list->contexts[i].ctid);
1563 :
1564 0 : if ((user_list->contexts[i].context_description) &&
1565 0 : (user_list->contexts[i].context_description[0] != '\0'))
1566 0 : fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
1567 0 : (int)(user_list->contexts[i].log_level),
1568 0 : (int)(user_list->contexts[i].trace_status),
1569 : user_list->contexts[i].context_description);
1570 : else
1571 0 : fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
1572 0 : (int)(user_list->contexts[i].log_level),
1573 0 : (int)(user_list->contexts[i].trace_status));
1574 : }
1575 :
1576 0 : fclose(fd);
1577 : }
1578 : else {
1579 0 : dlt_vlog(LOG_ERR,
1580 : "%s: Cannot open %s. No context information stored\n",
1581 : __func__,
1582 : filename);
1583 : }
1584 : }
1585 :
1586 : return 0;
1587 : }
1588 :
1589 0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
1590 : {
1591 : FILE *fd;
1592 :
1593 0 : PRINT_FUNCTION_VERBOSE(verbose);
1594 :
1595 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1596 : return -1;
1597 :
1598 0 : fd = fopen(filename, "w");
1599 :
1600 0 : if (fd != NULL) {
1601 : fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
1602 0 : fprintf(fd, "LoggingMode = %d\n", daemon->mode);
1603 :
1604 0 : fclose(fd);
1605 : }
1606 :
1607 : return 0;
1608 : }
1609 :
1610 9 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
1611 : {
1612 9 : if ((daemon == NULL) || (filename == NULL))
1613 : return -1;
1614 :
1615 : FILE *pFile;
1616 : char line[1024];
1617 : char token[1024];
1618 : char value[1024];
1619 : char *pch;
1620 :
1621 9 : PRINT_FUNCTION_VERBOSE(verbose);
1622 :
1623 9 : pFile = fopen (filename, "r");
1624 :
1625 9 : if (pFile != NULL) {
1626 : while (1) {
1627 : /* fetch line from configuration file */
1628 18 : if (fgets (line, 1024, pFile) != NULL) {
1629 9 : pch = strtok (line, " =\r\n");
1630 9 : token[0] = 0;
1631 9 : value[0] = 0;
1632 :
1633 18 : while (pch != NULL) {
1634 9 : if (strcmp(pch, "#") == 0)
1635 : break;
1636 :
1637 9 : if (token[0] == 0) {
1638 : strncpy(token, pch, sizeof(token) - 1);
1639 9 : token[sizeof(token) - 1] = 0;
1640 : }
1641 : else {
1642 : strncpy(value, pch, sizeof(value) - 1);
1643 0 : value[sizeof(value) - 1] = 0;
1644 0 : break;
1645 : }
1646 :
1647 9 : pch = strtok (NULL, " =\r\n");
1648 : }
1649 :
1650 9 : if (token[0] && value[0]) {
1651 : /* parse arguments here */
1652 0 : if (strcmp(token, "LoggingMode") == 0) {
1653 0 : daemon->mode = atoi(value);
1654 0 : dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
1655 : daemon->mode);
1656 : }
1657 : else {
1658 0 : dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
1659 : value);
1660 : }
1661 : }
1662 : }
1663 : else {
1664 : break;
1665 : }
1666 : }
1667 :
1668 9 : fclose (pFile);
1669 : }
1670 : else {
1671 0 : dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
1672 : }
1673 :
1674 : return 0;
1675 : }
1676 :
1677 41 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
1678 : {
1679 : DltUserHeader userheader;
1680 : DltUserControlMsgLogLevel usercontext;
1681 : DltReturnValue ret;
1682 : DltDaemonApplication *app;
1683 :
1684 41 : PRINT_FUNCTION_VERBOSE(verbose);
1685 :
1686 41 : if ((daemon == NULL) || (context == NULL)) {
1687 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
1688 0 : return -1;
1689 : }
1690 :
1691 41 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
1692 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
1693 0 : return -1;
1694 : }
1695 :
1696 41 : if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
1697 34 : (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
1698 32 : usercontext.log_level = (uint8_t) (context->log_level >
1699 : context->storage_log_level ? context->log_level : context->storage_log_level);
1700 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
1701 9 : usercontext.log_level =
1702 9 : (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
1703 :
1704 41 : usercontext.trace_status =
1705 41 : (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
1706 :
1707 41 : usercontext.log_level_pos = context->log_level_pos;
1708 :
1709 41 : dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
1710 41 : context->apid,
1711 41 : context->ctid,
1712 41 : context->log_level,
1713 41 : usercontext.log_level,
1714 : context->trace_status,
1715 : usercontext.trace_status);
1716 :
1717 : /* log to FIFO */
1718 41 : errno = 0;
1719 41 : ret = dlt_user_log_out2_with_timeout(context->user_handle,
1720 : &(userheader), sizeof(DltUserHeader),
1721 : &(usercontext), sizeof(DltUserControlMsgLogLevel));
1722 :
1723 41 : if (ret < DLT_RETURN_OK) {
1724 0 : dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
1725 : __func__,
1726 0 : errno != 0 ? strerror(errno) : "Unknown error");
1727 :
1728 0 : if (errno == EPIPE) {
1729 0 : app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
1730 0 : if (app != NULL)
1731 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
1732 : }
1733 : }
1734 :
1735 41 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
1736 : }
1737 :
1738 9 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
1739 : {
1740 : DltUserHeader userheader;
1741 : DltUserControlMsgLogState logstate;
1742 : DltReturnValue ret;
1743 :
1744 9 : PRINT_FUNCTION_VERBOSE(verbose);
1745 :
1746 9 : if ((daemon == NULL) || (app == NULL))
1747 : return -1;
1748 :
1749 9 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
1750 : return -1;
1751 :
1752 9 : logstate.log_state = daemon->connectionState;
1753 :
1754 : /* log to FIFO */
1755 9 : ret = dlt_user_log_out2_with_timeout(app->user_handle,
1756 : &(userheader), sizeof(DltUserHeader),
1757 : &(logstate), sizeof(DltUserControlMsgLogState));
1758 :
1759 9 : if (ret < DLT_RETURN_OK) {
1760 0 : if (errno == EPIPE)
1761 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
1762 : }
1763 :
1764 9 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
1765 : }
1766 :
1767 0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
1768 : const char *filename,
1769 : const char *filename1,
1770 : int InitialContextLogLevel,
1771 : int InitialContextTraceStatus,
1772 : int InitialEnforceLlTsStatus,
1773 : int verbose)
1774 : {
1775 : FILE *fd;
1776 :
1777 0 : PRINT_FUNCTION_VERBOSE(verbose);
1778 :
1779 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
1780 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1781 0 : return;
1782 : }
1783 :
1784 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
1785 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
1786 0 : return;
1787 : }
1788 :
1789 : /* Check for runtime cfg file and delete it, if available */
1790 0 : fd = fopen(filename, "r");
1791 :
1792 0 : if (fd != NULL) {
1793 : /* Close and delete file */
1794 0 : fclose(fd);
1795 0 : if (unlink(filename) != 0) {
1796 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
1797 0 : __func__, strerror(errno));
1798 : }
1799 : }
1800 :
1801 0 : fd = fopen(filename1, "r");
1802 :
1803 0 : if (fd != NULL) {
1804 : /* Close and delete file */
1805 0 : fclose(fd);
1806 0 : if (unlink(filename1) != 0) {
1807 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
1808 0 : __func__, strerror(errno));
1809 : }
1810 : }
1811 :
1812 0 : daemon->default_log_level = (int8_t) InitialContextLogLevel;
1813 0 : daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
1814 0 : daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
1815 :
1816 : /* Reset all other things (log level, trace status, etc.
1817 : * to default values */
1818 :
1819 : /* Inform user libraries about changed default log level/trace status */
1820 0 : dlt_daemon_user_send_default_update(daemon, verbose);
1821 : }
1822 :
1823 0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
1824 : {
1825 : int32_t count;
1826 : DltDaemonContext *context;
1827 : DltDaemonRegisteredUsers *user_list = NULL;
1828 :
1829 0 : PRINT_FUNCTION_VERBOSE(verbose);
1830 :
1831 0 : if (daemon == NULL) {
1832 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1833 0 : return;
1834 : }
1835 :
1836 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1837 :
1838 0 : if (user_list == NULL)
1839 : return;
1840 :
1841 0 : for (count = 0; count < user_list->num_contexts; count++) {
1842 0 : context = &(user_list->contexts[count]);
1843 :
1844 0 : if (context != NULL) {
1845 0 : if ((context->log_level == DLT_LOG_DEFAULT) ||
1846 0 : (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
1847 0 : if (context->user_handle >= DLT_FD_MINIMUM)
1848 0 : if (dlt_daemon_user_send_log_level(daemon,
1849 : context,
1850 : verbose) == -1)
1851 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
1852 : }
1853 : }
1854 : }
1855 : }
1856 :
1857 0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
1858 : int enforce_context_ll_and_ts,
1859 : int8_t context_log_level,
1860 : int8_t log_level,
1861 : int verbose)
1862 : {
1863 : int32_t count = 0;
1864 : DltDaemonContext *context = NULL;
1865 : DltDaemonRegisteredUsers *user_list = NULL;
1866 :
1867 0 : PRINT_FUNCTION_VERBOSE(verbose);
1868 :
1869 0 : if (daemon == NULL)
1870 : return;
1871 :
1872 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1873 :
1874 0 : if (user_list == NULL)
1875 : return;
1876 :
1877 0 : for (count = 0; count < user_list->num_contexts; count++) {
1878 0 : context = &(user_list->contexts[count]);
1879 :
1880 0 : if (context) {
1881 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
1882 0 : context->log_level = log_level;
1883 :
1884 0 : if (enforce_context_ll_and_ts) {
1885 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1886 : DltDaemonContextLogSettings *settings =
1887 : dlt_daemon_find_configured_app_id_ctx_id_settings(
1888 : daemon, context->apid, context->ctid);
1889 : if (settings != NULL) {
1890 : if (log_level > settings->log_level) {
1891 : context->log_level = settings->log_level;
1892 : }
1893 : } else
1894 : #endif
1895 0 : if (log_level > context_log_level) {
1896 0 : context->log_level = (int8_t)context_log_level;
1897 : }
1898 : }
1899 :
1900 0 : if (dlt_daemon_user_send_log_level(daemon,
1901 : context,
1902 : verbose) == -1)
1903 0 : dlt_vlog(LOG_WARNING,
1904 : "Cannot send log level %.4s:%.4s -> %i\n",
1905 0 : context->apid,
1906 0 : context->ctid,
1907 0 : context->log_level);
1908 : }
1909 : }
1910 : }
1911 : }
1912 :
1913 0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
1914 : {
1915 : int32_t count = 0;
1916 : DltDaemonContext *context = NULL;
1917 : DltDaemonRegisteredUsers *user_list = NULL;
1918 :
1919 0 : PRINT_FUNCTION_VERBOSE(verbose);
1920 :
1921 0 : if (daemon == NULL)
1922 : return;
1923 :
1924 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1925 :
1926 0 : if (user_list == NULL)
1927 : return;
1928 :
1929 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
1930 :
1931 0 : for (count = 0; count < user_list->num_contexts; count++) {
1932 0 : context = &(user_list->contexts[count]);
1933 :
1934 0 : if (context) {
1935 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
1936 0 : context->trace_status = trace_status;
1937 :
1938 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
1939 0 : dlt_vlog(LOG_WARNING,
1940 : "Cannot send trace status %.4s:%.4s -> %i\n",
1941 0 : context->apid,
1942 0 : context->ctid,
1943 0 : context->trace_status);
1944 : }
1945 : }
1946 : }
1947 : }
1948 :
1949 5 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
1950 : {
1951 : int32_t count;
1952 : DltDaemonApplication *app;
1953 : DltDaemonRegisteredUsers *user_list = NULL;
1954 :
1955 5 : PRINT_FUNCTION_VERBOSE(verbose);
1956 :
1957 5 : if (daemon == NULL) {
1958 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
1959 0 : return;
1960 : }
1961 :
1962 5 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1963 :
1964 5 : if (user_list == NULL)
1965 : return;
1966 :
1967 7 : for (count = 0; count < user_list->num_applications; count++) {
1968 2 : app = &(user_list->applications[count]);
1969 :
1970 2 : if (app != NULL) {
1971 2 : if (app->user_handle >= DLT_FD_MINIMUM)
1972 2 : if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
1973 0 : dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d\n", app->apid, app->pid);
1974 : }
1975 : }
1976 : }
1977 :
1978 16 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
1979 : {
1980 16 : switch (newState) {
1981 0 : case DLT_DAEMON_STATE_INIT:
1982 0 : dlt_log(LOG_INFO, "Switched to init state.\n");
1983 0 : daemon->state = DLT_DAEMON_STATE_INIT;
1984 0 : break;
1985 12 : case DLT_DAEMON_STATE_BUFFER:
1986 12 : dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
1987 12 : daemon->state = DLT_DAEMON_STATE_BUFFER;
1988 12 : break;
1989 0 : case DLT_DAEMON_STATE_BUFFER_FULL:
1990 0 : dlt_log(LOG_INFO, "Switched to buffer full state.\n");
1991 0 : daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
1992 0 : break;
1993 2 : case DLT_DAEMON_STATE_SEND_BUFFER:
1994 2 : dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
1995 2 : daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
1996 2 : break;
1997 2 : case DLT_DAEMON_STATE_SEND_DIRECT:
1998 2 : dlt_log(LOG_INFO, "Switched to send direct state.\n");
1999 2 : daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
2000 2 : break;
2001 : }
2002 16 : }
2003 :
2004 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2005 : void dlt_daemon_trigger_systemd_watchdog_if_necessary(unsigned int* last_trigger_time, unsigned int watchdog_trigger_interval) {
2006 : unsigned int uptime = dlt_uptime();
2007 : if ((uptime - *last_trigger_time) / 10000 >= watchdog_trigger_interval) {
2008 : if (sd_notify(0, "WATCHDOG=1") < 0)
2009 : dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
2010 : *last_trigger_time = uptime;
2011 : }
2012 : }
2013 : #endif
2014 :
2015 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
2016 : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
2017 : {
2018 : DltUserHeader userheader;
2019 : DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
2020 : uint32_t trace_load_settings_count;
2021 : DltReturnValue ret;
2022 :
2023 :
2024 : PRINT_FUNCTION_VERBOSE(verbose);
2025 :
2026 : if ((daemon == NULL) || (app == NULL)) return -1;
2027 :
2028 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
2029 :
2030 : DltTraceLoadSettings* app_settings = app->trace_load_settings;
2031 :
2032 : if (app_settings != NULL) {
2033 : trace_load_settings_count = app->trace_load_settings_count;
2034 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
2035 : for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
2036 : // App id is not transmitted as the user library only
2037 : // has one application ID
2038 : memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
2039 : trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
2040 : trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
2041 :
2042 : if (app_settings[i].ctid[0] == '\0') {
2043 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
2044 : app->apid,
2045 : app_settings[i].soft_limit,
2046 : app_settings[i].hard_limit);
2047 : } else {
2048 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
2049 : app->apid,
2050 : app_settings[i].ctid,
2051 : app_settings[i].soft_limit,
2052 : app_settings[i].hard_limit);
2053 : }
2054 :
2055 : }
2056 : }
2057 : else {
2058 : dlt_vlog(LOG_INFO,
2059 : "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
2060 :
2061 : trace_load_settings_count = 1;
2062 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
2063 :
2064 : memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
2065 : trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
2066 : trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
2067 : }
2068 :
2069 : /* log to FIFO */
2070 : ret = dlt_user_log_out3_with_timeout(app->user_handle,
2071 : &(userheader), sizeof(DltUserHeader),
2072 : &(trace_load_settings_count), sizeof(uint32_t),
2073 : trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
2074 :
2075 : if (ret < DLT_RETURN_OK && errno == EPIPE) {
2076 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2077 : }
2078 :
2079 : free(trace_load_settings_user_msg);
2080 :
2081 : return ret;
2082 : }
2083 : #endif
|