From 47c834c85ef8312a1e2b391026ed4c4029b374e1 Mon Sep 17 00:00:00 2001 From: Willy Hu Date: Fri, 1 May 2020 16:44:49 +0800 Subject: ril: [B5] Support traffic stats log convert tp pcap convert traffic stats log(extended_log_datastall_pkt.txt) to pcap when dump bugreport. Bug: 154492175 Test: 1. I do see extended_log_datastall.pcap file in dumstate_board.bin when I trigger bugreport. (data/vendor/radio/extended_logs/extended_log_datastall.txt) 2. I have do the test about incomplete/truncated logs, pcap just can parse to wrong information but not impact the dumpstate process. Change-Id: Iea892bc66bbce8d7f219ca1cde3701cebb35ff80 --- dumpstate/Android.mk | 3 +- dumpstate/DumpstateDevice.cpp | 133 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) (limited to 'dumpstate') diff --git a/dumpstate/Android.mk b/dumpstate/Android.mk index 69b20cf..b716215 100644 --- a/dumpstate/Android.mk +++ b/dumpstate/Android.mk @@ -32,7 +32,8 @@ LOCAL_SHARED_LIBRARIES := \ libdumpstateutil \ libhidlbase \ liblog \ - libutils + libutils \ + libpcap LOCAL_CFLAGS := -Werror -Wall diff --git a/dumpstate/DumpstateDevice.cpp b/dumpstate/DumpstateDevice.cpp index 543fade..99bbb43 100755 --- a/dumpstate/DumpstateDevice.cpp +++ b/dumpstate/DumpstateDevice.cpp @@ -28,6 +28,8 @@ #include #include +#include + #define _SVID_SOURCE #include @@ -52,6 +54,10 @@ #define VENDOR_VERBOSE_LOGGING_ENABLED_PROPERTY "persist.vendor.verbose_logging_enabled" +#define TIME_BUFFER 24 +#define STRING_BUFFER 550 +#define MAX_PACKET_LENGTH 150 + using android::os::dumpstate::CommandOptions; using android::os::dumpstate::DumpFileToFd; using android::os::dumpstate::PropertiesHelper; @@ -113,6 +119,127 @@ static void dumpLogs(int fd, std::string srcDir, std::string destDir, free(dirent_list); } +// Get timestamp and packet data +static void GetTimeStampAndPkt(char *pktbuf, unsigned char *packet, char *strtime, int totalbyte){ + int idxLog = 0; + int idxPkt = 0; + int firstPktDataIdx = 2; + int lastPktDataIdx = totalbyte - 2; + char arrTmpTime[19]; + char arrStrTime[TIME_BUFFER]; + char* tmpPktByteStr; + char* pktDataStr = pktbuf; + unsigned char arrPktData[MAX_PACKET_LENGTH]; + + memset(arrTmpTime, 0, sizeof(arrTmpTime)); + while ((tmpPktByteStr = strtok_r(pktDataStr, " ", &pktDataStr))) { + if(idxLog == 0) { + snprintf(arrTmpTime, sizeof(arrTmpTime),"%s", tmpPktByteStr); + } + if(idxLog == 1) { + snprintf(arrStrTime, sizeof(arrStrTime),"%s %s",arrTmpTime, tmpPktByteStr); + } + if(idxLog > firstPktDataIdx && idxLog <= lastPktDataIdx) { + int data; + unsigned char pktdata; + sscanf(tmpPktByteStr,"%02x", &data); + pktdata = (unsigned char)data; + arrPktData[idxPkt] = pktdata; + idxPkt++; + } + idxLog++; + } + memcpy(packet, arrPktData, MAX_PACKET_LENGTH); + memcpy(strtime, arrStrTime, TIME_BUFFER); +} + +static void ProcessPcapDump(FILE *fp, pcap_dumper_t *dumper) +{ + ALOGD("ProcessPcapDump(): enter"); + char strLogBuf[STRING_BUFFER]; + char arrPktBuf[STRING_BUFFER]; + char arrPktSplitBuf[STRING_BUFFER]; + char arrStrTime[TIME_BUFFER]; + unsigned char arrPktData[MAX_PACKET_LENGTH]; + + if(fp == NULL) { + ALOGD("can not read extended_log_datastall file!"); + return; + } + if(dumper == NULL) { + ALOGD("can not open pcap file."); + return; + } + + while (!feof(fp)) { + while (fgets(strLogBuf,STRING_BUFFER,fp)) { + if(strLogBuf[0] == '\n') { + continue; + } + memcpy(arrPktBuf, strLogBuf, sizeof(arrPktBuf)); + memcpy(arrPktSplitBuf, strLogBuf, sizeof(arrPktSplitBuf)); + + int countPktLen = 0; + char* tmpPktByteStr; + char* pktDataStr = arrPktSplitBuf; + while ((tmpPktByteStr = strtok_r(pktDataStr, " ", &pktDataStr))) { + countPktLen+=1; + } + + // Get timestamp and packet data + GetTimeStampAndPkt(arrPktBuf ,arrPktData, arrStrTime, countPktLen); + + // Build packet header + int timeMSec; + char* strTime; + char* strTimeMsec; + char* strTmpTime = arrStrTime; + struct pcap_pkthdr pcap_hdr; + while ((strTime = strtok_r(strTmpTime, ".", &strTmpTime))) { + time_t time; + struct tm timeStruct; + memset(&timeStruct, 0, sizeof(struct tm)); + if(strlen(strTime) == 19) { + strptime(strTime, "%Y-%m-%d %H:%M:%S", &timeStruct); + time = mktime(&timeStruct); + pcap_hdr.ts.tv_sec = time; + } + strTimeMsec = strtok_r(strTmpTime, ".", &strTmpTime); + timeMSec = atoi(strTimeMsec); + pcap_hdr.ts.tv_usec = timeMSec; + } + pcap_hdr.caplen = sizeof(arrPktData); + pcap_hdr.len = pcap_hdr.caplen; + pcap_dump((u_char *)dumper, &pcap_hdr, arrPktData); + } + } +} + +static void MergeAndConvertToPcap(char* logFile, char* oldlogFile, char* pcapFile) { + + ALOGD("DumpPcap(): enter"); + pcap_t *handle = pcap_open_dead(DLT_EN10MB, 1 << 16); + pcap_dumper_t *dumper = pcap_dump_open(handle, pcapFile); + + if(dumper == NULL) { + ALOGD("can not open pcap file."); + return; + } + + FILE *fp = fopen(oldlogFile, "r"); + if(fp != NULL) { + ProcessPcapDump(fp, dumper); + fclose(fp); + } + fp = fopen(logFile, "r"); + if(fp != NULL) { + ProcessPcapDump(fp, dumper); + fclose(fp); + } + pcap_dump_close(dumper); +} + + static void *dumpModemThread(void *data) { long fdModem = (long)data; @@ -169,6 +296,12 @@ static void *dumpModemThread(void *data) } RunCommandToFd(STDOUT_FILENO, "CP MODEM POWERON LOG", {"/vendor/bin/cp", diagPoweronLogPath.c_str(), modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build()); + // dump to pcap + char fpcapname[]="/data/vendor/radio/extended_logs/extended_log_datastall.pcap"; + char flogname[]="/data/vendor/radio/extended_logs/extended_log_datastall.txt"; + char flogoldname[]="/data/vendor/radio/extended_logs/extended_log_datastall.txt.old"; + MergeAndConvertToPcap(flogname, flogoldname, fpcapname); + if (!PropertiesHelper::IsUserBuild()) { char cmd[256] = { 0 }; -- cgit v1.2.3