Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebfebf79 authored by Willy Hu's avatar Willy Hu Committed by Cyan_Hsieh
Browse files

Merge "ril: [R3] Support traffic stats log convert tp pcap" into rvc-dev

Change-Id: I3acd893fde21421f0829aec0aa6e33a2c8b5d4e1
Change-Id: I3f7d75b70bb3d5cffbee104b91dde4911df28ab2
Change-Id: Ib4e1b48def4644938a3bf01670c6e900be351af1
Change-Id: Iac6549f8e18385446da2f799b699d76985ac38f1
Change-Id: I5667a1c757f28251a41074289d304961b29e81b5
Change-Id: Ie0990601373ab46bd4759970a9bde99ded1d7af9
parents 181611d6 21e01e77
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ LOCAL_SHARED_LIBRARIES := \
    libdumpstateutil \
    libhidlbase \
    liblog \
    libutils
    libutils \
    libpcap

LOCAL_CFLAGS := -Werror -Wall

+132 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@
#include <pthread.h>
#include <string.h>

#include <pcap.h>

#define _SVID_SOURCE
#include <dirent.h>

@@ -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,126 @@ 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 +295,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 };