From ca3342b88fce6999315e8150c1c15b14c9d06646 Mon Sep 17 00:00:00 2001 From: Omri Iluz Date: Tue, 21 Jan 2014 00:43:12 -0800 Subject: [PATCH] update to support command line options and makefile --- makefile | 19 +++++++ nrf24-btle-decoder.c | 133 +++++++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 61 deletions(-) create mode 100644 makefile diff --git a/makefile b/makefile new file mode 100644 index 0000000..eac495a --- /dev/null +++ b/makefile @@ -0,0 +1,19 @@ + +SHELL = /bin/sh +CC = gcc + +FLAGS = -std=gnu99 +CFLAGS = -Wall -O3 +OUTDIR = ./bin + +TARGET = $(OUTDIR)/nrf24-btle-decoder +SOURCES = nrf24-btle-decoder.c + +all: $(TARGET) + +$(TARGET): $(SOURCES) + $(CC) $(FLAGS) $(CFLAGS) -o $(TARGET) $(SOURCES) + +clean: + -rm -f $(TARGET) + -rm -f $(TARGET).exe diff --git a/nrf24-btle-decoder.c b/nrf24-btle-decoder.c index 2dfe0cb..ac381a4 100644 --- a/nrf24-btle-decoder.c +++ b/nrf24-btle-decoder.c @@ -40,24 +40,44 @@ Steve Markgraf, RTL-SDR Library - https://github.com/steve-m/librtlsdr #include #endif /* defined(WIN32) */ #include // For exit function +#include /* for getopt */ -uint8_t inline SwapBits(uint8_t a){ +/* Global variables */ +int32_t g_threshold; // Quantization threshold +int g_srate; // sample rate downconvert ratio - uint8_t v = 0; - - if(a & 0x80) v |= 0x01; - if(a & 0x40) v |= 0x02; - if(a & 0x20) v |= 0x04; - if(a & 0x10) v |= 0x08; - if(a & 0x08) v |= 0x10; - if(a & 0x04) v |= 0x20; - if(a & 0x02) v |= 0x40; - if(a & 0x01) v |= 0x80; - - return v; +/* Ring Buffer */ +#define RB_SIZE 1000 +int rb_head=-1; +int16_t *rb_buf; +/* Init Ring Buffer */ +void RB_init(void){ + rb_buf = (int16_t *)malloc(RB_SIZE*2); +} +/* increment Ring Buffer Head */ +void RB_inc(void){ + rb_head++; + rb_head=(rb_head)%RB_SIZE; } +/* Access Ring Buffer location l */ +#define RB(l) rb_buf[(rb_head+(l))%RB_SIZE] +/* end Ring Buffer */ + +/* helper functions */ +/* Quantize sample at location l by checking whether it's over the threshold */ +/* Important - takes into account the sample rate downconversion ratio */ +inline bool Quantize(int16_t l){ + return RB(l*g_srate) > g_threshold; +} +#define Q(l) Quantize(l) +uint8_t inline SwapBits(uint8_t a){ + return (uint8_t) (((a * 0x0802LU & 0x22110LU) | (a * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); +} +/* Calcualte CRC16-CCITT for the NRF packets. + * using custom start value to compensate for non byte aligned message (due to 9 bit PCF) + */ uint32_t NRFCrc(const uint8_t* data, size_t data_len) { uint8_t i; @@ -81,6 +101,7 @@ uint32_t NRFCrc(const uint8_t* data, size_t data_len) return (uint16_t)(crc & 0xffff); } +/* Calcualte custom CRC24 for BTLE */ uint32_t BTLECrc(const uint8_t* data, uint8_t len, uint8_t* dst){ uint8_t v, t, d; @@ -110,7 +131,7 @@ uint32_t BTLECrc(const uint8_t* data, uint8_t len, uint8_t* dst){ return crc; } - +/* whiten (descramble) BTLE packet using channel value */ void BTLEWhiten(uint8_t* data, uint8_t len, uint8_t chan){ uint8_t i; @@ -129,35 +150,6 @@ void BTLEWhiten(uint8_t* data, uint8_t len, uint8_t chan){ } } -/* Ring Buffer */ -#define RB_SIZE 1000 -int rb_head=-1; -int16_t *rb_buf; -/* Init Ring Buffer */ -void RB_init(void){ - rb_buf = (int16_t *)malloc(RB_SIZE*2); -} -/* increment Ring Buffer Head */ -void RB_inc(void){ - rb_head++; - rb_head=(rb_head)%RB_SIZE; -} -/* Access Ring Buffer location l */ -#define RB(l) rb_buf[(rb_head+(l))%RB_SIZE] -/* end Ring Buffer */ - -/* Global variables */ -int32_t g_threshold; // Quantization threshold -int g_srate; // sample rate downconvert ratio - -/* helper functions */ -/* Quantize sample at location l by checking whether it's over the threshold */ -/* Important - takes into account the sample rate downconversion ratio */ -inline bool Quantize(l){ - return RB(l*g_srate) > g_threshold; -} -#define Q(l) Quantize(l) - /* Extract quantization threshold from preamble sequence */ int32_t ExtractThreshold(void){ int32_t threshold=0; @@ -300,7 +292,7 @@ bool DecodeNRFPacket(int32_t sample, int srate){ /* extract packet length, avoid excessive length packets */ packet_length=(int)pcf>>3; - if (packet_length>32)packet_length=0; + if (packet_length>32) return false; /* extract data */ ExtractBytes(6*8+9, packet_data, packet_length); @@ -328,18 +320,18 @@ bool DecodeNRFPacket(int32_t sample, int srate){ } -bool DecodePacket(int32_t sample, int srate){ +bool DecodePacket(int decode_type, int32_t sample, int srate){ bool packet_detected=false; g_srate=srate; g_threshold = ExtractThreshold(); if (DetectPreamble()){ // btle - if (1){ + if (decode_type==2){ packet_detected |= DecodeBTLEPacket(sample, srate); } //NRF24 - if (1){ + if (decode_type==1){ packet_detected |= DecodeNRFPacket(sample, srate); } } @@ -349,13 +341,12 @@ bool DecodePacket(int32_t sample, int srate){ void usage(void) { fprintf(stderr, - "nrf24-btle-decoder, decode NRF24L01+ and Bluetooth Low Energy packets using RTL-SDR\n\n" - "Use:\tnrf24-btle-decoder -f freq [-options] [filename]\n" - "\t-f frequency_to_tune_to [Hz]\n" - "\t use multiple -f for scanning (requires squelch)\n" - "\t[-s sample_rate (default: 24k)]\n" - "\t[-d device_index (default: 0)]\n" - + "Usage:\tnrf24-btle-decoder [-t nrf|btle] [-d 1|2|8] \n\n" + "Important - this program input is a 2M samples per second bitstream generated by rtl_fm or equivalent\n" + " e.g. rtl_fm.exe -f 428m -s 2000k | nrf24-btle-decoder.exe -n -s 3\n\n" + "\t[-t packet_type (nrf or btle). defaults to nrf.] \n" + "\t[-d downsample_rate (1 for 2mbps , 2 for 1mbps, 8 for 256kbps), default to 2]\n" + "\t using packet type btle implies -d 2\n"); exit(1); } @@ -363,23 +354,43 @@ int main (int argc, char**argv){ int16_t cursamp; int32_t samples=0; int skipSamples; - - #if defined(WIN32) + int opt; + /* 1 for nrf, 2 for btle */ + int decode_type=1; + bool optfail=false; + int srate=2; + #if defined(WIN32) _setmode(_fileno(stdin), _O_BINARY); #endif /* defined(WIN32) */ - printf("NRF24L01+ and Bluetooth Low Energy decoder v0.4\n\n"); -while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:E:F:A:M:h")) != -1) { + printf("nrf24-btle-decoder, decode NRF24L01+ and Bluetooth Low Energy packets using RTL-SDR v0.4\n\n"); + while ((opt = getopt(argc, argv, "t:d:h")) != -1) { switch (opt) { + case 't': + if (strcmp("nrf", optarg) == 0) decode_type = 1; + else if (strcmp("btle", optarg) == 0) decode_type = 2; + else { + fprintf (stderr, "Unknown packet_type - %s.\n\n", optarg); + optfail=1; + } + break; case 'd': - //dongle.dev_index = verbose_device_search(optarg); - //dev_given = 1; + srate=(int)atoi(optarg); + if (srate!=1 && srate!=2 && srate!=8){ + fprintf (stderr, "illegal downsample rate - %d.\n\n", srate); + optfail=1; + } break; + case 'h': default: usage(); break; } } + if (decode_type==2) srate=2; + + if (argc < optind || optfail) usage(); + RB_init(); g_threshold = 0; @@ -390,7 +401,7 @@ while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:E:F:A:M:h")) != -1) { cursamp = (int16_t) ( fgetc(stdin) | fgetc(stdin)<<8); RB_inc(); RB(0)=(int)cursamp; - if (--skipSamples<1)if (DecodePacket(++samples,2)) skipSamples=20; + if (--skipSamples<1)if (DecodePacket(decode_type, ++samples, srate)) skipSamples=20; } printf("%"PRId32" samples received in %d seconds \n",samples,(int)(time(NULL)-start_time));