IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Git Source Tree
Root/
| Source at commit 805db6ebf5d80692158acadf88e239da9d3e67af created 6 years 3 months ago. By Stefan Schmidt, fw/atusb: add extra steps needed for HULUSB in README | |
|---|---|
| 1 | /* |
| 2 | * atrf-txrx/perdump.c - Analyze and dump a recorded PER test |
| 3 | * |
| 4 | * Written 2011 by Werner Almesberger |
| 5 | * Copyright 2011 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdint.h> |
| 15 | #include <stdlib.h> |
| 16 | #include <stdio.h> |
| 17 | |
| 18 | #include "pcap.h" |
| 19 | #include "perdump.h" |
| 20 | |
| 21 | |
| 22 | #define MAX_PSDU 127 |
| 23 | |
| 24 | |
| 25 | static const struct result_ops *ops; |
| 26 | |
| 27 | |
| 28 | static void analyze(uint8_t *buf, int len, double ts) |
| 29 | { |
| 30 | static int last = -1; |
| 31 | static double t0 = 0; |
| 32 | int freq[256]; |
| 33 | uint8_t best = 0; |
| 34 | int i; |
| 35 | |
| 36 | if (!t0) |
| 37 | t0 = ts; |
| 38 | for (i = 0; i != 256; i++) |
| 39 | freq[i] = 0; |
| 40 | for (i = 0; i != len; i++) { |
| 41 | freq[buf[i]]++; |
| 42 | if (!i || freq[buf[i]] > freq[best]) |
| 43 | best = buf[i]; |
| 44 | } |
| 45 | if (freq[best] <= len >> 1 && freq[best] != len) { |
| 46 | ops->undecided(len*2, ts-t0); |
| 47 | if (last != -1) |
| 48 | last++; /* probably :-) */ |
| 49 | return; |
| 50 | } |
| 51 | ops->packet(len*2, last == -1 ? 0 : (uint8_t) (best-last-1), ts-t0); |
| 52 | last = best; |
| 53 | for (i = 0; i != len; i++) { |
| 54 | uint8_t delta = buf[i] ^ best; |
| 55 | |
| 56 | if (delta & 0x0f) |
| 57 | ops->error(i*2); |
| 58 | if (delta & 0xf0) |
| 59 | ops->error(i*2+1); |
| 60 | } |
| 61 | |
| 62 | } |
| 63 | |
| 64 | |
| 65 | static int pcap_record(FILE *file, const char *name) |
| 66 | { |
| 67 | struct pcap_pkthdr hdr; |
| 68 | uint8_t buf[MAX_PSDU]; |
| 69 | size_t got; |
| 70 | |
| 71 | got = fread(&hdr, sizeof(hdr), 1, file); |
| 72 | if (!got) { |
| 73 | if (ferror(file)) { |
| 74 | perror(name); |
| 75 | exit(1); |
| 76 | } |
| 77 | return 0; |
| 78 | } |
| 79 | if (hdr.caplen > MAX_PSDU) { |
| 80 | fprintf(stderr, "packet too big %u > %u\n", |
| 81 | hdr.caplen, MAX_PSDU); |
| 82 | exit(1); |
| 83 | } |
| 84 | got = fread(buf, hdr.caplen, 1, file); |
| 85 | if (!got) { |
| 86 | if (ferror(file)) { |
| 87 | perror(name); |
| 88 | exit(1); |
| 89 | } |
| 90 | fprintf(stderr, "file truncated\n"); |
| 91 | exit(1); |
| 92 | } |
| 93 | analyze(buf, hdr.caplen, hdr.ts_sec+hdr.ts_usec/1000000.0); |
| 94 | return 1; |
| 95 | } |
| 96 | |
| 97 | |
| 98 | static void process_pcap(const char *name) |
| 99 | { |
| 100 | FILE *file; |
| 101 | struct pcap_file_header hdr; |
| 102 | size_t got; |
| 103 | |
| 104 | file = fopen(name, "r"); |
| 105 | if (!file) { |
| 106 | perror(name); |
| 107 | exit(1); |
| 108 | } |
| 109 | got = fread(&hdr, sizeof(hdr), 1, file); |
| 110 | if (!got) { |
| 111 | if (ferror(file)) { |
| 112 | perror(name); |
| 113 | exit(1); |
| 114 | } |
| 115 | return; |
| 116 | return; |
| 117 | } |
| 118 | if (hdr.magic != PCAP_FILE_MAGIC) { |
| 119 | fprintf(stderr, "unrecognized magic number 0x%08x " |
| 120 | "(expected 0x%08x)\n", hdr.magic, PCAP_FILE_MAGIC); |
| 121 | exit(1); |
| 122 | } |
| 123 | if (hdr.version_major != 2) { |
| 124 | fprintf(stderr, "unrecognized major number %u (expected %u)\n", |
| 125 | hdr.version_major, 2); |
| 126 | exit(1); |
| 127 | } |
| 128 | if (hdr.linktype != DLT_IEEE802_15_4) { |
| 129 | fprintf(stderr, "unrecognized link type 0x%x " |
| 130 | "(expected 0x%0x)\n", hdr.linktype, DLT_IEEE802_15_4); |
| 131 | exit(1); |
| 132 | } |
| 133 | if (ops->begin) |
| 134 | ops->begin(); |
| 135 | while (pcap_record(file, name)); |
| 136 | if (ops->finish) |
| 137 | ops->finish(); |
| 138 | fclose(file); |
| 139 | } |
| 140 | |
| 141 | |
| 142 | static void usage(const char *name) |
| 143 | { |
| 144 | fprintf(stderr, "usage: %s pcap-file\n", name); |
| 145 | exit(1); |
| 146 | } |
| 147 | |
| 148 | |
| 149 | int main(int argc, char **argv) |
| 150 | { |
| 151 | if (argc != 2) |
| 152 | usage(*argv); |
| 153 | ops = &text_ops; |
| 154 | process_pcap(argv[1]); |
| 155 | return 0; |
| 156 | } |
| 157 | |
