qca-wifi: Add CFR capture test application
Add CFR capture test application with streamfs APIs. This is test application to read CFR dump from driver Change-Id: I6925646678d1e87ecef2fb5405e992246a6d4eb4 CRs-Fixed: 2372061
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
1fdbc75a8c
commit
0314441503
174
tools/linux/cfr_test_app.c
Normal file
174
tools/linux/cfr_test_app.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: cfr capture test application
|
||||
* This file provides test application to dump cfr capture from driver
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define CFR_DUMP_STREAMFS_FILE "/sys/kernel/debug/%s/cfr_dump0"
|
||||
#define CFR_DUMP_FILE "/tmp/cfr_dump_%s.bin"
|
||||
|
||||
#define MAX_CAPTURE_SIZE 2048
|
||||
static char rbuffer[MAX_CAPTURE_SIZE];
|
||||
|
||||
int stop_capture;
|
||||
|
||||
void print_usage(char *argv[])
|
||||
{
|
||||
printf("Usage:cfr_test_app -i <interfacename>\n");
|
||||
}
|
||||
|
||||
void streamfs_read_handler(int sfd, int cfd)
|
||||
{
|
||||
int rlen = 0;
|
||||
|
||||
memset(rbuffer, 0, sizeof(rbuffer));
|
||||
rlen = read(sfd, rbuffer, sizeof(rbuffer));
|
||||
if (rlen <= 0)
|
||||
return;
|
||||
|
||||
write(cfd, rbuffer, rlen);
|
||||
}
|
||||
|
||||
int start_cfr_capture_daemon(int streamfs_fd, int cfr_dump_fd)
|
||||
{
|
||||
fd_set sfs_fdset;
|
||||
int maxfd = 0, retval = 0;
|
||||
|
||||
FD_ZERO(&sfs_fdset);
|
||||
FD_SET(streamfs_fd, &sfs_fdset);
|
||||
maxfd = streamfs_fd;
|
||||
|
||||
while (!stop_capture) {
|
||||
retval = select(maxfd + 1, &sfs_fdset, NULL, NULL, NULL);
|
||||
if (retval < 0) {
|
||||
perror("select()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (FD_ISSET(streamfs_fd, &sfs_fdset))
|
||||
streamfs_read_handler(streamfs_fd, cfr_dump_fd);
|
||||
}
|
||||
|
||||
close(streamfs_fd);
|
||||
close(cfr_dump_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int open_streamfs_file(char *iface)
|
||||
{
|
||||
int fd = -1;
|
||||
char filename[128];
|
||||
|
||||
snprintf(filename, sizeof(filename), CFR_DUMP_STREAMFS_FILE, iface);
|
||||
fd = open(filename, O_RDONLY);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int initialize_cfr_dump_file(char *iface)
|
||||
{
|
||||
int fd = -1;
|
||||
static char filename[128];
|
||||
char time[50] = {0};
|
||||
struct timeval tv = {0};
|
||||
time_t curtime = 0;
|
||||
struct tm *tm_val = NULL;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
curtime = tv.tv_sec;
|
||||
tm_val = localtime(&curtime);
|
||||
if (tm_val) {
|
||||
strftime(time, 50, "%Y_%m_%d_%T", tm_val);
|
||||
snprintf(filename, sizeof(filename), CFR_DUMP_FILE, time);
|
||||
fd = open(filename, O_WRONLY | O_CREAT);
|
||||
} else {
|
||||
perror("Unable to get time value to generate filename \n");
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Signal Hnadler to overide CTRL+C */
|
||||
void sig_handler(int signum)
|
||||
{
|
||||
stop_capture = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int option = 0;
|
||||
char *iface = NULL;
|
||||
int streamfs_fd = -1, cfr_dump_fd = -1;
|
||||
|
||||
while ((option = getopt(argc, argv, "i:")) != -1) {
|
||||
switch (option) {
|
||||
case 'i':
|
||||
iface = optarg;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid argument\n");
|
||||
print_usage(argv);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iface == NULL) {
|
||||
printf("Invalid interface option\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
streamfs_fd = open_streamfs_file(iface);
|
||||
|
||||
if (streamfs_fd < 0) {
|
||||
printf("Invalid interface: %s, CFR capture file not found\n", iface);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
cfr_dump_fd = initialize_cfr_dump_file(iface);
|
||||
|
||||
if (cfr_dump_fd < 0) {
|
||||
printf(" Could not open CFR dump file for write\n");
|
||||
close(streamfs_fd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Starting CFR capture deamon, Press CTRL+C to exit \n");
|
||||
signal(SIGINT, sig_handler);
|
||||
start_cfr_capture_daemon(streamfs_fd, cfr_dump_fd);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user