Date:2011-01-19 07:22:24 (9 years 6 months ago)
Author:Werner Almesberger
Commit:f9aee543234110dba3d0a2104024a668a1bc32ae
Message:atrf-txrx: added ability to record received frames in pcap format

- pcap.h: basic pcap file structure definitions
- atrf-txrx.c (usage, main): added option "-o file" to write received
frames to a pcap file instead of displaying them
- atrf-txrx.c (receive): moved code to receive and display a single message
into new function receive_message
- atrf-txrx.c (write_pcap_hdr, write_pcap_rec, receive_pcap): receive
messages into a pcap file
Files: tools/atrf-txrx/atrf-txrx.c (7 diffs)
tools/atrf-txrx/pcap.h (1 diff)

Change Details

tools/atrf-txrx/atrf-txrx.c
1919#include <math.h>
2020#include <signal.h>
2121#include <sys/wait.h>
22#include <sys/time.h>
2223
2324#include "at86rf230.h"
2425#include "atrf.h"
2526#include "misctxrx.h"
2627
28#include "pcap.h"
29
2730
2831/*
2932 * According to IEEE 802.15.4-2003 section E.2.6, channel 15 is the only
...... 
148151}
149152
150153
151static void receive(struct atrf_dsc *dsc)
154static void receive_message(struct atrf_dsc *dsc)
152155{
153156    uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
154157    int n, ok, i;
155158    uint8_t ed, lqi;
156159
157    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
158    /*
159     * 180 us, according to AVR2001 section 4.2. We time out after
160     * nominally 200 us.
161     */
162    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
163
164160    fprintf(stderr, "Ready.\n");
165161    wait_for_interrupt(dsc, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
166162        10, 0);
...... 
185181}
186182
187183
184static void write_pcap_hdr(FILE *file)
185{
186    struct pcap_file_header hdr = {
187        .magic = 0xa1b2c3d4,
188        .version_major = 2,
189        .version_minor = 4,
190        .thiszone = 0,
191        .sigfigs = 0,
192        .snaplen = MAX_PSDU,
193        .linktype = DLT_IEEE802_15_4
194    };
195
196    if (fwrite(&hdr, sizeof(hdr), 1, file) != 1) {
197        perror("fwrite");
198        exit(1);
199    }
200}
201
202
203static void write_pcap_rec(FILE *file, const struct timeval *tv,
204    const void *buf, int n)
205{
206    struct pcap_pkthdr hdr = {
207        .ts_sec = tv->tv_sec,
208        .ts_usec = tv->tv_usec,
209        .caplen = n,
210        .len = n
211    };
212
213    if (fwrite(&hdr, sizeof(hdr), 1, file) != 1) {
214        perror("fwrite");
215        exit(1);
216    }
217    if (fwrite(buf, n, 1, file) != 1) {
218        perror("fwrite");
219        exit(1);
220    }
221}
222
223
224static void receive_pcap(struct atrf_dsc *dsc, const char *name)
225{
226    FILE *file;
227    uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
228    struct timeval now;
229    int n;
230    int count = 0;
231
232    file = fopen(name, "w");
233    if (!file) {
234        perror(name);
235        exit(1);
236    }
237    write_pcap_hdr(file);
238    while (run) {
239        wait_for_interrupt(dsc,
240            IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
241            10, 0);
242        if (!run)
243            break;
244        gettimeofday(&now, NULL);
245        n = atrf_buf_read(dsc, buf, sizeof(buf));
246        if (n < 0)
247            exit(1);
248        if (n < 2) {
249            fprintf(stderr, "%d bytes received\n", n);
250            continue;
251        }
252        write_pcap_rec(file, &now, buf, n-1);
253        (void) write(2, ".", 1);
254        count++;
255    }
256    if (fclose(file) == EOF) {
257        perror(name);
258        exit(1);
259    }
260    fprintf(stderr, "%sreceived %d message%s\n", count ? "\n" : "",
261        count, count == 1 ? "" : "s");
262}
263
264
265static void receive(struct atrf_dsc *dsc, const char *name)
266{
267    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
268    /*
269     * 180 us, according to AVR2001 section 4.2. We time out after
270     * nominally 200 us.
271     */
272    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
273
274    if (name)
275        receive_pcap(dsc, name);
276    else
277        receive_message(dsc);
278}
279
280
188281static void transmit(struct atrf_dsc *dsc, const char *msg, int times)
189282{
190283    uint8_t buf[MAX_PSDU];
...... 
332425" wave in MHz: -2, -0.5, or +0.5\n"
333426" command shell command to run while transmitting (default: wait for\n"
334427" SIGINT instead)\n\n"
335" common options: [-c channel|-f freq] [-C mhz] [-p power] [-t trim]\n"
428" common options: [-c channel|-f freq] [-C mhz] [-o file] [-p power] "
429"[-t trim]\n"
336430" -c channel channel number, 11 to 26 (default %d)\n"
337431" -C mhz output clock at 1, 2, 4, 8, or 16 MHz (default: off)\n"
338432" -f freq frequency in MHz, 2405 to 2480 (default %d)\n"
433" -o file write received data to a file in pcap format\n"
339434" -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n"
340435" -t trim trim capacitor, 0 to 15 (default 0)\n"
341436        , name, name, DEFAULT_CHANNEL, 2405+5*(DEFAULT_CHANNEL-11),
...... 
354449    int c, freq;
355450    unsigned tmp, clkm = 0;
356451    int status = 0;
452    const char *pcap_file = NULL;
357453    struct atrf_dsc *dsc;
358454
359    while ((c = getopt(argc, argv, "c:C:f:p:t:T:")) != EOF)
455    while ((c = getopt(argc, argv, "c:C:f:o:p:t:T:")) != EOF)
360456        switch (c) {
361457        case 'c':
362458            channel = strtoul(optarg, &end, 0);
...... 
375471            if (channel < 11 || channel > 26)
376472                usage(*argv);
377473            break;
474        case 'o':
475            pcap_file = optarg;
476            break;
378477        case 'p':
379478            power = strtod(optarg, &end);
380479            if (*end)
...... 
419518        dsc = init_txrx(trim, clkm);
420519        set_channel(dsc, channel);
421520        if (!cont_tx)
422            receive(dsc);
521            receive(dsc, pcap_file);
423522        else {
424523            set_power(dsc, power, 0);
425524            status = test_mode(dsc, cont_tx, NULL);
tools/atrf-txrx/pcap.h
1/*
2 * pcap.h - Minimum pcap file definitions
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 * This header defines the few things we need to write files in the pcap
15 * format. The identifiers are the same as in the system's pcap/pcap.h, but
16 * the types have been standardized. Note that the timestamp parts have to be
17 * put separately, since "struct timeval" may be padded.
18 *
19 * The reason for having our own header instead of just using pcap/pcap.h is
20 * to avoid a build-dependency on libpcap.
21 */
22
23#ifndef PCAP_H
24#define PCAP_H
25
26#include <stdint.h>
27#include <sys/time.h>
28
29
30#define DLT_IEEE802_15_4 195
31
32struct pcap_file_header {
33    uint32_t magic;
34    uint16_t version_major;
35    uint16_t version_minor;
36    int32_t thiszone;
37    uint32_t sigfigs;
38    uint32_t snaplen;
39    uint32_t linktype;
40};
41
42struct pcap_pkthdr {
43    uint32_t ts_sec;
44    uint32_t ts_usec;
45    uint32_t caplen;
46    uint32_t len;
47};
48
49#endif /* !PCAP_H */

Archive Download the corresponding diff file



interactive