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.1 % 807 574
Test Date: 2026-08-27 10:11:10 Functions: 84.9 % 53 45

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

Generated by: LCOV version 2.0-1