1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-12-22 23:45:11 +02:00

tools/atrf-txrx/perdump: new utility to analyze a PER dump

- Makefile: added perdump
- perdump.h, perdump.c: read and analyze a PER dump in pcap format
- per-text.c: report PER test results as text on the console
This commit is contained in:
Werner Almesberger 2011-01-19 17:52:10 -03:00
parent 1fb05c221d
commit 6002759464
4 changed files with 283 additions and 2 deletions

View File

@ -1,8 +1,8 @@
#
# atrf-txrx/Makefile - Build the TX/RX test utility
#
# Written 2010 by Werner Almesberger
# Copyright 2010 Werner Almesberger
# Written 2010, 2011 by Werner Almesberger
# Copyright 2010, 2011 Werner Almesberger
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -16,3 +16,11 @@ MAIN = atrf-txrx
include ../Makefile.common
LDLIBS += -lm
CFLAGS += -g
all: perdump
perdump: perdump.o per-text.o
clean::
rm -f perdump.o per-text.o

View File

@ -0,0 +1,92 @@
/*
* atrf-txrx/per-text.h - Report PER on console as text
*
* Written 2011 by Werner Almesberger
* Copyright 2011 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdio.h>
#include "perdump.h"
static char line[65] = "";
static int packets = 0, garbled = 0, bad = 0, skipped = 0;
static int is_bad = 0;
static void flush(void)
{
if (*line)
printf("%s\n", line);
*line = 0;
}
static void text_undecided(int symbols)
{
int i;
flush();
for (i = 0; i != symbols/4; i++)
putchar('?');
putchar('\n');
}
static void text_packet(int symbols, int skip)
{
int i;
flush();
skipped += skip;
if (skip < 4)
for (i = 0; i != skip; i++)
putchar('\n');
else
printf("\n(%d)\n\n", skip);
for (i = 0; i != symbols/4; i++)
line[i] = '-';
line[i] = 0;
packets++;
is_bad = 0;
}
static void text_error(int symbol)
{
line[symbol >> 2] = '*';
if (!is_bad) {
bad++;
is_bad = 1;
}
}
static void text_finish(void)
{
double per;
flush();
if (packets+garbled)
per = (double) (bad+garbled)/(packets+garbled);
else
per = 0;
printf("\n%d total, %d bad, %d garbled, PER %f%%. %d skipped.\n",
packets+garbled, bad, garbled, 100*per, skipped);
}
struct result_ops text_ops = {
.begin = NULL,
.undecided = text_undecided,
.packet = text_packet,
.error = text_error,
.finish = text_finish,
};

153
tools/atrf-txrx/perdump.c Normal file
View File

@ -0,0 +1,153 @@
/*
* atrf-txrx/perdump.c - Analyze and dump a recorded PER test
*
* Written 2011 by Werner Almesberger
* Copyright 2011 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "pcap.h"
#include "perdump.h"
#define MAX_PSDU 127
static const struct result_ops *ops;
static void analyze(uint8_t *buf, int len)
{
static int last = -1;
int freq[256];
uint8_t best = 0;
int i;
for (i = 0; i != 256; i++)
freq[i] = 0;
for (i = 0; i != len; i++) {
freq[buf[i]]++;
if (!i || freq[buf[i]] > freq[best])
best = buf[i];
}
if (freq[best] <= len >> 1 && freq[best] != len) {
ops->undecided(len*2);
if (last != -1)
last++; /* probably :-) */
return;
}
ops->packet(len*2, last == -1 ? 0 : (uint8_t) (best-last-1));
last = best;
for (i = 0; i != len; i++) {
uint8_t delta = buf[i] ^ best;
if (delta & 0x0f)
ops->error(i*2);
if (delta & 0xf0)
ops->error(i*2+1);
}
}
static int pcap_record(FILE *file, const char *name)
{
struct pcap_pkthdr hdr;
uint8_t buf[MAX_PSDU];
size_t got;
got = fread(&hdr, sizeof(hdr), 1, file);
if (!got) {
if (ferror(file)) {
perror(name);
exit(1);
}
return 0;
}
if (hdr.caplen > MAX_PSDU) {
fprintf(stderr, "packet too big %u > %u\n",
hdr.caplen, MAX_PSDU);
exit(1);
}
got = fread(buf, hdr.caplen, 1, file);
if (!got) {
if (ferror(file)) {
perror(name);
exit(1);
}
fprintf(stderr, "file truncated\n");
exit(1);
}
analyze(buf, hdr.caplen);
return 1;
}
static void process_pcap(const char *name)
{
FILE *file;
struct pcap_file_header hdr;
size_t got;
file = fopen(name, "r");
if (!file) {
perror(name);
exit(1);
}
got = fread(&hdr, sizeof(hdr), 1, file);
if (!got) {
if (ferror(file)) {
perror(name);
exit(1);
}
return;
return;
}
if (hdr.magic != PCAP_FILE_MAGIC) {
fprintf(stderr, "unrecognized magic number 0x%08x "
"(expected 0x%08x)\n", hdr.magic, PCAP_FILE_MAGIC);
exit(1);
}
if (hdr.version_major != 2) {
fprintf(stderr, "unrecognized major number %u (expected %u)\n",
hdr.version_major, 2);
exit(1);
}
if (hdr.linktype != DLT_IEEE802_15_4) {
fprintf(stderr, "unrecognized link type 0x%x "
"(expected 0x%0x)\n", hdr.linktype, DLT_IEEE802_15_4);
exit(1);
}
if (ops->begin)
ops->begin();
while (pcap_record(file, name));
if (ops->finish)
ops->finish();
fclose(file);
}
static void usage(const char *name)
{
fprintf(stderr, "usage: %s pcap-file\n", name);
exit(1);
}
int main(int argc, char **argv)
{
if (argc != 2)
usage(*argv);
ops = &text_ops;
process_pcap(argv[1]);
return 0;
}

28
tools/atrf-txrx/perdump.h Normal file
View File

@ -0,0 +1,28 @@
/*
* atrf-txrx/perdump.h - Analyze and dump a recorded PER test
*
* Written 2011 by Werner Almesberger
* Copyright 2011 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef PERDUMP_H
#define PERDUMP_H
struct result_ops {
void (*begin)(void);
void (*undecided)(int symbols);
void (*packet)(int symbols, int skip);
void (*error)(int symbol);
void (*finish)(void);
};
extern struct result_ops text_ops;
#endif /* !PERDUMP_H */