From 5e1270dec72c175ad3ad3a26d2c3d402d0e07ebe Mon Sep 17 00:00:00 2001 From: Manikandan C Date: Wed, 7 Oct 2015 11:58:50 +0530 Subject: GetLogInfo: supported get log info in dlt-control added option to get log info in dlt-control app. The response parameter is parsed and the details are printed back to the console Signed-off-by: Manikandan C --- src/console/dlt-control.c | 501 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 460 insertions(+), 41 deletions(-) (limited to 'src/console') diff --git a/src/console/dlt-control.c b/src/console/dlt-control.c index 8db6467..49b7de8 100644 --- a/src/console/dlt-control.c +++ b/src/console/dlt-control.c @@ -67,6 +67,39 @@ #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 */ + +/* Option of GET_LOG_INFO */ +#define DLT_SERVICE_GET_LOG_INFO_OPT7 7 /* get Apid, ApDescription, Ctid, CtDescription, loglevel, tracestatus */ + +typedef struct +{ + char apid[DLT_ID_SIZE + 1]; /**< application id */ + char ctid[DLT_ID_SIZE + 1]; /**< context id */ + char *apid_desc; /**< apid description */ + char *ctid_desc; /**< ctxt description */ + int log_level; /**< log level */ + int trace_status; /**< trace_status */ + int disp; /**< display flag */ +} DltLoginfoDetail; + +typedef struct +{ + DltLoginfoDetail info[DLT_GLOGINFO_DATA_MAX]; /**< structure for each ctxt/app entry*/ + int count; /**< Number of app and ctxt entries */ +} DltLoginfo; + + +typedef struct +{ + uint32_t service_id; /**< service ID */ +} PACKED DltServiceGetDefaultLogLevel; + +DltClient g_dltclient; +DltLoginfo g_get_loginfo; + /* Function prototypes */ int dlt_receive_message_callback(DltMessage *message, void *data); @@ -88,7 +121,7 @@ typedef struct { int ivalue; int oflag; int gflag; - + int jvalue; int bvalue; char ecuid[4]; DltFile file; @@ -182,6 +215,50 @@ void usage() printf(" -i enable Enable timing packets (0=off - 1=on)\n"); printf(" -o Store configuration\n"); printf(" -g Reset to factory default\n"); + printf(" -j Get log info\n"); +} +/** + * Function for sending get log info ctrl msg and printing the response. + */ +void dlt_process_get_log_info(void) +{ + char apid[DLT_ID_SIZE+1] = {0}; + int cnt; + + dlt_getloginfo_init(); + + /* send control message*/ + if (0 != dlt_client_get_log_info(&g_dltclient)) + { + fprintf(stderr, "ERROR: Could not get log info\n"); + return; + } + + for (cnt = 0; cnt < g_get_loginfo.count; cnt++) + { + if (strncmp(apid, g_get_loginfo.info[cnt].apid, DLT_ID_SIZE) != 0) + { + printf("APID:%4s ", g_get_loginfo.info[cnt].apid); + apid[DLT_ID_SIZE] = 0; + dlt_set_id(apid, g_get_loginfo.info[cnt].apid); + + if (g_get_loginfo.info[cnt].apid_desc != 0) + { + printf("%s\n", g_get_loginfo.info[cnt].apid_desc); + } + else + { + printf("\n"); + } + } + + if (strncmp(apid, g_get_loginfo.info[cnt].apid, DLT_ID_SIZE) == 0) + { + printf("%4s %2d %2d %s\n", g_get_loginfo.info[cnt].ctid, g_get_loginfo.info[cnt].log_level, + g_get_loginfo.info[cnt].trace_status, g_get_loginfo.info[cnt].ctid_desc); + } + } + dlt_getloginfo_free(); } /** @@ -189,7 +266,6 @@ void usage() */ int main(int argc, char* argv[]) { - DltClient dltclient; DltReceiveData dltdata; int c; int index; @@ -213,11 +289,11 @@ int main(int argc, char* argv[]) dltdata.ivalue = -1; dltdata.oflag = -1; dltdata.gflag = -1; - + dltdata.jvalue = 0; /* Fetch command line arguments */ opterr = 0; - while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:og")) != -1) + while ((c = getopt (argc, argv, "vhye:b:a:c:s:m:x:t:l:r:d:f:i:ogj")) != -1) switch (c) { case 'v': @@ -311,7 +387,11 @@ int main(int argc, char* argv[]) dltdata.gflag = 1; break; } - + case 'j': + { + dltdata.jvalue = 1; + break; + } case '?': { if (optopt == 'o' || optopt == 'f') @@ -338,27 +418,27 @@ int main(int argc, char* argv[]) } /* Initialize DLT Client */ - dlt_client_init(&dltclient, dltdata.vflag); + dlt_client_init(&g_dltclient, dltdata.vflag); /* Register callback to be called when message was received */ dlt_client_register_message_callback(dlt_receive_message_callback); /* Setup DLT Client structure */ - dltclient.serial_mode = dltdata.yflag; + g_dltclient.serial_mode = dltdata.yflag; - if (dltclient.serial_mode==0) + if (g_dltclient.serial_mode==0) { for (index = optind; index < argc; index++) { - dltclient.servIP = argv[index]; + g_dltclient.servIP = argv[index]; } - if (dltclient.servIP == 0) + if (g_dltclient.servIP == 0) { /* no hostname selected, show usage and terminate */ fprintf(stderr,"ERROR: No hostname selected\n"); usage(); - dlt_client_cleanup(&dltclient,dltdata.vflag); + dlt_client_cleanup(&g_dltclient,dltdata.vflag); return -1; } } @@ -366,10 +446,10 @@ int main(int argc, char* argv[]) { for (index = optind; index < argc; index++) { - dltclient.serialDevice = argv[index]; + g_dltclient.serialDevice = argv[index]; } - if (dltclient.serialDevice == 0) + if (g_dltclient.serialDevice == 0) { /* no serial device name selected, show usage and terminate */ fprintf(stderr,"ERROR: No serial device name specified\n"); @@ -377,7 +457,7 @@ int main(int argc, char* argv[]) return -1; } - dlt_client_setbaudrate(&dltclient,dltdata.bvalue); + dlt_client_setbaudrate(&g_dltclient,dltdata.bvalue); } /* initialise structure to use DLT file */ @@ -396,7 +476,7 @@ int main(int argc, char* argv[]) } /* Connect to TCP socket or open serial device */ - if (dlt_client_connect(&dltclient, dltdata.vflag) != DLT_RETURN_ERROR) + if (dlt_client_connect(&g_dltclient, dltdata.vflag) != DLT_RETURN_ERROR) { /* send injection message */ if(dltdata.mvalue && dltdata.avalue && dltdata.cvalue) @@ -408,8 +488,15 @@ int main(int argc, char* argv[]) printf("ServiceId: %d\n",dltdata.svalue); printf("Message: %s\n",dltdata.mvalue); /* send control message in ascii */ - if (dlt_client_send_inject_msg(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.svalue,(uint8_t*)dltdata.mvalue,strlen(dltdata.mvalue)) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send inject message\n"); + if (dlt_client_send_inject_msg(&g_dltclient, + dltdata.avalue, + dltdata.cvalue, + dltdata.svalue, + (uint8_t*)dltdata.mvalue, + strlen(dltdata.mvalue)) != DLT_RETURN_OK) + { + fprintf(stderr, "ERROR: Could not send inject message\n"); + } } else if(dltdata.xvalue && dltdata.avalue && dltdata.cvalue) { @@ -423,10 +510,16 @@ int main(int argc, char* argv[]) printf("Message: %s\n",dltdata.xvalue); hexAsciiToBinary(dltdata.xvalue,buffer,&size); printf("Size: %d\n",size); - /* send control message in hex */ - if (dlt_client_send_inject_msg(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.svalue,buffer,size) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send inject message\n"); - } + /* send control message in hex */ + if (dlt_client_send_inject_msg(&g_dltclient, + dltdata.avalue, + dltdata.cvalue, + dltdata.svalue, + buffer,size) != DLT_RETURN_OK) + { + fprintf(stderr, "ERROR: Could not send inject message\n"); + } + } else if(dltdata.lvalue!=-1 && dltdata.avalue && dltdata.cvalue) { /* log level */ @@ -435,8 +528,13 @@ int main(int argc, char* argv[]) printf("ConId: %s\n",dltdata.cvalue); printf("Loglevel: %d\n",dltdata.lvalue); /* send control message*/ - if (dlt_client_send_log_level(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.lvalue) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send log level\n"); + if (dlt_client_send_log_level(&g_dltclient, + dltdata.avalue, + dltdata.cvalue, + dltdata.lvalue) != DLT_RETURN_OK) + { + fprintf(stderr, "ERROR: Could not send log level\n"); + } } else if(dltdata.rvalue!=-1 && dltdata.avalue && dltdata.cvalue) { @@ -446,8 +544,13 @@ int main(int argc, char* argv[]) printf("ConId: %s\n",dltdata.cvalue); printf("TraceStatus: %d\n",dltdata.rvalue); /* send control message in*/ - if (dlt_client_send_trace_status(&dltclient,dltdata.avalue,dltdata.cvalue,dltdata.rvalue) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send trace status\n"); + if (dlt_client_send_trace_status(&g_dltclient, + dltdata.avalue, + dltdata.cvalue, + dltdata.rvalue) != DLT_RETURN_OK) + { + fprintf(stderr, "ERROR: Could not send trace status\n"); + } } else if(dltdata.dvalue!=-1) { @@ -455,8 +558,10 @@ int main(int argc, char* argv[]) printf("Set default log level:\n"); printf("Loglevel: %d\n",dltdata.dvalue); /* send control message in*/ - if (dlt_client_send_default_log_level(&dltclient,dltdata.dvalue) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send default log level\n"); + if (dlt_client_send_default_log_level(&g_dltclient, dltdata.dvalue) != DLT_RETURN_OK) + { + fprintf (stderr, "ERROR: Could not send default log level\n"); + } } else if(dltdata.rvalue!=-1) { @@ -464,8 +569,10 @@ int main(int argc, char* argv[]) printf("Set default trace status:\n"); printf("TraceStatus: %d\n",dltdata.rvalue); /* send control message in*/ - if (dlt_client_send_default_trace_status(&dltclient,dltdata.rvalue) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send default trace status\n"); + if (dlt_client_send_default_trace_status(&g_dltclient, dltdata.rvalue) != DLT_RETURN_OK) + { + fprintf (stderr, "ERROR: Could not send default trace status\n"); + } } else if(dltdata.ivalue!=-1) { @@ -473,26 +580,37 @@ int main(int argc, char* argv[]) printf("Set timing pakets:\n"); printf("Timing packets: %d\n",dltdata.ivalue); /* send control message in*/ - if (dlt_client_send_timing_pakets(&dltclient,dltdata.ivalue) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send timing packets\n"); + if (dlt_client_send_timing_pakets(&g_dltclient, dltdata.ivalue) != DLT_RETURN_OK) + { + fprintf (stderr, "ERROR: Could not send timing packets\n"); + } } else if(dltdata.oflag!=-1) { /* default trace status */ printf("Store config\n"); /* send control message in*/ - if (dlt_client_send_store_config(&dltclient) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could not send store config\n"); + if (dlt_client_send_store_config(&g_dltclient) != DLT_RETURN_OK) + { + fprintf (stderr, "ERROR: Could not send store config\n"); + } } else if(dltdata.gflag!=-1) { /* reset to factory default */ printf("Reset to factory default\n"); /* send control message in*/ - if (dlt_client_send_reset_to_factory_default(&dltclient) != DLT_RETURN_OK) - fprintf (stderr, "ERROR: Could send reset to factory default\n"); + if (dlt_client_send_reset_to_factory_default(&g_dltclient) != DLT_RETURN_OK) + { + fprintf (stderr, "ERROR: Could send reset to factory default\n"); + } } - + else if (dltdata.jvalue == 1) + { + /* get log info */ + printf("Get log info:\n"); + dlt_process_get_log_info(); + } /* Dlt Client Main Loop */ //dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); @@ -500,7 +618,7 @@ int main(int argc, char* argv[]) usleep(dltdata.tvalue*1000); /* Dlt Client Cleanup */ - dlt_client_cleanup(&dltclient,dltdata.vflag); + dlt_client_cleanup(&g_dltclient,dltdata.vflag); } dlt_file_free(&(dltdata.file),dltdata.vflag); @@ -510,14 +628,315 @@ int main(int argc, char* argv[]) return 0; } -int dlt_receive_message_callback(DltMessage *message, void *data) +void dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len) { + char number16[6]={0}; + char *endptr; + int count; - if ((message==0) || (data==0)) - { + if ((rp == NULL) || (rp_count == NULL) || (wp == NULL)) + { + return; + } + /* ------------------------------------------------------ + from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00] + ------------------------------------------------------ */ + number16[0] = '+'; + number16[1] = '0'; + number16[2] = 'x'; + for (count = 0; count < (len - 1); count++) + { + number16[3] = *(rp + *rp_count + 0); + number16[4] = *(rp + *rp_count + 1); + *(wp + count) = strtol(number16, &endptr, 16); + *rp_count += 3; + } + *(wp + count) = 0; + return; +} + +uint16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count) +{ + char num_work[8]; + char *endptr; + + if ((rp == NULL) || (rp_count == NULL)) + { return -1; - } + } + /* ------------------------------------------------------ + from: [89 13 ] -> to: ['+0x'1389\0] -> to num + ------------------------------------------------------ */ + num_work[0] = '+'; + num_work[1] = '0'; + num_work[2] = 'x'; + num_work[3] = *(rp + *rp_count + 3); + num_work[4] = *(rp + *rp_count + 4); + num_work[5] = *(rp + *rp_count + 0); + num_work[6] = *(rp + *rp_count + 1); + num_work[7] = 0; + *rp_count += 6; + + return strtol(num_work, &endptr, 16); +} +int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count) +{ + char num_work[6]; + char *endptr; + + if ((rp == NULL) || (rp_count == NULL)) + { + return -1; + } + /* ------------------------------------------------------ + from: [89 ] -> to: ['0x'89\0] -> to num + ------------------------------------------------------ */ + num_work[0] = '0'; + num_work[1] = 'x'; + num_work[2] = *(rp + *rp_count + 0); + num_work[3] = *(rp + *rp_count + 1); + num_work[4] = 0; + *rp_count += 3; + + return (signed char)strtol(num_work, &endptr, 16); +} + +void dlt_getloginfo_init(void) +{ + int cnt; + + g_get_loginfo.count = 0; + for (cnt = 0; cnt < DLT_GLOGINFO_DATA_MAX; cnt++) + { + g_get_loginfo.info[cnt].apid_desc = NULL; + g_get_loginfo.info[cnt].ctid_desc = NULL; + } +} + +void dlt_getloginfo_free(void) +{ + int cnt; + + for (cnt = 0; cnt < DLT_GLOGINFO_DATA_MAX; cnt++) + { + if (g_get_loginfo.info[cnt].apid_desc != 0) + { + free(g_get_loginfo.info[cnt].apid_desc); + } + if (g_get_loginfo.info[cnt].ctid_desc != 0) + { + free(g_get_loginfo.info[cnt].ctid_desc); + } + } +} + +/** + * Function to parse the response text and identifying service id and its options. + */ +int dlt_set_loginfo_parse_service_id(char *resp_text, int *service_id, int *service_opt, char *cb_result) +{ + int ret; + char get_log_info_tag[13]; + char service_opt_str[3]; + + if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL) || (cb_result == NULL)) + { + return -1; + } + /* ascii type, syntax is 'get_log_info, ..' */ + /* check target id */ + strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info")); + ret = memcmp((void *)resp_text, (void *)get_log_info_tag, sizeof(get_log_info_tag)-1); + if (ret == 0) + { + *service_id = DLT_SERVICE_ID_GET_LOG_INFO; + *cb_result = 0; + /* reading the response mode from the resp_text. eg. option 7*/ + service_opt_str[0] = *(resp_text+14); + service_opt_str[1] = *(resp_text+15); + service_opt_str[2] = 0; + *service_opt = atoi( service_opt_str ); + } + + return ret; +} + +/** + * Main function to convert the response text in to proper get log info data and + * filling it in the DltLoginfo structure. + */ +int dlt_getloginfo_make_loginfo(char *resp_text, int service_opt) +{ + char *rp; + int rp_count; + int loginfo_count; + uint16_t reg_apid_count; + uint16_t reg_ctid_count; + uint16_t reg_apid_num; + uint16_t reg_ctid_num; + uint16_t reg_apid_dsc_len; + uint16_t reg_ctid_dsc_len; + char reg_apid[DLT_ID_SIZE+1]; + char reg_ctid[DLT_ID_SIZE+1]; + char *reg_apid_dsc; + char *reg_ctid_dsc; + + if (resp_text == NULL) + { + return -1; + } + /* ------------------------------------------------------ + get_log_info data structure(all data is ascii) + + get_log_info, aa, bb bb cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. .. + ~~ ~~~~~ ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~ + cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. .. + jj jj kk kk kk .. .. + ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~ + aa : get mode (fix value at 0x07) + bb bb : list num of apid (little endian) + cc cc cc cc: apid + dd dd : list num of ctid (little endian) + ee ee ee ee: ctid + ff : log level + gg : trase status + hh hh : description length of ctid + ii ii .. : description text of ctid + jj jj : description length of apid + kk kk .. : description text of apid + ------------------------------------------------------ */ + + /* create all target convert list */ + + /* rp set header */ + rp = (resp_text + DLT_GET_LOG_INFO_HEADER); + rp_count = 0; + /* get reg_apid_num */ + reg_apid_num = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); + loginfo_count = g_get_loginfo.count; + + if (reg_apid_num > DLT_GLOGINFO_APID_NUM_MAX) + { + fprintf(stderr, "GET_LOG_INFO ERROR: APID MAX Over\n"); + g_get_loginfo.count = 0; + return -1; + } + + /* search for target apid */ + for (reg_apid_count = 0; reg_apid_count < reg_apid_num; reg_apid_count++) + { + /* get reg_apid */ + dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, reg_apid, DLT_ID_SIZE+1); + /* get reg_ctid_num of current reg_apid */ + reg_ctid_num = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); + if (loginfo_count + reg_ctid_num > DLT_GLOGINFO_DATA_MAX) + { + fprintf(stderr, "GET_LOG_INFO ERROR: LOG DATA MAX Over\n"); + g_get_loginfo.count = 0; + return -1; + } + for (reg_ctid_count = 0; reg_ctid_count < reg_ctid_num; reg_ctid_count++) + { + /* get reg_ctid */ + dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, reg_ctid, DLT_ID_SIZE+1); + + g_get_loginfo.info[ loginfo_count ].apid[DLT_ID_SIZE] = 0; + dlt_set_id(g_get_loginfo.info[ loginfo_count ].apid, reg_apid); + g_get_loginfo.info[ loginfo_count ].ctid[DLT_ID_SIZE] = 0; + dlt_set_id(g_get_loginfo.info[ loginfo_count ].ctid, reg_ctid); + g_get_loginfo.info[ loginfo_count ].log_level = dlt_getloginfo_conv_ascii_to_int16_t(rp, &rp_count); + g_get_loginfo.info[ loginfo_count ].trace_status = dlt_getloginfo_conv_ascii_to_int16_t(rp, &rp_count); + + /* Description Information */ + if (service_opt == DLT_SERVICE_GET_LOG_INFO_OPT7) + { + reg_ctid_dsc_len = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); + reg_ctid_dsc = (char *)malloc(sizeof(char) * reg_ctid_dsc_len + 1); + if (reg_ctid_dsc == 0) + { + fprintf(stderr, "malloc failed for ctxt desc\n"); + return -1; + } + dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, reg_ctid_dsc, reg_ctid_dsc_len+1); + g_get_loginfo.info[ loginfo_count ].ctid_desc = reg_ctid_dsc; + } + loginfo_count++; + } + /* Description Information */ + if (service_opt == DLT_SERVICE_GET_LOG_INFO_OPT7) + { + reg_apid_dsc_len = dlt_getloginfo_conv_ascii_to_uint16_t(rp, &rp_count); + reg_apid_dsc = (char *)malloc(sizeof(char) * reg_apid_dsc_len + 1); + if (reg_apid_dsc == 0) + { + fprintf(stderr, "malloc failed for apid desc\n"); + return -1; + } + dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, reg_apid_dsc, reg_apid_dsc_len+1); + g_get_loginfo.info[ loginfo_count - reg_ctid_num ].apid_desc = reg_apid_dsc; + } + } + g_get_loginfo.count = loginfo_count; return 0; } + +int dlt_receive_message_callback(DltMessage *message, void *data) +{ + static char resp_text[DLT_RECEIVE_TEXTBUFSIZE]; + int ret; + int service_id; + int service_opt; + char cb_result; + + /* parameter check */ + if (message == NULL) + { + return -1; + } + /* to avoid warning */ + data = data; + + /* prepare storage header */ + if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) + { + dlt_set_storageheader(message->storageheader, message->headerextra.ecu); + } + else + { + dlt_set_storageheader(message->storageheader, "LCTL"); + } + + /* get response data */ + ret = dlt_message_header(message, resp_text, DLT_RECEIVE_TEXTBUFSIZE, 0); + if (ret < 0) + { + fprintf(stderr, "GET_LOG_INFO message_header result failed..\n"); + dlt_client_cleanup(&g_dltclient, 0); + return -1; + } + + ret = dlt_message_payload(message, resp_text, DLT_RECEIVE_TEXTBUFSIZE, DLT_OUTPUT_ASCII, 0); + if (ret < 0) + { + fprintf(stderr, "GET_LOG_INFO message_payload result failed..\n"); + dlt_client_cleanup(&g_dltclient, 0); + return -1; + } + + /* check service id */ + ret = dlt_set_loginfo_parse_service_id(resp_text, &service_id, &service_opt, &cb_result); + if ((ret == 0) && (service_id == DLT_SERVICE_ID_GET_LOG_INFO )) + { + ret = dlt_getloginfo_make_loginfo(resp_text, service_opt); + + if (ret != 0) + { + fprintf(stderr, "GET_LOG_INFO result failed..\n"); + } + dlt_client_cleanup(&g_dltclient, 0); + } + + return ret; +} -- cgit v1.2.1