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 11 : 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 11 : return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
105 : }
106 :
107 0 : static int dlt_daemon_cmp_apid_v2(const void* m1, const void* m2)
108 : {
109 0 : if ((m1 == NULL) || (m2 == NULL))
110 : return -1;
111 :
112 : const DltDaemonApplication* mi1 = (const DltDaemonApplication*)m1;
113 : const DltDaemonApplication* mi2 = (const DltDaemonApplication*)m2;
114 :
115 0 : if (mi1->apid2len < mi2->apid2len) {
116 : return -1;
117 0 : } else if (mi1->apid2len > mi2->apid2len) {
118 : return 1;
119 : }
120 :
121 0 : return memcmp(mi1->apid2, mi2->apid2, mi1->apid2len);
122 : }
123 :
124 10 : static int dlt_daemon_cmp_apid_ctid(const void* m1, const void* m2)
125 : {
126 10 : if ((m1 == NULL) || (m2 == NULL))
127 : return -1;
128 :
129 : int ret, cmp;
130 : const DltDaemonContext* mi1 = (const DltDaemonContext*)m1;
131 : const DltDaemonContext* mi2 = (const DltDaemonContext*)m2;
132 :
133 10 : cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
134 :
135 10 : if (cmp < 0)
136 : ret = -1;
137 10 : else if (cmp == 0)
138 10 : ret = memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
139 : else
140 : ret = 1;
141 :
142 : return ret;
143 : }
144 :
145 0 : static int dlt_daemon_cmp_apid_ctid_v2(const void* m1, const void* m2)
146 : {
147 0 : if ((m1 == NULL) || (m2 == NULL))
148 : return -1;
149 :
150 : int cmp;
151 : const DltDaemonContext* mi1 = (const DltDaemonContext*)m1;
152 : const DltDaemonContext* mi2 = (const DltDaemonContext*)m2;
153 :
154 0 : if (mi1->apid2len < mi2->apid2len) {
155 : return -1;
156 0 : } else if (mi1->apid2len > mi2->apid2len) {
157 : return 1;
158 : }
159 :
160 0 : cmp = memcmp(mi1->apid2, mi2->apid2, mi1->apid2len);
161 :
162 0 : if (cmp < 0) {
163 : return -1;
164 0 : } else if (cmp > 0) {
165 : return 1;
166 : } else {
167 0 : if (mi1->ctid2len < mi2->ctid2len) {
168 : return -1;
169 0 : } else if (mi1->ctid2len > mi2->ctid2len) {
170 : return 1;
171 : } else {
172 0 : return memcmp(mi1->ctid2, mi2->ctid2, mi1->ctid2len);
173 : }
174 : }
175 : }
176 :
177 68 : DltDaemonRegisteredUsers* dlt_daemon_find_users_list(DltDaemon* daemon, char* ecu, int verbose)
178 : {
179 68 : PRINT_FUNCTION_VERBOSE(verbose);
180 :
181 : int i = 0;
182 :
183 68 : if ((daemon == NULL) || (ecu == NULL)) {
184 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
185 0 : return (DltDaemonRegisteredUsers*)NULL;
186 : }
187 :
188 68 : for (i = 0; i < daemon->num_user_lists; i++)
189 56 : if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
190 56 : return &daemon->user_list[i];
191 :
192 12 : dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %4s\n", ecu);
193 12 : return (DltDaemonRegisteredUsers*)NULL;
194 : }
195 :
196 0 : DltDaemonRegisteredUsers* dlt_daemon_find_users_list_v2(DltDaemon* daemon, uint8_t eculen, char* ecu, int verbose)
197 : {
198 0 : PRINT_FUNCTION_VERBOSE(verbose);
199 :
200 : int i = 0;
201 :
202 0 : if ((daemon == NULL) || (ecu == NULL) || (eculen == 0)) {
203 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
204 0 : return (DltDaemonRegisteredUsers*)NULL;
205 : }
206 :
207 0 : for (i = 0; i < daemon->num_user_lists; i++)
208 0 : if (strncmp(ecu, daemon->user_list[i].ecuid2, daemon->user_list[i].ecuid2len) == 0)
209 0 : return &daemon->user_list[i];
210 :
211 0 : dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %s\n", ecu);
212 0 : return (DltDaemonRegisteredUsers*)NULL;
213 : }
214 :
215 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
216 :
217 : static int dlt_daemon_cmp_log_settings(const void* lhs, const void* rhs)
218 : {
219 : if ((lhs == NULL) || (rhs == NULL))
220 : return -1;
221 :
222 : DltDaemonContextLogSettings* settings1 = (DltDaemonContextLogSettings*)lhs;
223 : DltDaemonContextLogSettings* settings2 = (DltDaemonContextLogSettings*)rhs;
224 :
225 : int cmp = memcmp(settings1->apid, settings2->apid, DLT_ID_SIZE);
226 :
227 : if (cmp < 0)
228 : return -1;
229 : else if (cmp == 0)
230 : return memcmp(settings1->ctid, settings2->ctid, DLT_ID_SIZE);
231 : else
232 : return 1;
233 : }
234 :
235 : /**
236 : * Find configuration for app/ctx id specific log settings configuration
237 : * @param daemon pointer to dlt daemon struct
238 : * @param apid application id to use
239 : * @param ctid context id to use, can be NULL
240 : * @return pointer to log settings if found, otherwise NULL
241 : */
242 : DltDaemonContextLogSettings* dlt_daemon_find_configured_app_id_ctx_id_settings(
243 : const DltDaemon* daemon, const char* apid, const char* ctid)
244 : {
245 : DltDaemonContextLogSettings* app_id_settings = NULL;
246 : for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
247 : DltDaemonContextLogSettings* settings = &daemon->app_id_log_level_settings[i];
248 :
249 : if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
250 : if (app_id_settings != NULL)
251 : return app_id_settings;
252 : continue;
253 : }
254 :
255 : if (strlen(settings->ctid) == 0) {
256 : app_id_settings = settings;
257 : }
258 :
259 : if (ctid == NULL || strlen(ctid) == 0) {
260 : if (app_id_settings != NULL) {
261 : return app_id_settings;
262 : }
263 : } else {
264 : if (strncmp(ctid, settings->ctid, DLT_ID_SIZE) == 0) {
265 : return settings;
266 : }
267 : }
268 : }
269 :
270 : return app_id_settings;
271 : }
272 :
273 : /**
274 : * Find configuration for app/ctx id specific log settings configuration
275 : * for DLT V2
276 : * @param daemon pointer to dlt daemon struct
277 : * @param apid application id to use
278 : * @param ctid context id to use, can be NULL
279 : * @return pointer to log settings if found, otherwise NULL
280 : */
281 : DltDaemonContextLogSettingsV2* dlt_daemon_find_configured_app_id_ctx_id_settings_v2(
282 : const DltDaemon* daemon, const char* apid, const char* ctid)
283 : {
284 : DltDaemonContextLogSettingsV2* app_id_settings = NULL;
285 : for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
286 : DltDaemonContextLogSettingsV2* settings = &daemon->app_id_log_level_settings[i];
287 : // TBD: Check settings->apid, settings->apid2len in runtime
288 : if (strncmp(apid, settings->apid, settings->apidlen) != 0) {
289 : if (app_id_settings != NULL)
290 : return app_id_settings;
291 : continue;
292 : }
293 :
294 : if (strlen(settings->ctid) == 0) {
295 : app_id_settings = settings;
296 : }
297 :
298 : if (ctid == NULL || strlen(ctid) == 0) {
299 : if (app_id_settings != NULL) {
300 : return app_id_settings;
301 : }
302 : } else {
303 : if (strncmp(ctid, settings->ctid, settings->ctidlen) == 0) {
304 : return settings;
305 : }
306 : }
307 : }
308 :
309 : return app_id_settings;
310 : }
311 :
312 : /**
313 : * Find configured log levels in a given DltDaemonApplication for the passed context id.
314 : * @param app The application settings which contain the previously loaded ap id settings
315 : * @param ctid The context id to find.
316 : * @return Pointer to DltDaemonApplicationLogSettings containing the log level
317 : * for the requested application or NULL if none found.
318 : */
319 : DltDaemonContextLogSettings* dlt_daemon_find_app_log_level_config(
320 : const DltDaemonApplication* const app, const char* const ctid)
321 : {
322 : if (NULL == ctid)
323 : return NULL;
324 :
325 : DltDaemonContextLogSettings settings;
326 : memcpy(settings.apid, app->apid, DLT_ID_SIZE);
327 : memcpy(settings.ctid, ctid, DLT_ID_SIZE);
328 :
329 : DltDaemonContextLogSettings* log_settings = NULL;
330 : log_settings = (DltDaemonContextLogSettings*)bsearch(
331 : &settings, app->context_log_level_settings, (size_t)app->num_context_log_level_settings,
332 : sizeof(DltDaemonContextLogSettings), dlt_daemon_cmp_log_settings);
333 : return log_settings;
334 : }
335 :
336 : /* TODO: Add function dlt_daemon_find_app_log_level_config_v2 for DLTv2 */
337 :
338 : #endif
339 :
340 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
341 : int dlt_daemon_compare_trace_load_settings(const void* a, const void* b)
342 : {
343 : const DltTraceLoadSettings* s1 = (const DltTraceLoadSettings*)a;
344 : const DltTraceLoadSettings* s2 = (const DltTraceLoadSettings*)b;
345 :
346 : int cmp = strncmp(s1->apid, s2->apid, DLT_ID_SIZE);
347 : if (cmp != 0) {
348 : return cmp;
349 : }
350 :
351 : return strncmp(s1->ctid, s2->ctid, DLT_ID_SIZE);
352 : }
353 :
354 : DltReturnValue dlt_daemon_find_preconfigured_trace_load_settings(
355 : DltDaemon* const daemon, const char* apid, const char* ctid, DltTraceLoadSettings** settings, int* num_settings,
356 : int verbose)
357 : {
358 : PRINT_FUNCTION_VERBOSE(verbose);
359 : int i;
360 : *num_settings = 0;
361 : *settings = NULL;
362 :
363 : if ((daemon == NULL) || (apid == NULL)) {
364 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
365 : return DLT_RETURN_WRONG_PARAMETER;
366 : }
367 :
368 : if (NULL == daemon->preconfigured_trace_load_settings || daemon->preconfigured_trace_load_settings_count == 0) {
369 : return DLT_RETURN_OK;
370 : }
371 :
372 : for (i = 0; i < daemon->preconfigured_trace_load_settings_count; ++i) {
373 : // check if we can exit already, the trace load settings are sorted
374 : // and if the apid does not match anymore, but we already have settings
375 : // means we collected all settings
376 : if (strncmp(apid, daemon->preconfigured_trace_load_settings[i].apid, DLT_ID_SIZE) != 0) {
377 : if ((*num_settings) != 0)
378 : break;
379 : continue;
380 : }
381 :
382 : // If a ctid is passed, we only want to return entries where both match
383 : if (ctid != NULL && strlen(ctid) > 0) {
384 : if (strncmp(ctid, daemon->preconfigured_trace_load_settings[i].ctid, DLT_ID_SIZE) != 0) {
385 : continue;
386 : }
387 : }
388 :
389 : // Reallocate memory for the settings array with an additional slot for the new setting
390 : DltTraceLoadSettings* temp = realloc(*settings, (*num_settings + 1) * sizeof(DltTraceLoadSettings));
391 : if (temp == NULL) {
392 : dlt_vlog(LOG_ERR, "Failed to allocate memory for trace load settings\n");
393 : free(*settings); // Free any previously allocated memory
394 : *settings = NULL;
395 : *num_settings = 0;
396 : return DLT_RETURN_ERROR;
397 : }
398 : *settings = temp;
399 : // Copy preconfigured trace load settings into the app settings
400 : (*settings)[*num_settings] = daemon->preconfigured_trace_load_settings[i];
401 : (*num_settings)++;
402 : }
403 :
404 : qsort(*settings, (size_t)*num_settings, sizeof(DltTraceLoadSettings), dlt_daemon_compare_trace_load_settings);
405 : return DLT_RETURN_OK;
406 : }
407 : #endif
408 :
409 1 : int dlt_daemon_init_runtime_configuration(DltDaemon* daemon, const char* runtime_directory, int verbose)
410 : {
411 1 : PRINT_FUNCTION_VERBOSE(verbose);
412 : size_t append_length = 0;
413 :
414 1 : if (daemon == NULL)
415 : return DLT_RETURN_ERROR;
416 :
417 : /* Default */
418 1 : daemon->mode = DLT_USER_MODE_EXTERNAL;
419 :
420 1 : if (runtime_directory == NULL)
421 : return DLT_RETURN_ERROR;
422 :
423 : /* prepare filenames for configuration */
424 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
425 :
426 1 : if (runtime_directory[0]) {
427 0 : strncpy(daemon->runtime_application_cfg, runtime_directory, append_length);
428 0 : daemon->runtime_application_cfg[append_length] = 0;
429 : } else {
430 1 : strncpy(daemon->runtime_application_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
431 1 : daemon->runtime_application_cfg[append_length] = 0;
432 : }
433 :
434 : strcat(
435 1 : daemon->runtime_application_cfg,
436 : DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */
437 :
438 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
439 :
440 1 : if (runtime_directory[0]) {
441 0 : strncpy(daemon->runtime_context_cfg, runtime_directory, append_length);
442 0 : daemon->runtime_context_cfg[append_length] = 0;
443 : } else {
444 1 : strncpy(daemon->runtime_context_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
445 1 : daemon->runtime_context_cfg[append_length] = 0;
446 : }
447 :
448 : strcat(
449 1 : daemon->runtime_context_cfg,
450 : DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */
451 :
452 : append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
453 :
454 1 : if (runtime_directory[0]) {
455 0 : strncpy(daemon->runtime_configuration, runtime_directory, append_length);
456 0 : daemon->runtime_configuration[append_length] = 0;
457 : } else {
458 1 : strncpy(daemon->runtime_configuration, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
459 1 : daemon->runtime_configuration[append_length] = 0;
460 : }
461 :
462 : strcat(
463 1 : daemon->runtime_configuration,
464 : DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */
465 :
466 1 : return DLT_RETURN_OK;
467 : }
468 :
469 10 : int dlt_daemon_init(
470 : DltDaemon* daemon, unsigned long RingbufferMinSize, unsigned long RingbufferMaxSize,
471 : unsigned long RingbufferStepSize, const char* runtime_directory, int InitialContextLogLevel,
472 : int InitialContextTraceStatus, int ForceLLTS, int verbose)
473 : {
474 10 : PRINT_FUNCTION_VERBOSE(verbose);
475 :
476 10 : if ((daemon == NULL) || (runtime_directory == NULL))
477 : return -1;
478 :
479 10 : daemon->user_list = NULL;
480 10 : daemon->num_user_lists = 0;
481 :
482 10 : daemon->default_log_level = (int8_t)InitialContextLogLevel;
483 10 : daemon->default_trace_status = (int8_t)InitialContextTraceStatus;
484 10 : daemon->force_ll_ts = (int8_t)ForceLLTS;
485 :
486 10 : daemon->overflow_counter = 0;
487 :
488 10 : daemon->runtime_context_cfg_loaded = 0;
489 :
490 10 : daemon->connectionState = 0; /* no logger connected */
491 :
492 10 : daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */
493 :
494 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
495 : daemon->preconfigured_trace_load_settings = NULL;
496 : daemon->bytes_sent = 0;
497 : daemon->bytes_recv = 0;
498 : #endif
499 :
500 10 : daemon->sendserialheader = 0;
501 10 : daemon->timingpackets = 0;
502 :
503 10 : dlt_set_id(daemon->ecuid, "");
504 10 : daemon->ecuid2len = 0;
505 10 : memset(daemon->ecuid2, 0, DLT_V2_ID_SIZE);
506 :
507 : /* initialize ring buffer for client connection */
508 10 : dlt_vlog(
509 : LOG_INFO, "Ringbuffer configuration: %lu/%lu/%lu\n", RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize);
510 :
511 10 : if (dlt_buffer_init_dynamic(
512 : &(daemon->client_ringbuffer), (uint32_t)RingbufferMinSize, (uint32_t)RingbufferMaxSize,
513 : (uint32_t)RingbufferStepSize)
514 : < DLT_RETURN_OK)
515 : return -1;
516 :
517 10 : daemon->storage_handle = NULL;
518 : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
519 : daemon->received_message_since_last_watchdog_interval = 0;
520 : #endif
521 10 : return 0;
522 : }
523 :
524 1 : int dlt_daemon_free(DltDaemon* daemon, int verbose)
525 : {
526 : int i = 0;
527 : DltDaemonRegisteredUsers* user_list = NULL;
528 :
529 1 : PRINT_FUNCTION_VERBOSE(verbose);
530 :
531 1 : if ((daemon == NULL) || (daemon->user_list == NULL))
532 : return -1;
533 :
534 : /* free all registered user information */
535 2 : for (i = 0; i < daemon->num_user_lists; i++) {
536 1 : user_list = &daemon->user_list[i];
537 :
538 1 : if (user_list != NULL) {
539 : /* ignore return values */
540 1 : dlt_daemon_contexts_clear(daemon, user_list->ecu, verbose);
541 1 : dlt_daemon_applications_clear(daemon, user_list->ecu, verbose);
542 : }
543 : }
544 :
545 1 : free(daemon->user_list);
546 :
547 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
548 : if (daemon->app_id_log_level_settings != NULL) {
549 : free(daemon->app_id_log_level_settings);
550 : }
551 : #endif
552 :
553 1 : if (app_recv_buffer)
554 1 : free(app_recv_buffer);
555 :
556 : /* free ringbuffer */
557 1 : dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
558 :
559 1 : return 0;
560 : }
561 :
562 11 : int dlt_daemon_init_user_information(DltDaemon* daemon, DltGateway* gateway, int gateway_mode, int verbose)
563 : {
564 : int nodes = 1;
565 : int i = 1;
566 :
567 11 : PRINT_FUNCTION_VERBOSE(verbose);
568 :
569 11 : if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL)))
570 : return DLT_RETURN_ERROR;
571 :
572 11 : if (gateway_mode == 0) {
573 : /* initialize application list */
574 11 : daemon->user_list = calloc((size_t)nodes, sizeof(DltDaemonRegisteredUsers));
575 :
576 11 : if (daemon->user_list == NULL) {
577 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
578 0 : return DLT_RETURN_ERROR;
579 : }
580 :
581 11 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
582 11 : daemon->user_list[0].ecuid2len = daemon->ecuid2len;
583 11 : dlt_set_id_v2(daemon->user_list[0].ecuid2, daemon->ecuid2, daemon->ecuid2len);
584 11 : daemon->num_user_lists = 1;
585 : } else { /* gateway is active */
586 0 : nodes += gateway->num_connections;
587 :
588 : /* initialize application list */
589 0 : daemon->user_list = calloc((size_t)nodes, sizeof(DltDaemonRegisteredUsers));
590 :
591 0 : if (daemon->user_list == NULL) {
592 0 : dlt_log(LOG_ERR, "Allocating memory for user information");
593 0 : return DLT_RETURN_ERROR;
594 : }
595 :
596 0 : dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
597 0 : daemon->user_list[0].ecuid2len = daemon->ecuid2len;
598 0 : dlt_set_id_v2(daemon->user_list[0].ecuid2, daemon->ecuid2, daemon->ecuid2len);
599 0 : daemon->num_user_lists = nodes;
600 :
601 0 : for (i = 1; i < nodes; i++) {
602 0 : dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid);
603 0 : daemon->user_list[i].ecuid2len = gateway->connections[i - 1].ecuid2len;
604 0 : dlt_set_id_v2(
605 0 : daemon->user_list[i].ecuid2, gateway->connections[i - 1].ecuid2, gateway->connections[i - 1].ecuid2len);
606 : }
607 : }
608 :
609 : return DLT_RETURN_OK;
610 : }
611 :
612 5 : int dlt_daemon_applications_invalidate_fd(DltDaemon* daemon, char* ecu, int fd, int verbose)
613 : {
614 : int i;
615 : DltDaemonRegisteredUsers* user_list = NULL;
616 :
617 5 : PRINT_FUNCTION_VERBOSE(verbose);
618 :
619 5 : if ((daemon == NULL) || (ecu == NULL))
620 : return DLT_RETURN_ERROR;
621 :
622 5 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
623 :
624 5 : if (user_list != NULL) {
625 10 : for (i = 0; i < user_list->num_applications; i++)
626 5 : if (user_list->applications[i].user_handle == fd)
627 0 : user_list->applications[i].user_handle = DLT_FD_INIT;
628 :
629 : return DLT_RETURN_OK;
630 : }
631 :
632 : return DLT_RETURN_ERROR;
633 : }
634 :
635 0 : int dlt_daemon_applications_invalidate_fd_v2(DltDaemon* daemon, char* ecu, int fd, int verbose)
636 : {
637 : int i;
638 : DltDaemonRegisteredUsers* user_list = NULL;
639 :
640 0 : PRINT_FUNCTION_VERBOSE(verbose);
641 :
642 0 : if ((daemon == NULL) || (ecu == NULL))
643 : return DLT_RETURN_ERROR;
644 0 : uint8_t eculen = (uint8_t)strlen(ecu);
645 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
646 :
647 0 : if (user_list != NULL) {
648 0 : for (i = 0; i < user_list->num_applications; i++)
649 0 : if (user_list->applications[i].user_handle == fd)
650 0 : user_list->applications[i].user_handle = DLT_FD_INIT;
651 :
652 : return DLT_RETURN_OK;
653 : }
654 :
655 : return DLT_RETURN_ERROR;
656 : }
657 :
658 1 : int dlt_daemon_applications_clear(DltDaemon* daemon, char* ecu, int verbose)
659 : {
660 : int i;
661 : DltDaemonRegisteredUsers* user_list = NULL;
662 :
663 1 : PRINT_FUNCTION_VERBOSE(verbose);
664 :
665 1 : if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
666 : return DLT_RETURN_WRONG_PARAMETER;
667 :
668 1 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
669 :
670 1 : if (user_list == NULL)
671 : return DLT_RETURN_ERROR;
672 :
673 2 : for (i = 0; i < user_list->num_applications; i++)
674 1 : if (user_list->applications[i].application_description != NULL) {
675 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
676 : if (user_list->applications[i].context_log_level_settings)
677 : free(user_list->applications[i].context_log_level_settings);
678 : #endif
679 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
680 : if (user_list->applications[i].trace_load_settings) {
681 : free(user_list->applications[i].trace_load_settings);
682 : user_list->applications[i].trace_load_settings = NULL;
683 : user_list->applications[i].trace_load_settings_count = 0;
684 : }
685 : #endif
686 1 : free(user_list->applications[i].application_description);
687 1 : user_list->applications[i].application_description = NULL;
688 : }
689 :
690 1 : if (user_list->applications != NULL)
691 1 : free(user_list->applications);
692 :
693 1 : user_list->applications = NULL;
694 1 : user_list->num_applications = 0;
695 :
696 1 : return 0;
697 : }
698 :
699 0 : int dlt_daemon_applications_clear_v2(DltDaemon* daemon, char* ecu, int verbose)
700 : {
701 : int i;
702 : DltDaemonRegisteredUsers* user_list = NULL;
703 :
704 0 : PRINT_FUNCTION_VERBOSE(verbose);
705 :
706 0 : if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
707 : return DLT_RETURN_WRONG_PARAMETER;
708 :
709 0 : uint8_t eculen = (uint8_t)strlen(ecu);
710 :
711 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
712 :
713 0 : if (user_list == NULL)
714 : return DLT_RETURN_ERROR;
715 :
716 0 : for (i = 0; i < user_list->num_applications; i++)
717 0 : if (user_list->applications[i].application_description != NULL) {
718 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
719 : if (user_list->applications[i].context_log_level_settings)
720 : free(user_list->applications[i].context_log_level_settings);
721 : #endif
722 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
723 : if (user_list->applications[i].trace_load_settings) {
724 : free(user_list->applications[i].trace_load_settings);
725 : user_list->applications[i].trace_load_settings = NULL;
726 : user_list->applications[i].trace_load_settings_count = 0;
727 : }
728 : #endif
729 0 : free(user_list->applications[i].application_description);
730 0 : user_list->applications[i].application_description = NULL;
731 : }
732 :
733 0 : if (user_list->applications != NULL)
734 0 : free(user_list->applications);
735 :
736 0 : user_list->applications = NULL;
737 0 : user_list->num_applications = 0;
738 :
739 0 : return 0;
740 : }
741 :
742 3 : static void dlt_daemon_application_reset_user_handle(DltDaemon* daemon, DltDaemonApplication* application, int verbose)
743 : {
744 : DltDaemonRegisteredUsers* user_list;
745 : DltDaemonContext* context;
746 : int i;
747 :
748 3 : if (application->user_handle == DLT_FD_INIT)
749 : return;
750 :
751 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
752 0 : if (user_list != NULL) {
753 0 : for (i = 0; i < user_list->num_contexts; i++) {
754 0 : context = &user_list->contexts[i];
755 0 : if (context->user_handle == application->user_handle)
756 0 : context->user_handle = DLT_FD_INIT;
757 : }
758 : }
759 :
760 0 : if (application->owns_user_handle)
761 0 : close(application->user_handle);
762 :
763 0 : application->user_handle = DLT_FD_INIT;
764 0 : application->owns_user_handle = false;
765 : }
766 :
767 0 : static void dlt_daemon_application_reset_user_handle_v2(
768 : DltDaemon* daemon, DltDaemonApplication* application, int verbose)
769 : {
770 : DltDaemonRegisteredUsers* user_list;
771 : DltDaemonContext* context;
772 : int i;
773 :
774 0 : if (application->user_handle == DLT_FD_INIT)
775 : return;
776 :
777 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
778 0 : if (user_list != NULL) {
779 0 : for (i = 0; i < user_list->num_contexts; i++) {
780 0 : context = &user_list->contexts[i];
781 0 : if (context->user_handle == application->user_handle)
782 0 : context->user_handle = DLT_FD_INIT;
783 : }
784 : }
785 :
786 0 : if (application->owns_user_handle)
787 0 : close(application->user_handle);
788 :
789 0 : application->user_handle = DLT_FD_INIT;
790 0 : application->owns_user_handle = false;
791 : }
792 :
793 4 : DltDaemonApplication* dlt_daemon_application_add(
794 : DltDaemon* daemon, char* apid, pid_t pid, char* description, int fd, char* ecu, int verbose)
795 : {
796 : DltDaemonApplication* application;
797 : DltDaemonApplication* old;
798 : int new_application;
799 : int dlt_user_handle;
800 : bool owns_user_handle;
801 : DltDaemonRegisteredUsers* user_list = NULL;
802 : #ifdef DLT_DAEMON_USE_FIFO_IPC
803 : (void)fd; /* To avoid compiler warning : unused variable */
804 : char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
805 : #endif
806 :
807 4 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
808 : return (DltDaemonApplication*)NULL;
809 :
810 4 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
811 :
812 4 : if (user_list == NULL)
813 : return (DltDaemonApplication*)NULL;
814 :
815 4 : if (user_list->applications == NULL) {
816 4 : user_list->applications =
817 4 : (DltDaemonApplication*)malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
818 :
819 4 : if (user_list->applications == NULL)
820 : return (DltDaemonApplication*)NULL;
821 : }
822 :
823 : new_application = 0;
824 :
825 : /* Check if application [apid] is already available */
826 4 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
827 :
828 4 : if (application == NULL) {
829 4 : user_list->num_applications += 1;
830 :
831 4 : if (user_list->num_applications != 0) {
832 4 : if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
833 : /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
834 0 : old = user_list->applications;
835 0 : user_list->applications = (DltDaemonApplication*)malloc(
836 : (size_t)sizeof(DltDaemonApplication)
837 0 : * ((size_t)(user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1)
838 : * (size_t)DLT_DAEMON_APPL_ALLOC_SIZE);
839 :
840 0 : if (user_list->applications == NULL) {
841 0 : user_list->applications = old;
842 0 : user_list->num_applications -= 1;
843 0 : return (DltDaemonApplication*)NULL;
844 : }
845 :
846 0 : memcpy(
847 : user_list->applications, old,
848 0 : (size_t)sizeof(DltDaemonApplication) * (size_t)user_list->num_applications);
849 0 : free(old);
850 : }
851 : }
852 :
853 4 : application = &(user_list->applications[(size_t)(user_list->num_applications - 1)]);
854 :
855 4 : dlt_set_id(application->apid, apid);
856 4 : application->pid = 0;
857 4 : application->application_description = NULL;
858 4 : application->num_contexts = 0;
859 4 : application->user_handle = DLT_FD_INIT;
860 4 : application->owns_user_handle = false;
861 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
862 : application->trace_load_settings = NULL;
863 : application->trace_load_settings_count = 0;
864 : #endif
865 :
866 : new_application = 1;
867 :
868 0 : } else if ((pid != application->pid) && (application->pid != 0)) {
869 0 : dlt_vlog(
870 : LOG_WARNING,
871 : "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n", apid,
872 : pid, application->pid);
873 : }
874 :
875 : /* Store application description and pid of application */
876 4 : if (application->application_description) {
877 0 : free(application->application_description);
878 0 : application->application_description = NULL;
879 : }
880 :
881 4 : if (description != NULL) {
882 4 : application->application_description = malloc(strlen(description) + 1);
883 :
884 4 : if (application->application_description) {
885 4 : memcpy(application->application_description, description, strlen(description) + 1);
886 : } else {
887 0 : dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
888 0 : free(application);
889 0 : return (DltDaemonApplication*)NULL;
890 : }
891 : }
892 :
893 4 : if (application->pid != pid) {
894 3 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
895 3 : application->pid = 0;
896 : }
897 :
898 : /* open user pipe only if it is not yet opened */
899 4 : if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
900 : dlt_user_handle = DLT_FD_INIT;
901 : owns_user_handle = false;
902 :
903 : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
904 : if (fd >= DLT_FD_MINIMUM) {
905 : dlt_user_handle = fd;
906 : owns_user_handle = false;
907 : }
908 : #endif
909 : #ifdef DLT_DAEMON_USE_FIFO_IPC
910 : if (dlt_user_handle < DLT_FD_MINIMUM) {
911 : int ret = snprintf(filename, DLT_DAEMON_COMMON_TEXTBUFSIZE, "%s/dltpipes/dlt%d", dltFifoBaseDir, (int)pid);
912 3 : if (ret < 0 || ret >= DLT_DAEMON_COMMON_TEXTBUFSIZE) {
913 0 : filename[0] = '\0';
914 : }
915 :
916 : dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
917 :
918 3 : if (dlt_user_handle < 0) {
919 0 : int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
920 0 : dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
921 : } else {
922 : owns_user_handle = true;
923 : }
924 : }
925 : #endif
926 : /* check if file descriptor was already used, and make it invalid if it
927 : * is reused. This prevents sending messages to wrong file descriptor */
928 3 : dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
929 3 : dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
930 :
931 3 : application->user_handle = dlt_user_handle;
932 3 : application->owns_user_handle = owns_user_handle;
933 3 : application->pid = pid;
934 : }
935 :
936 : /* Sort */
937 4 : if (new_application) {
938 4 : qsort(
939 4 : user_list->applications, (size_t)user_list->num_applications, sizeof(DltDaemonApplication),
940 : dlt_daemon_cmp_apid);
941 :
942 : /* Find new position of application with apid*/
943 4 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
944 : }
945 :
946 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
947 : application->num_context_log_level_settings = 0;
948 : application->context_log_level_settings = NULL;
949 : #endif
950 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
951 : if (application->trace_load_settings == NULL) {
952 : DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
953 : int num_settings = 0;
954 : DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
955 : daemon, application->apid, NULL /*load settings for all contexts*/, &pre_configured_trace_load_settings,
956 : &num_settings, verbose);
957 :
958 : DltTraceLoadSettings* app_level = NULL;
959 : if ((find_trace_settings_return_value == DLT_RETURN_OK) && (pre_configured_trace_load_settings != NULL)
960 : && (num_settings != 0)) {
961 : application->trace_load_settings = pre_configured_trace_load_settings;
962 : application->trace_load_settings_count = num_settings;
963 : app_level = dlt_find_runtime_trace_load_settings(
964 : application->trace_load_settings, application->trace_load_settings_count, application->apid, NULL);
965 : }
966 :
967 : // app is not configured, set daemon defaults
968 : if (app_level == NULL) {
969 : DltTraceLoadSettings* temp = realloc(
970 : application->trace_load_settings,
971 : (application->trace_load_settings_count + 1) * sizeof(DltTraceLoadSettings));
972 :
973 : if (temp != NULL) {
974 : application->trace_load_settings = temp;
975 : ++application->trace_load_settings_count;
976 :
977 : app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
978 : memset(app_level, 0, sizeof(DltTraceLoadSettings));
979 : app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
980 : app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
981 : memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
982 : memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
983 : } else {
984 : dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
985 : }
986 :
987 : // We inserted the application id at the end, to make sure
988 : // Lookups are working properly later on, we have to sort the list again.
989 : qsort(
990 : application->trace_load_settings, (size_t)application->trace_load_settings_count,
991 : sizeof(DltTraceLoadSettings), dlt_daemon_compare_trace_load_settings);
992 : }
993 : }
994 :
995 : #endif
996 :
997 : return application;
998 : }
999 :
1000 0 : DltDaemonApplication* dlt_daemon_application_add_v2(
1001 : DltDaemon* daemon, uint8_t apidlen, char* apid, pid_t pid, char* description, int fd, uint8_t eculen, char* ecu,
1002 : int verbose)
1003 : {
1004 : DltDaemonApplication* application;
1005 : DltDaemonApplication* old;
1006 : int new_application;
1007 : int dlt_user_handle;
1008 : bool owns_user_handle;
1009 : DltDaemonRegisteredUsers* user_list = NULL;
1010 : #ifdef DLT_DAEMON_USE_FIFO_IPC
1011 : (void)fd; /* To avoid compiler warning : unused variable */
1012 : char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
1013 : #endif
1014 :
1015 0 : if ((daemon == NULL) || (apidlen == 0) || (eculen == 0) || (apid == NULL) || (ecu == NULL))
1016 : return (DltDaemonApplication*)NULL;
1017 :
1018 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
1019 :
1020 0 : if (user_list == NULL)
1021 : return (DltDaemonApplication*)NULL;
1022 :
1023 0 : if (user_list->applications == NULL) {
1024 0 : user_list->applications =
1025 0 : (DltDaemonApplication*)malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
1026 :
1027 0 : if (user_list->applications == NULL)
1028 : return (DltDaemonApplication*)NULL;
1029 : }
1030 :
1031 : new_application = 0;
1032 :
1033 : /* Check if application [apid] is already available */
1034 0 : dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
1035 :
1036 0 : if (application == NULL) {
1037 0 : user_list->num_applications += 1;
1038 :
1039 0 : if (user_list->num_applications != 0) {
1040 0 : if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
1041 : /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
1042 0 : old = user_list->applications;
1043 0 : user_list->applications = (DltDaemonApplication*)malloc(
1044 : sizeof(DltDaemonApplication)
1045 0 : * (((size_t)user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1)
1046 : * DLT_DAEMON_APPL_ALLOC_SIZE);
1047 :
1048 0 : if (user_list->applications == NULL) {
1049 0 : user_list->applications = old;
1050 0 : user_list->num_applications -= 1;
1051 0 : return (DltDaemonApplication*)NULL;
1052 : }
1053 :
1054 0 : memcpy(
1055 : user_list->applications, old, sizeof(DltDaemonApplication) * (size_t)user_list->num_applications);
1056 0 : free(old);
1057 : }
1058 : }
1059 :
1060 0 : application = &(user_list->applications[user_list->num_applications - 1]);
1061 :
1062 0 : memset(application->apid2, 0, DLT_V2_ID_SIZE);
1063 0 : application->apid2len = apidlen;
1064 0 : dlt_set_id_v2(application->apid2, apid, apidlen);
1065 0 : application->pid = 0;
1066 0 : application->application_description = NULL;
1067 0 : application->num_contexts = 0;
1068 0 : application->user_handle = DLT_FD_INIT;
1069 0 : application->owns_user_handle = false;
1070 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1071 : application->trace_load_settings = NULL;
1072 : application->trace_load_settings_count = 0;
1073 : #endif
1074 :
1075 : new_application = 1;
1076 0 : } else if ((pid != application->pid) && (application->pid != 0)) {
1077 0 : dlt_vlog(
1078 : LOG_WARNING,
1079 : "Duplicate registration of ApplicationID: '%s'; registering from PID %d, existing from PID %d\n", apid, pid,
1080 : application->pid);
1081 : }
1082 :
1083 : /* Store application description and pid of application */
1084 0 : if (application->application_description) {
1085 0 : free(application->application_description);
1086 0 : application->application_description = NULL;
1087 : }
1088 :
1089 0 : if (description != NULL) {
1090 0 : application->application_description = malloc(strlen(description) + 1);
1091 :
1092 0 : if (application->application_description) {
1093 0 : memcpy(application->application_description, description, strlen(description) + 1);
1094 : } else {
1095 0 : dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
1096 0 : free(application);
1097 0 : return (DltDaemonApplication*)NULL;
1098 : }
1099 : }
1100 :
1101 0 : if (application->pid != pid) {
1102 0 : dlt_daemon_application_reset_user_handle_v2(daemon, application, verbose);
1103 0 : application->pid = 0;
1104 : }
1105 :
1106 : /* open user pipe only if it is not yet opened */
1107 0 : if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
1108 : dlt_user_handle = DLT_FD_INIT;
1109 : owns_user_handle = false;
1110 :
1111 : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
1112 : if (fd >= DLT_FD_MINIMUM) {
1113 : dlt_user_handle = fd;
1114 : owns_user_handle = false;
1115 : }
1116 : #endif
1117 : #ifdef DLT_DAEMON_USE_FIFO_IPC
1118 : if (dlt_user_handle < DLT_FD_MINIMUM) {
1119 : int ret = snprintf(filename, DLT_DAEMON_COMMON_TEXTBUFSIZE, "%s/dltpipes/dlt%d", dltFifoBaseDir, pid);
1120 :
1121 0 : if (ret < 0 || ret >= DLT_DAEMON_COMMON_TEXTBUFSIZE) {
1122 0 : dlt_log(LOG_ERR, "Failed to construct FIFO filename - path too long!\n");
1123 0 : return NULL;
1124 : }
1125 :
1126 : dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
1127 :
1128 0 : if (dlt_user_handle < 0) {
1129 0 : int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
1130 0 : dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
1131 : } else {
1132 : owns_user_handle = true;
1133 : }
1134 : }
1135 : #endif
1136 : /* check if file descriptor was already used, and make it invalid if it
1137 : * is reused. This prevents sending messages to wrong file descriptor */
1138 0 : dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
1139 0 : dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
1140 :
1141 0 : application->user_handle = dlt_user_handle;
1142 0 : application->owns_user_handle = owns_user_handle;
1143 0 : application->pid = pid;
1144 : }
1145 :
1146 : /* Sort */
1147 0 : if (new_application) {
1148 0 : qsort(
1149 0 : user_list->applications, (size_t)user_list->num_applications, sizeof(DltDaemonApplication),
1150 : dlt_daemon_cmp_apid_v2);
1151 : /* Find new position of application with apid*/
1152 0 : dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
1153 : }
1154 :
1155 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1156 : application->num_context_log_level_settings = 0;
1157 : application->context_log_level_settings = NULL;
1158 : #endif
1159 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1160 : if (application->trace_load_settings == NULL) {
1161 : DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
1162 : int num_settings = 0;
1163 : DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
1164 : daemon, application->apid, NULL /*load settings for all contexts*/, &pre_configured_trace_load_settings,
1165 : &num_settings, verbose);
1166 :
1167 : DltTraceLoadSettings* app_level = NULL;
1168 : if ((find_trace_settings_return_value == DLT_RETURN_OK) && (pre_configured_trace_load_settings != NULL)
1169 : && (num_settings != 0)) {
1170 : application->trace_load_settings = pre_configured_trace_load_settings;
1171 : application->trace_load_settings_count = num_settings;
1172 : app_level = dlt_find_runtime_trace_load_settings(
1173 : application->trace_load_settings, application->trace_load_settings_count, application->apid, NULL);
1174 : }
1175 :
1176 : // app is not configured, set daemon defaults
1177 : if (app_level == NULL) {
1178 : DltTraceLoadSettings* temp = realloc(
1179 : application->trace_load_settings,
1180 : (application->trace_load_settings_count + 1) * sizeof(DltTraceLoadSettings));
1181 :
1182 : if (temp != NULL) {
1183 : application->trace_load_settings = temp;
1184 : ++application->trace_load_settings_count;
1185 :
1186 : app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
1187 : memset(app_level, 0, sizeof(DltTraceLoadSettings));
1188 : app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
1189 : app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
1190 : memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
1191 : memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
1192 : } else {
1193 : dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
1194 : }
1195 :
1196 : // We inserted the application id at the end, to make sure
1197 : // Lookups are working properly later on, we have to sort the list again.
1198 : qsort(
1199 : application->trace_load_settings, (size_t)application->trace_load_settings_count,
1200 : sizeof(DltTraceLoadSettings), dlt_daemon_compare_trace_load_settings);
1201 : }
1202 : }
1203 :
1204 : #endif
1205 :
1206 0 : return application;
1207 : }
1208 :
1209 0 : int dlt_daemon_application_del(DltDaemon* daemon, DltDaemonApplication* application, char* ecu, int verbose)
1210 : {
1211 : int pos;
1212 : DltDaemonRegisteredUsers* user_list = NULL;
1213 :
1214 0 : PRINT_FUNCTION_VERBOSE(verbose);
1215 :
1216 0 : if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
1217 : return -1;
1218 :
1219 0 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1220 :
1221 0 : if (user_list == NULL)
1222 : return -1;
1223 :
1224 0 : if (user_list->num_applications > 0) {
1225 0 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
1226 :
1227 : /* Free description of application to be deleted */
1228 0 : if (application->application_description) {
1229 0 : free(application->application_description);
1230 0 : application->application_description = NULL;
1231 : }
1232 :
1233 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1234 : if (application->trace_load_settings != NULL) {
1235 : free(application->trace_load_settings);
1236 : application->trace_load_settings = NULL;
1237 : application->trace_load_settings_count = 0;
1238 : }
1239 : #endif
1240 0 : pos = (int)(application - (user_list->applications));
1241 :
1242 : /* move all applications above pos to pos */
1243 0 : memmove(
1244 0 : &(user_list->applications[pos]), &(user_list->applications[pos + 1]),
1245 0 : (size_t)sizeof(DltDaemonApplication) * (size_t)((user_list->num_applications - 1) - pos));
1246 :
1247 : /* Clear last application */
1248 0 : memset(&(user_list->applications[user_list->num_applications - 1]), 0, sizeof(DltDaemonApplication));
1249 :
1250 0 : user_list->num_applications--;
1251 : }
1252 :
1253 : return 0;
1254 : }
1255 :
1256 0 : int dlt_daemon_application_del_v2(
1257 : DltDaemon* daemon, DltDaemonApplication* application, uint8_t eculen, char* ecu, int verbose)
1258 : {
1259 : int pos;
1260 : DltDaemonRegisteredUsers* user_list = NULL;
1261 :
1262 0 : PRINT_FUNCTION_VERBOSE(verbose);
1263 :
1264 0 : if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
1265 : return -1;
1266 :
1267 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
1268 :
1269 0 : if (user_list == NULL)
1270 : return -1;
1271 :
1272 0 : if (user_list->num_applications > 0) {
1273 0 : dlt_daemon_application_reset_user_handle_v2(daemon, application, verbose);
1274 :
1275 : /* Free description of application to be deleted */
1276 0 : if (application->application_description) {
1277 0 : free(application->application_description);
1278 0 : application->application_description = NULL;
1279 : }
1280 :
1281 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1282 : if (application->trace_load_settings != NULL) {
1283 : free(application->trace_load_settings);
1284 : application->trace_load_settings = NULL;
1285 : application->trace_load_settings_count = 0;
1286 : }
1287 : #endif
1288 0 : pos = (int)(application - (user_list->applications));
1289 :
1290 : /* move all applications above pos to pos */
1291 0 : memmove(
1292 0 : &(user_list->applications[pos]), &(user_list->applications[pos + 1]),
1293 0 : sizeof(DltDaemonApplication) * (size_t)((user_list->num_applications - 1) - pos));
1294 : // TBD: Check usage of sizeof(DltDaemonApplication) since added new ptr members
1295 :
1296 : /* Clear last application */
1297 0 : memset(&(user_list->applications[user_list->num_applications - 1]), 0, sizeof(DltDaemonApplication));
1298 : // TBD: Check usage of sizeof(DltDaemonApplication) since added new ptr members
1299 :
1300 0 : user_list->num_applications--;
1301 : }
1302 :
1303 : return 0;
1304 : }
1305 :
1306 16 : DltDaemonApplication* dlt_daemon_application_find(DltDaemon* daemon, char* apid, char* ecu, int verbose)
1307 : {
1308 : DltDaemonApplication application;
1309 : DltDaemonRegisteredUsers* user_list = NULL;
1310 :
1311 16 : PRINT_FUNCTION_VERBOSE(verbose);
1312 :
1313 16 : if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
1314 : return (DltDaemonApplication*)NULL;
1315 :
1316 16 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1317 :
1318 16 : if ((user_list == NULL) || (user_list->num_applications == 0))
1319 : return (DltDaemonApplication*)NULL;
1320 :
1321 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
1322 11 : if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0)
1323 11 : || (memcmp(apid, user_list->applications[user_list->num_applications - 1].apid, DLT_ID_SIZE) > 0))
1324 : return (DltDaemonApplication*)NULL;
1325 :
1326 11 : dlt_set_id(application.apid, apid);
1327 11 : return (DltDaemonApplication*)bsearch(
1328 11 : &application, user_list->applications, (size_t)user_list->num_applications, sizeof(DltDaemonApplication),
1329 : dlt_daemon_cmp_apid);
1330 : }
1331 :
1332 0 : void dlt_daemon_application_find_v2(
1333 : DltDaemon* daemon, uint8_t apidlen, char* apid, uint8_t eculen, char* ecu, int verbose,
1334 : DltDaemonApplication** application)
1335 : {
1336 : DltDaemonRegisteredUsers* user_list = NULL;
1337 0 : PRINT_FUNCTION_VERBOSE(verbose);
1338 : DltDaemonApplication search_app;
1339 : memset(search_app.apid2, 0, DLT_V2_ID_SIZE);
1340 :
1341 0 : if ((daemon == NULL) || (daemon->user_list == NULL) || (apidlen == 0) || (apid == NULL) || (eculen == 0)
1342 0 : || (ecu == NULL)) {
1343 0 : *application = NULL;
1344 0 : return;
1345 : }
1346 :
1347 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
1348 :
1349 0 : if ((user_list == NULL) || (user_list->num_applications == 0)) {
1350 0 : *application = NULL;
1351 0 : return;
1352 : }
1353 :
1354 0 : search_app.apid2len = apidlen;
1355 0 : dlt_set_id_v2(search_app.apid2, apid, apidlen);
1356 :
1357 : // Search using the temporary structure
1358 0 : *application = (DltDaemonApplication*)bsearch(
1359 0 : &search_app, user_list->applications, (size_t)user_list->num_applications, sizeof(DltDaemonApplication),
1360 : dlt_daemon_cmp_apid_v2);
1361 :
1362 0 : return;
1363 : }
1364 :
1365 :
1366 1 : int dlt_daemon_applications_load(DltDaemon* daemon, const char* filename, int verbose)
1367 : {
1368 : FILE* fd;
1369 : ID4 apid;
1370 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
1371 : char* ret;
1372 : char* pb;
1373 :
1374 1 : PRINT_FUNCTION_VERBOSE(verbose);
1375 :
1376 1 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1377 : return -1;
1378 :
1379 1 : fd = fopen(filename, "r");
1380 :
1381 1 : if (fd == NULL) {
1382 1 : dlt_vlog(LOG_WARNING, "%s: cannot open file %s: %s\n", __func__, filename, strerror(errno));
1383 :
1384 1 : return -1;
1385 : }
1386 :
1387 0 : while (!feof(fd)) {
1388 : /* Clear buf */
1389 : memset(buf, 0, sizeof(buf));
1390 :
1391 : /* Get line */
1392 : ret = fgets(buf, sizeof(buf), fd);
1393 :
1394 0 : if (NULL == ret) {
1395 : /* fgets always null pointer if the last byte of the file is a new line
1396 : * We need to check here if there was an error or was it feof.*/
1397 0 : if (ferror(fd)) {
1398 0 : dlt_vlog(LOG_WARNING, "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n", __func__, strerror(errno));
1399 0 : fclose(fd);
1400 0 : return -1;
1401 0 : } else if (feof(fd)) {
1402 0 : fclose(fd);
1403 0 : return 0;
1404 : } else {
1405 0 : dlt_vlog(LOG_WARNING, "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n", __func__);
1406 0 : fclose(fd);
1407 0 : return -1;
1408 : }
1409 : }
1410 :
1411 0 : if (strcmp(buf, "") != 0) {
1412 : /* Split line */
1413 0 : pb = strtok(buf, ":");
1414 :
1415 0 : if (pb != NULL) {
1416 0 : dlt_set_id(apid, pb);
1417 0 : pb = strtok(NULL, ":");
1418 :
1419 0 : if (pb != NULL) {
1420 : /* pb contains now the description */
1421 : /* pid is unknown at loading time */
1422 0 : if (dlt_daemon_application_add(daemon, apid, 0, pb, -1, daemon->ecuid, verbose) == 0) {
1423 0 : dlt_vlog(LOG_WARNING, "%s: dlt_daemon_application_add failed for %4s\n", __func__, apid);
1424 0 : fclose(fd);
1425 0 : return -1;
1426 : }
1427 : }
1428 : }
1429 : }
1430 : }
1431 :
1432 0 : fclose(fd);
1433 :
1434 0 : return 0;
1435 : }
1436 :
1437 0 : int dlt_daemon_applications_save(DltDaemon* daemon, const char* filename, int verbose)
1438 : {
1439 : FILE* fd;
1440 : int i;
1441 :
1442 : char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
1443 : DltDaemonRegisteredUsers* user_list = NULL;
1444 :
1445 0 : PRINT_FUNCTION_VERBOSE(verbose);
1446 :
1447 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1448 : return -1;
1449 :
1450 : memset(apid, 0, sizeof(apid));
1451 :
1452 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
1453 :
1454 0 : if (user_list == NULL)
1455 : return -1;
1456 :
1457 0 : if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
1458 0 : fd = fopen(filename, "w");
1459 :
1460 0 : if (fd != NULL) {
1461 0 : for (i = 0; i < user_list->num_applications; i++) {
1462 0 : dlt_set_id(apid, user_list->applications[i].apid);
1463 :
1464 0 : if ((user_list->applications[i].application_description)
1465 0 : && (user_list->applications[i].application_description[0] != '\0'))
1466 : fprintf(fd, "%s:%s:\n", apid, user_list->applications[i].application_description);
1467 : else
1468 : fprintf(fd, "%s::\n", apid);
1469 : }
1470 :
1471 0 : fclose(fd);
1472 : } else {
1473 0 : dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n", __func__, filename);
1474 : }
1475 : }
1476 :
1477 : return 0;
1478 : }
1479 0 : int dlt_daemon_applications_save_v2(DltDaemon* daemon, const char* filename, int verbose)
1480 : {
1481 : FILE* fd;
1482 : int i;
1483 :
1484 : char apid[DLT_V2_ID_SIZE];
1485 : DltDaemonRegisteredUsers* user_list = NULL;
1486 :
1487 0 : PRINT_FUNCTION_VERBOSE(verbose);
1488 :
1489 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
1490 : return -1;
1491 :
1492 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
1493 :
1494 0 : if (user_list == NULL)
1495 : return -1;
1496 :
1497 0 : if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
1498 0 : fd = fopen(filename, "w");
1499 :
1500 0 : if (fd != NULL) {
1501 0 : for (i = 0; i < user_list->num_applications; i++) {
1502 0 : dlt_set_id_v2(apid, user_list->applications[i].apid2, user_list->applications[i].apid2len);
1503 :
1504 0 : if ((user_list->applications[i].application_description)
1505 0 : && (user_list->applications[i].application_description[0] != '\0'))
1506 : fprintf(fd, "%s:%s:\n", apid, user_list->applications[i].application_description);
1507 : else
1508 : fprintf(fd, "%s::\n", apid);
1509 : }
1510 :
1511 0 : fclose(fd);
1512 : } else {
1513 0 : dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n", __func__, filename);
1514 : }
1515 : }
1516 :
1517 : return 0;
1518 : }
1519 :
1520 5 : DltDaemonContext* dlt_daemon_context_add(
1521 : DltDaemon* daemon, char* apid, char* ctid, int8_t log_level, int8_t trace_status, int log_level_pos,
1522 : int user_handle, char* description, char* ecu, int verbose)
1523 : {
1524 : DltDaemonApplication* application;
1525 : DltDaemonContext* context;
1526 : DltDaemonContext* old;
1527 : int new_context = 0;
1528 : DltDaemonRegisteredUsers* user_list = NULL;
1529 :
1530 5 : PRINT_FUNCTION_VERBOSE(verbose);
1531 :
1532 5 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1533 : return (DltDaemonContext*)NULL;
1534 :
1535 5 : if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
1536 : return (DltDaemonContext*)NULL;
1537 :
1538 5 : if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
1539 : return (DltDaemonContext*)NULL;
1540 :
1541 5 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1542 :
1543 5 : if (user_list == NULL)
1544 : return (DltDaemonContext*)NULL;
1545 :
1546 5 : if (user_list->contexts == NULL) {
1547 4 : user_list->contexts = (DltDaemonContext*)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1548 :
1549 4 : if (user_list->contexts == NULL)
1550 : return (DltDaemonContext*)NULL;
1551 : }
1552 :
1553 : /* Check if application [apid] is available */
1554 5 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
1555 :
1556 5 : if (application == NULL)
1557 : return (DltDaemonContext*)NULL;
1558 :
1559 : /* Check if context [apid, ctid] is already available */
1560 5 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1561 :
1562 5 : if (context == NULL) {
1563 5 : user_list->num_contexts += 1;
1564 :
1565 5 : if (user_list->num_contexts != 0) {
1566 5 : if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
1567 : /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
1568 0 : old = user_list->contexts;
1569 0 : user_list->contexts = (DltDaemonContext*)calloc(
1570 : 1, (size_t)sizeof(DltDaemonContext)
1571 0 : * ((size_t)(user_list->num_contexts / DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1)
1572 : * (size_t)DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1573 :
1574 0 : if (user_list->contexts == NULL) {
1575 0 : user_list->contexts = old;
1576 0 : user_list->num_contexts -= 1;
1577 0 : return (DltDaemonContext*)NULL;
1578 : }
1579 :
1580 0 : memcpy(user_list->contexts, old, (size_t)sizeof(DltDaemonContext) * (size_t)user_list->num_contexts);
1581 0 : free(old);
1582 : }
1583 : }
1584 :
1585 5 : context = &(user_list->contexts[(size_t)(user_list->num_contexts - 1)]);
1586 : memset(context, 0, sizeof(DltDaemonContext));
1587 :
1588 5 : dlt_set_id(context->apid, apid);
1589 5 : dlt_set_id(context->ctid, ctid);
1590 :
1591 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1592 : context->trace_load_settings = NULL;
1593 : #endif
1594 :
1595 5 : application->num_contexts++;
1596 : new_context = 1;
1597 : }
1598 :
1599 : /* Set context description */
1600 5 : if (context->context_description) {
1601 0 : free(context->context_description);
1602 0 : context->context_description = NULL;
1603 : }
1604 :
1605 5 : if (description != NULL) {
1606 5 : context->context_description = malloc(strlen(description) + 1);
1607 :
1608 5 : if (context->context_description) {
1609 5 : memcpy(context->context_description, description, strlen(description) + 1);
1610 : }
1611 : }
1612 :
1613 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1614 : /* configure initial log level */
1615 : DltDaemonContextLogSettings* settings = NULL;
1616 : settings = dlt_daemon_find_configured_app_id_ctx_id_settings(daemon, context->apid, ctid);
1617 :
1618 : if (settings != NULL) {
1619 : /* set log level */
1620 : log_level = settings->log_level;
1621 :
1622 : DltDaemonContextLogSettings* ct_settings = NULL;
1623 : ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
1624 :
1625 : /* ct_settings != null: context and app id combination already exists */
1626 : if (ct_settings == NULL) {
1627 : /* copy the configuration into the DltDaemonApplication for faster access later */
1628 : DltDaemonContextLogSettings* tmp = realloc(
1629 : application->context_log_level_settings,
1630 : (++application->num_context_log_level_settings) * sizeof(DltDaemonContextLogSettings));
1631 : application->context_log_level_settings = tmp;
1632 :
1633 : ct_settings = &application->context_log_level_settings[application->num_context_log_level_settings - 1];
1634 : memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
1635 : memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
1636 : }
1637 : }
1638 : #endif
1639 :
1640 5 : if ((strncmp(daemon->ecuid, ecu, DLT_ID_SIZE) == 0) && (daemon->force_ll_ts)) {
1641 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1642 : if (log_level > daemon->default_log_level && settings == NULL)
1643 : #else
1644 0 : if (log_level > daemon->default_log_level)
1645 : #endif
1646 : log_level = daemon->default_log_level;
1647 :
1648 0 : if (trace_status > daemon->default_trace_status)
1649 : trace_status = daemon->default_trace_status;
1650 :
1651 0 : dlt_vlog(LOG_NOTICE, "Adapting ll_ts for context: %.4s:%.4s with %i %i\n", apid, ctid, log_level, trace_status);
1652 : }
1653 :
1654 : /* Store log level and trace status,
1655 : * if this is a new context, or
1656 : * if this is an old context and the runtime cfg was not loaded */
1657 5 : if ((new_context == 1) || ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
1658 5 : context->log_level = log_level;
1659 5 : context->trace_status = trace_status;
1660 : }
1661 :
1662 5 : context->log_level_pos = log_level_pos;
1663 5 : context->user_handle = user_handle;
1664 :
1665 : /* In case a context is loaded from runtime config file,
1666 : * the user_handle is 0 and we mark that context as predefined.
1667 : */
1668 5 : if (context->user_handle == 0)
1669 0 : context->predefined = true;
1670 : else
1671 5 : context->predefined = false;
1672 :
1673 : /* Sort */
1674 5 : if (new_context) {
1675 5 : qsort(user_list->contexts, (size_t)user_list->num_contexts, sizeof(DltDaemonContext), dlt_daemon_cmp_apid_ctid);
1676 :
1677 : /* Find new position of context with apid, ctid */
1678 5 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1679 : }
1680 :
1681 : return context;
1682 : }
1683 :
1684 0 : DltDaemonContext* dlt_daemon_context_add_v2(
1685 : DltDaemon* daemon, uint8_t apidlen, char* apid, uint8_t ctidlen, char* ctid, int8_t log_level, int8_t trace_status,
1686 : int log_level_pos, int user_handle, char* description, uint8_t eculen, char* ecu, int verbose)
1687 : {
1688 : DltDaemonContext* context;
1689 : DltDaemonContext* old;
1690 : int new_context = 0;
1691 : DltDaemonRegisteredUsers* user_list = NULL;
1692 0 : DltDaemonApplication* application = NULL;
1693 :
1694 0 : PRINT_FUNCTION_VERBOSE(verbose);
1695 :
1696 0 : if ((daemon == NULL) || (apid == NULL) || (ctid == NULL) || (ecu == NULL) || (apidlen == 0) || (ctidlen == 0))
1697 : return (DltDaemonContext*)NULL;
1698 :
1699 0 : if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
1700 : return (DltDaemonContext*)NULL;
1701 :
1702 0 : if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
1703 : return (DltDaemonContext*)NULL;
1704 :
1705 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
1706 :
1707 0 : if (user_list == NULL)
1708 : return (DltDaemonContext*)NULL;
1709 :
1710 0 : if (user_list->contexts == NULL) {
1711 0 : user_list->contexts = (DltDaemonContext*)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1712 :
1713 0 : if (user_list->contexts == NULL)
1714 : return (DltDaemonContext*)NULL;
1715 : }
1716 :
1717 : /* Check if application [apid] is available */
1718 0 : dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
1719 :
1720 :
1721 0 : if (application == NULL) {
1722 : return (DltDaemonContext*)NULL;
1723 : }
1724 :
1725 : /* Check if context [apid, ctid] is already available */
1726 0 : context = dlt_daemon_context_find_v2(daemon, apidlen, apid, ctidlen, ctid, eculen, ecu, verbose);
1727 :
1728 0 : if (context == NULL) {
1729 0 : user_list->num_contexts += 1;
1730 0 : if (user_list->num_contexts != 0) {
1731 0 : if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
1732 : /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
1733 0 : old = user_list->contexts;
1734 0 : user_list->contexts = (DltDaemonContext*)calloc(
1735 : 1, (size_t)sizeof(DltDaemonContext)
1736 0 : * (((size_t)user_list->num_contexts / DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1)
1737 : * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1738 :
1739 0 : if (user_list->contexts == NULL) {
1740 0 : user_list->contexts = old;
1741 0 : user_list->num_contexts -= 1;
1742 0 : return (DltDaemonContext*)NULL;
1743 : }
1744 :
1745 0 : memcpy(user_list->contexts, old, (size_t)sizeof(DltDaemonContext) * (size_t)user_list->num_contexts);
1746 0 : free(old);
1747 : }
1748 : }
1749 0 : context = &(user_list->contexts[user_list->num_contexts - 1]);
1750 : memset(context, 0, sizeof(DltDaemonContext));
1751 :
1752 0 : context->apid2 = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
1753 0 : if (context->apid2 == NULL) {
1754 : return (DltDaemonContext*)NULL;
1755 : }
1756 0 : dlt_set_id_v2(context->apid2, apid, apidlen);
1757 0 : context->apid2len = apidlen;
1758 0 : context->ctid2 = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
1759 0 : if (context->ctid2 == NULL) {
1760 0 : free(context->apid2);
1761 0 : context->apid2 = NULL;
1762 0 : return (DltDaemonContext*)NULL;
1763 : }
1764 0 : dlt_set_id_v2(context->ctid2, ctid, ctidlen);
1765 0 : context->ctid2len = ctidlen;
1766 :
1767 0 : application->num_contexts++;
1768 : new_context = 1;
1769 : }
1770 :
1771 : /* Set context description */
1772 0 : if (context->context_description) {
1773 0 : free(context->context_description);
1774 0 : context->context_description = NULL;
1775 : }
1776 :
1777 0 : if (description != NULL) {
1778 0 : context->context_description = malloc(strlen(description) + 1);
1779 :
1780 0 : if (context->context_description) {
1781 0 : memcpy(context->context_description, description, strlen(description) + 1);
1782 : }
1783 : }
1784 :
1785 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1786 : /* configure initial log level */
1787 : DltDaemonContextLogSettings* settings = NULL;
1788 : settings = dlt_daemon_find_configured_app_id_ctx_id_settings(daemon, context->apid, ctid);
1789 :
1790 : if (settings != NULL) {
1791 : /* set log level */
1792 : log_level = settings->log_level;
1793 :
1794 : DltDaemonContextLogSettings* ct_settings = NULL;
1795 : ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
1796 :
1797 : /* ct_settings != null: context and app id combination already exists */
1798 : if (ct_settings == NULL) {
1799 : /* copy the configuration into the DltDaemonApplication for faster access later */
1800 : DltDaemonContextLogSettings* tmp = realloc(
1801 : application->context_log_level_settings,
1802 : (++application->num_context_log_level_settings) * sizeof(DltDaemonContextLogSettings));
1803 : application->context_log_level_settings = tmp;
1804 :
1805 : ct_settings = &application->context_log_level_settings[application->num_context_log_level_settings - 1];
1806 : memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
1807 : memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
1808 : }
1809 : }
1810 : #endif
1811 :
1812 0 : if ((strncmp(daemon->ecuid2, ecu, eculen) == 0) && (daemon->force_ll_ts)) {
1813 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1814 : if (log_level > daemon->default_log_level && settings == NULL)
1815 : #else
1816 0 : if (log_level > daemon->default_log_level)
1817 : #endif
1818 : log_level = daemon->default_log_level;
1819 :
1820 0 : if (trace_status > daemon->default_trace_status)
1821 : trace_status = daemon->default_trace_status;
1822 :
1823 0 : dlt_vlog(
1824 : LOG_NOTICE, "Adapting ll_ts for context: %s:%s with %i %i\n", apid, ctid, log_level,
1825 : trace_status); // TBD: adjust length %.6s according to apidlen and ctidlen
1826 : }
1827 :
1828 : /* Store log level and trace status,
1829 : * if this is a new context, or
1830 : * if this is an old context and the runtime cfg was not loaded */
1831 0 : if ((new_context == 1) || ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
1832 0 : context->log_level = log_level;
1833 0 : context->trace_status = trace_status;
1834 : }
1835 :
1836 0 : context->log_level_pos = log_level_pos;
1837 0 : context->user_handle = user_handle;
1838 :
1839 : /* In case a context is loaded from runtime config file,
1840 : * the user_handle is 0 and we mark that context as predefined.
1841 : */
1842 0 : if (context->user_handle == 0)
1843 0 : context->predefined = true;
1844 : else
1845 0 : context->predefined = false;
1846 :
1847 : /* Sort */
1848 0 : if (new_context) {
1849 0 : qsort(
1850 0 : user_list->contexts, (size_t)user_list->num_contexts, sizeof(DltDaemonContext),
1851 : dlt_daemon_cmp_apid_ctid_v2);
1852 :
1853 : /* Find new position of context with apid, ctid */
1854 0 : context = dlt_daemon_context_find_v2(daemon, apidlen, apid, ctidlen, ctid, eculen, ecu, verbose);
1855 : }
1856 : return context;
1857 : }
1858 :
1859 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1860 : static void dlt_daemon_free_context_log_settings(DltDaemonApplication* application, DltDaemonContext* context)
1861 : {
1862 : DltDaemonContextLogSettings* ct_settings;
1863 : int i;
1864 : int skipped = 0;
1865 :
1866 : ct_settings = dlt_daemon_find_app_log_level_config(application, context->ctid);
1867 : if (ct_settings == NULL) {
1868 : return;
1869 : }
1870 :
1871 : /* move all data forward */
1872 : for (i = 0; i < application->num_context_log_level_settings; ++i) {
1873 : /* skip given context to delete it */
1874 : if (i + skipped < application->num_context_log_level_settings
1875 : && strncmp(application->context_log_level_settings[i + skipped].ctid, context->ctid, DLT_ID_SIZE) == 0) {
1876 : ++skipped;
1877 : continue;
1878 : }
1879 :
1880 : memcpy(
1881 : &application->context_log_level_settings[i - skipped], &application->context_log_level_settings[i],
1882 : sizeof(DltDaemonContextLogSettings));
1883 : }
1884 :
1885 : application->num_context_log_level_settings -= skipped;
1886 :
1887 : /* if size is equal to zero, and ptr is not NULL, then realloc is equivalent to free(ptr) */
1888 : application->context_log_level_settings = realloc(
1889 : application->context_log_level_settings,
1890 : sizeof(DltDaemonContextLogSettings) * (application->num_context_log_level_settings));
1891 : }
1892 : #endif
1893 :
1894 0 : int dlt_daemon_context_del(DltDaemon* daemon, DltDaemonContext* context, char* ecu, int verbose)
1895 : {
1896 : int pos;
1897 : DltDaemonApplication* application;
1898 : DltDaemonRegisteredUsers* user_list = NULL;
1899 :
1900 0 : PRINT_FUNCTION_VERBOSE(verbose);
1901 :
1902 0 : if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
1903 : return -1;
1904 :
1905 0 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1906 :
1907 0 : if (user_list == NULL)
1908 : return -1;
1909 :
1910 0 : if (user_list->num_contexts > 0) {
1911 0 : application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose);
1912 :
1913 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1914 : dlt_daemon_free_context_log_settings(application, context);
1915 : #endif
1916 : /* Free description of context to be deleted */
1917 0 : if (context->context_description) {
1918 0 : free(context->context_description);
1919 0 : context->context_description = NULL;
1920 : }
1921 :
1922 0 : pos = (int)(context - (user_list->contexts));
1923 :
1924 : /* move all contexts above pos to pos */
1925 0 : memmove(
1926 0 : &(user_list->contexts[pos]), &(user_list->contexts[pos + 1]),
1927 0 : (size_t)sizeof(DltDaemonContext) * (size_t)((user_list->num_contexts - 1) - pos));
1928 :
1929 : /* Clear last context */
1930 0 : memset(&(user_list->contexts[(size_t)(user_list->num_contexts - 1)]), 0, (size_t)sizeof(DltDaemonContext));
1931 :
1932 0 : user_list->num_contexts--;
1933 :
1934 : /* Check if application [apid] is available */
1935 0 : if (application != NULL)
1936 0 : application->num_contexts--;
1937 : }
1938 :
1939 : return 0;
1940 : }
1941 :
1942 0 : int dlt_daemon_context_del_v2(DltDaemon* daemon, DltDaemonContext* context, uint8_t eculen, char* ecu, int verbose)
1943 : {
1944 : int pos;
1945 : DltDaemonApplication* application;
1946 : DltDaemonRegisteredUsers* user_list = NULL;
1947 :
1948 0 : PRINT_FUNCTION_VERBOSE(verbose);
1949 :
1950 0 : if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
1951 : return -1;
1952 :
1953 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
1954 :
1955 0 : if (user_list == NULL)
1956 : return -1;
1957 :
1958 0 : if (user_list->num_contexts > 0) {
1959 0 : dlt_daemon_application_find_v2(daemon, context->apid2len, context->apid2, eculen, ecu, verbose, &application);
1960 :
1961 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
1962 : dlt_daemon_free_context_log_settings(application, context);
1963 : #endif
1964 : /* Free description of context to be deleted */
1965 0 : if (context->context_description) {
1966 0 : free(context->context_description);
1967 0 : context->context_description = NULL;
1968 : }
1969 :
1970 0 : pos = (int)(context - (user_list->contexts));
1971 :
1972 : /* move all contexts above pos to pos */
1973 0 : memmove(
1974 0 : &(user_list->contexts[pos]), &(user_list->contexts[pos + 1]),
1975 0 : (size_t)sizeof(DltDaemonContext) * (size_t)((user_list->num_contexts - 1) - pos));
1976 :
1977 : /* Clear last context */
1978 0 : memset(&(user_list->contexts[user_list->num_contexts - 1]), 0, sizeof(DltDaemonContext));
1979 :
1980 0 : user_list->num_contexts--;
1981 :
1982 : /* Check if application [apid] is available */
1983 0 : if (application != NULL)
1984 0 : application->num_contexts--;
1985 : }
1986 :
1987 : return 0;
1988 : }
1989 :
1990 27 : DltDaemonContext* dlt_daemon_context_find(DltDaemon* daemon, char* apid, char* ctid, char* ecu, int verbose)
1991 : {
1992 : DltDaemonContext context;
1993 : DltDaemonRegisteredUsers* user_list = NULL;
1994 :
1995 27 : PRINT_FUNCTION_VERBOSE(verbose);
1996 :
1997 27 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1998 : return (DltDaemonContext*)NULL;
1999 :
2000 27 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
2001 :
2002 27 : if ((user_list == NULL) || (user_list->num_contexts == 0))
2003 : return (DltDaemonContext*)NULL;
2004 :
2005 : /* Check, if apid is smaller than smallest apid or greater than greatest apid */
2006 9 : if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0)
2007 9 : || (memcmp(apid, user_list->contexts[user_list->num_contexts - 1].apid, DLT_ID_SIZE) > 0))
2008 : return (DltDaemonContext*)NULL;
2009 :
2010 9 : dlt_set_id(context.apid, apid);
2011 9 : dlt_set_id(context.ctid, ctid);
2012 :
2013 9 : return (DltDaemonContext*)bsearch(
2014 9 : &context, user_list->contexts, (size_t)user_list->num_contexts, sizeof(DltDaemonContext),
2015 : dlt_daemon_cmp_apid_ctid);
2016 : }
2017 :
2018 0 : DltDaemonContext* dlt_daemon_context_find_v2(
2019 : DltDaemon* daemon, uint8_t apidlen, char* apid, uint8_t ctidlen, char* ctid, uint8_t eculen, char* ecu, int verbose)
2020 : {
2021 : DltDaemonContext context;
2022 : DltDaemonRegisteredUsers* user_list = NULL;
2023 0 : PRINT_FUNCTION_VERBOSE(verbose);
2024 :
2025 0 : if ((daemon == NULL) || (apidlen == 0) || (apid == NULL) || (ctidlen == 0) || (ctid == NULL) || (eculen == 0)
2026 0 : || (ecu == NULL))
2027 : return (DltDaemonContext*)NULL;
2028 :
2029 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
2030 :
2031 0 : if ((user_list == NULL) || (user_list->num_contexts == 0))
2032 : return (DltDaemonContext*)NULL;
2033 :
2034 0 : context.apid2 = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
2035 0 : if (context.apid2 == NULL) {
2036 : return (DltDaemonContext*)NULL;
2037 : }
2038 0 : dlt_set_id_v2(context.apid2, apid, apidlen);
2039 0 : context.apid2len = apidlen;
2040 0 : context.ctid2 = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
2041 0 : if (context.ctid2 == NULL) {
2042 0 : free(context.apid2);
2043 0 : return (DltDaemonContext*)NULL;
2044 : }
2045 0 : dlt_set_id_v2(context.ctid2, ctid, ctidlen);
2046 0 : context.ctid2len = ctidlen;
2047 :
2048 0 : DltDaemonContext* result = (DltDaemonContext*)bsearch(
2049 0 : &context, user_list->contexts, (size_t)user_list->num_contexts, sizeof(DltDaemonContext),
2050 : dlt_daemon_cmp_apid_ctid_v2);
2051 :
2052 : // Free temporary allocated memory
2053 0 : free(context.apid2);
2054 0 : free(context.ctid2);
2055 :
2056 0 : return result;
2057 : }
2058 :
2059 5 : int dlt_daemon_contexts_invalidate_fd(DltDaemon* daemon, char* ecu, int fd, int verbose)
2060 : {
2061 : int i;
2062 : DltDaemonRegisteredUsers* user_list = NULL;
2063 :
2064 5 : PRINT_FUNCTION_VERBOSE(verbose);
2065 :
2066 5 : if ((daemon == NULL) || (ecu == NULL))
2067 : return -1;
2068 :
2069 5 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
2070 :
2071 5 : if (user_list != NULL) {
2072 9 : for (i = 0; i < user_list->num_contexts; i++)
2073 4 : if (user_list->contexts[i].user_handle == fd)
2074 0 : user_list->contexts[i].user_handle = DLT_FD_INIT;
2075 :
2076 : return 0;
2077 : }
2078 :
2079 : return -1;
2080 : }
2081 :
2082 0 : int dlt_daemon_contexts_invalidate_fd_v2(DltDaemon* daemon, char* ecu, int fd, int verbose)
2083 : {
2084 : int i;
2085 : DltDaemonRegisteredUsers* user_list = NULL;
2086 :
2087 0 : PRINT_FUNCTION_VERBOSE(verbose);
2088 :
2089 0 : if ((daemon == NULL) || (ecu == NULL))
2090 : return -1;
2091 0 : uint8_t eculen = (uint8_t)strlen(ecu);
2092 0 : user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
2093 :
2094 0 : if (user_list != NULL) {
2095 0 : for (i = 0; i < user_list->num_contexts; i++)
2096 0 : if (user_list->contexts[i].user_handle == fd)
2097 0 : user_list->contexts[i].user_handle = DLT_FD_INIT;
2098 :
2099 : return 0;
2100 : }
2101 :
2102 : return -1;
2103 : }
2104 :
2105 1 : int dlt_daemon_contexts_clear(DltDaemon* daemon, char* ecu, int verbose)
2106 : {
2107 : int i;
2108 : DltDaemonRegisteredUsers* users = NULL;
2109 :
2110 1 : PRINT_FUNCTION_VERBOSE(verbose);
2111 :
2112 1 : if ((daemon == NULL) || (ecu == NULL))
2113 : return DLT_RETURN_WRONG_PARAMETER;
2114 :
2115 1 : users = dlt_daemon_find_users_list(daemon, ecu, verbose);
2116 :
2117 1 : if (users == NULL)
2118 : return DLT_RETURN_ERROR;
2119 :
2120 3 : for (i = 0; i < users->num_contexts; i++) {
2121 2 : if (users->contexts[i].context_description != NULL) {
2122 2 : free(users->contexts[i].context_description);
2123 2 : users->contexts[i].context_description = NULL;
2124 : }
2125 2 : if (users->contexts[i].apid2 != NULL) {
2126 0 : free(users->contexts[i].apid2);
2127 0 : users->contexts[i].apid2 = NULL;
2128 : }
2129 2 : if (users->contexts[i].ctid2 != NULL) {
2130 0 : free(users->contexts[i].ctid2);
2131 0 : users->contexts[i].ctid2 = NULL;
2132 : }
2133 : }
2134 :
2135 1 : if (users->contexts) {
2136 1 : free(users->contexts);
2137 1 : users->contexts = NULL;
2138 : }
2139 :
2140 2 : for (i = 0; i < users->num_applications; i++)
2141 1 : users->applications[i].num_contexts = 0;
2142 :
2143 1 : users->num_contexts = 0;
2144 :
2145 1 : return 0;
2146 : }
2147 :
2148 0 : int dlt_daemon_contexts_load(DltDaemon* daemon, const char* filename, int verbose)
2149 : {
2150 : FILE* fd;
2151 : ID4 apid, ctid;
2152 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
2153 : char* ret;
2154 : char* pb;
2155 : int ll, ts;
2156 :
2157 0 : PRINT_FUNCTION_VERBOSE(verbose);
2158 :
2159 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2160 : return -1;
2161 :
2162 0 : fd = fopen(filename, "r");
2163 :
2164 0 : if (fd == NULL) {
2165 0 : dlt_vlog(LOG_WARNING, "DLT runtime-context load, cannot open file %s: %s\n", filename, strerror(errno));
2166 :
2167 0 : return -1;
2168 : }
2169 :
2170 0 : while (!feof(fd)) {
2171 : /* Clear buf */
2172 : memset(buf, 0, sizeof(buf));
2173 :
2174 : /* Get line */
2175 : ret = fgets(buf, sizeof(buf), fd);
2176 :
2177 0 : if (NULL == ret) {
2178 : /* fgets always returns null pointer if the last byte of the file is a new line.
2179 : * We need to check here if there was an error or was it feof.*/
2180 0 : if (ferror(fd)) {
2181 0 : dlt_vlog(LOG_WARNING, "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n", __func__, strerror(errno));
2182 0 : fclose(fd);
2183 0 : return -1;
2184 0 : } else if (feof(fd)) {
2185 0 : fclose(fd);
2186 0 : return 0;
2187 : } else {
2188 0 : dlt_vlog(LOG_WARNING, "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n", __func__);
2189 0 : fclose(fd);
2190 0 : return -1;
2191 : }
2192 : }
2193 :
2194 0 : if (strcmp(buf, "") != 0) {
2195 : /* Split line */
2196 0 : pb = strtok(buf, ":");
2197 :
2198 0 : if (pb != NULL) {
2199 0 : dlt_set_id(apid, pb);
2200 0 : pb = strtok(NULL, ":");
2201 :
2202 0 : if (pb != NULL) {
2203 0 : dlt_set_id(ctid, pb);
2204 0 : pb = strtok(NULL, ":");
2205 :
2206 0 : if (pb != NULL) {
2207 0 : sscanf(pb, "%d", &ll);
2208 0 : pb = strtok(NULL, ":");
2209 :
2210 0 : if (pb != NULL) {
2211 0 : sscanf(pb, "%d", &ts);
2212 0 : pb = strtok(NULL, ":");
2213 :
2214 0 : if (pb != NULL) {
2215 : /* pb contains now the description */
2216 :
2217 : /* log_level_pos, and user_handle are unknown at loading time */
2218 0 : if (dlt_daemon_context_add(
2219 0 : daemon, apid, ctid, (int8_t)ll, (int8_t)ts, 0, 0, pb, daemon->ecuid, verbose)
2220 : == NULL) {
2221 0 : dlt_vlog(LOG_WARNING, "%s dlt_daemon_context_add failed\n", __func__);
2222 0 : fclose(fd);
2223 0 : return -1;
2224 : }
2225 : }
2226 : }
2227 : }
2228 : }
2229 : }
2230 : }
2231 : }
2232 :
2233 0 : fclose(fd);
2234 :
2235 0 : return 0;
2236 : }
2237 :
2238 0 : int dlt_daemon_contexts_save(DltDaemon* daemon, const char* filename, int verbose)
2239 : {
2240 : FILE* fd;
2241 : int i;
2242 :
2243 : char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
2244 : DltDaemonRegisteredUsers* user_list = NULL;
2245 :
2246 0 : PRINT_FUNCTION_VERBOSE(verbose);
2247 :
2248 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2249 : return -1;
2250 :
2251 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2252 :
2253 0 : if (user_list == NULL)
2254 : return -1;
2255 :
2256 : memset(apid, 0, sizeof(apid));
2257 : memset(ctid, 0, sizeof(ctid));
2258 :
2259 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
2260 0 : fd = fopen(filename, "w");
2261 :
2262 0 : if (fd != NULL) {
2263 0 : for (i = 0; i < user_list->num_contexts; i++) {
2264 0 : dlt_set_id(apid, user_list->contexts[i].apid);
2265 0 : dlt_set_id(ctid, user_list->contexts[i].ctid);
2266 :
2267 0 : if ((user_list->contexts[i].context_description)
2268 0 : && (user_list->contexts[i].context_description[0] != '\0'))
2269 0 : fprintf(
2270 0 : fd, "%s:%s:%d:%d:%s:\n", apid, ctid, (int)(user_list->contexts[i].log_level),
2271 0 : (int)(user_list->contexts[i].trace_status), user_list->contexts[i].context_description);
2272 : else
2273 0 : fprintf(
2274 0 : fd, "%s:%s:%d:%d::\n", apid, ctid, (int)(user_list->contexts[i].log_level),
2275 0 : (int)(user_list->contexts[i].trace_status));
2276 : }
2277 :
2278 0 : fclose(fd);
2279 : } else {
2280 0 : dlt_vlog(LOG_ERR, "%s: Cannot open %s. No context information stored\n", __func__, filename);
2281 : }
2282 : }
2283 :
2284 : return 0;
2285 : }
2286 :
2287 0 : int dlt_daemon_contexts_save_v2(DltDaemon* daemon, const char* filename, int verbose)
2288 : {
2289 : FILE* fd;
2290 : int i;
2291 :
2292 : char apid[DLT_V2_ID_SIZE];
2293 : char ctid[DLT_V2_ID_SIZE];
2294 : DltDaemonRegisteredUsers* user_list = NULL;
2295 :
2296 0 : PRINT_FUNCTION_VERBOSE(verbose);
2297 :
2298 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2299 : return -1;
2300 :
2301 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2302 :
2303 0 : if (user_list == NULL)
2304 : return -1;
2305 :
2306 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
2307 0 : fd = fopen(filename, "w");
2308 :
2309 0 : if (fd != NULL) {
2310 0 : for (i = 0; i < user_list->num_contexts; i++) {
2311 0 : dlt_set_id_v2(apid, user_list->contexts[i].apid2, user_list->contexts[i].apid2len);
2312 0 : dlt_set_id_v2(ctid, user_list->contexts[i].ctid2, user_list->contexts[i].ctid2len);
2313 :
2314 0 : if ((user_list->contexts[i].context_description)
2315 0 : && (user_list->contexts[i].context_description[0] != '\0'))
2316 0 : fprintf(
2317 0 : fd, "%s:%s:%d:%d:%s:\n", apid, ctid, (int)(user_list->contexts[i].log_level),
2318 0 : (int)(user_list->contexts[i].trace_status), user_list->contexts[i].context_description);
2319 : else
2320 0 : fprintf(
2321 0 : fd, "%s:%s:%d:%d::\n", apid, ctid, (int)(user_list->contexts[i].log_level),
2322 0 : (int)(user_list->contexts[i].trace_status));
2323 : }
2324 :
2325 0 : fclose(fd);
2326 : } else {
2327 0 : dlt_vlog(LOG_ERR, "%s: Cannot open %s. No context information stored\n", __func__, filename);
2328 : }
2329 : }
2330 :
2331 : return 0;
2332 : }
2333 :
2334 0 : int dlt_daemon_configuration_save(DltDaemon* daemon, const char* filename, int verbose)
2335 : {
2336 : FILE* fd;
2337 :
2338 0 : PRINT_FUNCTION_VERBOSE(verbose);
2339 :
2340 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2341 : return -1;
2342 :
2343 0 : fd = fopen(filename, "w");
2344 :
2345 0 : if (fd != NULL) {
2346 : fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
2347 0 : fprintf(fd, "LoggingMode = %d\n", daemon->mode);
2348 :
2349 0 : fclose(fd);
2350 : }
2351 :
2352 : return 0;
2353 : }
2354 :
2355 1 : int dlt_daemon_configuration_load(DltDaemon* daemon, const char* filename, int verbose)
2356 : {
2357 1 : if ((daemon == NULL) || (filename == NULL))
2358 : return -1;
2359 :
2360 : FILE* pFile;
2361 : char line[1024];
2362 : char token[1024];
2363 : char value[1024];
2364 : char* pch;
2365 :
2366 1 : PRINT_FUNCTION_VERBOSE(verbose);
2367 :
2368 1 : pFile = fopen(filename, "r");
2369 :
2370 1 : if (pFile != NULL) {
2371 : while (1) {
2372 : /* fetch line from configuration file */
2373 2 : if (fgets(line, 1024, pFile) != NULL) {
2374 1 : pch = strtok(line, " =\r\n");
2375 1 : token[0] = 0;
2376 1 : value[0] = 0;
2377 :
2378 2 : while (pch != NULL) {
2379 1 : if (strcmp(pch, "#") == 0)
2380 : break;
2381 :
2382 1 : if (token[0] == 0) {
2383 : strncpy(token, pch, sizeof(token) - 1);
2384 1 : token[sizeof(token) - 1] = 0;
2385 : } else {
2386 : strncpy(value, pch, sizeof(value) - 1);
2387 0 : value[sizeof(value) - 1] = 0;
2388 0 : break;
2389 : }
2390 :
2391 1 : pch = strtok(NULL, " =\r\n");
2392 : }
2393 :
2394 1 : if (token[0] && value[0]) {
2395 : /* parse arguments here */
2396 0 : if (strcmp(token, "LoggingMode") == 0) {
2397 0 : daemon->mode = atoi(value);
2398 0 : dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token, daemon->mode);
2399 : } else {
2400 0 : dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token, value);
2401 : }
2402 : }
2403 : } else {
2404 : break;
2405 : }
2406 : }
2407 :
2408 1 : fclose(pFile);
2409 : } else {
2410 0 : dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
2411 : }
2412 :
2413 : return 0;
2414 : }
2415 :
2416 5 : int dlt_daemon_user_send_log_level(DltDaemon* daemon, DltDaemonContext* context, int verbose)
2417 : {
2418 : DltUserHeader userheader;
2419 : DltUserControlMsgLogLevel usercontext;
2420 : DltReturnValue ret;
2421 : DltDaemonApplication* app;
2422 :
2423 5 : PRINT_FUNCTION_VERBOSE(verbose);
2424 :
2425 5 : if ((daemon == NULL) || (context == NULL)) {
2426 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
2427 0 : return -1;
2428 : }
2429 :
2430 5 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
2431 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
2432 0 : return -1;
2433 : }
2434 :
2435 5 : if ((context->storage_log_level != DLT_LOG_DEFAULT)
2436 4 : && (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
2437 2 : usercontext.log_level = (uint8_t)(context->log_level > context->storage_log_level ? context->log_level :
2438 : context->storage_log_level);
2439 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
2440 3 : usercontext.log_level =
2441 3 : (uint8_t)((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
2442 :
2443 5 : usercontext.trace_status =
2444 5 : (uint8_t)((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status :
2445 : context->trace_status);
2446 :
2447 5 : usercontext.log_level_pos = context->log_level_pos;
2448 :
2449 5 : dlt_vlog(
2450 5 : LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n", context->apid, context->ctid,
2451 5 : context->log_level, usercontext.log_level, context->trace_status, usercontext.trace_status);
2452 :
2453 : /* log to FIFO */
2454 5 : errno = 0;
2455 5 : ret = dlt_user_log_out2_with_timeout(
2456 : context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
2457 :
2458 5 : if (ret < DLT_RETURN_OK) {
2459 0 : dlt_vlog(
2460 : LOG_ERR, "Failed to send data to application in %s: %s", __func__,
2461 0 : errno != 0 ? strerror(errno) : "Unknown error");
2462 :
2463 0 : if (errno == EPIPE || errno == EBADF) {
2464 0 : app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
2465 0 : if (app != NULL)
2466 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2467 : }
2468 : }
2469 :
2470 5 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2471 : }
2472 :
2473 0 : int dlt_daemon_user_send_log_level_v2(DltDaemon* daemon, DltDaemonContext* context, int verbose)
2474 : {
2475 : DltUserHeader userheader;
2476 : DltUserControlMsgLogLevel usercontext;
2477 : DltReturnValue ret;
2478 0 : DltDaemonApplication* app = NULL;
2479 :
2480 0 : PRINT_FUNCTION_VERBOSE(verbose);
2481 :
2482 0 : if ((daemon == NULL) || (context == NULL)) {
2483 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
2484 0 : return -1;
2485 : }
2486 :
2487 0 : if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
2488 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
2489 0 : return -1;
2490 : }
2491 :
2492 0 : if ((context->storage_log_level != DLT_LOG_DEFAULT)
2493 0 : && (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
2494 0 : usercontext.log_level = (uint8_t)(context->log_level > context->storage_log_level ? context->log_level :
2495 : context->storage_log_level);
2496 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
2497 0 : usercontext.log_level =
2498 0 : (uint8_t)((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
2499 :
2500 0 : usercontext.trace_status =
2501 0 : (uint8_t)((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status :
2502 : context->trace_status);
2503 :
2504 0 : usercontext.log_level_pos = context->log_level_pos;
2505 :
2506 0 : dlt_vlog(
2507 : LOG_NOTICE, "Send log-level to context: %s:%s [%i -> %i] [%i -> %i]\n", context->apid2, context->ctid2,
2508 0 : context->log_level, usercontext.log_level, context->trace_status, usercontext.trace_status);
2509 :
2510 : /* log to FIFO */
2511 0 : errno = 0;
2512 0 : ret = dlt_user_log_out2_with_timeout(
2513 : context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
2514 :
2515 0 : if (ret < DLT_RETURN_OK) {
2516 0 : dlt_vlog(
2517 : LOG_ERR, "Failed to send data to application in %s: %s", __func__,
2518 0 : errno != 0 ? strerror(errno) : "Unknown error");
2519 :
2520 0 : if (errno == EPIPE || errno == EBADF) {
2521 0 : dlt_daemon_application_find_v2(
2522 0 : daemon, context->apid2len, context->apid2, daemon->ecuid2len, daemon->ecuid2, verbose, &app);
2523 0 : if (app != NULL)
2524 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2525 : }
2526 : }
2527 0 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2528 : }
2529 :
2530 2 : int dlt_daemon_user_send_log_state(DltDaemon* daemon, DltDaemonApplication* app, int verbose)
2531 : {
2532 : DltUserHeader userheader;
2533 : DltUserControlMsgLogState logstate;
2534 : DltReturnValue ret;
2535 :
2536 2 : PRINT_FUNCTION_VERBOSE(verbose);
2537 :
2538 2 : if ((daemon == NULL) || (app == NULL))
2539 : return -1;
2540 :
2541 2 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
2542 : return -1;
2543 :
2544 2 : logstate.log_state = (int8_t)daemon->connectionState;
2545 :
2546 : /* log to FIFO */
2547 2 : ret = dlt_user_log_out2_with_timeout(
2548 : app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState));
2549 :
2550 2 : if (ret < DLT_RETURN_OK) {
2551 0 : if (errno == EPIPE || errno == EBADF)
2552 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2553 : }
2554 :
2555 2 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2556 : }
2557 :
2558 0 : int dlt_daemon_user_send_log_state_v2(DltDaemon* daemon, DltDaemonApplication* app, int verbose)
2559 : {
2560 : DltUserHeader userheader;
2561 : DltUserControlMsgLogState logstate;
2562 : DltReturnValue ret;
2563 :
2564 0 : PRINT_FUNCTION_VERBOSE(verbose);
2565 :
2566 0 : if ((daemon == NULL) || (app == NULL))
2567 : return -1;
2568 :
2569 0 : if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
2570 : return -1;
2571 :
2572 0 : logstate.log_state = (int8_t)daemon->connectionState;
2573 :
2574 : /* log to FIFO */
2575 0 : ret = dlt_user_log_out2_with_timeout(
2576 : app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate.log_state), sizeof(int8_t));
2577 :
2578 0 : if (ret < DLT_RETURN_OK) {
2579 0 : if (errno == EPIPE || errno == EBADF)
2580 0 : dlt_daemon_application_reset_user_handle_v2(daemon, app, verbose);
2581 : }
2582 :
2583 0 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2584 : }
2585 :
2586 0 : void dlt_daemon_control_reset_to_factory_default(
2587 : DltDaemon* daemon, const char* filename, const char* filename1, int InitialContextLogLevel,
2588 : int InitialContextTraceStatus, int InitialEnforceLlTsStatus, int verbose)
2589 : {
2590 : FILE* fd;
2591 :
2592 0 : PRINT_FUNCTION_VERBOSE(verbose);
2593 :
2594 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
2595 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2596 0 : return;
2597 : }
2598 :
2599 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
2600 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
2601 0 : return;
2602 : }
2603 :
2604 : /* Check for runtime cfg file and delete it, if available */
2605 0 : fd = fopen(filename, "r");
2606 :
2607 0 : if (fd != NULL) {
2608 : /* Close and delete file */
2609 0 : fclose(fd);
2610 0 : if (unlink(filename) != 0) {
2611 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n", __func__, strerror(errno));
2612 : }
2613 : }
2614 :
2615 0 : fd = fopen(filename1, "r");
2616 :
2617 0 : if (fd != NULL) {
2618 : /* Close and delete file */
2619 0 : fclose(fd);
2620 0 : if (unlink(filename1) != 0) {
2621 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n", __func__, strerror(errno));
2622 : }
2623 : }
2624 :
2625 0 : daemon->default_log_level = (int8_t)InitialContextLogLevel;
2626 0 : daemon->default_trace_status = (int8_t)InitialContextTraceStatus;
2627 0 : daemon->force_ll_ts = (int8_t)InitialEnforceLlTsStatus;
2628 :
2629 : /* Reset all other things (log level, trace status, etc.
2630 : * to default values */
2631 :
2632 : /* Inform user libraries about changed default log level/trace status */
2633 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2634 : }
2635 :
2636 0 : void dlt_daemon_control_reset_to_factory_default_v2(
2637 : DltDaemon* daemon, const char* filename, const char* filename1, int InitialContextLogLevel,
2638 : int InitialContextTraceStatus, int InitialEnforceLlTsStatus, int verbose)
2639 : {
2640 : FILE* fd;
2641 :
2642 0 : PRINT_FUNCTION_VERBOSE(verbose);
2643 :
2644 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
2645 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2646 0 : return;
2647 : }
2648 :
2649 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
2650 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
2651 0 : return;
2652 : }
2653 :
2654 : /* Check for runtime cfg file and delete it, if available */
2655 0 : fd = fopen(filename, "r");
2656 :
2657 0 : if (fd != NULL) {
2658 : /* Close and delete file */
2659 0 : fclose(fd);
2660 0 : if (unlink(filename) != 0) {
2661 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n", __func__, strerror(errno));
2662 : }
2663 : }
2664 :
2665 0 : fd = fopen(filename1, "r");
2666 :
2667 0 : if (fd != NULL) {
2668 : /* Close and delete file */
2669 0 : fclose(fd);
2670 0 : if (unlink(filename1) != 0) {
2671 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n", __func__, strerror(errno));
2672 : }
2673 : }
2674 :
2675 0 : daemon->default_log_level = (int8_t)InitialContextLogLevel;
2676 0 : daemon->default_trace_status = (int8_t)InitialContextTraceStatus;
2677 0 : daemon->force_ll_ts = (int8_t)InitialEnforceLlTsStatus;
2678 :
2679 : /* Reset all other things (log level, trace status, etc.
2680 : * to default values */
2681 :
2682 : /* Inform user libraries about changed default log level/trace status */
2683 0 : dlt_daemon_user_send_default_update_v2(daemon, verbose);
2684 : }
2685 :
2686 0 : void dlt_daemon_user_send_default_update(DltDaemon* daemon, int verbose)
2687 : {
2688 : int32_t count;
2689 : DltDaemonContext* context;
2690 : DltDaemonRegisteredUsers* user_list = NULL;
2691 :
2692 0 : PRINT_FUNCTION_VERBOSE(verbose);
2693 :
2694 0 : if (daemon == NULL) {
2695 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2696 0 : return;
2697 : }
2698 :
2699 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2700 :
2701 0 : if (user_list == NULL)
2702 : return;
2703 :
2704 0 : for (count = 0; count < user_list->num_contexts; count++) {
2705 0 : context = &(user_list->contexts[count]);
2706 :
2707 0 : if (context != NULL) {
2708 0 : if ((context->log_level == DLT_LOG_DEFAULT) || (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
2709 0 : if (context->user_handle >= DLT_FD_MINIMUM)
2710 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
2711 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
2712 : }
2713 : }
2714 : }
2715 : }
2716 :
2717 0 : void dlt_daemon_user_send_default_update_v2(DltDaemon* daemon, int verbose)
2718 : {
2719 : int32_t count;
2720 : DltDaemonContext* context;
2721 : DltDaemonRegisteredUsers* user_list = NULL;
2722 :
2723 0 : PRINT_FUNCTION_VERBOSE(verbose);
2724 :
2725 0 : if (daemon == NULL) {
2726 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2727 0 : return;
2728 : }
2729 :
2730 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2731 :
2732 0 : if (user_list == NULL)
2733 : return;
2734 :
2735 0 : for (count = 0; count < user_list->num_contexts; count++) {
2736 0 : context = &(user_list->contexts[count]);
2737 :
2738 0 : if (context != NULL) {
2739 0 : if ((context->log_level == DLT_LOG_DEFAULT) || (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
2740 0 : if (context->user_handle >= DLT_FD_MINIMUM)
2741 0 : if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
2742 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
2743 : }
2744 : }
2745 : }
2746 : }
2747 :
2748 0 : void dlt_daemon_user_send_all_log_level_update(
2749 : DltDaemon* daemon, int enforce_context_ll_and_ts, int8_t context_log_level, int8_t log_level, int verbose)
2750 : {
2751 : int32_t count = 0;
2752 : DltDaemonContext* context = NULL;
2753 : DltDaemonRegisteredUsers* user_list = NULL;
2754 :
2755 0 : PRINT_FUNCTION_VERBOSE(verbose);
2756 :
2757 0 : if (daemon == NULL)
2758 : return;
2759 :
2760 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2761 :
2762 0 : if (user_list == NULL)
2763 : return;
2764 :
2765 0 : for (count = 0; count < user_list->num_contexts; count++) {
2766 0 : context = &(user_list->contexts[count]);
2767 :
2768 0 : if (context) {
2769 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
2770 0 : context->log_level = log_level;
2771 :
2772 0 : if (enforce_context_ll_and_ts) {
2773 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
2774 : DltDaemonContextLogSettings* settings =
2775 : dlt_daemon_find_configured_app_id_ctx_id_settings(daemon, context->apid, context->ctid);
2776 : if (settings != NULL) {
2777 : if (log_level > settings->log_level) {
2778 : context->log_level = settings->log_level;
2779 : }
2780 : } else
2781 : #endif
2782 0 : if (log_level > context_log_level) {
2783 0 : context->log_level = (int8_t)context_log_level;
2784 : }
2785 : }
2786 :
2787 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
2788 0 : dlt_vlog(
2789 0 : LOG_WARNING, "Cannot send log level %.4s:%.4s -> %i\n", context->apid, context->ctid,
2790 0 : context->log_level);
2791 : }
2792 : }
2793 : }
2794 : }
2795 :
2796 0 : void dlt_daemon_user_send_all_log_level_update_v2(
2797 : DltDaemon* daemon, int enforce_context_ll_and_ts, int8_t context_log_level, int8_t log_level, int verbose)
2798 : {
2799 : int32_t count = 0;
2800 : DltDaemonContext* context = NULL;
2801 : DltDaemonRegisteredUsers* user_list = NULL;
2802 :
2803 0 : PRINT_FUNCTION_VERBOSE(verbose);
2804 :
2805 0 : if (daemon == NULL)
2806 : return;
2807 :
2808 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2809 :
2810 0 : if (user_list == NULL)
2811 : return;
2812 :
2813 0 : for (count = 0; count < user_list->num_contexts; count++) {
2814 0 : context = &(user_list->contexts[count]);
2815 :
2816 0 : if (context) {
2817 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
2818 0 : context->log_level = log_level;
2819 :
2820 0 : if (enforce_context_ll_and_ts) {
2821 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
2822 : // TBD: Check if function params require apid/ctid lengths
2823 : DltDaemonContextLogSettingsV2* settings =
2824 : dlt_daemon_find_configured_app_id_ctx_id_settings_v2(daemon, context->apid, context->ctid);
2825 : if (settings != NULL) {
2826 : if (log_level > settings->log_level) {
2827 : context->log_level = settings->log_level;
2828 : }
2829 : } else
2830 : #endif
2831 0 : if (log_level > context_log_level) {
2832 0 : context->log_level = (int8_t)context_log_level;
2833 : }
2834 : }
2835 :
2836 0 : if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
2837 0 : dlt_vlog(
2838 0 : LOG_WARNING, "Cannot send log level %.4s:%.4s -> %i\n", context->apid, context->ctid,
2839 0 : context->log_level);
2840 : }
2841 : }
2842 : }
2843 : }
2844 :
2845 0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon* daemon, int8_t trace_status, int verbose)
2846 : {
2847 : int32_t count = 0;
2848 : DltDaemonContext* context = NULL;
2849 : DltDaemonRegisteredUsers* user_list = NULL;
2850 :
2851 0 : PRINT_FUNCTION_VERBOSE(verbose);
2852 :
2853 0 : if (daemon == NULL)
2854 : return;
2855 :
2856 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2857 :
2858 0 : if (user_list == NULL)
2859 : return;
2860 :
2861 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
2862 :
2863 0 : for (count = 0; count < user_list->num_contexts; count++) {
2864 0 : context = &(user_list->contexts[count]);
2865 :
2866 0 : if (context) {
2867 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
2868 0 : context->trace_status = trace_status;
2869 :
2870 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
2871 0 : dlt_vlog(
2872 0 : LOG_WARNING, "Cannot send trace status %.4s:%.4s -> %i\n", context->apid, context->ctid,
2873 0 : context->trace_status);
2874 : }
2875 : }
2876 : }
2877 : }
2878 :
2879 0 : void dlt_daemon_user_send_all_trace_status_update_v2(DltDaemon* daemon, int8_t trace_status, int verbose)
2880 : {
2881 : int32_t count = 0;
2882 : DltDaemonContext* context = NULL;
2883 : DltDaemonRegisteredUsers* user_list = NULL;
2884 :
2885 0 : PRINT_FUNCTION_VERBOSE(verbose);
2886 :
2887 0 : if (daemon == NULL)
2888 : return;
2889 :
2890 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2891 :
2892 0 : if (user_list == NULL)
2893 : return;
2894 :
2895 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
2896 :
2897 0 : for (count = 0; count < user_list->num_contexts; count++) {
2898 0 : context = &(user_list->contexts[count]);
2899 :
2900 0 : if (context) {
2901 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
2902 0 : context->trace_status = trace_status;
2903 :
2904 0 : if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
2905 0 : dlt_vlog(
2906 0 : LOG_WARNING, "Cannot send trace status %.*s:%.*s -> %i\n", context->apid2len, context->apid2,
2907 0 : context->ctid2len, context->ctid2, context->trace_status);
2908 : }
2909 : }
2910 : }
2911 : }
2912 :
2913 1 : void dlt_daemon_user_send_all_log_state(DltDaemon* daemon, int verbose)
2914 : {
2915 : int32_t count;
2916 : DltDaemonApplication* app;
2917 : DltDaemonRegisteredUsers* user_list = NULL;
2918 :
2919 1 : PRINT_FUNCTION_VERBOSE(verbose);
2920 :
2921 1 : if (daemon == NULL) {
2922 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2923 0 : return;
2924 : }
2925 :
2926 1 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2927 :
2928 1 : if (user_list == NULL)
2929 : return;
2930 :
2931 2 : for (count = 0; count < user_list->num_applications; count++) {
2932 1 : app = &(user_list->applications[count]);
2933 :
2934 1 : if (app != NULL) {
2935 1 : if (app->user_handle >= DLT_FD_MINIMUM) {
2936 1 : if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
2937 0 : dlt_vlog(
2938 0 : LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d %s\n", app->apid, app->pid,
2939 : __func__);
2940 : }
2941 : }
2942 : }
2943 : }
2944 :
2945 0 : void dlt_daemon_user_send_all_log_state_v2(DltDaemon* daemon, int verbose)
2946 : {
2947 : int32_t count;
2948 : DltDaemonApplication* app;
2949 : DltDaemonRegisteredUsers* user_list = NULL;
2950 :
2951 0 : PRINT_FUNCTION_VERBOSE(verbose);
2952 :
2953 0 : if (daemon == NULL) {
2954 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2955 0 : return;
2956 : }
2957 :
2958 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2959 :
2960 0 : if (user_list == NULL)
2961 : return;
2962 :
2963 0 : for (count = 0; count < user_list->num_applications; count++) {
2964 0 : app = &(user_list->applications[count]);
2965 :
2966 0 : if (app != NULL) {
2967 0 : if (app->user_handle >= DLT_FD_MINIMUM) {
2968 0 : if (dlt_daemon_user_send_log_state_v2(daemon, app, verbose) == -1) {
2969 0 : dlt_vlog(
2970 0 : LOG_WARNING, "Cannot send log state to Apid: %s, PID: %d %s\n", app->apid2, app->pid, __func__);
2971 : }
2972 : }
2973 : }
2974 : }
2975 : }
2976 :
2977 2 : void dlt_daemon_change_state(DltDaemon* daemon, DltDaemonState newState)
2978 : {
2979 2 : switch (newState) {
2980 0 : case DLT_DAEMON_STATE_INIT:
2981 0 : dlt_log(LOG_INFO, "Switched to init state.\n");
2982 0 : daemon->state = DLT_DAEMON_STATE_INIT;
2983 0 : break;
2984 2 : case DLT_DAEMON_STATE_BUFFER:
2985 2 : dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
2986 2 : daemon->state = DLT_DAEMON_STATE_BUFFER;
2987 2 : break;
2988 0 : case DLT_DAEMON_STATE_BUFFER_FULL:
2989 0 : dlt_log(LOG_INFO, "Switched to buffer full state.\n");
2990 0 : daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
2991 0 : break;
2992 0 : case DLT_DAEMON_STATE_SEND_BUFFER:
2993 0 : dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
2994 0 : daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
2995 0 : break;
2996 0 : case DLT_DAEMON_STATE_SEND_DIRECT:
2997 0 : dlt_log(LOG_INFO, "Switched to send direct state.\n");
2998 0 : daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
2999 0 : break;
3000 : }
3001 2 : }
3002 :
3003 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3004 : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon* daemon)
3005 : {
3006 : if (daemon->watchdog_trigger_interval == 0) {
3007 : return false;
3008 : }
3009 :
3010 : const unsigned int uptime_seconds = dlt_uptime() / 10000;
3011 : const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
3012 : if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
3013 : return false;
3014 : }
3015 : if (sd_notify(0, "WATCHDOG=1") < 0) {
3016 : dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
3017 : return false;
3018 : } else
3019 : daemon->watchdog_last_trigger_time = uptime_seconds;
3020 :
3021 : return true;
3022 : }
3023 :
3024 : #endif
3025 :
3026 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
3027 : int dlt_daemon_user_send_trace_load_config(DltDaemon* const daemon, DltDaemonApplication* app, const int verbose)
3028 : {
3029 : DltUserHeader userheader;
3030 : DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
3031 : uint32_t trace_load_settings_count;
3032 : DltReturnValue ret;
3033 :
3034 :
3035 : PRINT_FUNCTION_VERBOSE(verbose);
3036 :
3037 : if ((daemon == NULL) || (app == NULL))
3038 : return -1;
3039 :
3040 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK)
3041 : return -1;
3042 :
3043 : DltTraceLoadSettings* app_settings = app->trace_load_settings;
3044 :
3045 : if (app_settings != NULL) {
3046 : trace_load_settings_count = app->trace_load_settings_count;
3047 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
3048 : for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
3049 : // App id is not transmitted as the user library only
3050 : // has one application ID
3051 : memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
3052 : trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
3053 : trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
3054 :
3055 : if (app_settings[i].ctid[0] == '\0') {
3056 : dlt_vlog(
3057 : LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n", app->apid,
3058 : app_settings[i].soft_limit, app_settings[i].hard_limit);
3059 : } else {
3060 : dlt_vlog(
3061 : LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
3062 : app->apid, app_settings[i].ctid, app_settings[i].soft_limit, app_settings[i].hard_limit);
3063 : }
3064 : }
3065 : } else {
3066 : dlt_vlog(LOG_INFO, "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
3067 :
3068 : trace_load_settings_count = 1;
3069 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
3070 :
3071 : memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
3072 : trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
3073 : trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
3074 : }
3075 :
3076 : /* log to FIFO */
3077 : ret = dlt_user_log_out3_with_timeout(
3078 : app->user_handle, &(userheader), sizeof(DltUserHeader), &(trace_load_settings_count), sizeof(uint32_t),
3079 : trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
3080 :
3081 : if (ret < DLT_RETURN_OK) {
3082 : if (errno == EPIPE || errno == EBADF)
3083 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
3084 : }
3085 :
3086 : free(trace_load_settings_user_msg);
3087 :
3088 : return ret;
3089 : }
3090 : #endif
|