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 31 : 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 31 : 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 164 : static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
125 : {
126 164 : 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 164 : cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
134 :
135 164 : if (cmp < 0)
136 : ret = -1;
137 164 : else if (cmp == 0)
138 164 : 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 118 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon,
178 : char *ecu,
179 : int verbose)
180 : {
181 118 : PRINT_FUNCTION_VERBOSE(verbose);
182 :
183 : int i = 0;
184 :
185 118 : if ((daemon == NULL) || (ecu == NULL)) {
186 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
187 0 : return (DltDaemonRegisteredUsers *)NULL;
188 : }
189 :
190 118 : for (i = 0; i < daemon->num_user_lists; i++)
191 106 : if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
192 106 : 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 5 : 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 5 : PRINT_FUNCTION_VERBOSE(verbose);
630 :
631 5 : if ((daemon == NULL) || (ecu == NULL))
632 : return DLT_RETURN_ERROR;
633 :
634 5 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
635 :
636 5 : if (user_list != NULL) {
637 10 : for (i = 0; i < user_list->num_applications; i++)
638 5 : 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 2 : for (i = 0; i < user_list->num_applications; i++)
689 1 : 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 1 : free(user_list->applications[i].application_description);
703 1 : user_list->applications[i].application_description = NULL;
704 : }
705 :
706 1 : if (user_list->applications != NULL)
707 1 : 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 3 : 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 3 : 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 4 : 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 4 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
833 : return (DltDaemonApplication *)NULL;
834 :
835 4 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
836 :
837 4 : if (user_list == NULL)
838 : return (DltDaemonApplication *)NULL;
839 :
840 4 : if (user_list->applications == NULL) {
841 4 : user_list->applications = (DltDaemonApplication *)
842 4 : malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
843 :
844 4 : 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 4 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
852 :
853 4 : if (application == NULL) {
854 4 : user_list->num_applications += 1;
855 :
856 4 : if (user_list->num_applications != 0) {
857 4 : 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 4 : application = &(user_list->applications[(size_t)(user_list->num_applications - 1)]);
879 :
880 4 : dlt_set_id(application->apid, apid);
881 4 : application->pid = 0;
882 4 : application->application_description = NULL;
883 4 : application->num_contexts = 0;
884 4 : application->user_handle = DLT_FD_INIT;
885 4 : 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 4 : if (application->application_description) {
906 0 : free(application->application_description);
907 0 : application->application_description = NULL;
908 : }
909 :
910 4 : if (description != NULL) {
911 4 : application->application_description = malloc(strlen(description) + 1);
912 :
913 4 : if (application->application_description) {
914 4 : 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 4 : if (application->pid != pid) {
923 3 : dlt_daemon_application_reset_user_handle(daemon, application, verbose);
924 3 : application->pid = 0;
925 : }
926 :
927 : /* open user pipe only if it is not yet opened */
928 4 : 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 3 : 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 3 : 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 3 : dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
962 3 : dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
963 :
964 3 : application->user_handle = dlt_user_handle;
965 3 : application->owns_user_handle = owns_user_handle;
966 3 : application->pid = pid;
967 : }
968 :
969 : /* Sort */
970 4 : if (new_application) {
971 4 : qsort(user_list->applications,
972 4 : (size_t) user_list->num_applications,
973 : sizeof(DltDaemonApplication),
974 : dlt_daemon_cmp_apid);
975 :
976 : /* Find new position of application with apid*/
977 4 : 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 36 : 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 36 : PRINT_FUNCTION_VERBOSE(verbose);
1392 :
1393 36 : if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
1394 36 : (apid[0] == '\0') || (ecu == NULL))
1395 : return (DltDaemonApplication *)NULL;
1396 :
1397 36 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1398 :
1399 36 : 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 31 : if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
1404 31 : (memcmp(apid,
1405 31 : user_list->applications[user_list->num_applications - 1].apid,
1406 : DLT_ID_SIZE) > 0))
1407 : return (DltDaemonApplication *)NULL;
1408 :
1409 31 : dlt_set_id(application.apid, apid);
1410 31 : return (DltDaemonApplication *)bsearch(&application,
1411 31 : user_list->applications,
1412 31 : (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 15 : 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 15 : PRINT_FUNCTION_VERBOSE(verbose);
1664 :
1665 15 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
1666 15 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
1667 : return (DltDaemonContext *)NULL;
1668 :
1669 15 : if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
1670 : return (DltDaemonContext *)NULL;
1671 :
1672 15 : if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
1673 : return (DltDaemonContext *)NULL;
1674 :
1675 15 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
1676 :
1677 15 : if (user_list == NULL)
1678 : return (DltDaemonContext *)NULL;
1679 :
1680 15 : if (user_list->contexts == NULL) {
1681 4 : user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
1682 :
1683 4 : if (user_list->contexts == NULL)
1684 : return (DltDaemonContext *)NULL;
1685 : }
1686 :
1687 : /* Check if application [apid] is available */
1688 15 : application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
1689 :
1690 15 : if (application == NULL)
1691 : return (DltDaemonContext *)NULL;
1692 :
1693 : /* Check if context [apid, ctid] is already available */
1694 15 : context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
1695 :
1696 15 : if (context == NULL) {
1697 15 : user_list->num_contexts += 1;
1698 :
1699 15 : if (user_list->num_contexts != 0) {
1700 15 : 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 15 : context = &(user_list->contexts[(size_t)(user_list->num_contexts - 1)]);
1722 : memset(context, 0, sizeof(DltDaemonContext));
1723 :
1724 15 : dlt_set_id(context->apid, apid);
1725 15 : dlt_set_id(context->ctid, ctid);
1726 :
1727 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
1728 : context->trace_load_settings = NULL;
1729 : #endif
1730 :
1731 15 : application->num_contexts++;
1732 : new_context = 1;
1733 : }
1734 :
1735 : /* Set context description */
1736 15 : if (context->context_description) {
1737 0 : free(context->context_description);
1738 0 : context->context_description = NULL;
1739 : }
1740 :
1741 15 : if (description != NULL) {
1742 15 : context->context_description = malloc(strlen(description) + 1);
1743 :
1744 15 : if (context->context_description) {
1745 15 : 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 15 : 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 15 : if ((new_context == 1) ||
1802 0 : ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
1803 15 : context->log_level = log_level;
1804 15 : context->trace_status = trace_status;
1805 : }
1806 :
1807 15 : context->log_level_pos = log_level_pos;
1808 15 : 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 15 : if (context->user_handle == 0)
1814 0 : context->predefined = true;
1815 : else
1816 15 : context->predefined = false;
1817 :
1818 : /* Sort */
1819 15 : if (new_context) {
1820 15 : qsort(user_list->contexts,
1821 15 : (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 15 : 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 = NULL;
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 47 : 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 47 : PRINT_FUNCTION_VERBOSE(verbose);
2182 :
2183 47 : if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
2184 47 : (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
2185 : return (DltDaemonContext *)NULL;
2186 :
2187 47 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
2188 :
2189 47 : 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 29 : if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
2194 29 : (memcmp(apid,
2195 29 : user_list->contexts[user_list->num_contexts - 1].apid,
2196 : DLT_ID_SIZE) > 0))
2197 : return (DltDaemonContext *)NULL;
2198 :
2199 29 : dlt_set_id(context.apid, apid);
2200 29 : dlt_set_id(context.ctid, ctid);
2201 :
2202 29 : return (DltDaemonContext *)bsearch(&context,
2203 29 : user_list->contexts,
2204 29 : (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 5 : 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 5 : PRINT_FUNCTION_VERBOSE(verbose);
2267 :
2268 5 : if ((daemon == NULL) || (ecu == NULL))
2269 : return -1;
2270 :
2271 5 : user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
2272 :
2273 5 : if (user_list != NULL) {
2274 29 : for (i = 0; i < user_list->num_contexts; i++)
2275 24 : 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 13 : for (i = 0; i < users->num_contexts; i++) {
2326 12 : if (users->contexts[i].context_description != NULL) {
2327 12 : free(users->contexts[i].context_description);
2328 12 : users->contexts[i].context_description = NULL;
2329 : }
2330 12 : if (users->contexts[i].apid2 != NULL) {
2331 0 : free(users->contexts[i].apid2);
2332 0 : users->contexts[i].apid2 = NULL;
2333 : }
2334 12 : if (users->contexts[i].ctid2 != NULL) {
2335 0 : free(users->contexts[i].ctid2);
2336 0 : users->contexts[i].ctid2 = NULL;
2337 : }
2338 : }
2339 :
2340 1 : if (users->contexts) {
2341 1 : free(users->contexts);
2342 1 : users->contexts = NULL;
2343 : }
2344 :
2345 2 : for (i = 0; i < users->num_applications; i++)
2346 1 : users->applications[i].num_contexts = 0;
2347 :
2348 1 : users->num_contexts = 0;
2349 :
2350 1 : return 0;
2351 : }
2352 :
2353 0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
2354 : {
2355 : FILE *fd;
2356 : ID4 apid, ctid;
2357 : char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
2358 : char *ret;
2359 : char *pb;
2360 : int ll, ts;
2361 :
2362 0 : PRINT_FUNCTION_VERBOSE(verbose);
2363 :
2364 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2365 : return -1;
2366 :
2367 0 : fd = fopen(filename, "r");
2368 :
2369 0 : if (fd == NULL) {
2370 0 : dlt_vlog(LOG_WARNING,
2371 : "DLT runtime-context load, cannot open file %s: %s\n",
2372 : filename,
2373 0 : strerror(errno));
2374 :
2375 0 : return -1;
2376 : }
2377 :
2378 0 : while (!feof(fd)) {
2379 : /* Clear buf */
2380 : memset(buf, 0, sizeof(buf));
2381 :
2382 : /* Get line */
2383 : ret = fgets(buf, sizeof(buf), fd);
2384 :
2385 0 : if (NULL == ret) {
2386 : /* fgets always returns null pointer if the last byte of the file is a new line.
2387 : * We need to check here if there was an error or was it feof.*/
2388 0 : if (ferror(fd)) {
2389 0 : dlt_vlog(LOG_WARNING,
2390 : "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
2391 : __func__,
2392 0 : strerror(errno));
2393 0 : fclose(fd);
2394 0 : return -1;
2395 : }
2396 0 : else if (feof(fd))
2397 : {
2398 0 : fclose(fd);
2399 0 : return 0;
2400 : }
2401 : else {
2402 0 : dlt_vlog(LOG_WARNING,
2403 : "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
2404 : __func__);
2405 0 : fclose(fd);
2406 0 : return -1;
2407 : }
2408 : }
2409 :
2410 0 : if (strcmp(buf, "") != 0) {
2411 : /* Split line */
2412 0 : pb = strtok(buf, ":");
2413 :
2414 0 : if (pb != NULL) {
2415 0 : dlt_set_id(apid, pb);
2416 0 : pb = strtok(NULL, ":");
2417 :
2418 0 : if (pb != NULL) {
2419 0 : dlt_set_id(ctid, pb);
2420 0 : pb = strtok(NULL, ":");
2421 :
2422 0 : if (pb != NULL) {
2423 0 : sscanf(pb, "%d", &ll);
2424 0 : pb = strtok(NULL, ":");
2425 :
2426 0 : if (pb != NULL) {
2427 0 : sscanf(pb, "%d", &ts);
2428 0 : pb = strtok(NULL, ":");
2429 :
2430 0 : if (pb != NULL) {
2431 : /* pb contains now the description */
2432 :
2433 : /* log_level_pos, and user_handle are unknown at loading time */
2434 0 : if (dlt_daemon_context_add(daemon,
2435 : apid,
2436 : ctid,
2437 0 : (int8_t)ll,
2438 0 : (int8_t)ts,
2439 : 0,
2440 : 0,
2441 : pb,
2442 0 : daemon->ecuid,
2443 : verbose) == NULL) {
2444 0 : dlt_vlog(LOG_WARNING,
2445 : "%s dlt_daemon_context_add failed\n",
2446 : __func__);
2447 0 : fclose(fd);
2448 0 : return -1;
2449 : }
2450 : }
2451 : }
2452 : }
2453 : }
2454 : }
2455 : }
2456 : }
2457 :
2458 0 : fclose(fd);
2459 :
2460 0 : return 0;
2461 : }
2462 :
2463 0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
2464 : {
2465 : FILE *fd;
2466 : int i;
2467 :
2468 : char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
2469 : DltDaemonRegisteredUsers *user_list = NULL;
2470 :
2471 0 : PRINT_FUNCTION_VERBOSE(verbose);
2472 :
2473 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2474 : return -1;
2475 :
2476 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2477 :
2478 0 : if (user_list == NULL)
2479 : return -1;
2480 :
2481 : memset(apid, 0, sizeof(apid));
2482 : memset(ctid, 0, sizeof(ctid));
2483 :
2484 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
2485 0 : fd = fopen(filename, "w");
2486 :
2487 0 : if (fd != NULL) {
2488 0 : for (i = 0; i < user_list->num_contexts; i++) {
2489 0 : dlt_set_id(apid, user_list->contexts[i].apid);
2490 0 : dlt_set_id(ctid, user_list->contexts[i].ctid);
2491 :
2492 0 : if ((user_list->contexts[i].context_description) &&
2493 0 : (user_list->contexts[i].context_description[0] != '\0'))
2494 0 : fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
2495 0 : (int)(user_list->contexts[i].log_level),
2496 0 : (int)(user_list->contexts[i].trace_status),
2497 : user_list->contexts[i].context_description);
2498 : else
2499 0 : fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
2500 0 : (int)(user_list->contexts[i].log_level),
2501 0 : (int)(user_list->contexts[i].trace_status));
2502 : }
2503 :
2504 0 : fclose(fd);
2505 : }
2506 : else {
2507 0 : dlt_vlog(LOG_ERR,
2508 : "%s: Cannot open %s. No context information stored\n",
2509 : __func__,
2510 : filename);
2511 : }
2512 : }
2513 :
2514 : return 0;
2515 : }
2516 :
2517 0 : int dlt_daemon_contexts_save_v2(DltDaemon *daemon, const char *filename, int verbose)
2518 : {
2519 : FILE *fd;
2520 : int i;
2521 :
2522 : char apid[DLT_V2_ID_SIZE];
2523 : char ctid[DLT_V2_ID_SIZE];
2524 : DltDaemonRegisteredUsers *user_list = NULL;
2525 :
2526 0 : PRINT_FUNCTION_VERBOSE(verbose);
2527 :
2528 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2529 : return -1;
2530 :
2531 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2532 :
2533 0 : if (user_list == NULL)
2534 : return -1;
2535 :
2536 0 : if ((user_list->contexts) && (user_list->num_contexts > 0)) {
2537 0 : fd = fopen(filename, "w");
2538 :
2539 0 : if (fd != NULL) {
2540 0 : for (i = 0; i < user_list->num_contexts; i++) {
2541 0 : dlt_set_id_v2(apid, user_list->contexts[i].apid2, user_list->contexts[i].apid2len);
2542 0 : dlt_set_id_v2(ctid, user_list->contexts[i].ctid2, user_list->contexts[i].ctid2len);
2543 :
2544 0 : if ((user_list->contexts[i].context_description) &&
2545 0 : (user_list->contexts[i].context_description[0] != '\0'))
2546 0 : fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
2547 0 : (int)(user_list->contexts[i].log_level),
2548 0 : (int)(user_list->contexts[i].trace_status),
2549 : user_list->contexts[i].context_description);
2550 : else
2551 0 : fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
2552 0 : (int)(user_list->contexts[i].log_level),
2553 0 : (int)(user_list->contexts[i].trace_status));
2554 : }
2555 :
2556 0 : fclose(fd);
2557 : }
2558 : else {
2559 0 : dlt_vlog(LOG_ERR,
2560 : "%s: Cannot open %s. No context information stored\n",
2561 : __func__,
2562 : filename);
2563 : }
2564 : }
2565 :
2566 : return 0;
2567 : }
2568 :
2569 0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
2570 : {
2571 : FILE *fd;
2572 :
2573 0 : PRINT_FUNCTION_VERBOSE(verbose);
2574 :
2575 0 : if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
2576 : return -1;
2577 :
2578 0 : fd = fopen(filename, "w");
2579 :
2580 0 : if (fd != NULL) {
2581 : fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
2582 0 : fprintf(fd, "LoggingMode = %d\n", daemon->mode);
2583 :
2584 0 : fclose(fd);
2585 : }
2586 :
2587 : return 0;
2588 : }
2589 :
2590 1 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
2591 : {
2592 1 : if ((daemon == NULL) || (filename == NULL))
2593 : return -1;
2594 :
2595 : FILE *pFile;
2596 : char line[1024];
2597 : char token[1024];
2598 : char value[1024];
2599 : char *pch;
2600 :
2601 1 : PRINT_FUNCTION_VERBOSE(verbose);
2602 :
2603 1 : pFile = fopen (filename, "r");
2604 :
2605 1 : if (pFile != NULL) {
2606 : while (1) {
2607 : /* fetch line from configuration file */
2608 2 : if (fgets (line, 1024, pFile) != NULL) {
2609 1 : pch = strtok (line, " =\r\n");
2610 1 : token[0] = 0;
2611 1 : value[0] = 0;
2612 :
2613 2 : while (pch != NULL) {
2614 1 : if (strcmp(pch, "#") == 0)
2615 : break;
2616 :
2617 1 : if (token[0] == 0) {
2618 : strncpy(token, pch, sizeof(token) - 1);
2619 1 : token[sizeof(token) - 1] = 0;
2620 : }
2621 : else {
2622 : strncpy(value, pch, sizeof(value) - 1);
2623 0 : value[sizeof(value) - 1] = 0;
2624 0 : break;
2625 : }
2626 :
2627 1 : pch = strtok (NULL, " =\r\n");
2628 : }
2629 :
2630 1 : if (token[0] && value[0]) {
2631 : /* parse arguments here */
2632 0 : if (strcmp(token, "LoggingMode") == 0) {
2633 0 : daemon->mode = atoi(value);
2634 0 : dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
2635 : daemon->mode);
2636 : }
2637 : else {
2638 0 : dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
2639 : value);
2640 : }
2641 : }
2642 : }
2643 : else {
2644 : break;
2645 : }
2646 : }
2647 :
2648 1 : fclose (pFile);
2649 : }
2650 : else {
2651 0 : dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
2652 : }
2653 :
2654 : return 0;
2655 : }
2656 :
2657 15 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
2658 : {
2659 : DltUserHeader userheader;
2660 : DltUserControlMsgLogLevel usercontext;
2661 : DltReturnValue ret;
2662 : DltDaemonApplication *app;
2663 :
2664 15 : PRINT_FUNCTION_VERBOSE(verbose);
2665 :
2666 15 : if ((daemon == NULL) || (context == NULL)) {
2667 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
2668 0 : return -1;
2669 : }
2670 :
2671 15 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
2672 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
2673 0 : return -1;
2674 : }
2675 :
2676 15 : if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
2677 14 : (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
2678 12 : usercontext.log_level = (uint8_t) (context->log_level >
2679 : context->storage_log_level ? context->log_level : context->storage_log_level);
2680 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
2681 3 : usercontext.log_level =
2682 3 : (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
2683 :
2684 15 : usercontext.trace_status =
2685 15 : (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
2686 :
2687 15 : usercontext.log_level_pos = context->log_level_pos;
2688 :
2689 15 : dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
2690 15 : context->apid,
2691 15 : context->ctid,
2692 15 : context->log_level,
2693 15 : usercontext.log_level,
2694 : context->trace_status,
2695 : usercontext.trace_status);
2696 :
2697 : /* log to FIFO */
2698 15 : errno = 0;
2699 15 : ret = dlt_user_log_out2_with_timeout(context->user_handle,
2700 : &(userheader), sizeof(DltUserHeader),
2701 : &(usercontext), sizeof(DltUserControlMsgLogLevel));
2702 :
2703 15 : if (ret < DLT_RETURN_OK) {
2704 0 : dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
2705 : __func__,
2706 0 : errno != 0 ? strerror(errno) : "Unknown error");
2707 :
2708 0 : if (errno == EPIPE || errno == EBADF) {
2709 0 : app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
2710 0 : if (app != NULL)
2711 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2712 : }
2713 : }
2714 :
2715 15 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2716 : }
2717 :
2718 0 : int dlt_daemon_user_send_log_level_v2(DltDaemon *daemon, DltDaemonContext *context, int verbose)
2719 : {
2720 : DltUserHeader userheader;
2721 : DltUserControlMsgLogLevel usercontext;
2722 : DltReturnValue ret;
2723 0 : DltDaemonApplication *app = NULL;
2724 :
2725 0 : PRINT_FUNCTION_VERBOSE(verbose);
2726 :
2727 0 : if ((daemon == NULL) || (context == NULL)) {
2728 0 : dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
2729 0 : return -1;
2730 : }
2731 :
2732 0 : if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
2733 0 : dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
2734 0 : return -1;
2735 : }
2736 :
2737 0 : if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
2738 0 : (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
2739 0 : usercontext.log_level = (uint8_t) (context->log_level >
2740 : context->storage_log_level ? context->log_level : context->storage_log_level);
2741 : else /* Storage log level is not updated (is DEFAULT) then no device is yet connected so ignore */
2742 0 : usercontext.log_level =
2743 0 : (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
2744 :
2745 0 : usercontext.trace_status =
2746 0 : (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
2747 :
2748 0 : usercontext.log_level_pos = context->log_level_pos;
2749 :
2750 0 : dlt_vlog(LOG_NOTICE, "Send log-level to context: %s:%s [%i -> %i] [%i -> %i]\n",
2751 : context->apid2,
2752 : context->ctid2,
2753 0 : context->log_level,
2754 0 : usercontext.log_level,
2755 : context->trace_status,
2756 : usercontext.trace_status);
2757 :
2758 : /* log to FIFO */
2759 0 : errno = 0;
2760 0 : ret = dlt_user_log_out2_with_timeout(context->user_handle,
2761 : &(userheader), sizeof(DltUserHeader),
2762 : &(usercontext), sizeof(DltUserControlMsgLogLevel));
2763 :
2764 0 : if (ret < DLT_RETURN_OK) {
2765 0 : dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
2766 : __func__,
2767 0 : errno != 0 ? strerror(errno) : "Unknown error");
2768 :
2769 0 : if (errno == EPIPE || errno == EBADF) {
2770 0 : dlt_daemon_application_find_v2(daemon, context->apid2len, context->apid2,
2771 0 : daemon->ecuid2len, daemon->ecuid2, verbose, &app);
2772 0 : if (app != NULL)
2773 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2774 : }
2775 : }
2776 0 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2777 : }
2778 :
2779 2 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
2780 : {
2781 : DltUserHeader userheader;
2782 : DltUserControlMsgLogState logstate;
2783 : DltReturnValue ret;
2784 :
2785 2 : PRINT_FUNCTION_VERBOSE(verbose);
2786 :
2787 2 : if ((daemon == NULL) || (app == NULL))
2788 : return -1;
2789 :
2790 2 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
2791 : return -1;
2792 :
2793 2 : logstate.log_state = (int8_t)daemon->connectionState;
2794 :
2795 : /* log to FIFO */
2796 2 : ret = dlt_user_log_out2_with_timeout(app->user_handle,
2797 : &(userheader), sizeof(DltUserHeader),
2798 : &(logstate), sizeof(DltUserControlMsgLogState));
2799 :
2800 2 : if (ret < DLT_RETURN_OK) {
2801 0 : if (errno == EPIPE || errno == EBADF)
2802 0 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
2803 : }
2804 :
2805 2 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2806 : }
2807 :
2808 0 : int dlt_daemon_user_send_log_state_v2(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
2809 : {
2810 : DltUserHeader userheader;
2811 : DltUserControlMsgLogState logstate;
2812 : DltReturnValue ret;
2813 :
2814 0 : PRINT_FUNCTION_VERBOSE(verbose);
2815 :
2816 0 : if ((daemon == NULL) || (app == NULL))
2817 : return -1;
2818 :
2819 0 : if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
2820 : return -1;
2821 :
2822 0 : logstate.log_state = (int8_t)daemon->connectionState;
2823 :
2824 : /* log to FIFO */
2825 0 : ret = dlt_user_log_out2_with_timeout(app->user_handle,
2826 : &(userheader), sizeof(DltUserHeader),
2827 : &(logstate.log_state), sizeof(int8_t));
2828 :
2829 0 : if (ret < DLT_RETURN_OK) {
2830 0 : if (errno == EPIPE || errno == EBADF)
2831 0 : dlt_daemon_application_reset_user_handle_v2(daemon, app, verbose);
2832 : }
2833 :
2834 0 : return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
2835 : }
2836 :
2837 0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
2838 : const char *filename,
2839 : const char *filename1,
2840 : int InitialContextLogLevel,
2841 : int InitialContextTraceStatus,
2842 : int InitialEnforceLlTsStatus,
2843 : int verbose)
2844 : {
2845 : FILE *fd;
2846 :
2847 0 : PRINT_FUNCTION_VERBOSE(verbose);
2848 :
2849 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
2850 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2851 0 : return;
2852 : }
2853 :
2854 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
2855 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
2856 0 : return;
2857 : }
2858 :
2859 : /* Check for runtime cfg file and delete it, if available */
2860 0 : fd = fopen(filename, "r");
2861 :
2862 0 : if (fd != NULL) {
2863 : /* Close and delete file */
2864 0 : fclose(fd);
2865 0 : if (unlink(filename) != 0) {
2866 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
2867 0 : __func__, strerror(errno));
2868 : }
2869 : }
2870 :
2871 0 : fd = fopen(filename1, "r");
2872 :
2873 0 : if (fd != NULL) {
2874 : /* Close and delete file */
2875 0 : fclose(fd);
2876 0 : if (unlink(filename1) != 0) {
2877 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
2878 0 : __func__, strerror(errno));
2879 : }
2880 : }
2881 :
2882 0 : daemon->default_log_level = (int8_t) InitialContextLogLevel;
2883 0 : daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
2884 0 : daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
2885 :
2886 : /* Reset all other things (log level, trace status, etc.
2887 : * to default values */
2888 :
2889 : /* Inform user libraries about changed default log level/trace status */
2890 0 : dlt_daemon_user_send_default_update(daemon, verbose);
2891 : }
2892 :
2893 0 : void dlt_daemon_control_reset_to_factory_default_v2(DltDaemon *daemon,
2894 : const char *filename,
2895 : const char *filename1,
2896 : int InitialContextLogLevel,
2897 : int InitialContextTraceStatus,
2898 : int InitialEnforceLlTsStatus,
2899 : int verbose)
2900 : {
2901 : FILE *fd;
2902 :
2903 0 : PRINT_FUNCTION_VERBOSE(verbose);
2904 :
2905 0 : if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
2906 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2907 0 : return;
2908 : }
2909 :
2910 0 : if ((filename[0] == '\0') || (filename1[0] == '\0')) {
2911 0 : dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
2912 0 : return;
2913 : }
2914 :
2915 : /* Check for runtime cfg file and delete it, if available */
2916 0 : fd = fopen(filename, "r");
2917 :
2918 0 : if (fd != NULL) {
2919 : /* Close and delete file */
2920 0 : fclose(fd);
2921 0 : if (unlink(filename) != 0) {
2922 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
2923 0 : __func__, strerror(errno));
2924 : }
2925 : }
2926 :
2927 0 : fd = fopen(filename1, "r");
2928 :
2929 0 : if (fd != NULL) {
2930 : /* Close and delete file */
2931 0 : fclose(fd);
2932 0 : if (unlink(filename1) != 0) {
2933 0 : dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
2934 0 : __func__, strerror(errno));
2935 : }
2936 : }
2937 :
2938 0 : daemon->default_log_level = (int8_t) InitialContextLogLevel;
2939 0 : daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
2940 0 : daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
2941 :
2942 : /* Reset all other things (log level, trace status, etc.
2943 : * to default values */
2944 :
2945 : /* Inform user libraries about changed default log level/trace status */
2946 0 : dlt_daemon_user_send_default_update_v2(daemon, verbose);
2947 : }
2948 :
2949 0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
2950 : {
2951 : int32_t count;
2952 : DltDaemonContext *context;
2953 : DltDaemonRegisteredUsers *user_list = NULL;
2954 :
2955 0 : PRINT_FUNCTION_VERBOSE(verbose);
2956 :
2957 0 : if (daemon == NULL) {
2958 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2959 0 : return;
2960 : }
2961 :
2962 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
2963 :
2964 0 : if (user_list == NULL)
2965 : return;
2966 :
2967 0 : for (count = 0; count < user_list->num_contexts; count++) {
2968 0 : context = &(user_list->contexts[count]);
2969 :
2970 0 : if (context != NULL) {
2971 0 : if ((context->log_level == DLT_LOG_DEFAULT) ||
2972 0 : (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
2973 0 : if (context->user_handle >= DLT_FD_MINIMUM)
2974 0 : if (dlt_daemon_user_send_log_level(daemon,
2975 : context,
2976 : verbose) == -1)
2977 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
2978 : }
2979 : }
2980 : }
2981 : }
2982 :
2983 0 : void dlt_daemon_user_send_default_update_v2(DltDaemon *daemon, int verbose)
2984 : {
2985 : int32_t count;
2986 : DltDaemonContext *context;
2987 : DltDaemonRegisteredUsers *user_list = NULL;
2988 :
2989 0 : PRINT_FUNCTION_VERBOSE(verbose);
2990 :
2991 0 : if (daemon == NULL) {
2992 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
2993 0 : return;
2994 : }
2995 :
2996 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
2997 :
2998 0 : if (user_list == NULL)
2999 : return;
3000 :
3001 0 : for (count = 0; count < user_list->num_contexts; count++) {
3002 0 : context = &(user_list->contexts[count]);
3003 :
3004 0 : if (context != NULL) {
3005 0 : if ((context->log_level == DLT_LOG_DEFAULT) ||
3006 0 : (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
3007 0 : if (context->user_handle >= DLT_FD_MINIMUM)
3008 0 : if (dlt_daemon_user_send_log_level_v2(daemon,
3009 : context,
3010 : verbose) == -1)
3011 0 : dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
3012 : }
3013 : }
3014 : }
3015 : }
3016 :
3017 0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
3018 : int enforce_context_ll_and_ts,
3019 : int8_t context_log_level,
3020 : int8_t log_level,
3021 : int verbose)
3022 : {
3023 : int32_t count = 0;
3024 : DltDaemonContext *context = NULL;
3025 : DltDaemonRegisteredUsers *user_list = NULL;
3026 :
3027 0 : PRINT_FUNCTION_VERBOSE(verbose);
3028 :
3029 0 : if (daemon == NULL)
3030 : return;
3031 :
3032 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
3033 :
3034 0 : if (user_list == NULL)
3035 : return;
3036 :
3037 0 : for (count = 0; count < user_list->num_contexts; count++) {
3038 0 : context = &(user_list->contexts[count]);
3039 :
3040 0 : if (context) {
3041 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
3042 0 : context->log_level = log_level;
3043 :
3044 0 : if (enforce_context_ll_and_ts) {
3045 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
3046 : DltDaemonContextLogSettings *settings =
3047 : dlt_daemon_find_configured_app_id_ctx_id_settings(
3048 : daemon, context->apid, context->ctid);
3049 : if (settings != NULL) {
3050 : if (log_level > settings->log_level) {
3051 : context->log_level = settings->log_level;
3052 : }
3053 : } else
3054 : #endif
3055 0 : if (log_level > context_log_level) {
3056 0 : context->log_level = (int8_t)context_log_level;
3057 : }
3058 : }
3059 :
3060 0 : if (dlt_daemon_user_send_log_level(daemon,
3061 : context,
3062 : verbose) == -1)
3063 0 : dlt_vlog(LOG_WARNING,
3064 : "Cannot send log level %.4s:%.4s -> %i\n",
3065 0 : context->apid,
3066 0 : context->ctid,
3067 0 : context->log_level);
3068 : }
3069 : }
3070 : }
3071 : }
3072 :
3073 0 : void dlt_daemon_user_send_all_log_level_update_v2(DltDaemon *daemon,
3074 : int enforce_context_ll_and_ts,
3075 : int8_t context_log_level,
3076 : int8_t log_level,
3077 : int verbose)
3078 : {
3079 : int32_t count = 0;
3080 : DltDaemonContext *context = NULL;
3081 : DltDaemonRegisteredUsers *user_list = NULL;
3082 :
3083 0 : PRINT_FUNCTION_VERBOSE(verbose);
3084 :
3085 0 : if (daemon == NULL)
3086 : return;
3087 :
3088 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
3089 :
3090 0 : if (user_list == NULL)
3091 : return;
3092 :
3093 0 : for (count = 0; count < user_list->num_contexts; count++) {
3094 0 : context = &(user_list->contexts[count]);
3095 :
3096 0 : if (context) {
3097 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
3098 0 : context->log_level = log_level;
3099 :
3100 0 : if (enforce_context_ll_and_ts) {
3101 : #ifdef DLT_LOG_LEVEL_APP_CONFIG
3102 : //TBD: Check if function params require apid/ctid lengths
3103 : DltDaemonContextLogSettingsV2 *settings =
3104 : dlt_daemon_find_configured_app_id_ctx_id_settings_v2(
3105 : daemon, context->apid, context->ctid);
3106 : if (settings != NULL) {
3107 : if (log_level > settings->log_level) {
3108 : context->log_level = settings->log_level;
3109 : }
3110 : } else
3111 : #endif
3112 0 : if (log_level > context_log_level) {
3113 0 : context->log_level = (int8_t)context_log_level;
3114 : }
3115 : }
3116 :
3117 0 : if (dlt_daemon_user_send_log_level_v2(daemon,
3118 : context,
3119 : verbose) == -1)
3120 0 : dlt_vlog(LOG_WARNING,
3121 : "Cannot send log level %.4s:%.4s -> %i\n",
3122 0 : context->apid,
3123 0 : context->ctid,
3124 0 : context->log_level);
3125 : }
3126 : }
3127 : }
3128 : }
3129 :
3130 0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
3131 : {
3132 : int32_t count = 0;
3133 : DltDaemonContext *context = NULL;
3134 : DltDaemonRegisteredUsers *user_list = NULL;
3135 :
3136 0 : PRINT_FUNCTION_VERBOSE(verbose);
3137 :
3138 0 : if (daemon == NULL)
3139 : return;
3140 :
3141 0 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
3142 :
3143 0 : if (user_list == NULL)
3144 : return;
3145 :
3146 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
3147 :
3148 0 : for (count = 0; count < user_list->num_contexts; count++) {
3149 0 : context = &(user_list->contexts[count]);
3150 :
3151 0 : if (context) {
3152 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
3153 0 : context->trace_status = trace_status;
3154 :
3155 0 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
3156 0 : dlt_vlog(LOG_WARNING,
3157 : "Cannot send trace status %.4s:%.4s -> %i\n",
3158 0 : context->apid,
3159 0 : context->ctid,
3160 0 : context->trace_status);
3161 : }
3162 : }
3163 : }
3164 : }
3165 :
3166 0 : void dlt_daemon_user_send_all_trace_status_update_v2(DltDaemon *daemon, int8_t trace_status, int verbose)
3167 : {
3168 : int32_t count = 0;
3169 : DltDaemonContext *context = NULL;
3170 : DltDaemonRegisteredUsers *user_list = NULL;
3171 :
3172 0 : PRINT_FUNCTION_VERBOSE(verbose);
3173 :
3174 0 : if (daemon == NULL)
3175 : return;
3176 :
3177 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
3178 :
3179 0 : if (user_list == NULL)
3180 : return;
3181 :
3182 0 : dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
3183 :
3184 0 : for (count = 0; count < user_list->num_contexts; count++) {
3185 0 : context = &(user_list->contexts[count]);
3186 :
3187 0 : if (context) {
3188 0 : if (context->user_handle >= DLT_FD_MINIMUM) {
3189 0 : context->trace_status = trace_status;
3190 :
3191 0 : if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
3192 0 : dlt_vlog(LOG_WARNING,
3193 : "Cannot send trace status %.*s:%.*s -> %i\n",
3194 0 : context->apid2len,
3195 : context->apid2,
3196 0 : context->ctid2len,
3197 : context->ctid2,
3198 0 : context->trace_status);
3199 : }
3200 : }
3201 : }
3202 : }
3203 :
3204 1 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
3205 : {
3206 : int32_t count;
3207 : DltDaemonApplication *app;
3208 : DltDaemonRegisteredUsers *user_list = NULL;
3209 :
3210 1 : PRINT_FUNCTION_VERBOSE(verbose);
3211 :
3212 1 : if (daemon == NULL) {
3213 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
3214 0 : return;
3215 : }
3216 :
3217 1 : user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
3218 :
3219 1 : if (user_list == NULL)
3220 : return;
3221 :
3222 2 : for (count = 0; count < user_list->num_applications; count++) {
3223 1 : app = &(user_list->applications[count]);
3224 :
3225 1 : if (app != NULL) {
3226 1 : if (app->user_handle >= DLT_FD_MINIMUM) {
3227 1 : if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
3228 0 : dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d %s\n", app->apid, app->pid, __func__);
3229 : }
3230 : }
3231 : }
3232 : }
3233 :
3234 0 : void dlt_daemon_user_send_all_log_state_v2(DltDaemon *daemon, int verbose)
3235 : {
3236 : int32_t count;
3237 : DltDaemonApplication *app;
3238 : DltDaemonRegisteredUsers *user_list = NULL;
3239 :
3240 0 : PRINT_FUNCTION_VERBOSE(verbose);
3241 :
3242 0 : if (daemon == NULL) {
3243 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
3244 0 : return;
3245 : }
3246 :
3247 0 : user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
3248 :
3249 0 : if (user_list == NULL)
3250 : return;
3251 :
3252 0 : for (count = 0; count < user_list->num_applications; count++) {
3253 0 : app = &(user_list->applications[count]);
3254 :
3255 0 : if (app != NULL) {
3256 0 : if (app->user_handle >= DLT_FD_MINIMUM) {
3257 0 : if (dlt_daemon_user_send_log_state_v2(daemon, app, verbose) == -1) {
3258 0 : dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %s, PID: %d %s\n", app->apid2, app->pid, __func__);
3259 : }
3260 : }
3261 : }
3262 : }
3263 : }
3264 :
3265 2 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
3266 : {
3267 2 : switch (newState) {
3268 0 : case DLT_DAEMON_STATE_INIT:
3269 0 : dlt_log(LOG_INFO, "Switched to init state.\n");
3270 0 : daemon->state = DLT_DAEMON_STATE_INIT;
3271 0 : break;
3272 2 : case DLT_DAEMON_STATE_BUFFER:
3273 2 : dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
3274 2 : daemon->state = DLT_DAEMON_STATE_BUFFER;
3275 2 : break;
3276 0 : case DLT_DAEMON_STATE_BUFFER_FULL:
3277 0 : dlt_log(LOG_INFO, "Switched to buffer full state.\n");
3278 0 : daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
3279 0 : break;
3280 0 : case DLT_DAEMON_STATE_SEND_BUFFER:
3281 0 : dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
3282 0 : daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
3283 0 : break;
3284 0 : case DLT_DAEMON_STATE_SEND_DIRECT:
3285 0 : dlt_log(LOG_INFO, "Switched to send direct state.\n");
3286 0 : daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
3287 0 : break;
3288 : }
3289 2 : }
3290 :
3291 : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
3292 : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon *daemon) {
3293 : if (daemon->watchdog_trigger_interval == 0) {
3294 : return false;
3295 : }
3296 :
3297 : const unsigned int uptime_seconds = dlt_uptime() / 10000;
3298 : const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
3299 : if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
3300 : return false;
3301 : }
3302 : if (sd_notify(0, "WATCHDOG=1") < 0) {
3303 : dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
3304 : return false;
3305 : }
3306 : else
3307 : daemon->watchdog_last_trigger_time = uptime_seconds;
3308 :
3309 : return true;
3310 : }
3311 :
3312 : #endif
3313 :
3314 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
3315 : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
3316 : {
3317 : DltUserHeader userheader;
3318 : DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
3319 : uint32_t trace_load_settings_count;
3320 : DltReturnValue ret;
3321 :
3322 :
3323 : PRINT_FUNCTION_VERBOSE(verbose);
3324 :
3325 : if ((daemon == NULL) || (app == NULL)) return -1;
3326 :
3327 : if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
3328 :
3329 : DltTraceLoadSettings* app_settings = app->trace_load_settings;
3330 :
3331 : if (app_settings != NULL) {
3332 : trace_load_settings_count = app->trace_load_settings_count;
3333 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
3334 : for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
3335 : // App id is not transmitted as the user library only
3336 : // has one application ID
3337 : memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
3338 : trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
3339 : trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
3340 :
3341 : if (app_settings[i].ctid[0] == '\0') {
3342 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
3343 : app->apid,
3344 : app_settings[i].soft_limit,
3345 : app_settings[i].hard_limit);
3346 : } else {
3347 : dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
3348 : app->apid,
3349 : app_settings[i].ctid,
3350 : app_settings[i].soft_limit,
3351 : app_settings[i].hard_limit);
3352 : }
3353 :
3354 : }
3355 : }
3356 : else {
3357 : dlt_vlog(LOG_INFO,
3358 : "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
3359 :
3360 : trace_load_settings_count = 1;
3361 : trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
3362 :
3363 : memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
3364 : trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
3365 : trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
3366 : }
3367 :
3368 : /* log to FIFO */
3369 : ret = dlt_user_log_out3_with_timeout(app->user_handle,
3370 : &(userheader), sizeof(DltUserHeader),
3371 : &(trace_load_settings_count), sizeof(uint32_t),
3372 : trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
3373 :
3374 : if (ret < DLT_RETURN_OK) {
3375 : if (errno == EPIPE || errno == EBADF)
3376 : dlt_daemon_application_reset_user_handle(daemon, app, verbose);
3377 : }
3378 :
3379 : free(trace_load_settings_user_msg);
3380 :
3381 : return ret;
3382 : }
3383 : #endif
|