Skip to content

Commit

Permalink
update to support command line options and makefile
Browse files Browse the repository at this point in the history
  • Loading branch information
omriiluz committed Jan 21, 2014
1 parent 9c39209 commit ca3342b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 61 deletions.
19 changes: 19 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -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
133 changes: 72 additions & 61 deletions nrf24-btle-decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,44 @@ Steve Markgraf, RTL-SDR Library - https://github.com/steve-m/librtlsdr
#include <fcntl.h>
#endif /* defined(WIN32) */
#include <stdlib.h> // For exit function
#include <unistd.h> /* 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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -349,37 +341,56 @@ 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);
}

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;

Expand All @@ -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));
Expand Down

0 comments on commit ca3342b

Please sign in to comment.