Line data Source code
1 : /**
2 : * Copyright (C) 2013 - 2015 Advanced Driver Information Technology.
3 : * This code is developed by Advanced Driver Information Technology.
4 : * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
5 : *
6 : * DLT offline log storage functionality source file.
7 : *
8 : * \copyright
9 : * This Source Code Form is subject to the terms of the
10 : * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
11 : * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 : *
13 : *
14 : * \author Syed Hameed <shameed@jp.adit-jv.com> ADIT 2013 - 2015
15 : * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015
16 : *
17 : * \file: dlt_offline_logstorage.c
18 : * For further information see http://www.covesa.org/.
19 : */
20 : #include <stdio.h>
21 : #include <string.h>
22 : #include <stdlib.h>
23 : #include <limits.h>
24 : #include <ctype.h>
25 : #include <syslog.h>
26 : #include <sys/stat.h>
27 : #include <sys/stat.h>
28 : #include <unistd.h>
29 : #include <dirent.h>
30 : #include <time.h>
31 :
32 : #include "dlt_offline_logstorage.h"
33 : #include "dlt_offline_logstorage_internal.h"
34 : #include "dlt_offline_logstorage_behavior.h"
35 : #include "dlt_config_file_parser.h"
36 :
37 : #define DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR 1
38 : #define DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR 2
39 : #define DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE 3
40 :
41 : #define GENERAL_BASE_NAME "General"
42 :
43 75 : DLT_STATIC void dlt_logstorage_filter_config_free(DltLogStorageFilterConfig *data)
44 : {
45 : DltLogStorageFileList *n = NULL;
46 : DltLogStorageFileList *n1 = NULL;
47 :
48 75 : if (data->apids) {
49 72 : free(data->apids);
50 72 : data->apids = NULL;
51 : }
52 :
53 75 : if (data->ctids) {
54 72 : free(data->ctids);
55 72 : data->ctids = NULL;
56 : }
57 :
58 75 : if (data->excluded_apids) {
59 0 : free(data->excluded_apids);
60 0 : data->excluded_apids = NULL;
61 : }
62 :
63 75 : if (data->excluded_ctids) {
64 0 : free(data->excluded_ctids);
65 0 : data->excluded_ctids = NULL;
66 : }
67 :
68 75 : if (data->file_name) {
69 70 : free(data->file_name);
70 70 : data->file_name = NULL;
71 : }
72 :
73 75 : if (data->working_file_name) {
74 27 : free(data->working_file_name);
75 27 : data->working_file_name = NULL;
76 : }
77 :
78 75 : if (data->ecuid != NULL) {
79 64 : free(data->ecuid);
80 64 : data->ecuid = NULL;
81 : }
82 :
83 75 : if (data->log != NULL)
84 3 : fclose(data->log);
85 :
86 : #ifdef DLT_LOGSTORAGE_USE_GZIP
87 : if (data->gzlog != NULL)
88 : gzclose(data->gzlog);
89 : #endif
90 :
91 75 : if (data->cache != NULL) {
92 23 : free(data->cache);
93 23 : data->cache = NULL;
94 : }
95 :
96 75 : n = data->records;
97 :
98 114 : while (n) {
99 : n1 = n;
100 39 : n = n->next;
101 39 : if (n1->name) {
102 39 : free(n1->name);
103 : n1->name = NULL;
104 : }
105 :
106 39 : free(n1);
107 : n1 = NULL;
108 : }
109 75 : }
110 :
111 : /**
112 : * dlt_logstorage_list_destroy
113 : *
114 : * Destroy Filter configurations list.
115 : *
116 : * @param list List of the filter configurations will be destroyed.
117 : * @param uconfig User configurations for log file
118 : * @param dev_path Path to the device
119 : * @param reason Reason for the destroying of Filter configurations list
120 : * @return 0 on success, -1 on error
121 : */
122 13 : DLT_STATIC int dlt_logstorage_list_destroy(DltLogStorageFilterList **list,
123 : DltLogStorageUserConfig *uconfig,
124 : char *dev_path,
125 : int reason)
126 : {
127 : DltLogStorageFilterList *tmp = NULL;
128 :
129 52 : while (*(list) != NULL) {
130 : tmp = *list;
131 39 : *list = (*list)->next;
132 39 : if (tmp->key_list != NULL)
133 : {
134 39 : free(tmp->key_list);
135 39 : tmp->key_list = NULL;
136 : }
137 :
138 39 : if (tmp->data != NULL) {
139 : /* sync data if necessary */
140 : /* ignore return value */
141 39 : tmp->data->dlt_logstorage_sync(tmp->data,
142 : uconfig,
143 : dev_path,
144 : reason);
145 :
146 39 : dlt_logstorage_filter_config_free(tmp->data);
147 :
148 39 : free(tmp->data);
149 : tmp->data = NULL;
150 : }
151 :
152 39 : free(tmp);
153 : tmp = NULL;
154 : }
155 :
156 13 : return 0;
157 : }
158 :
159 77 : DLT_STATIC int dlt_logstorage_list_add_config(DltLogStorageFilterConfig *data,
160 : DltLogStorageFilterConfig **listdata)
161 : {
162 77 : if (*(listdata) == NULL)
163 : return -1;
164 :
165 : /* copy the data to list */
166 : memcpy(*listdata, data, sizeof(DltLogStorageFilterConfig));
167 :
168 77 : if (data->apids != NULL)
169 72 : (*listdata)->apids = strdup(data->apids);
170 :
171 77 : if (data->ctids != NULL)
172 72 : (*listdata)->ctids = strdup(data->ctids);
173 :
174 77 : if (data->excluded_apids != NULL)
175 12 : (*listdata)->excluded_apids = strdup(data->excluded_apids);
176 :
177 77 : if (data->excluded_ctids != NULL)
178 12 : (*listdata)->excluded_ctids = strdup(data->excluded_ctids);
179 :
180 77 : if (data->file_name != NULL)
181 70 : (*listdata)->file_name = strdup(data->file_name);
182 :
183 77 : if (data->ecuid != NULL)
184 66 : (*listdata)->ecuid = strdup(data->ecuid);
185 :
186 : return 0;
187 : }
188 :
189 : /**
190 : * dlt_logstorage_list_add
191 : *
192 : * Add Filter configurations to the list.
193 : *
194 : * @param keys Keys will be added to the list.
195 : * @param num_keys Number of keys
196 : * @param data Filter configurations data will be added to the list.
197 : * @param list List of the filter configurations
198 : * @return 0 on success, -1 on error
199 : */
200 76 : DLT_STATIC int dlt_logstorage_list_add(char *keys,
201 : int num_keys,
202 : DltLogStorageFilterConfig *data,
203 : DltLogStorageFilterList **list)
204 : {
205 : DltLogStorageFilterList *tmp = NULL;
206 :
207 245 : while (*(list) != NULL) {
208 169 : list = &(*list)->next;
209 : }
210 :
211 76 : tmp = (DltLogStorageFilterList *)calloc(1, sizeof(DltLogStorageFilterList));
212 :
213 76 : if (tmp == NULL)
214 : return -1;
215 :
216 76 : tmp->key_list = (char *)calloc((size_t)num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
217 76 : if (tmp->key_list == NULL)
218 : {
219 0 : free(tmp);
220 : tmp = NULL;
221 0 : return -1;
222 : }
223 :
224 : memcpy(tmp->key_list, keys, (size_t)num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
225 76 : tmp->num_keys = num_keys;
226 76 : tmp->next = NULL;
227 76 : tmp->data = (DltLogStorageFilterConfig *)calloc(1, sizeof(DltLogStorageFilterConfig));
228 :
229 76 : if (tmp->data == NULL) {
230 0 : free(tmp->key_list);
231 : tmp->key_list = NULL;
232 0 : free(tmp);
233 : tmp = NULL;
234 0 : return -1;
235 : }
236 :
237 76 : if (dlt_logstorage_list_add_config(data, &(tmp->data)) != 0) {
238 0 : free(tmp->key_list);
239 : tmp->key_list = NULL;
240 0 : free(tmp->data);
241 : tmp->data = NULL;
242 0 : free(tmp);
243 : tmp = NULL;
244 0 : return -1;
245 : }
246 :
247 76 : *list = tmp;
248 :
249 76 : return 0;
250 : }
251 :
252 : /**
253 : * dlt_logstorage_list_find
254 : *
255 : * Find all Filter configurations corresponding with key provided.
256 : *
257 : * @param key Key to find the filter configurations
258 : * @param list List of the filter configurations
259 : * @param config Filter configurations corresponding with the key.
260 : * @return Number of the filter configuration found.
261 : */
262 40319 : DLT_STATIC int dlt_logstorage_list_find(char *key,
263 : DltLogStorageFilterList **list,
264 : DltLogStorageFilterConfig **config)
265 : {
266 : int i = 0;
267 : int num = 0;
268 :
269 460064 : while (*(list) != NULL) {
270 833781 : for (i = 0; i < (*list)->num_keys; i++)
271 : {
272 419745 : if (strncmp(((*list)->key_list
273 419745 : + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
274 : key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) == 0)
275 : {
276 5709 : config[num] = (*list)->data;
277 5709 : num++;
278 5709 : break;
279 : }
280 : }
281 419745 : list = &(*list)->next;
282 : }
283 :
284 40319 : return num;
285 : }
286 :
287 : /* Configuration file parsing helper functions */
288 :
289 19 : DLT_STATIC int dlt_logstorage_count_ids(const char *str)
290 : {
291 :
292 19 : if (str == NULL)
293 : return -1;
294 :
295 : /* delimiter is: "," */
296 : const char *p = str;
297 : int i = 0;
298 : int num = 1;
299 :
300 400 : while (p[i] != 0) {
301 322 : if (p[i] == ',')
302 18 : num++;
303 :
304 322 : i++;
305 : }
306 :
307 : return num;
308 : }
309 :
310 : /**
311 : * dlt_logstorage_free
312 : *
313 : * Free all allocated memory used in log storage handle
314 : *
315 : * @param handle DLT Logstorage handle
316 : * @param reason Reason for freeing the device
317 : *
318 : */
319 7 : void dlt_logstorage_free(DltLogStorage *handle, int reason)
320 : {
321 7 : if (handle == NULL) {
322 0 : dlt_vlog(LOG_ERR, "%s failed: handle is NULL\n", __func__);
323 0 : return;
324 : }
325 :
326 7 : dlt_logstorage_list_destroy(&(handle->config_list), &handle->uconfig,
327 7 : handle->device_mount_point, reason);
328 : }
329 :
330 :
331 : /**
332 : * dlt_logstorage_read_list_of_names
333 : *
334 : * Evaluate app and ctx names given in config file and create a list of names
335 : * acceptable by DLT Daemon. When using SET_APPLICATION_NAME and SET_CONTEXT_NAME
336 : * there is no constraint that these names have max 4 characters. Internally,
337 : * these names are cutted down to max 4 chars. To have create valid keys, the
338 : * internal representation of these names has to be considered.
339 : * Therefore, a given configuration of "AppLogName = App1,Application2,A3" will
340 : * be stored as "App1,Appl,A3".
341 : *
342 : * @param names to store the list of names
343 : * @param value string given in config file
344 : * @return 0 on success, -1 on error
345 : */
346 78 : DLT_STATIC int dlt_logstorage_read_list_of_names(char **names, const char *value)
347 : {
348 : int i = 0;
349 : int y = 0;
350 : size_t len = 0;
351 : char *tok;
352 : int num = 1;
353 :
354 78 : if ((names == NULL) || (value == NULL)) {
355 1 : dlt_vlog(LOG_ERR, "%s: Arguments are set to NULL\n", __func__);
356 1 : return -1;
357 : }
358 :
359 : /* free, alloce'd memory to store new apid/ctid */
360 77 : if (*names != NULL) {
361 5 : free(*names);
362 5 : *names = NULL;
363 : }
364 :
365 77 : len = strlen(value);
366 :
367 77 : if (len == 0) {
368 0 : dlt_vlog(LOG_ERR, "%s: Length of string given in config file is 0\n",
369 : __func__);
370 0 : return -1;
371 : }
372 :
373 : /* count number of delimiters to get actual number off names */
374 13 : num = dlt_logstorage_count_ids(value);
375 :
376 : /* need to alloc space for 5 chars, 4 for the name and "," and "\0" */
377 77 : *names = (char *)calloc((size_t)num * 5, sizeof(char));
378 :
379 77 : if (*names == NULL) {
380 0 : dlt_vlog(LOG_ERR, "%s: Cannot allocate memory\n", __func__);
381 0 : return -1;
382 : }
383 :
384 :
385 77 : char *tok_buf = strdup(value);
386 : char *tok_ptr = tok_buf;
387 77 : tok = strtok(tok_ptr, ",");
388 :
389 : i = 1;
390 :
391 :
392 169 : while (tok != NULL) {
393 92 : len = strlen(tok);
394 92 : len = DLT_OFFLINE_LOGSTORAGE_MIN(len, 4);
395 :
396 92 : int written = snprintf((*names + y), 5, "%.*s", (int)len, tok);
397 92 : if (written > 0 && written < 5) {
398 92 : if ((num > 1) && (i < num)) {
399 15 : (*names)[y + written] = ',';
400 15 : (*names)[y + written + 1] = '\0';
401 : }
402 92 : y += written + 1;
403 : } else {
404 : /* snprintf failed or truncated, do not advance y */
405 : break;
406 : }
407 92 : i++;
408 92 : tok = strtok(NULL, ",");
409 : }
410 :
411 77 : free(tok_buf);
412 :
413 77 : return 0;
414 : }
415 :
416 12 : DLT_STATIC int dlt_logstorage_set_number(unsigned int *number, unsigned int value)
417 : {
418 12 : if (value == 0) {
419 0 : dlt_log(LOG_ERR, "Invalid value of 0\n");
420 0 : return -1;
421 : }
422 :
423 80 : *number = value;
424 :
425 80 : return 0;
426 : }
427 :
428 : /**
429 : * dlt_logstorage_read_number
430 : *
431 : * Evaluate file size and number of files given in config file and set file size
432 : * The file number is checked by converting a string to an unsigned integer
433 : * width 0 > result < UINT_MAX (excludes 0!)
434 : * Non-digit characters including spaces and out of boundary will lead to an
435 : * error -1.
436 : *
437 : * @param number Number to be read
438 : * @param value string given in config file
439 : * @return 0 on success, -1 on error
440 : */
441 81 : DLT_STATIC int dlt_logstorage_read_number(unsigned int *number, char *value)
442 : {
443 : size_t i = 0;
444 : size_t len = 0;
445 : unsigned long size = 0;
446 :
447 81 : if (value == NULL)
448 : return -1;
449 :
450 80 : *number = 0;
451 80 : len = strlen(value);
452 :
453 : /* check if string consists of digits only */
454 308 : for (i = 0; i < len; i++)
455 228 : if (!isdigit((unsigned char)value[i])) {
456 0 : dlt_log(LOG_ERR, "Invalid, is not a number \n");
457 0 : return -1;
458 : }
459 :
460 80 : size = strtoul(value, NULL, 10);
461 80 : if (size > UINT_MAX) {
462 0 : dlt_log(LOG_ERR, "Value out of range for unsigned int\n");
463 0 : return -1;
464 : }
465 80 : return dlt_logstorage_set_number(number, (unsigned int)size);
466 : }
467 :
468 : /**
469 : * dlt_logstorage_get_keys_list
470 : *
471 : * Obtain key list and number of keys for id list passed
472 : * after splitting it between seperator (,)
473 : *
474 : * @param ids ID's
475 : * @param sep Seperator
476 : * @param list Prepared key list is stored here
477 : * @param numids Number of keys in the list is stored here
478 : * @return: 0 on success, error on failure*
479 : */
480 76 : DLT_STATIC int dlt_logstorage_get_keys_list(char *ids, char *sep, char **list,
481 : int *numids)
482 : {
483 : char *token = NULL;
484 76 : char *tmp_token = NULL;
485 : char *ids_local = NULL;
486 :
487 76 : *numids = 0;
488 :
489 : /* Duplicate the ids passed for using in strtok_r() */
490 76 : ids_local = strdup(ids);
491 :
492 76 : if (ids_local == NULL)
493 : return -1;
494 :
495 76 : token = strtok_r(ids_local, sep, &tmp_token);
496 :
497 76 : if (token == NULL) {
498 0 : free(ids_local);
499 0 : return -1;
500 : }
501 :
502 76 : *list = (char *)calloc((size_t)DLT_OFFLINE_LOGSTORAGE_MAXIDS * (DLT_ID_SIZE + 1), sizeof(char));
503 :
504 76 : if (*(list) == NULL) {
505 0 : free(ids_local);
506 0 : return -1;
507 : }
508 :
509 152 : while (token != NULL) {
510 : /* If it reached the max then other ids are ignored */
511 76 : if (*numids >= DLT_OFFLINE_LOGSTORAGE_MAXIDS) {
512 0 : free(ids_local);
513 0 : return 0;
514 : }
515 :
516 76 : snprintf(((*list) + ((*numids) * (DLT_ID_SIZE + 1))), DLT_ID_SIZE + 1, "%.*s", DLT_ID_SIZE, token);
517 76 : *numids = *numids + 1;
518 76 : token = strtok_r(NULL, sep, &tmp_token);
519 : }
520 :
521 76 : free(ids_local);
522 :
523 76 : return 0;
524 : }
525 :
526 24 : DLT_STATIC bool dlt_logstorage_check_excluded_ids(char *id, char *delim, char *excluded_ids)
527 : {
528 : char *token = NULL;
529 24 : char *tmp_token = NULL;
530 : char *ids_local = NULL;
531 :
532 24 : if ((id == NULL) || (delim == NULL) || (excluded_ids == NULL)) {
533 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
534 1 : return false;
535 : }
536 :
537 23 : ids_local = strdup(excluded_ids);
538 :
539 23 : if (ids_local == NULL) {
540 0 : dlt_vlog(LOG_ERR, "%s: Cannot duplicate string.\n", __func__);
541 0 : return false;
542 : }
543 :
544 23 : token = strtok_r(ids_local, delim, &tmp_token);
545 :
546 23 : if (token == NULL) {
547 0 : dlt_vlog(LOG_ERR, "%s: %s could not be parsed.\n", __func__, ids_local);
548 0 : free(ids_local);
549 0 : return false;
550 : }
551 :
552 39 : while (token != NULL) {
553 29 : if(strncmp(id, token, DLT_ID_SIZE) == 0) {
554 13 : free(ids_local);
555 13 : return true;
556 : }
557 :
558 16 : token = strtok_r(NULL, delim, &tmp_token);
559 : }
560 :
561 10 : free(ids_local);
562 10 : return false;
563 : }
564 :
565 : /**
566 : * dlt_logstorage_create_keys_only_ctid
567 : *
568 : * Prepares keys with context ID alone, will use ecuid if provided
569 : * (ecuid\:\:ctid) or (\:\:ctid)
570 : *
571 : * @param ecuid ECU ID
572 : * @param ctid Context ID
573 : * @param key Prepared key stored here
574 : * @return None
575 : */
576 0 : DLT_STATIC void dlt_logstorage_create_keys_only_ctid(char *ecuid, char *ctid,
577 : char *key)
578 : {
579 0 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 };
580 : const char *delimiter = "::";
581 :
582 0 : if (ecuid != NULL) {
583 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, delimiter);
584 : } else {
585 : snprintf(curr_str, sizeof(curr_str), "%s", delimiter);
586 : }
587 0 : if (ctid != NULL) {
588 0 : strncat(curr_str, ctid, sizeof(curr_str) - strlen(curr_str) - 1);
589 : }
590 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
591 0 : }
592 :
593 : /**
594 : * dlt_logstorage_create_keys_only_apid
595 : *
596 : * Prepares keys with application ID alone, will use ecuid if provided
597 : * (ecuid:apid::) or (:apid::)
598 : *
599 : * @param ecuid ECU ID
600 : * @param apid Application ID
601 : * @param key Prepared key stored here
602 : * @return None
603 : */
604 4 : DLT_STATIC void dlt_logstorage_create_keys_only_apid(char *ecuid, char *apid,
605 : char *key)
606 : {
607 4 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 };
608 : const char *colon = ":";
609 :
610 4 : if (ecuid != NULL) {
611 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, colon);
612 : } else {
613 : snprintf(curr_str, sizeof(curr_str), "%s", colon);
614 : }
615 4 : if (apid != NULL) {
616 4 : strncat(curr_str, apid, sizeof(curr_str) - strlen(curr_str) - 1);
617 : }
618 4 : strncat(curr_str, colon, sizeof(curr_str) - strlen(curr_str) - 1);
619 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
620 4 : }
621 :
622 : /**
623 : * dlt_logstorage_create_keys_multi
624 : *
625 : * Prepares keys with apid, ctid (ecuid:apid:ctid), will use ecuid if is provided
626 : * (ecuid:apid:ctid) or (:apid:ctid)
627 : *
628 : * @param ecuid ECU ID
629 : * @param apid Application ID
630 : * @param ctid Context ID
631 : * @param key Prepared key stored here
632 : * @return None
633 : */
634 34 : DLT_STATIC void dlt_logstorage_create_keys_multi(char *ecuid, char *apid,
635 : char *ctid, char *key)
636 : {
637 34 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 };
638 : const char *colon = ":";
639 :
640 34 : if (ecuid != NULL) {
641 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, colon);
642 : } else {
643 : snprintf(curr_str, sizeof(curr_str), "%s", colon);
644 : }
645 34 : if (apid != NULL) {
646 34 : strncat(curr_str, apid, sizeof(curr_str) - strlen(curr_str) - 1);
647 : }
648 34 : strncat(curr_str, colon, sizeof(curr_str) - strlen(curr_str) - 1);
649 34 : if (ctid != NULL) {
650 34 : strncat(curr_str, ctid, sizeof(curr_str) - strlen(curr_str) - 1);
651 : }
652 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
653 34 : }
654 :
655 : /**
656 : * dlt_logstorage_create_keys_only_ecu
657 : *
658 : * Prepares keys with only ecuid (ecuid::)
659 : *
660 : * @param ecuid ECU ID
661 : * @param key Prepared key stored here
662 : * @return None
663 : */
664 0 : DLT_STATIC void dlt_logstorage_create_keys_only_ecu(char *ecuid, char *key)
665 : {
666 0 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 };
667 :
668 : snprintf(curr_str, sizeof(curr_str), "%.*s::", DLT_ID_SIZE, ecuid);
669 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
670 0 : }
671 :
672 : /**
673 : * dlt_logstorage_create_keys
674 : *
675 : * Create keys for hash table
676 : *
677 : * From each section [filter] in offline logstorage configuration file, we
678 : * receive application and context id strings.
679 : * Application and context id can consist of
680 : * - a 4char long name
681 : * - a comma separated list of ids
682 : * - a wildcard: .*
683 : *
684 : * If both application and context id are set to wildcard, this will be treated
685 : * in the same way of the case application and context id are not present:
686 : * - EcuID must be specified
687 : *
688 : * If lists given for application and/or context id, all possible combinations
689 : * are returned as keys in a form "[apid][ctid], e.g. "APP1\:CTX1".
690 : * If wildcards are used, the non-wildcard value becomes the key, e.g. "APP1\:"
691 : * or "\:CTX2".
692 : *
693 : * @param[in] apids string given from filter configuration
694 : * @param[in] ctids string given from filter configuration
695 : * @param[in] ecuid string given from filter configuration
696 : * @param[out] keys keys to fill into hash table
697 : * @param[out] num_keys number of keys
698 : * @return: 0 on success, error on failure*
699 : */
700 38 : DLT_STATIC int dlt_logstorage_create_keys(char *apids,
701 : char *ctids,
702 : char *ecuid,
703 : char **keys,
704 : int *num_keys)
705 : {
706 : int i, j;
707 38 : int num_apids = 0;
708 38 : int num_ctids = 0;
709 38 : char *apid_list = NULL;
710 38 : char *ctid_list = NULL;
711 : char *curr_apid = NULL;
712 : char *curr_ctid = NULL;
713 38 : char curr_key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { 0 };
714 : int num_currkey = 0;
715 :
716 : /* Handle ecuid alone case here */
717 38 : if (((apids == NULL) && (ctids == NULL) && (ecuid != NULL)) ||
718 38 : ((apids != NULL) && (strncmp(apids, ".*", 2) == 0) &&
719 0 : (ctids != NULL) && (strncmp(ctids, ".*", 2) == 0) && (ecuid != NULL)) ) {
720 0 : dlt_logstorage_create_keys_only_ecu(ecuid, curr_key);
721 0 : *(num_keys) = 1;
722 0 : *(keys) = (char *)calloc((size_t)(*num_keys) * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
723 :
724 0 : if (*(keys) == NULL)
725 : return -1;
726 :
727 : strncpy(*keys, curr_key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1);
728 0 : (*keys)[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1] = '\0';
729 0 : return 0;
730 : }
731 :
732 38 : if ((apids == NULL) || (ctids == NULL)) {
733 0 : dlt_log(LOG_ERR, "Required inputs (apid and ctid) are NULL\n");
734 0 : return -1;
735 : }
736 :
737 : /* obtain key list and number of keys for application ids */
738 38 : if (dlt_logstorage_get_keys_list(apids, ",", &apid_list, &num_apids) != 0) {
739 0 : dlt_log(LOG_ERR, "Failed to obtain apid, check configuration file \n");
740 0 : return -1;
741 : }
742 :
743 : /* obtain key list and number of keys for context ids */
744 38 : if (dlt_logstorage_get_keys_list(ctids, ",", &ctid_list, &num_ctids) != 0) {
745 0 : dlt_log(LOG_ERR, "Failed to obtain ctid, check configuration file \n");
746 0 : free(apid_list);
747 0 : return -1;
748 : }
749 :
750 38 : *(num_keys) = num_apids * num_ctids;
751 :
752 : /* allocate memory for needed number of keys */
753 38 : *(keys) = (char *)calloc((size_t)(*num_keys) * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
754 :
755 38 : if (*(keys) == NULL) {
756 0 : free(apid_list);
757 0 : free(ctid_list);
758 0 : return -1;
759 : }
760 :
761 : /* store all combinations of apid ctid in keys */
762 76 : for (i = 0; i < num_apids; i++) {
763 38 : curr_apid = apid_list + (i * (DLT_ID_SIZE + 1));
764 :
765 76 : for (j = 0; j < num_ctids; j++) {
766 38 : curr_ctid = ctid_list + (j * (DLT_ID_SIZE + 1));
767 :
768 38 : if (strncmp(curr_apid, ".*", 2) == 0) /* only context id matters */
769 0 : dlt_logstorage_create_keys_only_ctid(ecuid, curr_ctid, curr_key);
770 38 : else if (strncmp(curr_ctid, ".*", 2) == 0) /* only app id matters*/
771 4 : dlt_logstorage_create_keys_only_apid(ecuid, curr_apid, curr_key);
772 : else /* key is combination of all */
773 34 : dlt_logstorage_create_keys_multi(ecuid, curr_apid, curr_ctid, curr_key);
774 :
775 38 : memcpy((*keys + (num_currkey * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
776 : curr_key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
777 38 : (*keys + (num_currkey * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN))[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1] = '\0';
778 38 : num_currkey += 1;
779 : memset(&curr_key[0], 0, sizeof(curr_key));
780 : }
781 : }
782 :
783 38 : free(apid_list);
784 38 : free(ctid_list);
785 :
786 38 : return 0;
787 : }
788 :
789 : /**
790 : * dlt_logstorage_prepare_table
791 : *
792 : * Prepares hash table with keys and data
793 : *
794 : * @param handle DLT Logstorage handle
795 : * @param data Holds all other configuration values
796 : * @return 0 on success, -1 on error
797 : */
798 38 : DLT_STATIC int dlt_logstorage_prepare_table(DltLogStorage *handle,
799 : DltLogStorageFilterConfig *data)
800 : {
801 : int ret = 0;
802 38 : int num_keys = 0;
803 : int found = 0;
804 38 : char *keys = NULL;
805 : DltNewestFileName *tmp = NULL;
806 : DltNewestFileName *prev_tmp = NULL;
807 : DltNewestFileName *new_tmp = NULL;
808 :
809 38 : if ((handle == NULL) || (data == NULL)) {
810 1 : dlt_vlog(LOG_ERR, "Invalid parameters in %s\n", __func__);
811 1 : return -1;
812 : }
813 :
814 37 : ret = dlt_logstorage_create_keys(data->apids,
815 : data->ctids,
816 : data->ecuid,
817 : &keys,
818 : &num_keys);
819 :
820 37 : if (ret != 0) {
821 0 : dlt_log(LOG_ERR, "Not able to create keys for hash table\n");
822 0 : return -1;
823 : }
824 :
825 : /* hash_add */
826 37 : if (dlt_logstorage_list_add(keys,
827 : num_keys,
828 : data,
829 : &(handle->config_list)) != 0)
830 : {
831 0 : dlt_log(LOG_ERR, "Adding to hash table failed, returning failure\n");
832 0 : dlt_logstorage_free(handle, DLT_LOGSTORAGE_SYNC_ON_ERROR);
833 0 : free(keys);
834 : keys = NULL;
835 0 : return -1;
836 : }
837 :
838 37 : if (data->file_name) {
839 36 : if (handle->newest_file_list != NULL) {
840 : tmp = handle->newest_file_list;
841 165 : while (tmp) {
842 139 : if (strcmp(tmp->file_name, data->file_name) == 0) {
843 : found = 1;
844 : break;
845 : }
846 : else {
847 : prev_tmp = tmp;
848 139 : tmp = tmp->next;
849 : }
850 : }
851 : }
852 :
853 26 : if (!found) {
854 36 : new_tmp = (DltNewestFileName *)calloc(1, sizeof(DltNewestFileName));
855 36 : if (new_tmp == NULL) {
856 : /* In this case, the existing list does not need to be freed.*/
857 0 : dlt_vlog(LOG_ERR,
858 : "Failed to allocate memory for new file name [%s]\n",
859 : data->file_name);
860 0 : free(keys);
861 : keys = NULL;
862 0 : return -1;
863 : }
864 36 : new_tmp->file_name = strdup(data->file_name);
865 36 : new_tmp->newest_file = NULL;
866 36 : new_tmp->next = NULL;
867 :
868 36 : if (handle->newest_file_list == NULL)
869 10 : handle->newest_file_list = new_tmp;
870 : else
871 26 : prev_tmp->next = new_tmp;
872 : }
873 : }
874 :
875 37 : free(keys);
876 : keys = NULL;
877 37 : return 0;
878 : }
879 :
880 : /**
881 : * dlt_logstorage_validate_filter_name
882 : *
883 : * Validates if the provided filter name is as required [FILTER<number>]
884 : *
885 : * @param name Filter name
886 : * @return 0 on success, -1 on error
887 : *
888 : */
889 38 : DLT_STATIC int dlt_logstorage_validate_filter_name(char *name)
890 : {
891 : size_t len = 0;
892 : int idx = 0;
893 : size_t config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION);
894 : size_t storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION);
895 : size_t control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION);
896 :
897 38 : if (name == NULL)
898 : return -1;
899 :
900 37 : len = strlen(name);
901 :
902 : /* Check if section header is of format "FILTER" followed by a number */
903 37 : if (strncmp(name,
904 : DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION,
905 : config_sec_len) == 0) {
906 45 : for (idx = (int)config_sec_len; (size_t)idx < len - 1; idx++)
907 8 : if (!isdigit((unsigned char)name[idx]))
908 : return -1;
909 : return 0;
910 : }
911 0 : else if (strncmp(name,
912 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION,
913 : storage_sec_len) == 0)
914 : {
915 0 : for (idx = (int)storage_sec_len; (size_t)idx < len - 1; idx++)
916 0 : if (!isdigit((unsigned char)name[idx]))
917 : return -1;
918 : return 0;
919 : }
920 0 : else if (strncmp(name,
921 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION,
922 : control_sec_len) == 0)
923 : {
924 0 : for (idx = (int)control_sec_len; (size_t)idx < len - 1; idx++)
925 0 : if (!isdigit((unsigned char)name[idx]))
926 : return -1;
927 : return 0;
928 : }
929 : else {
930 : return -1;
931 : }
932 : }
933 :
934 13 : DLT_STATIC void dlt_logstorage_filter_set_strategy(DltLogStorageFilterConfig *config,
935 : int strategy)
936 : {
937 13 : if (config == NULL)
938 : return;
939 :
940 : /* file based */
941 13 : if ((strategy == DLT_LOGSTORAGE_SYNC_ON_MSG) ||
942 : (strategy == DLT_LOGSTORAGE_SYNC_UNSET)) {
943 20 : config->dlt_logstorage_prepare = &dlt_logstorage_prepare_on_msg;
944 20 : config->dlt_logstorage_write = &dlt_logstorage_write_on_msg;
945 20 : config->dlt_logstorage_sync = &dlt_logstorage_sync_on_msg;
946 : }
947 : else { /* cache based */
948 25 : config->dlt_logstorage_prepare = &dlt_logstorage_prepare_msg_cache;
949 25 : config->dlt_logstorage_write = &dlt_logstorage_write_msg_cache;
950 25 : config->dlt_logstorage_sync = &dlt_logstorage_sync_msg_cache;
951 : }
952 : }
953 :
954 38 : DLT_STATIC int dlt_logstorage_check_apids(DltLogStorageFilterConfig *config,
955 : char *value)
956 : {
957 38 : if ((config == NULL) || (value == NULL)) {
958 1 : dlt_log(LOG_ERR, "Not able to create keys for hash table\n");
959 1 : return -1;
960 : }
961 :
962 37 : return dlt_logstorage_read_list_of_names(&config->apids, value);
963 : }
964 :
965 38 : DLT_STATIC int dlt_logstorage_check_ctids(DltLogStorageFilterConfig *config,
966 : char *value)
967 : {
968 38 : if ((config == NULL) || (value == NULL))
969 : return -1;
970 :
971 37 : return dlt_logstorage_read_list_of_names(&config->ctids, (const char*)value);
972 : }
973 :
974 2 : DLT_STATIC int dlt_logstorage_store_config_excluded_apids(DltLogStorageFilterConfig *config,
975 : char *value)
976 : {
977 2 : if ((config == NULL) || (value == NULL)) {
978 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
979 1 : return -1;
980 : }
981 :
982 1 : return dlt_logstorage_read_list_of_names(&config->excluded_apids, value);
983 : }
984 :
985 2 : DLT_STATIC int dlt_logstorage_store_config_excluded_ctids(DltLogStorageFilterConfig *config,
986 : char *value)
987 : {
988 2 : if ((config == NULL) || (value == NULL)) {
989 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
990 1 : return -1;
991 : }
992 :
993 1 : return dlt_logstorage_read_list_of_names(&config->excluded_ctids, (const char*)value);
994 : }
995 :
996 5 : DLT_STATIC int dlt_logstorage_set_loglevel(int *log_level,
997 : int value)
998 : {
999 37 : *log_level = value;
1000 37 : if ((value <= DLT_LOG_DEFAULT) || (value >= DLT_LOG_MAX)) {
1001 0 : *log_level = -1;
1002 0 : dlt_log(LOG_ERR, "Invalid log level \n");
1003 0 : return -1;
1004 : }
1005 : return 0;
1006 : }
1007 :
1008 38 : DLT_STATIC int dlt_logstorage_check_loglevel(DltLogStorageFilterConfig *config,
1009 : char *value)
1010 : {
1011 : int ll = -1;
1012 :
1013 38 : if ((config == NULL) || (value == NULL)) {
1014 1 : if (config != NULL)
1015 0 : config->log_level = 0;
1016 1 : dlt_vlog(LOG_ERR, "Invalid parameters in %s\n", __func__);
1017 1 : return -1;
1018 : }
1019 :
1020 37 : if (strcmp(value, "DLT_LOG_FATAL") == 0) {
1021 : ll = 1;
1022 : }
1023 36 : else if (strcmp(value, "DLT_LOG_ERROR") == 0)
1024 : {
1025 : ll = 2;
1026 : }
1027 32 : else if (strcmp(value, "DLT_LOG_WARN") == 0)
1028 : {
1029 : ll = 3;
1030 : }
1031 32 : else if (strcmp(value, "DLT_LOG_INFO") == 0)
1032 : {
1033 : ll = 4;
1034 : }
1035 0 : else if (strcmp(value, "DLT_LOG_DEBUG") == 0)
1036 : {
1037 : ll = 5;
1038 : }
1039 0 : else if (strcmp(value, "DLT_LOG_VERBOSE") == 0)
1040 : {
1041 : ll = 6;
1042 : }
1043 :
1044 5 : return dlt_logstorage_set_loglevel(&config->log_level, ll);
1045 : }
1046 :
1047 0 : DLT_STATIC int dlt_logstorage_check_reset_loglevel(DltLogStorageFilterConfig *config,
1048 : char *value)
1049 : {
1050 0 : if (config == NULL)
1051 : return -1;
1052 :
1053 0 : if (value == NULL) {
1054 0 : config->reset_log_level = 0;
1055 0 : return -1;
1056 : }
1057 :
1058 0 : if (strcmp(value, "DLT_LOG_OFF") == 0) {
1059 0 : config->reset_log_level = DLT_LOG_OFF;
1060 : }
1061 0 : else if (strcmp(value, "DLT_LOG_FATAL") == 0)
1062 : {
1063 0 : config->reset_log_level = DLT_LOG_FATAL;
1064 : }
1065 0 : else if (strcmp(value, "DLT_LOG_ERROR") == 0)
1066 : {
1067 0 : config->reset_log_level = DLT_LOG_ERROR;
1068 : }
1069 0 : else if (strcmp(value, "DLT_LOG_WARN") == 0)
1070 : {
1071 0 : config->reset_log_level = DLT_LOG_WARN;
1072 : }
1073 0 : else if (strcmp(value, "DLT_LOG_INFO") == 0)
1074 : {
1075 0 : config->reset_log_level = DLT_LOG_INFO;
1076 : }
1077 0 : else if (strcmp(value, "DLT_LOG_DEBUG") == 0)
1078 : {
1079 0 : config->reset_log_level = DLT_LOG_DEBUG;
1080 : }
1081 0 : else if (strcmp(value, "DLT_LOG_VERBOSE") == 0)
1082 : {
1083 0 : config->reset_log_level = DLT_LOG_VERBOSE;
1084 : }
1085 : else {
1086 0 : config->reset_log_level = -1;
1087 0 : dlt_log(LOG_ERR, "Invalid log level \n");
1088 0 : return -1;
1089 : }
1090 :
1091 : return 0;
1092 : }
1093 :
1094 39 : DLT_STATIC int dlt_logstorage_check_filename(DltLogStorageFilterConfig *config,
1095 : char *value)
1096 : {
1097 : size_t len;
1098 :
1099 39 : if ((value == NULL) || (strcmp(value, "") == 0))
1100 : return -1;
1101 :
1102 38 : if (config->file_name != NULL) {
1103 2 : free(config->file_name);
1104 2 : config->file_name = NULL;
1105 : }
1106 :
1107 38 : len = strlen(value);
1108 :
1109 38 : if (len == 0) {
1110 0 : dlt_vlog(LOG_ERR, "%s: Length of string given in config file is 0\n",
1111 : __func__);
1112 0 : return -1;
1113 : }
1114 :
1115 : /* do not allow the user to change directory by adding a relative path */
1116 38 : if (strstr(value, "..") == NULL) {
1117 37 : config->file_name = (char *)calloc(len + 1, sizeof(char));
1118 :
1119 37 : if (config->file_name == NULL) {
1120 0 : dlt_log(LOG_ERR,
1121 : "Cannot allocate memory for filename\n");
1122 0 : return -1;
1123 : }
1124 :
1125 : memcpy(config->file_name, value, len);
1126 37 : config->file_name[len] = '\0';
1127 : }
1128 : else {
1129 1 : dlt_log(LOG_ERR,
1130 : "Invalid filename, paths not accepted due to security issues\n");
1131 1 : return -1;
1132 : }
1133 :
1134 37 : return 0;
1135 : }
1136 :
1137 39 : DLT_STATIC int dlt_logstorage_check_filesize(DltLogStorageFilterConfig *config,
1138 : char *value)
1139 : {
1140 39 : if ((config == NULL) || (value == NULL))
1141 : return -1;
1142 :
1143 38 : return dlt_logstorage_read_number(&config->file_size, value);
1144 : }
1145 :
1146 38 : DLT_STATIC int dlt_logstorage_check_nofiles(DltLogStorageFilterConfig *config,
1147 : char *value)
1148 : {
1149 38 : if ((config == NULL) || (value == NULL))
1150 : return -1;
1151 :
1152 37 : return dlt_logstorage_read_number(&config->num_files, value);
1153 : }
1154 :
1155 4 : DLT_STATIC int dlt_logstorage_check_specificsize(DltLogStorageFilterConfig *config,
1156 : char *value)
1157 : {
1158 4 : if ((config == NULL) || (value == NULL))
1159 : return -1;
1160 :
1161 4 : return dlt_logstorage_read_number(&config->specific_size, value);
1162 : }
1163 :
1164 : /**
1165 : * dlt_logstorage_check_sync_strategy
1166 : *
1167 : * Evaluate sync strategy. The sync strategy is an optional filter
1168 : * configuration parameter.
1169 : * If the given value cannot be associated with a sync strategy, the default
1170 : * sync strategy will be assigned.
1171 : *
1172 : * @param config DltLogStorageFilterConfig
1173 : * @param value string given in config file
1174 : * @return 0 on success, -1 on error
1175 : */
1176 27 : DLT_STATIC int dlt_logstorage_check_sync_strategy(DltLogStorageFilterConfig *config,
1177 : char *value)
1178 : {
1179 27 : if ((config == NULL) || (value == NULL))
1180 : return -1;
1181 :
1182 26 : if (strcasestr(value, "ON_MSG") != NULL) {
1183 1 : config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG;
1184 1 : dlt_log(LOG_DEBUG, "ON_MSG found, ignore other if added\n");
1185 : }
1186 : else { /* ON_MSG not set, combination of cache based strategies possible */
1187 :
1188 25 : if (strcasestr(value, "ON_DAEMON_EXIT") != NULL)
1189 8 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT;
1190 :
1191 25 : if (strcasestr(value, "ON_DEMAND") != NULL)
1192 4 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEMAND;
1193 :
1194 25 : if (strcasestr(value, "ON_DEVICE_DISCONNECT") != NULL)
1195 0 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT;
1196 :
1197 25 : if (strcasestr(value, "ON_SPECIFIC_SIZE") != NULL)
1198 4 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE;
1199 :
1200 25 : if (strcasestr(value, "ON_FILE_SIZE") != NULL)
1201 12 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE;
1202 :
1203 25 : if (config->sync == 0) {
1204 1 : dlt_log(LOG_WARNING,
1205 : "Unknown sync strategies. Set default ON_MSG\n");
1206 1 : config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG;
1207 1 : return 1;
1208 : }
1209 : }
1210 :
1211 : return 0;
1212 : }
1213 :
1214 : /**
1215 : * dlt_logstorage_check_overwrite_strategy
1216 : *
1217 : * Evaluate overwrite strategy. The sync strategy is an optional filter
1218 : * configuration parameter.
1219 : * If the given value cannot be associated with a strategy, the default
1220 : * strategy will be assigned.
1221 : *
1222 : * @param[in] config DltLogStorageFilterConfig
1223 : * @param[in] value string given in config file
1224 : * @return 0 on success, 1 on unknown value, -1 on error
1225 : */
1226 30 : DLT_STATIC int dlt_logstorage_check_overwrite_strategy(DltLogStorageFilterConfig *config,
1227 : char *value)
1228 : {
1229 30 : if ((config == NULL) || (value == NULL))
1230 : return -1;
1231 :
1232 30 : if (strcasestr(value, "DISCARD_OLD") != NULL) {
1233 12 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_OLD;
1234 18 : } else if (strcasestr(value, "DISCARD_NEW") != NULL) {
1235 18 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_NEW;
1236 : } else {
1237 0 : dlt_log(LOG_WARNING,
1238 : "Unknown overwrite strategy. Set default DISCARD_OLD\n");
1239 0 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_OLD;
1240 0 : return 1;
1241 : }
1242 :
1243 : return 0;
1244 : }
1245 :
1246 : /**
1247 : * dlt_logstorage_check_disable_network
1248 : *
1249 : * Evaluate disable network. The disable network is an optional filter
1250 : * configuration parameter.
1251 : * If the given value cannot be associated with a flag, the default
1252 : * flag will be assigned.
1253 : *
1254 : * @param[in] config DltLogStorageFilterConfig
1255 : * @param[in] value string given in config file
1256 : * @return 0 on success, 1 on unknown value, -1 on error
1257 : */
1258 1 : DLT_STATIC int dlt_logstorage_check_disable_network(DltLogStorageFilterConfig *config,
1259 : char *value)
1260 : {
1261 1 : if ((config == NULL) || (value == NULL))
1262 : return -1;
1263 :
1264 1 : if (strcasestr(value, "ON") != NULL) {
1265 1 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_ON;
1266 0 : } else if (strcasestr(value, "OFF") != NULL) {
1267 0 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1268 : } else {
1269 0 : dlt_log(LOG_WARNING,
1270 : "Unknown disable network flag. Set default OFF\n");
1271 0 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1272 0 : return 1;
1273 : }
1274 :
1275 : return 0;
1276 : }
1277 :
1278 : /**
1279 : * dlt_logstorage_check_gzip_compression
1280 : *
1281 : * Evaluate gzip compression. The gzip compression is an optional filter
1282 : * configuration parameter.
1283 : * If the given value cannot be associated with a flag, the default
1284 : * flag will be assigned.
1285 : *
1286 : * @param[in] config DltLogStorageFilterConfig
1287 : * @param[in] value string given in config file
1288 : * @return 0 on success, 1 on unknown value, -1 on error
1289 : */
1290 0 : DLT_STATIC int dlt_logstorage_check_gzip_compression(DltLogStorageFilterConfig *config,
1291 : char *value)
1292 : {
1293 : #ifdef DLT_LOGSTORAGE_USE_GZIP
1294 : if ((config == NULL) || (value == NULL))
1295 : return -1;
1296 :
1297 : if (strcasestr(value, "ON") != NULL) {
1298 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_ON;
1299 : } else if (strcasestr(value, "OFF") != NULL) {
1300 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_OFF;
1301 : } else {
1302 : dlt_log(LOG_WARNING, "Unknown gzip compression flag\n");
1303 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_ERROR;
1304 : return 1;
1305 : }
1306 : #else
1307 : (void)value;
1308 0 : dlt_log(LOG_WARNING, "dlt-daemon not compiled with logstorage gzip support\n");
1309 0 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_OFF;
1310 : #endif
1311 0 : return 0;
1312 : }
1313 :
1314 : /**
1315 : * dlt_logstorage_check_ecuid
1316 : *
1317 : * Evaluate if ECU idenfifier given in config file
1318 : *
1319 : * @param config DltLogStorageFilterConfig
1320 : * @param value string given in config file
1321 : * @return 0 on success, -1 on error
1322 : */
1323 34 : DLT_STATIC int dlt_logstorage_check_ecuid(DltLogStorageFilterConfig *config,
1324 : char *value)
1325 : {
1326 : size_t len;
1327 :
1328 34 : if ((config == NULL) || (value == NULL) || (value[0] == '\0'))
1329 : return -1;
1330 :
1331 33 : if (config->ecuid != NULL) {
1332 1 : free(config->ecuid);
1333 1 : config->ecuid = NULL;
1334 : }
1335 :
1336 33 : len = strlen(value);
1337 33 : config->ecuid = (char *)calloc(len + 1, sizeof(char));
1338 :
1339 33 : if (config->ecuid == NULL)
1340 : return -1;
1341 :
1342 : memcpy(config->ecuid, value, len);
1343 33 : config->ecuid[len] = '\0';
1344 :
1345 33 : return 0;
1346 : }
1347 :
1348 : DLT_STATIC DltLogstorageFilterConf
1349 : filter_cfg_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1350 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1351 : .key = "LogAppName",
1352 : .func = dlt_logstorage_check_apids,
1353 : .is_opt = 1
1354 : },
1355 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1356 : .key = "ContextName",
1357 : .func = dlt_logstorage_check_ctids,
1358 : .is_opt = 1
1359 : },
1360 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1361 : .key = "ExcludedLogAppName",
1362 : .func = dlt_logstorage_store_config_excluded_apids,
1363 : .is_opt = 1
1364 : },
1365 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1366 : .key = "ExcludedContextName",
1367 : .func = dlt_logstorage_store_config_excluded_ctids,
1368 : .is_opt = 1
1369 : },
1370 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1371 : .key = "LogLevel",
1372 : .func = dlt_logstorage_check_loglevel,
1373 : .is_opt = 0
1374 : },
1375 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1376 : .key = NULL,
1377 : .func = dlt_logstorage_check_reset_loglevel,
1378 : .is_opt = 0
1379 : },
1380 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1381 : .key = "File",
1382 : .func = dlt_logstorage_check_filename,
1383 : .is_opt = 0
1384 : },
1385 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1386 : .key = "FileSize",
1387 : .func = dlt_logstorage_check_filesize,
1388 : .is_opt = 0
1389 : },
1390 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1391 : .key = "NOFiles",
1392 : .func = dlt_logstorage_check_nofiles,
1393 : .is_opt = 0
1394 : },
1395 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1396 : .key = "SyncBehavior",
1397 : .func = dlt_logstorage_check_sync_strategy,
1398 : .is_opt = 1
1399 : },
1400 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1401 : .key = "OverwriteBehavior",
1402 : .func = dlt_logstorage_check_overwrite_strategy,
1403 : .is_opt = 1
1404 : },
1405 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1406 : .key = "EcuID",
1407 : .func = dlt_logstorage_check_ecuid,
1408 : .is_opt = 1
1409 : },
1410 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1411 : .key = "SpecificSize",
1412 : .func = dlt_logstorage_check_specificsize,
1413 : .is_opt = 1
1414 : },
1415 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1416 : .key = "GzipCompression",
1417 : .func = dlt_logstorage_check_gzip_compression,
1418 : .is_opt = 1
1419 : },
1420 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1421 : .key = "DisableNetwork",
1422 : .func = dlt_logstorage_check_disable_network,
1423 : .is_opt = 1
1424 : }
1425 : };
1426 :
1427 : /* */
1428 : DLT_STATIC DltLogstorageFilterConf
1429 : filter_nonverbose_storage_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1430 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1431 : .key = NULL,
1432 : .func = dlt_logstorage_check_apids,
1433 : .is_opt = 0
1434 : },
1435 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1436 : .key = NULL,
1437 : .func = dlt_logstorage_check_ctids,
1438 : .is_opt = 0
1439 : },
1440 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1441 : .key = NULL,
1442 : .func = dlt_logstorage_store_config_excluded_apids,
1443 : .is_opt = 1
1444 : },
1445 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1446 : .key = NULL,
1447 : .func = dlt_logstorage_store_config_excluded_ctids,
1448 : .is_opt = 1
1449 : },
1450 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1451 : .key = NULL,
1452 : .func = dlt_logstorage_check_loglevel,
1453 : .is_opt = 0
1454 : },
1455 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1456 : .key = NULL,
1457 : .func = NULL,
1458 : .is_opt = 0
1459 : },
1460 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1461 : .key = "File",
1462 : .func = dlt_logstorage_check_filename,
1463 : .is_opt = 0
1464 : },
1465 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1466 : .key = "FileSize",
1467 : .func = dlt_logstorage_check_filesize,
1468 : .is_opt = 0
1469 : },
1470 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1471 : .key = "NOFiles",
1472 : .func = dlt_logstorage_check_nofiles,
1473 : .is_opt = 0
1474 : },
1475 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1476 : .key = NULL,
1477 : .func = dlt_logstorage_check_sync_strategy,
1478 : .is_opt = 1
1479 : },
1480 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1481 : .key = NULL,
1482 : .func = dlt_logstorage_check_overwrite_strategy,
1483 : .is_opt = 1
1484 : },
1485 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1486 : .key = "EcuID",
1487 : .func = dlt_logstorage_check_ecuid,
1488 : .is_opt = 0
1489 : },
1490 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1491 : .key = NULL,
1492 : .func = dlt_logstorage_check_specificsize,
1493 : .is_opt = 1
1494 : },
1495 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1496 : .key = "GzipCompression",
1497 : .func = dlt_logstorage_check_gzip_compression,
1498 : .is_opt = 1
1499 : },
1500 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1501 : .key = NULL,
1502 : .func = dlt_logstorage_check_disable_network,
1503 : .is_opt = 1
1504 : }
1505 : };
1506 :
1507 : DLT_STATIC DltLogstorageFilterConf
1508 : filter_nonverbose_control_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1509 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1510 : .key = "LogAppName",
1511 : .func = dlt_logstorage_check_apids,
1512 : .is_opt = 0
1513 : },
1514 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1515 : .key = "ContextName",
1516 : .func = dlt_logstorage_check_ctids,
1517 : .is_opt = 0
1518 : },
1519 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1520 : .key = NULL,
1521 : .func = dlt_logstorage_store_config_excluded_apids,
1522 : .is_opt = 1
1523 : },
1524 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1525 : .key = NULL,
1526 : .func = dlt_logstorage_store_config_excluded_ctids,
1527 : .is_opt = 1
1528 : },
1529 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1530 : .key = "LogLevel",
1531 : .func = dlt_logstorage_check_loglevel,
1532 : .is_opt = 0
1533 : },
1534 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1535 : .key = "ResetLogLevel",
1536 : .func = dlt_logstorage_check_reset_loglevel,
1537 : .is_opt = 1
1538 : },
1539 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1540 : .key = NULL,
1541 : .func = dlt_logstorage_check_filename,
1542 : .is_opt = 0
1543 : },
1544 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1545 : .key = NULL,
1546 : .func = dlt_logstorage_check_filesize,
1547 : .is_opt = 0
1548 : },
1549 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1550 : .key = NULL,
1551 : .func = dlt_logstorage_check_nofiles,
1552 : .is_opt = 0
1553 : },
1554 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1555 : .key = NULL,
1556 : .func = dlt_logstorage_check_sync_strategy,
1557 : .is_opt = 1
1558 : },
1559 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1560 : .key = NULL,
1561 : .func = dlt_logstorage_check_overwrite_strategy,
1562 : .is_opt = 1
1563 : },
1564 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1565 : .key = "EcuID",
1566 : .func = dlt_logstorage_check_ecuid,
1567 : .is_opt = 0
1568 : },
1569 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1570 : .key = NULL,
1571 : .func = dlt_logstorage_check_specificsize,
1572 : .is_opt = 1
1573 : },
1574 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1575 : .key = "GzipCompression",
1576 : .func = dlt_logstorage_check_gzip_compression,
1577 : .is_opt = 1
1578 : },
1579 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1580 : .key = NULL,
1581 : .func = dlt_logstorage_check_disable_network,
1582 : .is_opt = 1
1583 : }
1584 : };
1585 :
1586 : /**
1587 : * Check filter configuration parameter is valid.
1588 : *
1589 : * @param config DltLogStorageFilterConfig
1590 : * @param ctype DltLogstorageFilterConfType
1591 : * @param value specified property value from configuration file
1592 : * @return 0 on success, -1 otherwise
1593 : */
1594 26 : DLT_STATIC int dlt_logstorage_check_param(DltLogStorageFilterConfig *config,
1595 : DltLogstorageFilterConfType ctype,
1596 : char *value)
1597 : {
1598 26 : if ((config == NULL) || (value == NULL))
1599 : return -1;
1600 :
1601 25 : if (ctype < DLT_LOGSTORAGE_FILTER_CONF_COUNT)
1602 25 : return filter_cfg_entries[ctype].func(config, value);
1603 :
1604 : return -1;
1605 : }
1606 :
1607 540 : DLT_STATIC int dlt_logstorage_get_filter_section_value(DltConfigFile *config_file,
1608 : char *sec_name,
1609 : DltLogstorageFilterConf entry,
1610 : char *value)
1611 : {
1612 : int ret = 0;
1613 :
1614 540 : if ((config_file == NULL) || (sec_name == NULL))
1615 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1616 :
1617 540 : if (entry.key != NULL) {
1618 504 : ret = dlt_config_file_get_value(config_file, sec_name,
1619 : entry.key,
1620 : value);
1621 :
1622 504 : if ((ret != 0) && (entry.is_opt == 0)) {
1623 0 : dlt_vlog(LOG_WARNING,
1624 : "Invalid configuration in section: %s -> %s : %s\n",
1625 : sec_name, entry.key, value);
1626 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1627 : }
1628 :
1629 197 : if ((ret != 0) && (entry.is_opt == 1)) {
1630 197 : dlt_vlog(LOG_DEBUG, "Optional parameter %s not specified\n",
1631 : entry.key);
1632 197 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1633 : }
1634 : }
1635 : else {
1636 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1637 : }
1638 :
1639 : return 0;
1640 : }
1641 :
1642 540 : DLT_STATIC int dlt_logstorage_get_filter_value(DltConfigFile *config_file,
1643 : char *sec_name,
1644 : int index,
1645 : char *value)
1646 : {
1647 : int ret = 0;
1648 : size_t config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION);
1649 : size_t storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION);
1650 : size_t control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION);
1651 :
1652 540 : if ((config_file == NULL) || (sec_name == NULL))
1653 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1654 :
1655 : /* Branch based on section name, no complete string compare needed */
1656 540 : if (strncmp(sec_name,
1657 : DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION,
1658 : config_sec_len) == 0) {
1659 540 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1660 : filter_cfg_entries[index],
1661 : value);
1662 : }
1663 0 : else if (strncmp(sec_name,
1664 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION,
1665 : storage_sec_len) == 0) {
1666 0 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1667 : filter_nonverbose_storage_entries[index],
1668 : value);
1669 : }
1670 0 : else if ((strncmp(sec_name,
1671 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION,
1672 : control_sec_len) == 0)) {
1673 0 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1674 : filter_nonverbose_control_entries[index],
1675 : value);
1676 : }
1677 : else {
1678 0 : dlt_log(LOG_ERR, "Error: Section name not valid \n");
1679 : ret = DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1680 : }
1681 :
1682 : return ret;
1683 : }
1684 :
1685 36 : DLT_STATIC int dlt_logstorage_setup_table(DltLogStorage *handle,
1686 : DltLogStorageFilterConfig *tmp_data)
1687 : {
1688 : int ret = 0;
1689 :
1690 : /* depending on the specified strategy set function pointers for
1691 : * prepare, write and sync */
1692 36 : dlt_logstorage_filter_set_strategy(tmp_data, tmp_data->sync);
1693 :
1694 36 : ret = dlt_logstorage_prepare_table(handle, tmp_data);
1695 :
1696 36 : if (ret != 0) {
1697 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1698 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1699 : }
1700 :
1701 36 : return ret;
1702 : }
1703 : /*Return :
1704 : * DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR - On filter properties or value is not valid
1705 : * DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR - On error while storing in hash table
1706 : */
1707 :
1708 36 : DLT_STATIC int dlt_daemon_offline_setup_filter_properties(DltLogStorage *handle,
1709 : DltConfigFile *config_file,
1710 : char *sec_name)
1711 : {
1712 : DltLogStorageFilterConfig tmp_data;
1713 36 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1] = { '\0' };
1714 : int i = 0;
1715 : int ret = 0;
1716 :
1717 36 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL))
1718 : return DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1719 :
1720 : memset(&tmp_data, 0, sizeof(DltLogStorageFilterConfig));
1721 36 : tmp_data.log_level = DLT_LOG_VERBOSE;
1722 : tmp_data.reset_log_level = DLT_LOG_OFF;
1723 36 : tmp_data.disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1724 :
1725 576 : for (i = 0; i < DLT_LOGSTORAGE_FILTER_CONF_COUNT; i++) {
1726 540 : ret = dlt_logstorage_get_filter_value(config_file, sec_name, i, value);
1727 :
1728 540 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR)
1729 : return ret;
1730 :
1731 540 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE)
1732 233 : continue;
1733 :
1734 : /* check value and store temporary */
1735 307 : ret = dlt_logstorage_check_param(&tmp_data, i, value);
1736 :
1737 307 : if (ret != 0) {
1738 0 : if (tmp_data.apids != NULL) {
1739 0 : free(tmp_data.apids);
1740 : tmp_data.apids = NULL;
1741 : }
1742 :
1743 0 : if (tmp_data.ctids != NULL) {
1744 0 : free(tmp_data.ctids);
1745 : tmp_data.ctids = NULL;
1746 : }
1747 :
1748 0 : if (tmp_data.excluded_apids != NULL) {
1749 0 : free(tmp_data.excluded_apids);
1750 : tmp_data.excluded_apids = NULL;
1751 : }
1752 :
1753 0 : if (tmp_data.excluded_ctids != NULL) {
1754 0 : free(tmp_data.excluded_ctids);
1755 : tmp_data.excluded_ctids = NULL;
1756 : }
1757 :
1758 0 : if (tmp_data.file_name != NULL) {
1759 0 : free(tmp_data.file_name);
1760 : tmp_data.file_name = NULL;
1761 : }
1762 :
1763 0 : if (tmp_data.working_file_name != NULL) {
1764 0 : free(tmp_data.working_file_name);
1765 : tmp_data.working_file_name = NULL;
1766 : }
1767 :
1768 0 : if (tmp_data.ecuid != NULL) {
1769 0 : free(tmp_data.ecuid);
1770 : tmp_data.ecuid = NULL;
1771 : }
1772 :
1773 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1774 : }
1775 : }
1776 :
1777 36 : if(dlt_logstorage_count_ids(tmp_data.excluded_apids) > 1 && dlt_logstorage_count_ids(tmp_data.excluded_ctids) > 1) {
1778 0 : dlt_vlog(LOG_WARNING, "%s: Logstorage does not support both multiple excluded applications and contexts\n", __func__);
1779 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1780 : }
1781 :
1782 : /* filter configuration is valid */
1783 36 : ret = dlt_logstorage_setup_table(handle, &tmp_data);
1784 :
1785 36 : if (ret != 0) {
1786 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1787 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1788 : }
1789 : else { /* move to next free filter configuration, if no error occurred */
1790 36 : handle->num_configs += 1;
1791 : }
1792 :
1793 : /* free tmp_data */
1794 36 : dlt_logstorage_filter_config_free(&tmp_data);
1795 :
1796 36 : return ret;
1797 : }
1798 :
1799 : /**
1800 : * dlt_logstorage_check_maintain_logstorage_loglevel
1801 : *
1802 : * Evaluate to maintain the logstorage loglevel setting. This is an optional
1803 : * configuration parameter
1804 : * If the given value cannot be associated with an overwrite, the default value
1805 : * will be assigned.
1806 : *
1807 : * @param config DltLogStorage
1808 : * @param value string given in config file
1809 : * @return 0 on success, -1 on error
1810 : */
1811 0 : DLT_STATIC int dlt_logstorage_check_maintain_logstorage_loglevel(DltLogStorage *handle,
1812 : char *value)
1813 : {
1814 0 : if ((handle == NULL) || (value == NULL))
1815 : {
1816 : return -1;
1817 : }
1818 :
1819 0 : if ((strncmp(value, "OFF", 3) == 0) || (strncmp(value, "0", 1) == 0))
1820 : {
1821 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF;
1822 : }
1823 0 : else if ((strncmp(value, "ON", 2) == 0) || (strncmp(value, "1", 1) == 0))
1824 : {
1825 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1826 : }
1827 : else
1828 : {
1829 0 : dlt_vlog(LOG_ERR,
1830 : "Wrong value for Maintain logstorage loglevel section name: %s\n", value);
1831 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1832 0 : return -1;
1833 : }
1834 :
1835 : return 0;
1836 : }
1837 :
1838 : DLT_STATIC DltLogstorageGeneralConf
1839 : general_cfg_entries[DLT_LOGSTORAGE_GENERAL_CONF_COUNT] = {
1840 : [DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL] = {
1841 : .key = "MaintainLogstorageLogLevel",
1842 : .func = dlt_logstorage_check_maintain_logstorage_loglevel,
1843 : .is_opt = 1
1844 : }
1845 : };
1846 :
1847 : /**
1848 : * Check if DltLogstorage General configuration parameter is valid.
1849 : *
1850 : * @param handle pointer to DltLogstorage structure
1851 : * @param ctype Logstorage general configuration type
1852 : * @param value specified property value from configuration file
1853 : * @return 0 on success, -1 otherwise
1854 : */
1855 0 : DLT_STATIC int dlt_logstorage_check_general_param(DltLogStorage *handle,
1856 : DltLogstorageGeneralConfType ctype,
1857 : char *value)
1858 : {
1859 0 : if ((handle == NULL) || (value == NULL))
1860 : {
1861 : return -1;
1862 : }
1863 :
1864 0 : if (ctype < DLT_LOGSTORAGE_GENERAL_CONF_COUNT)
1865 : {
1866 0 : return general_cfg_entries[ctype].func(handle, value);
1867 : }
1868 :
1869 : return -1;
1870 : }
1871 :
1872 0 : DLT_STATIC int dlt_daemon_setup_general_properties(DltLogStorage *handle,
1873 : DltConfigFile *config_file,
1874 : char *sec_name)
1875 : {
1876 : DltLogstorageGeneralConfType type = DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL;
1877 0 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {0};
1878 :
1879 0 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL))
1880 : {
1881 : return -1;
1882 : }
1883 :
1884 0 : for ( ; type < DLT_LOGSTORAGE_GENERAL_CONF_COUNT ; type++)
1885 : {
1886 0 : if (dlt_config_file_get_value(config_file,
1887 : sec_name,
1888 0 : general_cfg_entries[type].key,
1889 : value) == 0)
1890 : {
1891 0 : if (dlt_logstorage_check_general_param(handle, type, value) != 0)
1892 : {
1893 0 : dlt_vlog(LOG_WARNING,
1894 : "General parameter %s [%s] is invalid\n",
1895 : general_cfg_entries[type].key, value);
1896 : }
1897 : }
1898 : else
1899 : {
1900 0 : if (general_cfg_entries[type].is_opt == 1)
1901 : {
1902 0 : dlt_vlog(LOG_DEBUG,
1903 : "Optional General parameter %s not given\n",
1904 : general_cfg_entries[type].key);
1905 : }
1906 : else
1907 : {
1908 0 : dlt_vlog(LOG_ERR,
1909 : "General parameter %s not given\n",
1910 : general_cfg_entries[type].key);
1911 0 : return -1;
1912 : }
1913 : }
1914 : }
1915 :
1916 : return 0;
1917 : }
1918 :
1919 : /**
1920 : * dlt_logstorage_store_filters
1921 : *
1922 : * This function reads the filter keys and values
1923 : * and stores them into the hash map
1924 : *
1925 : * @param handle DLT Logstorage handle
1926 : * @param config_file_name Configuration file name
1927 : * @return 0 on success, -1 on error, 1 on warning
1928 : *
1929 : */
1930 11 : DLT_STATIC int dlt_logstorage_store_filters(DltLogStorage *handle,
1931 : char *config_file_name)
1932 : {
1933 : DltConfigFile *config = NULL;
1934 : int sec = 0;
1935 11 : int num_sec = 0;
1936 : int ret = 0;
1937 : /* we have to make sure that this function returns success if atleast one
1938 : * filter configuration is valid and stored */
1939 : int valid = -1;
1940 :
1941 11 : if (config_file_name == NULL) {
1942 1 : dlt_vlog(LOG_ERR, "%s unexpected parameter received\n", __func__);
1943 1 : return -1;
1944 : }
1945 :
1946 10 : config = dlt_config_file_init(config_file_name);
1947 :
1948 10 : if (config == NULL) {
1949 0 : dlt_log(LOG_CRIT, "Failed to open filter configuration file\n");
1950 0 : return -1;
1951 : }
1952 :
1953 10 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF;
1954 10 : dlt_config_file_get_num_sections(config, &num_sec);
1955 :
1956 46 : for (sec = 0; sec < num_sec; sec++) {
1957 : char sec_name[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1];
1958 :
1959 36 : if (dlt_config_file_get_section_name(config, sec, sec_name) == -1) {
1960 0 : dlt_log(LOG_CRIT, "Failed to read section name\n");
1961 0 : dlt_config_file_release(config);
1962 0 : return -1;
1963 : }
1964 :
1965 36 : if (strstr(sec_name, GENERAL_BASE_NAME) != NULL) {
1966 0 : if (dlt_daemon_setup_general_properties(handle, config, sec_name) == -1)
1967 : {
1968 0 : dlt_log(LOG_CRIT, "General configuration is invalid\n");
1969 0 : continue;
1970 : }
1971 : }
1972 36 : else if (dlt_logstorage_validate_filter_name(sec_name) == 0)
1973 : {
1974 36 : ret = dlt_daemon_offline_setup_filter_properties(handle, config, sec_name);
1975 :
1976 36 : if (ret == DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR) {
1977 : break;
1978 : }
1979 36 : else if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR)
1980 : {
1981 : valid = 1;
1982 0 : dlt_vlog(LOG_WARNING,
1983 : "%s filter configuration is invalid \n",
1984 : sec_name);
1985 : /* Continue reading next filter section */
1986 0 : continue;
1987 : }
1988 : else
1989 : /* Filter properties read and stored successfuly */
1990 36 : if (valid != 1)
1991 : valid = 0;
1992 : }
1993 : else { /* unknown section */
1994 0 : dlt_vlog(LOG_WARNING, "Unknown section: %s", sec_name);
1995 : }
1996 : }
1997 :
1998 10 : dlt_config_file_release(config);
1999 :
2000 10 : return valid;
2001 : }
2002 :
2003 : /**
2004 : * dlt_logstorage_load_config
2005 : *
2006 : * Read dlt_logstorage.conf file and setup filters in hash table
2007 : * Hash table key consists of "APID:CTID", e.g "APP1:CTX1". If
2008 : * wildcards used for application id or context id, the hash table
2009 : * key consists of none wildcard value, e.g. apid=.*, cxid=CTX1
2010 : * results in "CTX1".
2011 : *
2012 : * Combination of two wildcards is not allowed if ECUID is not specified.
2013 : *
2014 : * @param handle DLT Logstorage handle
2015 : * @return 0 on success, -1 on error, 1 on warning
2016 : */
2017 10 : DLT_STATIC int dlt_logstorage_load_config(DltLogStorage *handle)
2018 : {
2019 10 : char config_file_name[PATH_MAX] = {0};
2020 : int ret = 0;
2021 :
2022 : /* Check if handle is NULL or already initialized or already configured */
2023 10 : if ((handle == NULL) ||
2024 9 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED))
2025 : return -1;
2026 :
2027 : /* Check if this device config was already setup */
2028 9 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) {
2029 0 : dlt_vlog(LOG_ERR,
2030 : "%s: Device already configured. Send disconnect first.\n",
2031 : __func__);
2032 0 : return -1;
2033 : }
2034 :
2035 9 : if (snprintf(config_file_name,
2036 : PATH_MAX,
2037 : "%s/%s",
2038 9 : handle->device_mount_point,
2039 : DLT_OFFLINE_LOGSTORAGE_CONFIG_FILE_NAME) < 0) {
2040 0 : dlt_log(LOG_ERR,
2041 : "Creating configuration file path string failed\n");
2042 0 : return -1;
2043 : }
2044 9 : config_file_name[PATH_MAX - 1] = 0;
2045 9 : ret = dlt_logstorage_store_filters(handle, config_file_name);
2046 :
2047 9 : if (ret == 1) {
2048 0 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
2049 0 : return 1;
2050 : }
2051 9 : else if (ret != 0)
2052 : {
2053 0 : dlt_log(LOG_ERR,
2054 : "dlt_logstorage_load_config Error : Storing filters failed\n");
2055 0 : return -1;
2056 : }
2057 :
2058 9 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
2059 :
2060 9 : return 0;
2061 : }
2062 :
2063 : /**
2064 : * dlt_logstorage_device_connected
2065 : *
2066 : * Initializes DLT Offline Logstorage with respect to device status
2067 : *
2068 : * @param handle DLT Logstorage handle
2069 : * @param mount_point Device mount path
2070 : * @return 0 on success, -1 on error, 1 on warning
2071 : */
2072 9 : int dlt_logstorage_device_connected(DltLogStorage *handle, const char *mount_point)
2073 : {
2074 9 : if ((handle == NULL) || (mount_point == NULL)) {
2075 1 : dlt_log(LOG_ERR, "Handle error \n");
2076 1 : return -1;
2077 : }
2078 :
2079 8 : if (handle->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
2080 0 : dlt_log(LOG_WARNING,
2081 : "Device already connected. Send disconnect, connect request\n");
2082 :
2083 0 : dlt_logstorage_device_disconnected(
2084 : handle,
2085 : DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
2086 : }
2087 :
2088 8 : strncpy(handle->device_mount_point, mount_point, DLT_MOUNT_PATH_MAX);
2089 8 : handle->device_mount_point[DLT_MOUNT_PATH_MAX] = 0;
2090 8 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED;
2091 8 : handle->config_status = 0;
2092 8 : handle->write_errors = 0;
2093 8 : handle->num_configs = 0;
2094 8 : handle->newest_file_list = NULL;
2095 :
2096 8 : switch (handle->config_mode) {
2097 8 : case DLT_LOGSTORAGE_CONFIG_FILE:
2098 : /* Setup logstorage with config file settings */
2099 8 : return dlt_logstorage_load_config(handle);
2100 : default:
2101 : return -1;
2102 : }
2103 : }
2104 :
2105 : /**
2106 : * dlt_logstorage_device_disconnected
2107 : *
2108 : * De-Initializes DLT Offline Logstorage with respect to device status
2109 : *
2110 : * @param handle DLT Logstorage handle
2111 : * @param reason Reason for disconnect
2112 : * @return 0 on success, -1 on error
2113 : *
2114 : */
2115 8 : int dlt_logstorage_device_disconnected(DltLogStorage *handle, int reason)
2116 : {
2117 : DltNewestFileName *tmp = NULL;
2118 8 : if (handle == NULL)
2119 : return -1;
2120 :
2121 : /* If configuration loading was done, free it */
2122 7 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)
2123 6 : dlt_logstorage_free(handle, reason);
2124 :
2125 : /* Reset all device status */
2126 7 : memset(handle->device_mount_point, 0, sizeof(char) * (DLT_MOUNT_PATH_MAX + 1));
2127 7 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED;
2128 7 : handle->config_status = 0;
2129 7 : handle->write_errors = 0;
2130 7 : handle->num_configs = 0;
2131 :
2132 39 : while (handle->newest_file_list) {
2133 : tmp = handle->newest_file_list;
2134 32 : handle->newest_file_list = tmp->next;
2135 32 : if (tmp->file_name) {
2136 32 : free(tmp->file_name);
2137 : tmp->file_name = NULL;
2138 : }
2139 32 : if (tmp->newest_file) {
2140 23 : free(tmp->newest_file);
2141 : tmp->newest_file = NULL;
2142 : }
2143 32 : free(tmp);
2144 : tmp = NULL;
2145 : }
2146 :
2147 : return 0;
2148 : }
2149 :
2150 : /**
2151 : * dlt_logstorage_get_loglevel_by_key
2152 : *
2153 : * Obtain the log level for the provided key
2154 : * This function can be used to obtain log level when the actual
2155 : * key stored in the Hash map is availble with the caller
2156 : *
2157 : * @param handle DltLogstorage handle
2158 : * @param key key to search for in Hash MAP
2159 : * @return log level on success:, -1 on error
2160 : */
2161 37 : int dlt_logstorage_get_loglevel_by_key(DltLogStorage *handle, char *key)
2162 : {
2163 37 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
2164 : int num_configs = 0;
2165 : int i = 0;
2166 : int log_level = 0;
2167 :
2168 : /* Check if handle is NULL,already initialized or already configured */
2169 37 : if ((handle == NULL) ||
2170 37 : (key == NULL) ||
2171 36 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2172 36 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
2173 : return -1;
2174 :
2175 36 : num_configs = dlt_logstorage_list_find(key, &(handle->config_list), config);
2176 :
2177 36 : if (num_configs == 0)
2178 : {
2179 0 : dlt_vlog(LOG_WARNING, "Configuration for key [%s] not found!\n", key);
2180 0 : return -1;
2181 : }
2182 36 : else if (num_configs == 1)
2183 : {
2184 36 : if (config[0] != NULL)
2185 : {
2186 36 : log_level = config[0]->log_level;
2187 : }
2188 : }
2189 : else
2190 : {
2191 : /**
2192 : * Multiple configurations found, raise a warning to the user and go
2193 : * for the more verbose one.
2194 : */
2195 0 : dlt_vlog(LOG_WARNING, "Multiple configuration for key [%s] found,"
2196 : " return the highest log level!\n", key);
2197 :
2198 0 : for (i = 0; i < num_configs; i++)
2199 : {
2200 0 : if ((config[i] != NULL) && (config[i]->log_level > log_level))
2201 : {
2202 : log_level = config[i]->log_level;
2203 : }
2204 : }
2205 : }
2206 :
2207 : return log_level;
2208 : }
2209 :
2210 : /**
2211 : * dlt_logstorage_get_config
2212 : *
2213 : * Obtain the configuration data of all filters for provided apid and ctid
2214 : *
2215 : * @param handle DltLogStorage handle
2216 : * @param config [out] Pointer to array of filter configurations
2217 : * @param apid application id
2218 : * @param ctid context id
2219 : * @param ecuid ecu id
2220 : * @return number of configurations found
2221 : */
2222 5885 : int dlt_logstorage_get_config(DltLogStorage *handle,
2223 : DltLogStorageFilterConfig **config,
2224 : char *apid,
2225 : char *ctid,
2226 : char *ecuid)
2227 : {
2228 : DltLogStorageFilterConfig **cur_config_ptr = NULL;
2229 5885 : char key[DLT_CONFIG_FILE_SECTIONS_MAX][DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] = { { '\0' }, { '\0' }, { '\0' } };
2230 : int i = 0;
2231 : size_t apid_len = 0;
2232 : size_t ctid_len = 0;
2233 : size_t ecuid_len = 0;
2234 : int num_configs = 0;
2235 : int num = 0;
2236 :
2237 : /* Check if handle is NULL,already initialized or already configured */
2238 5885 : if ((handle == NULL) || (config == NULL) ||
2239 5884 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2240 5884 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) ||
2241 : (ecuid == NULL))
2242 : return 0;
2243 :
2244 : /* Prepare possible keys with
2245 : * Possible combinations are
2246 : * ecu::
2247 : * ecu:apid:ctid
2248 : * :apid:ctid
2249 : * ecu::ctid
2250 : * ecu:apid:
2251 : * ::ctid
2252 : * :apid: */
2253 :
2254 5884 : ecuid_len = strlen(ecuid);
2255 5884 : if (ecuid_len > DLT_ID_SIZE)
2256 : ecuid_len = DLT_ID_SIZE;
2257 :
2258 5884 : if ((apid == NULL) && (ctid == NULL)) {
2259 : /* ecu:: */
2260 0 : snprintf(key[0], sizeof(key[0]), "%.*s::", (int)ecuid_len, ecuid);
2261 :
2262 0 : num_configs = dlt_logstorage_list_find(key[0], &(handle->config_list),
2263 : config);
2264 0 : return num_configs;
2265 : }
2266 :
2267 5884 : if (apid != NULL){
2268 5884 : apid_len = strlen(apid);
2269 5884 : if (apid_len > DLT_ID_SIZE)
2270 : apid_len = DLT_ID_SIZE;
2271 : }
2272 5884 : if (ctid != NULL){
2273 5884 : ctid_len = strlen(ctid);
2274 5884 : if (ctid_len > DLT_ID_SIZE)
2275 : ctid_len = DLT_ID_SIZE;
2276 : }
2277 :
2278 : /* :apid: */
2279 5884 : snprintf(key[0], sizeof(key[0]), ":%.*s:", (int)apid_len, apid ? apid : "");
2280 :
2281 : /* ::ctid */
2282 5884 : snprintf(key[1], sizeof(key[1]), "::%.*s", (int)ctid_len, ctid ? ctid : "");
2283 :
2284 : /* :apid:ctid */
2285 : snprintf(key[2], sizeof(key[2]), ":%.*s:%.*s", (int)apid_len, apid ? apid : "", (int)ctid_len, ctid ? ctid : "");
2286 :
2287 : /* ecu:apid:ctid */
2288 5884 : snprintf(key[3], sizeof(key[3]), "%.*s:%.*s:%.*s",
2289 : (int)ecuid_len, ecuid,
2290 : (int)apid_len, apid ? apid : "",
2291 : (int)ctid_len, ctid ? ctid : "");
2292 :
2293 : /* ecu:apid: */
2294 : snprintf(key[4], sizeof(key[4]), "%.*s:%.*s:",
2295 : (int)ecuid_len, ecuid,
2296 : (int)apid_len, apid ? apid : "");
2297 :
2298 : /* ecu::ctid */
2299 : snprintf(key[5], sizeof(key[5]), "%.*s::%.*s",
2300 : (int)ecuid_len, ecuid,
2301 : (int)ctid_len, ctid ? ctid : "");
2302 :
2303 : /* ecu:: */
2304 : snprintf(key[6], sizeof(key[6]), "%.*s::",
2305 : (int)ecuid_len, ecuid);
2306 :
2307 45864 : for (i = 0; i < DLT_OFFLINE_LOGSTORAGE_MAX_POSSIBLE_KEYS; i++)
2308 : {
2309 40282 : cur_config_ptr = &config[num_configs];
2310 40282 : num = dlt_logstorage_list_find(key[i], &(handle->config_list),
2311 : cur_config_ptr);
2312 40282 : num_configs += num;
2313 : /* If all filter configurations matched, stop and return */
2314 40282 : if (num_configs == handle->num_configs)
2315 : {
2316 : break;
2317 : }
2318 : }
2319 :
2320 : return num_configs;
2321 : }
2322 :
2323 : /**
2324 : * dlt_logstorage_filter
2325 : *
2326 : * Check if log message need to be stored in a certain device based on filter
2327 : * config
2328 : * - get all DltLogStorageFilterConfig from hash table possible by given
2329 : * apid/ctid (apid:, :ctid, apid:ctid
2330 : * - for each found structure, compare message log level with configured one
2331 : *
2332 : * @param handle DltLogStorage handle
2333 : * @param config Pointer to array of filter configurations
2334 : * @param apid application id
2335 : * @param ctid context id
2336 : * @param log_level Log level of message
2337 : * @param ecuid EcuID given in the message
2338 : * @return number of found configurations
2339 : */
2340 5850 : DLT_STATIC int dlt_logstorage_filter(DltLogStorage *handle,
2341 : DltLogStorageFilterConfig **config,
2342 : char *apid,
2343 : char *ctid,
2344 : char *ecuid,
2345 : int log_level)
2346 : {
2347 : int i = 0;
2348 : int num = 0;
2349 :
2350 5850 : if ((handle == NULL) || (config == NULL) || (ecuid == NULL))
2351 : return -1;
2352 :
2353 : /* filter on names: find DltLogStorageFilterConfig structures */
2354 5849 : num = dlt_logstorage_get_config(handle, config, apid, ctid, ecuid);
2355 :
2356 5849 : if (num == 0) {
2357 231 : dlt_vlog(LOG_DEBUG,
2358 : "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]\n",
2359 : __func__, apid, ctid, ecuid);
2360 231 : return 0;
2361 : }
2362 :
2363 11254 : for (i = 0 ; i < num ; i++)
2364 : {
2365 5636 : if (config[i] == NULL)
2366 : {
2367 0 : dlt_vlog(LOG_DEBUG,
2368 : "%s: config[%d] is NULL, continue the filter loop\n",
2369 : __func__, i);
2370 0 : continue;
2371 : }
2372 :
2373 : /* filter on log level */
2374 5636 : if (log_level > config[i]->log_level) {
2375 6 : dlt_vlog(LOG_DEBUG,
2376 : "%s: Requested log level (%d) is higher than config[%d]->log_level (%d). Set the config to NULL and continue the filter loop\n",
2377 : __func__, log_level, i, config[i]->log_level);
2378 6 : config[i] = NULL;
2379 6 : continue;
2380 : }
2381 :
2382 : /* filter on ECU id only if EcuID is set */
2383 5630 : if (config[i]->ecuid != NULL) {
2384 5630 : if (strncmp(ecuid, config[i]->ecuid, DLT_ID_SIZE) != 0)
2385 : {
2386 0 : dlt_vlog(LOG_DEBUG,
2387 : "%s: ECUID does not match (Requested=%s, config[%d]=%s). Set the config to NULL and continue the filter loop\n",
2388 : __func__, ecuid, i, config[i]->ecuid);
2389 0 : config[i] = NULL;
2390 0 : continue;
2391 : }
2392 : }
2393 :
2394 5630 : if(config[i]->excluded_apids != NULL && config[i]->excluded_ctids != NULL) {
2395 : /* Filter on excluded application and context */
2396 6 : if(apid != NULL && ctid != NULL && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)
2397 3 : && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2398 3 : dlt_vlog(LOG_DEBUG, "%s: %s matches with [%s] and %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2399 3 : __func__, apid, config[i]->excluded_apids, ctid, config[i]->excluded_ctids);
2400 3 : config[i] = NULL;
2401 : }
2402 : }
2403 5624 : else if(config[i]->excluded_apids == NULL) {
2404 : /* Only filter on excluded contexts */
2405 5618 : if(ctid != NULL && config[i]->excluded_ctids != NULL && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2406 3 : dlt_vlog(LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2407 3 : __func__, ctid, config[i]->excluded_ctids);
2408 3 : config[i] = NULL;
2409 : }
2410 : }
2411 6 : else if(config[i]->excluded_ctids == NULL) {
2412 : /* Only filter on excluded applications */
2413 6 : if(apid != NULL && config[i]->excluded_apids != NULL && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)) {
2414 3 : dlt_vlog(LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2415 3 : __func__, apid, config[i]->excluded_apids);
2416 3 : config[i] = NULL;
2417 : }
2418 : }
2419 : }
2420 :
2421 : return num;
2422 : }
2423 :
2424 : /**
2425 : * dlt_logstorage_write
2426 : *
2427 : * Write a message to one or more configured log files, based on filter
2428 : * configuration.
2429 : *
2430 : * @param handle DltLogStorage handle
2431 : * @param uconfig User configurations for log file
2432 : * @param data1 Data buffer of message header
2433 : * @param size1 Size of message header buffer
2434 : * @param data2 Data buffer of extended message body
2435 : * @param size2 Size of extended message body
2436 : * @param data3 Data buffer of message body
2437 : * @param size3 Size of message body
2438 : * @param disable_nw Flag to disable network routing
2439 : * @return 0 on success or write errors < max write errors, -1 on error
2440 : */
2441 5843 : int dlt_logstorage_write(DltLogStorage *handle,
2442 : DltLogStorageUserConfig *uconfig,
2443 : unsigned char *data1,
2444 : int size1,
2445 : unsigned char *data2,
2446 : int size2,
2447 : unsigned char *data3,
2448 : int size3,
2449 : int *disable_nw)
2450 : {
2451 5843 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
2452 :
2453 : int i = 0;
2454 : int ret = 0;
2455 : int num = 0;
2456 : int err = 0;
2457 : /* data2 contains DltStandardHeader, DltStandardHeaderExtra and
2458 : * DltExtendedHeader. We are interested in ecuid, apid, ctid and loglevel */
2459 : DltExtendedHeader *extendedHeader = NULL;
2460 : DltStandardHeaderExtra *extraHeader = NULL;
2461 : DltStandardHeader *standardHeader = NULL;
2462 : size_t standardHeaderExtraLen = sizeof(DltStandardHeaderExtra);
2463 : size_t header_len = 0;
2464 : DltNewestFileName *tmp = NULL;
2465 : int found = 0;
2466 :
2467 : int log_level = -1;
2468 :
2469 5843 : if ((handle == NULL) || (uconfig == NULL) ||
2470 5842 : (data1 == NULL) || (data2 == NULL) || (data3 == NULL) ||
2471 5842 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2472 5842 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
2473 : return 0;
2474 :
2475 : /* Calculate real length of DltStandardHeaderExtra */
2476 : standardHeader = (DltStandardHeader *)data2;
2477 :
2478 5842 : if (!DLT_IS_HTYP_WEID(standardHeader->htyp))
2479 : standardHeaderExtraLen -= (size_t)DLT_ID_SIZE;
2480 :
2481 5842 : if (!DLT_IS_HTYP_WSID(standardHeader->htyp))
2482 5 : standardHeaderExtraLen -= (size_t)DLT_SIZE_WSID;
2483 :
2484 5842 : if (!DLT_IS_HTYP_WTMS(standardHeader->htyp))
2485 2 : standardHeaderExtraLen -= (size_t)DLT_SIZE_WTMS;
2486 :
2487 : extraHeader = (DltStandardHeaderExtra *)(data2
2488 : + sizeof(DltStandardHeader));
2489 :
2490 5842 : if (DLT_IS_HTYP_UEH(standardHeader->htyp)) {
2491 5842 : header_len = sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + standardHeaderExtraLen;
2492 :
2493 : /* check if size2 is big enough to contain expected DLT message header */
2494 5842 : if ((size_t)size2 < header_len) {
2495 0 : dlt_vlog(LOG_ERR, "%s: DLT message header is too small\n", __func__);
2496 0 : return 0;
2497 : }
2498 :
2499 5842 : extendedHeader = (DltExtendedHeader *)(data2
2500 5842 : + sizeof(DltStandardHeader) + standardHeaderExtraLen);
2501 :
2502 5842 : log_level = DLT_GET_MSIN_MTIN(extendedHeader->msin);
2503 :
2504 : /* check if log message need to be stored in a certain device based on
2505 : * filter configuration */
2506 5842 : num = dlt_logstorage_filter(handle, config, extendedHeader->apid,
2507 5842 : extendedHeader->ctid, extraHeader->ecu, log_level);
2508 :
2509 5842 : if ((num == 0) || (num == -1)) {
2510 231 : dlt_vlog(LOG_DEBUG,
2511 : "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]!\n",
2512 : __func__, extendedHeader->apid, extendedHeader->ctid, extraHeader->ecu);
2513 231 : return 0;
2514 : }
2515 : }
2516 : else {
2517 0 : header_len = sizeof(DltStandardHeader) + standardHeaderExtraLen;
2518 :
2519 : /* check if size2 is big enough to contain expected DLT message header */
2520 0 : if ((size_t)size2 < header_len) {
2521 0 : dlt_log(LOG_ERR, "DLT message header is too small (without extended header)\n");
2522 0 : return 0;
2523 : }
2524 :
2525 : log_level = DLT_LOG_VERBOSE;
2526 :
2527 : /* check if log message need to be stored in a certain device based on
2528 : * filter configuration */
2529 0 : num = dlt_logstorage_filter(handle, config, NULL,
2530 0 : NULL, extraHeader->ecu, log_level);
2531 :
2532 0 : if ((num == 0) || (num == -1)) {
2533 0 : dlt_log(LOG_DEBUG, "No valid filter configuration found!\n");
2534 0 : return 0;
2535 : }
2536 : }
2537 :
2538 : /* store log message in every found filter */
2539 11226 : for (i = 0; i < num; i++)
2540 : {
2541 5615 : if (config[i] == NULL)
2542 : {
2543 6 : dlt_vlog(LOG_DEBUG,
2544 : "%s: config[%d] is NULL. Continue the filter loop\n",
2545 : __func__, i);
2546 6 : continue;
2547 : }
2548 :
2549 : /* If file name is not present, the filter is non verbose control filter
2550 : * hence skip storing */
2551 5609 : if (config[i]->file_name == NULL)
2552 : {
2553 0 : dlt_vlog(LOG_DEBUG,
2554 : "%s: config[%d]->file_name is NULL, which equals to non verbose control filter. Continue the filter loop\n",
2555 : __func__, i);
2556 0 : continue;
2557 : }
2558 :
2559 : /* Disable network routing */
2560 5609 : if ((config[i]->disable_network_routing & DLT_LOGSTORAGE_DISABLE_NW_ON) > 0) {
2561 201 : *disable_nw = 1;
2562 201 : if (config[i]->ecuid == NULL)
2563 0 : dlt_vlog(LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__,
2564 : config[i]->apids, config[i]->ctids);
2565 : else
2566 201 : dlt_vlog(LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__,
2567 : config[i]->apids, config[i]->ctids, config[i]->ecuid);
2568 : }
2569 :
2570 5609 : if (config[i]->skip == 1)
2571 : {
2572 2157 : dlt_vlog(LOG_DEBUG,
2573 : "%s: config[%d] (filename=%s) is skipped. Continue the filter loop\n",
2574 : __func__, i, config[i]->file_name);
2575 2157 : continue;
2576 : }
2577 :
2578 3452 : tmp = handle->newest_file_list;
2579 23250 : while (tmp) {
2580 23250 : if (strcmp(tmp->file_name, config[i]->file_name) == 0) {
2581 : found = 1;
2582 : break;
2583 : }
2584 : else {
2585 19798 : tmp = tmp->next;
2586 : }
2587 : }
2588 3452 : if (!found) {
2589 0 : dlt_vlog(LOG_ERR, "Cannot find out record for filename [%s]\n",
2590 : config[i]->file_name);
2591 0 : return -1;
2592 : }
2593 :
2594 : /* prepare log file (create and/or open)*/
2595 3452 : if (config[i]->ecuid == NULL)
2596 0 : dlt_vlog(LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__,
2597 : config[i]->apids, config[i]->ctids);
2598 : else
2599 3452 : dlt_vlog(LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__,
2600 : config[i]->apids, config[i]->ctids, config[i]->ecuid);
2601 :
2602 3452 : if (tmp != NULL) {
2603 3452 : ret = config[i]->dlt_logstorage_prepare(config[i],
2604 : uconfig,
2605 3452 : handle->device_mount_point,
2606 3452 : size1 + size2 + size3,
2607 : tmp);
2608 : }
2609 :
2610 3452 : if (ret == 0 && config[i]->skip == 1) {
2611 4 : continue;
2612 : }
2613 :
2614 3428 : if ((ret == 0) &&
2615 3428 : (config[i]->sync == DLT_LOGSTORAGE_SYNC_UNSET ||
2616 : config[i]->sync == DLT_LOGSTORAGE_SYNC_ON_MSG)) {
2617 : /* It is abnormal if working file is still NULL after preparation. */
2618 339 : if (!config[i]->working_file_name) {
2619 0 : dlt_vlog(LOG_ERR, "Failed to prepare working file for %s\n",
2620 : config[i]->file_name);
2621 0 : return -1;
2622 : }
2623 : else {
2624 : /* After preparation phase, update newest file info
2625 : * it means there is new file created, newest file info must be updated.
2626 : */
2627 339 : if (tmp->newest_file) {
2628 332 : free(tmp->newest_file);
2629 332 : tmp->newest_file = NULL;
2630 : }
2631 339 : tmp->newest_file = strdup(config[i]->working_file_name);
2632 339 : tmp->wrap_id = config[i]->wrap_id;
2633 : }
2634 : }
2635 :
2636 3448 : if (ret == 0) { /* log data (write) */
2637 3428 : ret = config[i]->dlt_logstorage_write(config[i],
2638 : uconfig,
2639 3428 : handle->device_mount_point,
2640 : data1,
2641 : size1,
2642 : data2,
2643 : size2,
2644 : data3,
2645 : size3);
2646 :
2647 3428 : if (ret == 0) {
2648 : /* In case of behavior CACHED_BASED, the newest file info
2649 : * must be updated right after writing phase.
2650 : * That is because in writing phase, it could also perform
2651 : * sync to file which actions could impact to the log file info.
2652 : * If both working file name and newest file name are unavailable,
2653 : * it means the sync to file is not performed yet, wait for next times.
2654 : */
2655 3428 : if (config[i]->sync != DLT_LOGSTORAGE_SYNC_ON_MSG &&
2656 : config[i]->sync != DLT_LOGSTORAGE_SYNC_UNSET) {
2657 3089 : if (config[i]->working_file_name) {
2658 1688 : if (tmp->newest_file) {
2659 1672 : free(tmp->newest_file);
2660 1672 : tmp->newest_file = NULL;
2661 : }
2662 1688 : tmp->newest_file = strdup(config[i]->working_file_name);
2663 1688 : tmp->wrap_id = config[i]->wrap_id;
2664 : }
2665 : }
2666 :
2667 : /* flush to be sure log is stored on device */
2668 3428 : ret = config[i]->dlt_logstorage_sync(config[i],
2669 : uconfig,
2670 : handle->device_mount_point,
2671 : DLT_LOGSTORAGE_SYNC_ON_MSG);
2672 :
2673 3428 : if (ret != 0)
2674 0 : dlt_log(LOG_ERR,
2675 : "dlt_logstorage_write: Unable to sync.\n");
2676 : }
2677 : else {
2678 0 : handle->write_errors += 1;
2679 :
2680 0 : if (handle->write_errors >=
2681 : DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS)
2682 : err = -1;
2683 :
2684 0 : dlt_log(LOG_ERR,
2685 : "dlt_logstorage_write: Unable to write.\n");
2686 : }
2687 : }
2688 : else {
2689 20 : handle->prepare_errors += 1;
2690 :
2691 20 : if (handle->prepare_errors >=
2692 : DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS) {
2693 4 : config[i]->skip = 1;
2694 4 : dlt_vlog(LOG_WARNING,
2695 : "%s: Unable to prepare. Skip filename [%s] because maxmimum trial has been reached.\n",
2696 : __func__, config[i]->file_name);
2697 : } else {
2698 16 : dlt_vlog(LOG_ERR,
2699 : "%s: Unable to prepare.\n", __func__);
2700 : }
2701 : }
2702 : }
2703 :
2704 : return err;
2705 : }
2706 :
2707 : /**
2708 : * dlt_logstorage_sync_caches
2709 : *
2710 : * Write Cache data to file
2711 : *
2712 : * @param handle DltLogStorage handle
2713 : * @return 0 on success, -1 on error
2714 : */
2715 4 : int dlt_logstorage_sync_caches(DltLogStorage *handle)
2716 : {
2717 : DltLogStorageFilterList **tmp = NULL;
2718 :
2719 4 : if (handle == NULL)
2720 : return -1;
2721 :
2722 4 : tmp = &(handle->config_list);
2723 :
2724 30 : while (*(tmp) != NULL) {
2725 26 : if ((*tmp)->data != NULL) {
2726 26 : if ((*tmp)->data->dlt_logstorage_sync((*tmp)->data,
2727 : &handle->uconfig,
2728 26 : handle->device_mount_point,
2729 : DLT_LOGSTORAGE_SYNC_ON_DEMAND) != 0)
2730 0 : dlt_vlog(LOG_ERR,
2731 : "%s: Sync failed. Continue with next cache.\n",
2732 : __func__);
2733 : }
2734 :
2735 26 : tmp = &(*tmp)->next;
2736 :
2737 : }
2738 :
2739 : return 0;
2740 : }
|