LCOV - code coverage report
Current view: top level - offlinelogstorage - dlt_offline_logstorage.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 71.6 % 816 584
Test Date: 2025-12-23 11:07:30 Functions: 86.8 % 53 46

            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              : }
        

Generated by: LCOV version 2.0-1