summaryrefslogtreecommitdiff
path: root/tools/fwdebuglog
diff options
context:
space:
mode:
authorNagaraj <c_lnun@qca.qualcomm.com>2014-09-05 11:51:04 -0700
committerAnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com>2014-09-29 19:40:16 +0530
commit8f7528489da31731869d64cdf7b5112dbcd504ca (patch)
tree94b41f7889d34d53ace6e16249d6b39c9baf81d7 /tools/fwdebuglog
parentd0e4e30492b6a645c80e57dae0f36d136ad14223 (diff)
cnss_diag:Add support to log wlan host logs.
Register to the Driver to recv nl messages containing wlan driver messages, diag logs and events and route them to QXDM, console and file. Modifed to support pack format specifier for double digit. CRs-Fixed: 717919 Change-Id: I904aeddf5e156ee48f0c218eb0da75b283a042d2
Diffstat (limited to 'tools/fwdebuglog')
-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;