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