From b76f05754928ad559987e8a00350386a6d6b88d2 Mon Sep 17 00:00:00 2001 From: "S. Hameed" Date: Wed, 13 May 2015 16:13:24 +0900 Subject: Offline Logstorage [2/4]: DLT Daemon extension Signed-off-by: S. Hameed --- src/daemon/dlt_daemon_offline_logstorage.c | 514 +++++++++++++++++++++++++++++ src/daemon/dlt_daemon_offline_logstorage.h | 116 +++++++ 2 files changed, 630 insertions(+) create mode 100644 src/daemon/dlt_daemon_offline_logstorage.c create mode 100644 src/daemon/dlt_daemon_offline_logstorage.h diff --git a/src/daemon/dlt_daemon_offline_logstorage.c b/src/daemon/dlt_daemon_offline_logstorage.c new file mode 100644 index 0000000..7410225 --- /dev/null +++ b/src/daemon/dlt_daemon_offline_logstorage.c @@ -0,0 +1,514 @@ +/** +* @licence app begin@ +* Copyright (C) 2013 - 2015 Advanced Driver Information Technology. +* This code is developed by Advanced Driver Information Technology. +* Copyright of Advanced Driver Information Technology, Bosch and DENSO. +* +* DLT offline log storage functionality source file. +* +* \copyright +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* +* \author Syed Hameed ADIT 2013 - 2015 +* \author Christoph Lipka ADIT 2015 +* +* \file: dlt_daemon_offline_logstorage.c +* For further information see http://www.genivi.org/. +* @licence end@ +*/ + +#include +#include +#include +#include + +#include "dlt_daemon_offline_logstorage.h" + + +/** + * dlt_logstorage_split_key +* + * Split a given key into appid and ctxid. + * If APID: - appid = APID and ctxid = .* + * If :CTID - ctxid = CTID and appid = .* + * Else appid = APID and ctxid = CTID + * + * @param key Given key of filter hash map + * @param appid Application id + * @param ctxid Context id + * @return 0 on success, -1 on error + */ +int dlt_logstorage_split_key(char *key, char *appid, char *ctxid) +{ + char *tok = NULL; + int len = 0; + int ret = 0; + char *sep = NULL; + + if (key == NULL) + { + return -1; + } + + len = strlen(key); + + sep = strchr (key, ':'); + if(sep == NULL) + { + return -1; + } + + /* key is context id only */ + if(key[0] == ':') + { + if(len > (DLT_ID_SIZE+1)) + return -1; + + strncpy(ctxid,(key+1),(len-1)); + strncpy(appid, ".*",2); + } + /* key is application id only */ + else if (key[len-1] == ':') + { + if(len > (DLT_ID_SIZE+1)) + return -1; + + strncpy(appid,key,(len-1)); + strncpy(ctxid, ".*",2); + } + /* key is appid:ctxid */ + else + { + if(len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) + return -1; + + /* copy appid and ctxid */ + tok = strtok(key, ":"); + if (tok != NULL) + strncpy(appid,tok,DLT_ID_SIZE); + else + ret = -1; + + tok = strtok(NULL, ":"); + if (tok != NULL) + strncpy(ctxid,tok,DLT_ID_SIZE); + else + ret = -1; + } + + return ret; +} + +/** + * dlt_logstorage_update_all_contexts + * + * Update log level of all contexts of the application by updating the daemon internal table + * The compare flags (cmp_flag) indicates if Id has to be compared with application ID + * or Context id of the daemon internal table + * The log levels are reset if current log level provided is -1 (not sent to application in this case) + * Reset and sent to application if current log level provided is 0 + * + * @param daemon DltDaemon structure + * @param id application id or context id + * @param curr_log_level log level to be set to context + * @param cmp_flag compare flag (1 id is apid, 2 id is ctxid) + * @param verbose If set to true verbose information is printed out + * @return 0 on success, -1 on error + */ +int dlt_logstorage_update_all_contexts(DltDaemon *daemon, char *id, int curr_log_level, int cmp_flag, int verbose) +{ + int i = 0; + char tmp_id[DLT_ID_SIZE+1]; + int old_log_level = -1; + + if((daemon == 0) || (id == NULL)) + return -1; + + if((cmp_flag < 0 ) || (cmp_flag > 2 )) + return -1; + + memset(tmp_id, 0, sizeof(tmp_id)); + + for(i = 0; i < daemon->num_contexts; i++) + { + if(cmp_flag == 1) + dlt_set_id(tmp_id, daemon->contexts[i].apid); + else + dlt_set_id(tmp_id, daemon->contexts[i].ctid); + + if(strcmp(id, tmp_id) == 0) + { + if(curr_log_level > 0) + { + old_log_level = daemon->contexts[i].storage_log_level; + + daemon->contexts[i].storage_log_level = DLT_OFFLINE_LOGSTORAGE_MAX(curr_log_level, daemon->contexts[i].storage_log_level); + + if(daemon->contexts[i].storage_log_level > old_log_level) + { + if(dlt_daemon_user_send_log_level(daemon, &daemon->contexts[i], verbose) == -1) + { + dlt_log(LOG_ERR, "Unable to update loglevel\n"); + return -1; + } + } + } + else /* The request is to reset log levels */ + { + /* Set storage level to -1, to clear log levels */ + daemon->contexts[i].storage_log_level = -1; + + if(curr_log_level == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL) + { + if(dlt_daemon_user_send_log_level(daemon, &daemon->contexts[i], verbose) == -1) + { + dlt_log(LOG_ERR, "Unable to reset loglevel\n"); + return -1; + } + } + + } + } + } + return 0; +} + +/** + * dlt_logstorage_update_context + * + * Update log level of a context by updating the daemon internal table + * The log levels are reset if current log level provided is -1 (not sent to application in this case) + * Reset and sent to application if current log level provided is 0 + * + * @param daemon DltDaemon structure + * @param apid application id + * @param ctxid context id + * @param curr_log_level log level to be set to context + * @param verbose If set to true verbose information is printed out + * @return 0 on success, -1 on error + */ +int dlt_logstorage_update_context(DltDaemon *daemon, char *apid, char *ctxid, int curr_log_level , int verbose) +{ + DltDaemonContext *context = NULL; + int old_log_level = -1; + + if((daemon == 0) || (apid == NULL) || (ctxid == NULL)) + return -1; + + context = dlt_daemon_context_find(daemon, apid, ctxid, verbose); + if(context != NULL) + { + if(curr_log_level > 0) + { + old_log_level = context->storage_log_level; + + context->storage_log_level = DLT_OFFLINE_LOGSTORAGE_MAX(curr_log_level, context->storage_log_level); + if(context->storage_log_level > old_log_level) + { + if(dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) + { + dlt_log(LOG_ERR, "Unable to update loglevel\n"); + return -1; + } + } + } + else + { + context->storage_log_level = -1; + + if(curr_log_level == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL) + { + if(dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) + { + dlt_log(LOG_ERR, "Unable to update loglevel\n"); + return -1; + } + } + + } + } + return 0; +} + +/** + * dlt_logstorage_update_context_loglevel + * + * Update all contexts or particular context depending provided key + * + * @param daemon Pointer to DLT Daemon structure + * @param key Filter key stored in Hash Map + * @param curr_log_level log level to be set to context + * @param verbose If set to true verbose information is printed out + * @return 0 on success, -1 on error + */ +int dlt_logstorage_update_context_loglevel(DltDaemon *daemon, char *key, int curr_log_level , int verbose) +{ + + int cmp_flag=0; + char appid[DLT_ID_SIZE+1] = {'\0'}; + char ctxid[DLT_ID_SIZE+1] = {'\0'}; + + PRINT_FUNCTION_VERBOSE(verbose); + + if((daemon == 0) || (key == NULL)) + return -1; + + memset(appid, 0, sizeof(appid)); + memset(ctxid, 0, sizeof(ctxid)); + + if(dlt_logstorage_split_key(key, appid, ctxid) != 0) + { + dlt_log(LOG_ERR, "Error while updating application log levels (splt key)\n"); + return -1; + } + + if(strcmp(ctxid, ".*") == 0) /* wildcard for context id, find all contexts of given application id */ + { + cmp_flag = 1; + + if(dlt_logstorage_update_all_contexts(daemon, appid, curr_log_level, cmp_flag, verbose) != 0) + return -1; + } + else if(strcmp(appid, ".*") == 0) /* wildcard for application id, find all contexts with context id */ + { + cmp_flag = 2; + + if(dlt_logstorage_update_all_contexts(daemon, ctxid, curr_log_level, cmp_flag, verbose) != 0) + return -1; + } + else /* In case of given application id, context id pair, call available context find function */ + { + if(dlt_logstorage_update_context(daemon, appid, ctxid, curr_log_level, verbose) != 0) + return -1; + } + return 0; +} + +/** + * dlt_daemon_logstorage_reset_application_loglevel + * + * Reset storage log level of all running applications + * 2 steps for resetting + * 1. Setup storage_loglevel of all contexts configured for the requested device to -1 + * 2. Re-run update log level for all other configured devices + * + * @param daemon Pointer to DLT Daemon structure + * @param dev_num Number of attached DLT Logstorage device + * @param max_device Maximum storage devices setup by the daemon + * @param verbose If set to true verbose information is printed out + */ +void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon, int dev_num, int max_device, int verbose) +{ + DltLogStorage *handle = NULL; + int i = 0; + char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] = {'\0'}; + int num_device_configured = 0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if((daemon == 0) || (dev_num < 0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for dlt_daemon_logstorage_reset_application_loglevel\n"); + return; + } + + handle = &(daemon->storage_handle[dev_num]); + if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) + || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) + { + return; + } + + /* First, check number of devices configured */ + for(i = 0; istorage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) + { + num_device_configured += 1; + } + } + + /* for all filters (keys) check if application context are already running and log level need to be reset*/ + for(i = 0; i < handle->num_filter_keys; i++) + { + memset(key, 0, sizeof(key)); + + strncpy(key, (handle->filter_keys + i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN), DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN); + + if(num_device_configured == 1) + /* Reset context log level and send to application */ + dlt_logstorage_update_context_loglevel(daemon, key, DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL, verbose); + else + /* Reset context log level do not send to application as other devices can have same configuration */ + dlt_logstorage_update_context_loglevel(daemon, key, DLT_DAEMON_LOGSTORAGE_RESET_LOGLEVEL, verbose); + } + + /* Re-run update log level for all other configured devices */ + for(i=0; istorage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) + { + dlt_daemon_logstorage_update_application_loglevel(daemon, i, verbose); + } + } + return; +} + +/** + * dlt_daemon_logstorage_update_application_loglevel + * + * Update log level of all running applications with new filter configuration available due + * to newly attached DltLogstorage device. The log level is only updated when the current + * application log level is less than the log level obtained from the storage configuration file + * + * @param daemon Pointer to DLT Daemon structure + * @param dev_num Number of attached DLT Logstorage device + * @param verbose If set to true verbose information is printed out + */ +void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon, int dev_num, int verbose) +{ + DltLogStorage *handle = NULL; + int i = 0; + char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] = {'\0'}; + + + PRINT_FUNCTION_VERBOSE(verbose); + + if((daemon == 0) || (dev_num < 0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for dlt_daemon_logstorage_update_application_loglevel\n"); + return; + } + + handle = &(daemon->storage_handle[dev_num]); + if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) + || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)) + { + return; + } + + /* for all filters (keys) check if application or context already running and log level need to be updated*/ + for(i = 0; i < handle->num_filter_keys; i++) + { + int log_level = -1; + + memset(key, 0, sizeof(key)); + + strncpy(key, (handle->filter_keys + i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN), DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN); + + /* Obtain storage configuration data */ + log_level = dlt_logstorage_get_loglevel_by_key(handle, key); + if(log_level < 0) + { + dlt_log(LOG_ERR, "Failed to get log level by key \n"); + return; + } + + /* Update context log level with storage configuration log level */ + dlt_logstorage_update_context_loglevel(daemon, key, log_level, verbose); + } + return; +} + +/** + * dlt_daemon_logstorage_get_loglevel + * + * Obtain log level as a union of all configured storage devices and filters for the + * provided application id and context id + * + * @param daemon Pointer to DLT Daemon structure + * @param max_device Maximum storage devices setup by the daemon + * @param apid Application ID + * @param ctid Context ID + * @return Log level on success, -1 on error + */ +int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon, int max_device, char *apid, char *ctid) +{ + DltLogStorageConfigData **config = NULL; + int i = 0; + int j = 0; + int8_t storage_loglevel = -1; + int8_t retrvd_loglevel = -1; + int num_config = 0; + + if((daemon == 0) || (max_device == 0) || (apid == NULL) || (ctid == NULL)) + return -1; + + for(i = 0; istorage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) + { + config = dlt_logstorage_get_config(&(daemon->storage_handle[i]), apid, ctid, &num_config); + if(config != NULL) + { + for(j = 0; jlog_level; + storage_loglevel = DLT_OFFLINE_LOGSTORAGE_MAX(retrvd_loglevel, storage_loglevel); + } + free(config); + } + } + } + return storage_loglevel; +} + +/** + * dlt_daemon_logstorage_write + * + * Write log message to all attached storage device. If the called dlt_logstorage_write function is not able + * to write to the device, DltDaemon will disconnect this device. + * + * @param daemon Pointer to Dlt Daemon structure + * @param max_devices number of configured storage devices + * @param data1 message header buffer + * @param size1 message header buffer size + * @param data2 message extended header buffer + * @param size2 message extended header size + * @param data3 message data buffer + * @param size3 message data size + */ +void dlt_daemon_logstorage_write(DltDaemon *daemon, int max_devices, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3) +{ + int i = 0; + + /* data2 contains DltStandardHeader, DltStandardHeaderExtra and DltExtendedHeader. We are interested + * in last one, because it contains apid, ctid and loglevel */ + DltExtendedHeader ext; + char apid[4] = {0}; + char ctid[4] = {0}; + int log_level = -1; + + if (daemon == NULL || max_devices <= 0 || data1 == NULL || data2 == NULL || data3 == NULL + || ((unsigned int)size2 < (sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra) + sizeof(DltExtendedHeader)))) + { + dlt_log(LOG_INFO, "dlt_daemon_logstorage_write: message type is not log. Skip storing.\n"); + return; + } + + memset(&ext, 0, sizeof(DltExtendedHeader)); + memcpy(&ext, data2 + sizeof(DltStandardHeader) + sizeof(DltStandardHeaderExtra), sizeof(DltExtendedHeader)); + + dlt_set_id(apid, ext.apid); + dlt_set_id(ctid, ext.ctid); + log_level = DLT_GET_MSIN_MTIN(ext.msin); + + for (i = 0; i < max_devices; i++) + { + if (daemon->storage_handle[i].config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) + { + if (dlt_logstorage_write(&(daemon->storage_handle[i]), apid, ctid, log_level, data1, size1, data2, size2, data3, size3) != 0) + { + dlt_log(LOG_ERR,"dlt_daemon_logstorage_write: dlt_logstorage_write failed. Disable storage device\n"); + /* DLT_OFFLINE_LOGSTORAGE_MAX_WRITE_ERRORS happened, therefore remove logstorage device */ + dlt_logstorage_device_disconnected(&(daemon->storage_handle[i])); + } + } + } +} diff --git a/src/daemon/dlt_daemon_offline_logstorage.h b/src/daemon/dlt_daemon_offline_logstorage.h new file mode 100644 index 0000000..26e5686 --- /dev/null +++ b/src/daemon/dlt_daemon_offline_logstorage.h @@ -0,0 +1,116 @@ +/** +* @licence app begin@ +* Copyright (C) 2013 - 2015 Advanced Driver Information Technology. +* This code is developed by Advanced Driver Information Technology. +* Copyright of Advanced Driver Information Technology, Bosch and DENSO. +* +* DLT offline log storage functionality header file. +* +* \copyright +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with +* this file, You can obtain one at http://mozilla.org/MPL/2.0/. +* +* +* \author Syed Hameed ADIT 2013 - 2015 +* \author Christoph Lipka ADIT 2015 +* +* \file: dlt_daemon_offline_logstorage.h +* For further information see http://www.genivi.org/. +* @licence end@ +*/ + +/******************************************************************************* +* ** +* SRC-MODULE: dlt_daemon_offline_logstorage.h ** +* ** +* TARGET : linux ** +* ** +* PROJECT : DLT ** +* ** +* AUTHOR : Syed Hameed shameed@jp.adit-jv.com ** +* Christoph Lipka clipka@jp.adit-jv.com ** +* PURPOSE : ** +* ** +* REMARKS : ** +* ** +* PLATFORM DEPENDANT [yes/no]: yes ** +* ** +* TO BE CHANGED BY USER [yes/no]: no ** +* ** +******************************************************************************/ + +/******************************************************************************* +* Author Identity ** +******************************************************************************* +* ** +* Initials Name Company ** +* -------- ------------------------- ---------------------------------- ** +* sh Syed Hameed ADIT ** +* cl Christoph Lipka ADIT ** + *******************************************************************************/ +#ifndef DLT_DAEMON_OFFLINE_LOGSTORAGE_H +#define DLT_DAEMON_OFFLINE_LOGSTORAGE_H + +#include "dlt-daemon.h" +#include "dlt_daemon_common.h" + +#include "dlt_offline_logstorage.h" + +#define DLT_DAEMON_LOGSTORAGE_RESET_LOGLEVEL -1 +#define DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL 0 + +/** + * dlt_daemon_logstorage_get_loglevel + * + * Obtain log level as a union of all configured storage devices and filters for the + * provided application id and context id + * + * @param daemon Pointer to DLT Daemon structure + * @param max_device Maximum storage devices setup by the daemon + * @param apid Application ID + * @param ctid Context ID + * @return Log level on success, -1 on error + */ +int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon, int max_device, char *apid, char *ctid); +/** + * dlt_daemon_logstorage_reset_application_loglevel + * + * Reset storage log level of all running applications with -1 + * + * @param daemon Pointer to DLT Daemon structure + * @param dev_num Number of attached DLT Logstorage device + * @param verbose If set to true verbose information is printed out + */ +void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon, int dev_num, int max_device, int verbose); +/** + * dlt_daemon_logstorage_update_application_loglevel + * + * Update log level of all running applications with new filter configuration available due + * to newly attached DltLogstorage device. The log level is only updated when the current + * application log level is less than the log level obtained from the storage configuration file + * + * @param daemon Pointer to DLT Daemon structure + * @param dev_num Number of attached DLT Logstorage device + * @param verbose if set to true verbose information is printed out + */ +void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon, int dev_num, int verbose); + +/** + * dlt_daemon_logstorage_write + * + * Write log message to all attached storage device. If the called dlt_logstorage_write function is not able + * to write to the device, DltDaemon will disconnect this device. + * + * @param daemon Pointer to Dlt Daemon structure + * @param max_devices number of configured storage devices + * @param apid application id + * @param ctid context id + * @param log_level log level + * @param data1 message header buffer + * @param size1 message header buffer size + * @param data2 message data buffer + * @param size2 message data size + */ +void dlt_daemon_logstorage_write(DltDaemon *daemon, int max_devices, unsigned char *data1, int size1, unsigned char *data2, int size2, unsigned char *data3, int size3); +#endif /* DLT_DAEMON_OFFLINE_LOGSTORAGE_H */ -- cgit v1.2.1