summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/fwdebuglog/cld-diag-parser.c155
-rw-r--r--tools/fwdebuglog/cld-diag-parser.h26
-rw-r--r--tools/fwdebuglog/cld-fwlog-netlink.c121
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;