From a966393ad7003d02870bceffa08df5ddf4bbf864 Mon Sep 17 00:00:00 2001 From: Manikandan C Date: Thu, 28 Jan 2016 13:57:07 +0530 Subject: dlt-control: Provision to control entire system log level 1. support for setting log level using wildcards for both app and context 2. support for setting entire system log level Signed-off-by: Manikandan C Change-Id: I92f8c5461903f092cd50f05f644013432940a87b --- include/dlt/dlt_client.h | 7 ++ include/dlt/dlt_protocol.h | 1 + src/console/dlt-control.c | 135 +++++++++++++++++++++++++--------- src/daemon/dlt_daemon_client.c | 161 ++++++++++++++++++++++++++++++++++------- src/daemon/dlt_daemon_client.h | 10 +++ src/daemon/dlt_daemon_common.c | 29 ++++++++ src/daemon/dlt_daemon_common.h | 9 +++ src/lib/dlt_client.c | 32 +++++++- 8 files changed, 322 insertions(+), 62 deletions(-) diff --git a/include/dlt/dlt_client.h b/include/dlt/dlt_client.h index 676ffeb..a4d3181 100644 --- a/include/dlt/dlt_client.h +++ b/include/dlt/dlt_client.h @@ -206,6 +206,13 @@ DltReturnValue dlt_client_send_trace_status(DltClient *client, char *apid, char * @return Value from DltReturnValue enum */ DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defaultLogLevel); +/** + * Send the log level to all contexts registered with dlt daemon + * @param client pointer to dlt client structure + * @param LogLevel Log Level to be set + * @return negative value if there was an error + */ +int dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel); /** * Send the default trace status to the dlt daemon * @param client pointer to dlt client structure diff --git a/include/dlt/dlt_protocol.h b/include/dlt/dlt_protocol.h index 4600d2e..ee9c326 100644 --- a/include/dlt/dlt_protocol.h +++ b/include/dlt/dlt_protocol.h @@ -201,6 +201,7 @@ #define DLT_SERVICE_ID_OFFLINE_LOGSTORAGE 0xf05 /**< Service ID: Offline log storage */ #define DLT_SERVICE_ID_PASSIVE_NODE_CONNECT 0xf0E /**< Service ID: (Dis)Connect passive Node */ #define DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS 0xf0F /**< Service ID: Passive Node status information */ +#define DLT_SERVICE_ID_SET_ALL_LOG_LEVEL 0xf10 /**< Service ID: set all log level */ #define DLT_SERVICE_ID_CALLSW_CINJECTION 0xFFF /**< Service ID: Message Injection (minimal ID) */ /* diff --git a/src/console/dlt-control.c b/src/console/dlt-control.c index 15a1435..e5cda97 100644 --- a/src/console/dlt-control.c +++ b/src/console/dlt-control.c @@ -62,15 +62,18 @@ #include /* for open() */ #include "dlt_client.h" +#include "dlt_user.h" #define DLT_RECEIVE_TEXTBUFSIZE 10024 /* Size of buffer for text output */ +#define DLT_CTRL_SOCK "/tmp/dlt-ctrl.sock" + #define DLT_RECEIVE_ECU_ID "RECV" #define DLT_GLOGINFO_APID_NUM_MAX 150 #define DLT_GLOGINFO_DATA_MAX 800 #define DLT_GET_LOG_INFO_HEADER 18 /*Get log info header size in response text */ - +#define DLT_INVALID_LOG_LEVEL 0xF /* Option of GET_LOG_INFO */ #define DLT_SERVICE_GET_LOG_INFO_OPT7 7 /* get Apid, ApDescription, Ctid, CtDescription, loglevel, tracestatus */ @@ -208,7 +211,14 @@ void usage() printf(" -m message Control message injection in ASCII\n"); printf(" -x message Control message injection in Hex e.g. 'ad 01 24 ef'\n"); printf(" -t milliseconds Timeout to terminate application (Default:1000)'\n"); - printf(" -l loglevel Set the log level (0=off - 5=verbose,255=default)\n"); + printf(" -l loglevel Set the log level (0=off - 6=verbose default= -1)\n"); + printf(" supported options:\n"); + printf(" -l level -a appid -c ctid\n"); + printf(" -l level -a abc* (set level for all ctxts of apps name starts with abc)\n"); + printf(" -l level -a appid (set level for all ctxts of this app)\n"); + printf(" -l level -c xyz* (set level for all ctxts whose name starts with xyz)\n"); + printf(" -l level -c ctxid (set level for the particular ctxt)\n"); + printf(" -l level (set level for all the registered contexts)\n"); printf(" -r tracestatus Set the trace status (0=off - 1=on,255=default)\n"); printf(" -d loglevel Set the default log level (0=off - 5=verbose)\n"); printf(" -f tracestatus Set the default trace status (0=off - 1=on)\n"); @@ -216,6 +226,7 @@ void usage() printf(" -o Store configuration\n"); printf(" -g Reset to factory default\n"); printf(" -j Get log info\n"); + printf(" -u unix port\n"); } /** * Function for sending get log info ctrl msg and printing the response. @@ -269,6 +280,7 @@ int main(int argc, char* argv[]) DltReceiveData dltdata; int c; int index; + char *endptr = NULL; /* Initialize dltdata */ dltdata.vflag = 0; @@ -282,7 +294,7 @@ int main(int argc, char* argv[]) dltdata.mvalue = 0; dltdata.xvalue = 0; dltdata.tvalue = 1000; - dltdata.lvalue = -1; + dltdata.lvalue = DLT_INVALID_LOG_LEVEL; dltdata.rvalue = -1; dltdata.dvalue = -1; dltdata.fvalue = -1; @@ -293,7 +305,7 @@ int main(int argc, char* argv[]) /* Fetch command line arguments */ opterr = 0; - while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:ogj")) != -1) + while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:ogju")) != -1) switch (c) { case 'v': @@ -307,10 +319,10 @@ int main(int argc, char* argv[]) return -1; } case 'y': - { - dltdata.yflag = 1; - break; - } + { + dltdata.yflag = DLT_CLIENT_MODE_SERIAL; + break; + } case 'e': { dltdata.evalue = optarg; @@ -323,15 +335,25 @@ int main(int argc, char* argv[]) } case 'a': - { - dltdata.avalue = optarg; - break; - } + { + dltdata.avalue = optarg; + if (strlen(dltdata.avalue) > DLT_ID_SIZE) + { + fprintf (stderr, "Invalid appid\n"); + return -1; + } + break; + } case 'c': - { - dltdata.cvalue = optarg; - break; - } + { + dltdata.cvalue = optarg; + if (strlen(dltdata.cvalue) > DLT_ID_SIZE) + { + fprintf (stderr, "Invalid context id\n"); + return -1; + } + break; + } case 's': { dltdata.svalue = atoi(optarg); @@ -353,10 +375,15 @@ int main(int argc, char* argv[]) break; } case 'l': - { - dltdata.lvalue = atoi(optarg);; - break; - } + { + dltdata.lvalue = strtol(optarg, &endptr, 10); + if ((dltdata.lvalue < DLT_LOG_DEFAULT) || (dltdata.lvalue > DLT_LOG_VERBOSE)) + { + fprintf (stderr, "invalid log level, supported log level 0-6\n"); + return -1; + } + break; + } case 'r': { dltdata.rvalue = atoi(optarg);; @@ -392,6 +419,11 @@ int main(int argc, char* argv[]) dltdata.jvalue = 1; break; } + case 'u': + { + dltdata.yflag = DLT_CLIENT_MODE_UNIX; + break; + } case '?': { if (optopt == 'o' || optopt == 'f') @@ -424,7 +456,19 @@ int main(int argc, char* argv[]) dlt_client_register_message_callback(dlt_receive_message_callback); /* Setup DLT Client structure */ - g_dltclient.mode = dltdata.yflag; + if (dltdata.yflag == DLT_CLIENT_MODE_SERIAL) + { + g_dltclient.mode = DLT_CLIENT_MODE_SERIAL; + } + else if (dltdata.yflag == DLT_CLIENT_MODE_UNIX) + { + g_dltclient.mode = DLT_CLIENT_MODE_UNIX; + g_dltclient.socketPath = DLT_CTRL_SOCK; + } + else + { + g_dltclient.mode = DLT_CLIENT_MODE_TCP; + } if (g_dltclient.mode==DLT_CLIENT_MODE_TCP) { @@ -442,7 +486,7 @@ int main(int argc, char* argv[]) return -1; } } - else + else if (g_dltclient.mode == DLT_CLIENT_MODE_SERIAL) { for (index = optind; index < argc; index++) { @@ -520,22 +564,41 @@ int main(int argc, char* argv[]) fprintf(stderr, "ERROR: Could not send inject message\n"); } } - else if(dltdata.lvalue!=-1 && dltdata.avalue && dltdata.cvalue) - { - /* log level */ - printf("Set log level:\n"); - printf("AppId: %s\n",dltdata.avalue); - printf("ConId: %s\n",dltdata.cvalue); - printf("Loglevel: %d\n",dltdata.lvalue); - /* send control message*/ - if (dlt_client_send_log_level(&g_dltclient, - dltdata.avalue, - dltdata.cvalue, - dltdata.lvalue) != DLT_RETURN_OK) + else if (dltdata.lvalue != DLT_INVALID_LOG_LEVEL) /*&& dltdata.avalue && dltdata.cvalue)*/ + { + if ((dltdata.avalue == 0) && (dltdata.cvalue == 0)) { - fprintf(stderr, "ERROR: Could not send log level\n"); + if (dltdata.vflag) + { + printf("Set all log level:\n"); + printf("Loglevel: %d\n", dltdata.lvalue); + } + if (0 != dlt_client_send_all_log_level(&g_dltclient, + dltdata.lvalue)) + { + fprintf(stderr, "ERROR: Could not send log level\n"); + } } - } + else + { + /* log level */ + if (dltdata.vflag) + { + printf("Set log level:\n"); + printf("AppId: %s\n", dltdata.avalue); + printf("ConId: %s\n", dltdata.cvalue); + printf("Loglevel: %d\n", dltdata.lvalue); + } + /* send control message*/ + if (0 != dlt_client_send_log_level(&g_dltclient, + dltdata.avalue, + dltdata.cvalue, + dltdata.lvalue)) + { + fprintf(stderr, "ERROR: Could not send log level\n"); + } + } + } else if(dltdata.rvalue!=-1 && dltdata.avalue && dltdata.cvalue) { /* trace status */ diff --git a/src/daemon/dlt_daemon_client.c b/src/daemon/dlt_daemon_client.c index efd8dae..24be8e4 100644 --- a/src/daemon/dlt_daemon_client.c +++ b/src/daemon/dlt_daemon_client.c @@ -563,6 +563,11 @@ int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLoca dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter,"",verbose); break; } + case DLT_SERVICE_ID_SET_ALL_LOG_LEVEL: + { + dlt_daemon_control_set_all_log_level(sock, daemon, daemon_local, msg, verbose); + break; + } case DLT_SERVICE_ID_OFFLINE_LOGSTORAGE: { dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose); @@ -1524,18 +1529,87 @@ void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltDaemon } } -void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) +void dlt_daemon_send_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltDaemonContext *context,int8_t loglevel, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); - char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE]; - DltServiceSetLogLevel *req; - DltDaemonContext *context; - int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL; + int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL; + int8_t old_log_level = 0; - int8_t old_log_level; + old_log_level = context->log_level; + context->log_level = loglevel; /* No endianess conversion necessary*/ - if ((daemon==0) || (msg==0)) + if ((context->user_handle >= DLT_FD_MINIMUM) && + (dlt_daemon_user_send_log_level(daemon, context, verbose)==0)) + { + dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + dlt_log(LOG_ERR, "Log level could not be sent!\n"); + context->log_level = old_log_level; + dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + +} + +void dlt_daemon_find_multiple_context_and_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int8_t app_flag, char *str, int8_t len, int8_t loglevel, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + int8_t count = 0; + DltDaemonContext *context = NULL; + char src_str[DLT_ID_SIZE +1] = {0}; + int8_t ret = 0; + + if (daemon == 0) + { + return; + } + + for (count = 0; count < daemon->num_contexts; count++) + { + context = &(daemon->contexts[count]); + + if (context) + { + if (app_flag == 1) + { + strncpy(src_str, context->apid, DLT_ID_SIZE); + } + else + { + strncpy(src_str, context->ctid, DLT_ID_SIZE); + } + ret = strncmp(src_str, str, len); + if (ret == 0) + { + dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose); + } + else if ((ret > 0) && (app_flag == 1)) + { + break; + } + else + { + continue; + } + } + } +} + +void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + char apid[DLT_ID_SIZE+1] = {0}; + char ctid[DLT_ID_SIZE+1] = {0}; + DltServiceSetLogLevel *req = NULL; + DltDaemonContext *context = NULL; + int8_t appid_length = 0; + int8_t ctxtid_length = 0; + + if ((daemon == 0) || (msg == 0)) { return; } @@ -1544,32 +1618,39 @@ void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltDaemonLoca dlt_set_id(apid, req->apid); dlt_set_id(ctid, req->ctid); - - context=dlt_daemon_context_find(daemon, apid, ctid, verbose); - - /* Set log level */ - if (context!=0) + appid_length = strlen(apid); + ctxtid_length = strlen(ctid); + if ((appid_length != 0) && (apid[appid_length-1] == '*') && (ctid[0] == 0)) /*appid provided having '*' in it and ctid is null*/ + { + dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 1, apid, appid_length-1, req->log_level, verbose); + } + else if ((ctxtid_length != 0) && (ctid[ctxtid_length-1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and appid is null*/ { - old_log_level = context->log_level; - context->log_level = req->log_level; /* No endianess conversion necessary*/ + dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 0, ctid, ctxtid_length-1, req->log_level, verbose); + } + else if ((appid_length != 0) && (apid[appid_length-1] != '*') && (ctid[0] == 0)) /*only app id case*/ + { + dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 1, apid, DLT_ID_SIZE, req->log_level, verbose); + } + else if ((ctxtid_length != 0) && (ctid[ctxtid_length-1] != '*') && (apid[0] == 0)) /*only context id case*/ + { + dlt_daemon_find_multiple_context_and_send(sock, daemon, daemon_local, 0, ctid, DLT_ID_SIZE, req->log_level, verbose); + } + else + { + context=dlt_daemon_context_find(daemon, apid, ctid, verbose); - if ((context->user_handle >= DLT_FD_MINIMUM) && - (dlt_daemon_user_send_log_level(daemon, context, verbose)==0)) + /* Set log level */ + if (context!=0) { - dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); + dlt_daemon_send_log_level(sock, daemon, daemon_local, context, req->log_level, verbose); } else { - //dlt_log(LOG_ERR, "Log level could not be sent!\n"); - context->log_level = old_log_level; - dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + dlt_log(LOG_ERR, "Context not found!\n"); + dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_SET_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); } } - else - { - //dlt_log(LOG_ERR, "Context not found!\n"); - dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); - } } void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) @@ -1651,6 +1732,36 @@ void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDa } } +void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + DltServiceSetDefaultLogLevel *req = NULL; + int32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL; + int8_t loglevel = 0; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetDefaultLogLevel*) (msg->databuffer); + + /* No endianess conversion necessary */ + if ((req != NULL) && (req->log_level <= DLT_LOG_VERBOSE)) + { + loglevel = req->log_level; /* No endianess conversion necessary */ + /* Send Update to all contexts using the new log level */ + dlt_daemon_user_send_all_update(daemon, loglevel, verbose); + + dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose) { PRINT_FUNCTION_VERBOSE(verbose); diff --git a/src/daemon/dlt_daemon_client.h b/src/daemon/dlt_daemon_client.h index 7128ddb..275ee3e 100644 --- a/src/daemon/dlt_daemon_client.h +++ b/src/daemon/dlt_daemon_client.h @@ -229,6 +229,16 @@ void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltDaemonL * @param verbose if set to true verbose information is printed out. */ void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); +/** + * Process and generate response to received set all log level control message + * @param sock connection handle used for sending response + * @param daemon pointer to dlt daemon structure + * @param daemon_local pointer to dlt daemon local structure + * @param msg pointer to received control message + * @param verbose if set to true verbose information is printed out. + */ +void dlt_daemon_control_set_all_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose); + /** * Process and generate response to received set default trace status control message * @param sock connection handle used for sending response diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c index 6523136..988bd7b 100644 --- a/src/daemon/dlt_daemon_common.c +++ b/src/daemon/dlt_daemon_common.c @@ -1275,6 +1275,35 @@ void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose) } } +void dlt_daemon_user_send_all_update(DltDaemon *daemon, int8_t log_level, int verbose) +{ + int32_t count = 0; + DltDaemonContext *context = NULL; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon == NULL) + { + return; + } + + for (count = 0; count < daemon->num_contexts; count++) + { + context = &(daemon->contexts[count]); + if (context) + { + if (context->user_handle >= DLT_FD_MINIMUM) + { + context->log_level = log_level; + if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) + { + return; + } + } + } + } +} + void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose) { int32_t count; diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h index 71d3dce..02d2860 100644 --- a/src/daemon/dlt_daemon_common.h +++ b/src/daemon/dlt_daemon_common.h @@ -354,6 +354,15 @@ int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,i */ void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose); +/** + * Send user messages to all user applications context, or trace status + * to update with the new log level + * @param daemon pointer to dlt daemon structure + * @param log level to be set + * @param verbose if set to true verbose information is printed out. + */ +void dlt_daemon_user_send_all_update(DltDaemon *daemon, int8_t log_level, int verbose); + /** * Send user messages to all user applications the log status * everytime the client is connected or disconnected. diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c index 20291d5..2b37598 100644 --- a/src/lib/dlt_client.c +++ b/src/lib/dlt_client.c @@ -498,7 +498,7 @@ DltReturnValue dlt_client_send_ctrl_msg(DltClient *client, char *apid, char *cti msg.standardheader->len = DLT_HTOBE_16(len); /* Send data (without storage header) */ - if (client->mode) + if ((client->mode == DLT_CLIENT_MODE_TCP) || (client->mode == DLT_CLIENT_MODE_SERIAL)) { /* via FileDescriptor */ ret=write(client->sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader)); @@ -697,6 +697,36 @@ DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defa return DLT_RETURN_OK; } +DltReturnValue dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel) +{ + DltServiceSetDefaultLogLevel *req; + uint8_t *payload; + + payload = (uint8_t *) malloc(sizeof(DltServiceSetDefaultLogLevel)); + + if (payload == 0) + { + return DLT_RETURN_ERROR; + } + + req = (DltServiceSetDefaultLogLevel *) payload; + + req->service_id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL; + req->log_level = LogLevel; + dlt_set_id(req->com, "remo"); + + /* free message */ + if (dlt_client_send_ctrl_msg(client, "APP", "CON", payload, sizeof(DltServiceSetDefaultLogLevel)) == -1) + { + free(payload); + return DLT_RETURN_ERROR; + } + + free(payload); + + return DLT_RETURN_OK; +} + DltReturnValue dlt_client_send_default_trace_status(DltClient *client, uint8_t defaultTraceStatus) { DltServiceSetDefaultLogLevel *req; -- cgit v1.2.1