diff options
| -rw-r--r-- | tools/fwdebuglog/cld-diag-parser.c | 155 | ||||
| -rw-r--r-- | tools/fwdebuglog/cld-diag-parser.h | 26 | ||||
| -rw-r--r-- | tools/fwdebuglog/cld-fwlog-netlink.c | 121 |
3 files changed, 227 insertions, 75 deletions
diff --git a/tools/fwdebuglog/cld-diag-parser.c b/tools/fwdebuglog/cld-diag-parser.c index 10d1e9cef060..6af0e1600d4c 100644 --- a/tools/fwdebuglog/cld-diag-parser.c +++ b/tools/fwdebuglog/cld-diag-parser.c @@ -415,19 +415,25 @@ static void format_pack( const char *pack, char *buf, uint32_t buflen) { char c; - uint32_t num = 0,index = 0; + uint32_t num = 0, index = 0, i = 0; + boolean isfound = 0; memset(buf, 0 , buflen); while ((c = fmt_next_char(&pack)) != '\0') { if (index >= buflen -1) break; - if (is_digit(c)) { - num = (num* 10) + (c - '0'); + while (is_digit(c)) { + num = (i++ * 10) + (c - '0'); c = fmt_next_char(&pack); - while(num--) { + isfound = TRUE; + } + if (isfound) { + while (num--) { buf[index++] = c; - if(index >= buflen -1) + if (index >= buflen -1) break; } + num = 0; + i = 0; } else buf[index++] = c; @@ -435,9 +441,9 @@ format_pack( const char *pack, char *buf, uint32_t buflen) buf[index] = '\0'; } -static void +static int diag_printf(const char *buf, uint16_t vdevid, uint16_t level, - uint32_t optionflag, uint32_t timestamp) + uint32_t optionflag, uint32_t timestamp, FILE *log_out) { char pbuf[512]; if (vdevid < DBGLOG_MAX_VDEVID) @@ -472,8 +478,14 @@ diag_printf(const char *buf, uint16_t vdevid, uint16_t level, MSG_SPRINTF_1(MSG_SSID_WLAN, MSG_LEGACY_FATAL, "%s", pbuf); break; } - } else + } else if (optionflag & CONSOLE_FLAG) { android_printf("%s\n", pbuf); + } + else if (optionflag & LOGFILE_FLAG) { + if (log_out) + return fprintf(log_out, "%s\n", pbuf); + } + return 0; } /* @@ -596,7 +608,7 @@ get_numberofentries() boolean isfound = FALSE; if ((fd = fopen(DB_FILE_PATH, "r")) == NULL) { diag_printf("[Error] : While opening the file\n", - 0, 4, goptionflag, 0); + 0, 4, goptionflag, 0, NULL); return 0; } while ( fgets (line, sizeof(line), fd) != NULL ) { @@ -640,7 +652,7 @@ parse_dbfile() /*Open the data.msc file*/ if ((fd = fopen(DB_FILE_PATH , "r")) == NULL) { diag_printf("[Error] : While opening the file\n", - 0, 4, goptionflag, 0); + 0, 4, goptionflag, 0, NULL); return 0; } memset(line, 0 , sizeof(line)); @@ -716,6 +728,47 @@ parse_dbfile() return n_entries; } +int +cnssdiag_register_kernel_logging(int sock_fd, struct nlmsghdr *nlh) +{ + tAniNlHdr *wnl; + tAniNlAppRegReq *regReq; + int regMsgLen = 0; + + if (!nlh) + return -1; + /* Only the msg header is being carried */ + nlh->nlmsg_len = aniNlAlign(sizeof(tAniNlHdr)); + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_HOST_MSG; + nlh->nlmsg_flags = NLM_F_REQUEST; + nlh->nlmsg_seq++; + wnl = (tAniNlHdr *)nlh; + wnl->radio = 0; + wnl->wmsg.length = sizeof(tAniHdr); + wnl->wmsg.type = ANI_NL_MSG_LOG_REG_TYPE; + if (sendto(sock_fd, (char*)wnl, nlh->nlmsg_len,0,NULL, 0) < 0) { + return -1; + } + + regMsgLen = aniNlLen(sizeof(tAniNlAppRegReq)); + nlh->nlmsg_len = aniNlAlign(sizeof(tAniNlHdr)) + regMsgLen; + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = WLAN_NL_MSG_CNSS_HOST_EVENT_LOG; + nlh->nlmsg_flags = NLM_F_REQUEST; + nlh->nlmsg_seq++; + wnl = (tAniNlHdr *)nlh; + wnl->radio = 0; + wnl->wmsg.length = regMsgLen; + wnl->wmsg.type = htons(ANI_NL_MSG_LOG_REG_TYPE); + regReq = (tAniNlAppRegReq *)(wnl + 1); + regReq->pid = getpid(); + if (sendto(sock_fd, (char*)wnl, nlh->nlmsg_len,0,NULL, 0) < 0) { + return -1; + } + return 0; +} + static int32_t sendcnss_cmd(int sock_fd, int32_t cmd) { @@ -844,7 +897,8 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, */ diag_initialize(1, sock_fd, optionflag); if (!gisdiag_init) { - diag_printf("**ERROR** Diag not Initialized", 0, 4, optionflag, 0); + diag_printf("**ERROR** Diag not Initialized", + 0, 4, optionflag, 0, NULL); return -1; } @@ -854,7 +908,7 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, " Data.msc Version %d doesn't match" " with Firmware version %d", gdiag_header->file_version, version); - diag_printf(buf, 0, 4, optionflag, 0); + diag_printf(buf, 0, 4, optionflag, 0, NULL); return -1; } buffer = (uint32_t *)datap ; @@ -958,7 +1012,9 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) printf("%d: %s\n", lrecord, buf); - res = fprintf(log_out, "%s\n", buf); + res = diag_printf( + buf, vdevid, vdevlevel, optionflag, timestamp, log_out + ); //fseek(log_out, lrecord * res, SEEK_SET); if (lrecord == max_records) { lrecord = 0; @@ -968,7 +1024,7 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, } if (optionflag & (CONSOLE_FLAG | QXDM_FLAG)) diag_printf( - buf, vdevid, vdevlevel, optionflag, timestamp + buf, vdevid, vdevlevel, optionflag, timestamp, NULL ); } else { @@ -981,13 +1037,13 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, snprintf(buf, BUF_SIZ, "****WARNING****, undefined moduleid = %d no t" " found", moduleid); - diag_printf(buf, 0, 4, optionflag, timestamp); + diag_printf(buf, 0, 4, optionflag, timestamp, NULL); } break; default: snprintf(buf, BUF_SIZ, "****WARNING****, FWMSG ID %d not found", id); - diag_printf(buf, 0, 4, optionflag, timestamp); + diag_printf(buf, 0, 4, optionflag, timestamp, NULL); printf( "NOT found id = %d\n", id); } } @@ -995,7 +1051,7 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, break; default: diag_printf(" ****WARNING**** WRONG DIAG ID", 0, - 4, optionflag, timestamp); + 4, optionflag, timestamp, NULL); return 0; } count += payloadlen + 8; @@ -1058,3 +1114,68 @@ PACK(void *) cnss_wlan_handle(PACK(void *)req_pkt, uint16_t pkt_len) debug_printf("%s:Allocate response buffer error", __func__ ); return rsp; } + +void process_cnss_host_message(tAniNlHdr *wnl, int32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records) +{ + char *wlanLog = (char *)&wnl->wmsg.length + sizeof(wnl->wmsg.length); + char *charCache = NULL ; + + /* Assuming every kmsg is terminated by a '\n' character,split the + * wlanLog buffer received from the driver and log individual messages + */ + while((charCache = strchr(wlanLog, '\n'))!= NULL) { + *charCache = '\0'; + if (optionflag & QXDM_FLAG) { + WLAN_LOG_TO_DIAG(MSG_SSID_WLAN_RESERVED_10, MSG_LEGACY_MED, + wlanLog); + } + else if (optionflag & LOGFILE_FLAG) { + int32_t lrecord = 0; + uint32_t res = 0; + lrecord = *record; + lrecord++; + if (!((optionflag & SILENT_FLAG) == SILENT_FLAG)) + printf("%d: %s\n", lrecord, wlanLog); + res = fprintf(log_out, "%s\n", wlanLog); + if (lrecord == max_records) { + lrecord = 0; + fseek(log_out, lrecord * res, SEEK_SET); + } + *record = lrecord; + } + else if (optionflag & CONSOLE_FLAG) { + android_printf("%s\n", wlanLog); + } + wlanLog = charCache++; + } +} + +void process_cnss_host_diag_events_log(char *pData, int32_t optionflag) +{ + uint32_t diag_type = 0; + + if (optionflag & QXDM_FLAG) { + if (pData) { + diag_type = *(uint32_t*) pData; + pData += sizeof(uint32_t); + } + if (diag_type == DIAG_TYPE_LOGS) { + log_hdr_type *pHdr = (log_hdr_type*)pData; + if (log_status(pHdr->code)) + { + log_set_timestamp(pHdr); + log_submit(pHdr); + } + } + else if (diag_type == DIAG_TYPE_EVENTS) { + uint16_t event_id; + uint16_t length; + event_id = *(uint16_t*)pData; + pData += sizeof(uint16_t); + length = *(uint16_t*)pData; + pData += sizeof(uint16_t); + event_report_payload(event_id,length,pData); + } + } +} diff --git a/tools/fwdebuglog/cld-diag-parser.h b/tools/fwdebuglog/cld-diag-parser.h index 2519ca539933..513c4e9239dc 100644 --- a/tools/fwdebuglog/cld-diag-parser.h +++ b/tools/fwdebuglog/cld-diag-parser.h @@ -28,6 +28,8 @@ #ifndef _CLD_DIAG_PARSER_H #define _CLD_DIAG_PARSER_H +#define FEATURE_LOG_EXPOSED_HEADER + #include <stdint.h> #include "event.h" #include "msg.h" @@ -36,7 +38,11 @@ #include "diagpkt.h" #include "diagcmd.h" #include "diag.h" -#include "diagi.h" + +#ifdef ANDROID +#include "aniNlMsg.h" +#include "aniNlFuncs.h" +#endif /* KERNEL DEFS START */ #define DBGLOG_MAX_VDEVID 15 /* 0-15 */ @@ -198,15 +204,17 @@ static inline unsigned int get_32(const unsigned char *pos) /* KENEL DEFS END */ #define WLAN_NL_MSG_CNSS_DIAG 27 /* Msg type between user space/wlan driver */ -#define WLAN_NL_MSG_CNSS_MSG 28 +#define WLAN_NL_MSG_CNSS_HOST_MSG 28 +#define WLAN_NL_MSG_CNSS_HOST_EVENT_LOG 17 #define CNSS_WLAN_DIAG 0x07 #define CNSS_WLAN_SSR_TYPE 0x01 #define CNSS_WLAN_LEVEL_TYPE 0x02 /* NL messgage Carries actual Logs from Driver */ -#define ANI_NL_MSG_LOG_MSG_TYPE 89 +#define ANI_NL_MSG_LOG_HOST_MSG_TYPE 89 +#define ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE 0x5050 /* NL message Registration Req/Response to and from Driver */ -#define ANI_NL_MSG_LOG_REG_TYPE 1 -#define MAX_MSG_SIZE 8192 +#define ANI_NL_MSG_LOG_REG_TYPE 0x0001 +#define MAX_MSG_SIZE 50000 #define DIAG_MSG_MAX_LEN 4096 #define DIAG_MSG_OVERHEAD_LEN 48 @@ -261,5 +269,13 @@ process_diagfw_msg(uint8_t *datap, uint16_t len, uint32_t optionflag, int diag_msg_handler(uint32_t id, char *payload, uint16_t vdevid, uint32_t timestamp); +int +cnssdiag_register_kernel_logging(int sock_fd, struct nlmsghdr *nlh); + +void process_cnss_host_message(tAniNlHdr *wnl, int32_t optionflag, + FILE *log_out, int32_t *record, int32_t max_records); + +void process_cnss_host_diag_events_log(char *pData, int32_t optionflag); + #endif diff --git a/tools/fwdebuglog/cld-fwlog-netlink.c b/tools/fwdebuglog/cld-fwlog-netlink.c index 7e2c19997f29..f58bf0816c95 100644 --- a/tools/fwdebuglog/cld-fwlog-netlink.c +++ b/tools/fwdebuglog/cld-fwlog-netlink.c @@ -58,10 +58,6 @@ #include "cld-diag-parser.h" #ifdef ANDROID -#include "aniNlMsg.h" -#include "aniAsfHdr.h" -#include "aniAsfMem.h" - /* CAPs needed * CAP_NET_RAW : Use RAW and packet socket * CAP_NET_ADMIN : NL broadcast receive @@ -255,6 +251,7 @@ static void stop(int32_t signum) exit(0); } + void process_cnss_log_file(uint8_t *dbgbuf) { uint16_t length = 0; @@ -285,10 +282,10 @@ void process_cnss_log_file(uint8_t *dbgbuf) * Read the payload and process accordingly. * */ -void process_cnss_diag_msg(uint8_t *eventbuf) +void process_cnss_diag_msg(tAniNlHdr *wnl) { uint8_t *dbgbuf; - tAniNlHdr *wnl = (tAniNlHdr *)eventbuf; + uint8_t *eventbuf = (uint8_t *)NLMSG_DATA(wnl); uint16_t diag_type = 0; uint32_t event_id = 0; uint16_t length = 0; @@ -303,39 +300,48 @@ void process_cnss_diag_msg(uint8_t *eventbuf) length = *(uint16_t *)eventbuf; eventbuf += sizeof(uint16_t); - if (diag_type == DIAG_TYPE_FW_EVENT) { - eventbuf += sizeof(uint32_t); - event_id = *(uint32_t *)eventbuf; - eventbuf += sizeof(uint32_t); - if (optionflag & QXDM_FLAG) { - if (length) - event_report_payload(event_id, length, eventbuf); - else - event_report(event_id); - } - } else if (diag_type == DIAG_TYPE_FW_LOG) { - /* Do nothing for now */ - } else if (diag_type == DIAG_TYPE_FW_DEBUG_MSG) { - slot =(struct dbglog_slot *)dbgbuf; - length = get_le32((uint8_t *)&slot->length); - dropped = get_le32((uint8_t *)&slot->dropped); - if (optionflag & LOGFILE_FLAG) - process_cnss_log_file(dbgbuf); - else if (optionflag & (CONSOLE_FLAG | QXDM_FLAG)) - dbglog_parse_debug_logs(&slot->payload[0], length, dropped); - } else if (diag_type == DIAG_TYPE_FW_MSG) { - uint32_t version = 0; - slot = (struct dbglog_slot *)dbgbuf; - length = get_32((uint8_t *)&slot->length); - version = get_le32((uint8_t *)&slot->dropped); - process_diagfw_msg(&slot->payload[0], length, optionflag, log_out, - &record, max_records, version, sock_fd); - } else if (diag_type == DIAG_TYPE_HOST_MSG) { - slot = (struct dbglog_slot *)dbgbuf; - length = get_32((uint8_t *)&slot->length); - process_diaghost_msg(slot->payload, length); + if (wnl->nlh.nlmsg_type == WLAN_NL_MSG_CNSS_HOST_MSG + && (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_MSG_TYPE)) { + process_cnss_host_message(wnl, optionflag, log_out, &record, max_records); + } else if (wnl->nlh.nlmsg_type == WLAN_NL_MSG_CNSS_HOST_EVENT_LOG + && (wnl->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE)) { + process_cnss_host_diag_events_log((char *)((char *)&wnl->wmsg.length + + sizeof(wnl->wmsg.length)), optionflag); } else { - /* Do nothing for now */ + if (diag_type == DIAG_TYPE_FW_EVENT) { + eventbuf += sizeof(uint32_t); + event_id = *(uint32_t *)eventbuf; + eventbuf += sizeof(uint32_t); + if (optionflag & QXDM_FLAG) { + if (length) + event_report_payload(event_id, length, eventbuf); + else + event_report(event_id); + } + } else if (diag_type == DIAG_TYPE_FW_LOG) { + /* Do nothing for now */ + } else if (diag_type == DIAG_TYPE_FW_DEBUG_MSG) { + slot =(struct dbglog_slot *)dbgbuf; + length = get_le32((uint8_t *)&slot->length); + dropped = get_le32((uint8_t *)&slot->dropped); + if (optionflag & LOGFILE_FLAG) + process_cnss_log_file(dbgbuf); + else if (optionflag & (CONSOLE_FLAG | QXDM_FLAG)) + dbglog_parse_debug_logs(&slot->payload[0], length, dropped); + } else if (diag_type == DIAG_TYPE_FW_MSG) { + uint32_t version = 0; + slot = (struct dbglog_slot *)dbgbuf; + length = get_32((uint8_t *)&slot->length); + version = get_le32((uint8_t *)&slot->dropped); + process_diagfw_msg(&slot->payload[0], length, optionflag, log_out, + &record, max_records, version, sock_fd); + } else if (diag_type == DIAG_TYPE_HOST_MSG) { + slot = (struct dbglog_slot *)dbgbuf; + length = get_32((uint8_t *)&slot->length); + process_diaghost_msg(slot->payload, length); + } else { + /* Do nothing for now */ + } } } @@ -379,16 +385,18 @@ static uint32_t initialize(int32_t sock_fd) dest_addr.nl_pid = 0; /* For Linux Kernel */ dest_addr.nl_groups = 0; /* unicast */ - if (nlh) - free(nlh); - nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(RECLEN)); + if (nlh) { + free(nlh); + nlh = NULL; + } + nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_MSG_SIZE)); if (nlh == NULL) { fprintf(stderr, "Cannot allocate memory \n"); close(sock_fd); return -1; } - memset(nlh, 0, NLMSG_SPACE(RECLEN)); - nlh->nlmsg_len = NLMSG_SPACE(RECLEN); + memset(nlh, 0, NLMSG_SPACE(MAX_MSG_SIZE)); + nlh->nlmsg_len = NLMSG_SPACE(MAX_MSG_SIZE); nlh->nlmsg_pid = getpid(); nlh->nlmsg_type = WLAN_NL_MSG_CNSS_DIAG; nlh->nlmsg_flags = NLM_F_REQUEST; @@ -436,23 +444,27 @@ int32_t main(int32_t argc, char *argv[]) memset(dbglogoutfile, 0, PATH_MAX); memcpy(dbglogoutfile, optarg, strlen(optarg)); optionflag |= LOGFILE_FLAG; - break; + break; case 'c': optionflag |= CONSOLE_FLAG; - break; + break; case 'q': optionflag |= QXDM_FLAG; - break; + break; case 'r': rec_limit = strtoul(optarg, NULL, 0); - break; + break; case 's': optionflag |= SILENT_FLAG; - break; + break; + + case 'd': + optionflag |= DEBUG_FLAG; + break; default: usage(); } @@ -488,6 +500,7 @@ int32_t main(int32_t argc, char *argv[]) } initialize(sock_fd); + cnssdiag_register_kernel_logging(sock_fd, nlh); signal(SIGINT, stop); signal(SIGTERM, stop); @@ -535,6 +548,7 @@ int32_t main(int32_t argc, char *argv[]) } initialize(sock_fd); diag_initialize(isDriverLoaded, sock_fd, optionflag); + cnssdiag_register_kernel_logging(sock_fd, nlh); } } else if ((isDriverLoaded == TRUE) && (res == SIZEOF_NL_MSG_UNLOAD)) { @@ -544,12 +558,13 @@ int32_t main(int32_t argc, char *argv[]) isDriverLoaded = FALSE; diag_initialize(isDriverLoaded, sock_fd, optionflag); } - } else if((res >= sizeof(struct dbglog_slot)) && - ((res != SIZEOF_NL_MSG_LOAD) && - (res != SIZEOF_NL_MSG_UNLOAD))) { + } else if (((res >= sizeof(struct dbglog_slot)) && + (res != SIZEOF_NL_MSG_LOAD) && + (res != SIZEOF_NL_MSG_UNLOAD)) || + (nlh->nlmsg_type == WLAN_NL_MSG_CNSS_HOST_EVENT_LOG)) { isDriverLoaded = TRUE; - eventbuf = (uint8_t *)NLMSG_DATA(nlh); - process_cnss_diag_msg(eventbuf); + process_cnss_diag_msg((tAniNlHdr *)nlh); + memset(nlh,0,NLMSG_SPACE(MAX_MSG_SIZE)); } else { /* Ignore other messages that might be broadcast */ continue; |
