X-Git-Url: https://git.rvb.name/rtl-433.git/blobdiff_plain/337eb4ba945097205fbb6a3ca7912fb0697092d1..a3166201c6f1fa7e56c7e4b86083a42fffb0c568:/src/rtl_433.c~ diff --git a/src/rtl_433.c~ b/src/rtl_433.c~ deleted file mode 100644 index 98685ac..0000000 --- a/src/rtl_433.c~ +++ /dev/null @@ -1,1231 +0,0 @@ -/* - * rtl_433, turns your Realtek RTL2832 based DVB dongle into a 433.92MHz generic data receiver - * Copyright (C) 2012 by Benjamin Larsson - * - * Based on rtl_sdr - * - * Copyright (C) 2012 by Steve Markgraf - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "rtl-sdr.h" -#include "rtl_433.h" -#include "rtl_433_devices.h" - -static int do_exit = 0; -static int do_exit_async = 0, frequencies = 0, events = 0; -uint32_t frequency[MAX_PROTOCOLS]; -time_t rawtime_old; -int flag; -uint32_t samp_rate = DEFAULT_SAMPLE_RATE; -static uint32_t bytes_to_read = 0; -static rtlsdr_dev_t *dev = NULL; -static uint16_t scaled_squares[256]; -static int override_short = 0; -static int override_long = 0; -int debug_output = 0; - -int debug_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS], int16_t bits_per_row[BITBUF_ROWS]) { - int i,j,k; - int rows_used[BITBUF_ROWS]; - int col_max = 0; - int row_cnt = 0; - - // determine what part of bb[][] has non-zero data to avoid - // outputting lots of empty rows - for (i=0 ; i 0 ; j--) { - if (bb[i][j] != 0) - break; - } - if (j != 0) { - rows_used[i] = 1; - row_cnt++; - if (j > col_max) - col_max = j; - } else { - rows_used[i] = 0; - } - } - - if (!row_cnt) { - fprintf(stderr, "debug_callback: empty data array\n"); - return 0; - } - - fprintf(stderr, "\n"); - for (i=0 ; i=0 ; k--) { - if (bb[i][j] & 1<bits_buffer, 0, BITBUF_ROWS * BITBUF_COLS); - memset(p->bits_per_row, 0, BITBUF_ROWS); - p->bits_col_idx = 0; - p->bits_bit_col_idx = 7; - p->bits_row_idx = 0; - p->bit_rows = 0; -} - -static void demod_add_bit(struct protocol_state* p, int bit) { - p->bits_buffer[p->bits_row_idx][p->bits_col_idx] |= bit << p->bits_bit_col_idx; - p->bits_bit_col_idx--; - if (p->bits_bit_col_idx < 0) { - p->bits_bit_col_idx = 7; - p->bits_col_idx++; - if (p->bits_col_idx > BITBUF_COLS - 1) { - p->bits_col_idx = BITBUF_COLS - 1; - // fprintf(stderr, "p->bits_col_idx>%i!\n", BITBUF_COLS-1); - } - } - p->bits_per_row[p->bit_rows]++; -} - -static void demod_next_bits_packet(struct protocol_state* p) { - p->bits_col_idx = 0; - p->bits_row_idx++; - p->bits_bit_col_idx = 7; - if (p->bits_row_idx > BITBUF_ROWS - 1) { - p->bits_row_idx = BITBUF_ROWS - 1; - //fprintf(stderr, "p->bits_row_idx>%i!\n", BITBUF_ROWS-1); - } - p->bit_rows++; - if (p->bit_rows > BITBUF_ROWS - 1) - p->bit_rows -= 1; -} - -static void demod_print_bits_packet(struct protocol_state* p) { - int i, j, k; - - fprintf(stderr, "\n"); - for (i = 0; i < p->bit_rows + 1; i++) { - fprintf(stderr, "[%02d] {%d} ", i, p->bits_per_row[i]); - for (j = 0; j < ((p->bits_per_row[i] + 8) / 8); j++) { - fprintf(stderr, "%02x ", p->bits_buffer[i][j]); - } - fprintf(stderr, ": "); - for (j = 0; j < ((p->bits_per_row[i] + 8) / 8); j++) { - for (k = 7; k >= 0; k--) { - if (p->bits_buffer[i][j] & 1 << k) - fprintf(stderr, "1"); - else - fprintf(stderr, "0"); - } - // fprintf(stderr, "=0x%x ",demod->bits_buffer[i][j]); - fprintf(stderr, " "); - } - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - return; -} - -static void register_protocol(struct dm_state *demod, r_device *t_dev) { - struct protocol_state *p = calloc(1, sizeof (struct protocol_state)); - p->short_limit = (float) t_dev->short_limit / ((float) DEFAULT_SAMPLE_RATE / (float) samp_rate); - p->long_limit = (float) t_dev->long_limit / ((float) DEFAULT_SAMPLE_RATE / (float) samp_rate); - p->reset_limit = (float) t_dev->reset_limit / ((float) DEFAULT_SAMPLE_RATE / (float) samp_rate); - p->modulation = t_dev->modulation; - p->callback = t_dev->json_callback; - demod_reset_bits_packet(p); - - demod->r_devs[demod->r_dev_num] = p; - demod->r_dev_num++; - - fprintf(stderr, "Registering protocol[%02d] %s\n", demod->r_dev_num, t_dev->name); - - if (demod->r_dev_num > MAX_PROTOCOLS) - fprintf(stderr, "Max number of protocols reached %d\n", MAX_PROTOCOLS); -} - - -static unsigned int counter = 0; -static unsigned int print = 1; -static unsigned int print2 = 0; -static unsigned int pulses_found = 0; -static unsigned int prev_pulse_start = 0; -static unsigned int pulse_start = 0; -static unsigned int pulse_end = 0; -static unsigned int pulse_avg = 0; -static unsigned int signal_start = 0; -static unsigned int signal_end = 0; -static unsigned int signal_pulse_data[4000][3] = { - {0}}; -static unsigned int signal_pulse_counter = 0; - -static void classify_signal() { - unsigned int i, k, max = 0, min = 1000000, t; - unsigned int delta, count_min, count_max, min_new, max_new, p_limit; - unsigned int a[3], b[2], a_cnt[3], a_new[3], b_new[2]; - unsigned int signal_distance_data[4000] = {0}; - struct protocol_state p = {0}; - unsigned int signal_type; - - if (!signal_pulse_data[0][0]) - return; - - for (i = 0; i < 1000; i++) { - if (signal_pulse_data[i][0] > 0) { - //fprintf(stderr, "[%03d] s: %d\t e:\t %d\t l:%d\n", - //i, signal_pulse_data[i][0], signal_pulse_data[i][1], - //signal_pulse_data[i][2]); - if (signal_pulse_data[i][2] > max) - max = signal_pulse_data[i][2]; - if (signal_pulse_data[i][2] <= min) - min = signal_pulse_data[i][2]; - } - } - t = (max + min) / 2; - //fprintf(stderr, "\n\nMax: %d, Min: %d t:%d\n", max, min, t); - - delta = (max - min)*(max - min); - - //TODO use Lloyd-Max quantizer instead - k = 1; - while ((k < 10) && (delta > 0)) { - min_new = 0; - count_min = 0; - max_new = 0; - count_max = 0; - - for (i = 0; i < 1000; i++) { - if (signal_pulse_data[i][0] > 0) { - if (signal_pulse_data[i][2] < t) { - min_new = min_new + signal_pulse_data[i][2]; - count_min++; - } else { - max_new = max_new + signal_pulse_data[i][2]; - count_max++; - } - } - } - if (count_min != 0 && count_max != 0) { - min_new = min_new / count_min; - max_new = max_new / count_max; - } - - delta = (min - min_new)*(min - min_new) + (max - max_new)*(max - max_new); - min = min_new; - max = max_new; - t = (min + max) / 2; - - fprintf(stderr, "Iteration %d. t: %d min: %d (%d) max: %d (%d) delta %d\n", k, t, min, count_min, max, count_max, delta); - k++; - } - - for (i = 0; i < 1000; i++) { - if (signal_pulse_data[i][0] > 0) { - //fprintf(stderr, "%d\n", signal_pulse_data[i][1]); - } - } - /* 50% decision limit */ - if (min != 0 && max / min > 1) { - fprintf(stderr, "Pulse coding: Short pulse length %d - Long pulse length %d\n", min, max); - signal_type = 2; - } else { - fprintf(stderr, "Distance coding: Pulse length %d\n", (min + max) / 2); - signal_type = 1; - } - p_limit = (max + min) / 2; - - /* Initial guesses */ - a[0] = 1000000; - a[2] = 0; - for (i = 1; i < 1000; i++) { - if (signal_pulse_data[i][0] > 0) { - // fprintf(stderr, "[%03d] s: %d\t e:\t %d\t l:%d\t d:%d\n", - // i, signal_pulse_data[i][0], signal_pulse_data[i][1], - // signal_pulse_data[i][2], signal_pulse_data[i][0]-signal_pulse_data[i-1][1]); - signal_distance_data[i - 1] = signal_pulse_data[i][0] - signal_pulse_data[i - 1][1]; - if (signal_distance_data[i - 1] > a[2]) - a[2] = signal_distance_data[i - 1]; - if (signal_distance_data[i - 1] <= a[0]) - a[0] = signal_distance_data[i - 1]; - } - } - min = a[0]; - max = a[2]; - a[1] = (a[0] + a[2]) / 2; - // for (i=0 ; i<1 ; i++) { - // b[i] = (a[i]+a[i+1])/2; - // } - b[0] = (a[0] + a[1]) / 2; - b[1] = (a[1] + a[2]) / 2; - // fprintf(stderr, "a[0]: %d\t a[1]: %d\t a[2]: %d\t\n",a[0],a[1],a[2]); - // fprintf(stderr, "b[0]: %d\t b[1]: %d\n",b[0],b[1]); - - k = 1; - delta = 10000000; - while ((k < 10) && (delta > 0)) { - for (i = 0; i < 3; i++) { - a_new[i] = 0; - a_cnt[i] = 0; - } - - for (i = 0; i < 1000; i++) { - if (signal_distance_data[i] > 0) { - if (signal_distance_data[i] < b[0]) { - a_new[0] += signal_distance_data[i]; - a_cnt[0]++; - } else if (signal_distance_data[i] < b[1] && signal_distance_data[i] >= b[0]) { - a_new[1] += signal_distance_data[i]; - a_cnt[1]++; - } else if (signal_distance_data[i] >= b[1]) { - a_new[2] += signal_distance_data[i]; - a_cnt[2]++; - } - } - } - - // fprintf(stderr, "Iteration %d.", k); - delta = 0; - for (i = 0; i < 3; i++) { - if (a_cnt[i]) - a_new[i] /= a_cnt[i]; - delta += (a[i] - a_new[i])*(a[i] - a_new[i]); - // fprintf(stderr, "\ta[%d]: %d (%d)", i, a_new[i], a[i]); - a[i] = a_new[i]; - } - // fprintf(stderr, " delta %d\n", delta); - - if (a[0] < min) { - a[0] = min; - // fprintf(stderr, "Fixing a[0] = %d\n", min); - } - if (a[2] > max) { - a[0] = max; - // fprintf(stderr, "Fixing a[2] = %d\n", max); - } - // if (a[1] == 0) { - // a[1] = (a[2]+a[0])/2; - // fprintf(stderr, "Fixing a[1] = %d\n", a[1]); - // } - - // fprintf(stderr, "Iteration %d.", k); - for (i = 0; i < 2; i++) { - // fprintf(stderr, "\tb[%d]: (%d) ", i, b[i]); - b[i] = (a[i] + a[i + 1]) / 2; - // fprintf(stderr, "%d ", b[i]); - } - // fprintf(stderr, "\n"); - k++; - } - - if (override_short) { - p_limit = override_short; - a[0] = override_short; - } - - if (override_long) { - a[1] = override_long; - } - - if (a[1] 0) { - if (signal_distance_data[i] < (a[0] + a[1]) / 2) { - // fprintf(stderr, "0 [%d] %d < %d\n",i, signal_distance_data[i], (a[0]+a[1])/2); - demod_add_bit(&p, 0); - } else if ((signal_distance_data[i] > (a[0] + a[1]) / 2) && (signal_distance_data[i] < (a[1] + a[2]) / 2)) { - // fprintf(stderr, "0 [%d] %d > %d\n",i, signal_distance_data[i], (a[0]+a[1])/2); - demod_add_bit(&p, 1); - } else if (signal_distance_data[i] > (a[1] + a[2]) / 2) { - // fprintf(stderr, "0 [%d] %d > %d\n",i, signal_distance_data[i], (a[1]+a[2])/2); - demod_next_bits_packet(&p); - } - - } - - } - demod_print_bits_packet(&p); - } - if (signal_type == 2) { - for (i = 0; i < 1000; i++) { - if (signal_pulse_data[i][2] > 0) { - if (signal_pulse_data[i][2] < p_limit) { - // fprintf(stderr, "0 [%d] %d < %d\n",i, signal_pulse_data[i][2], p_limit); - demod_add_bit(&p, 0); - } else { - // fprintf(stderr, "1 [%d] %d > %d\n",i, signal_pulse_data[i][2], p_limit); - demod_add_bit(&p, 1); - } - if ((signal_distance_data[i] >= (a[1] + a[2]) / 2)) { - // fprintf(stderr, "\\n [%d] %d > %d\n",i, signal_distance_data[i], (a[1]+a[2])/2); - demod_next_bits_packet(&p); - } - - - } - } - demod_print_bits_packet(&p); - } - - for (i = 0; i < 1000; i++) { - signal_pulse_data[i][0] = 0; - signal_pulse_data[i][1] = 0; - signal_pulse_data[i][2] = 0; - signal_distance_data[i] = 0; - } - -}; - -static void pwm_analyze(struct dm_state *demod, int16_t *buf, uint32_t len) { - unsigned int i; - - for (i = 0; i < len; i++) { - if (buf[i] > demod->level_limit) { - if (!signal_start) - signal_start = counter; - if (print) { - pulses_found++; - pulse_start = counter; - signal_pulse_data[signal_pulse_counter][0] = counter; - signal_pulse_data[signal_pulse_counter][1] = -1; - signal_pulse_data[signal_pulse_counter][2] = -1; - if (debug_output) fprintf(stderr, "pulse_distance %d\n", counter - pulse_end); - if (debug_output) fprintf(stderr, "pulse_start distance %d\n", pulse_start - prev_pulse_start); - if (debug_output) fprintf(stderr, "pulse_start[%d] found at sample %d, value = %d\n", pulses_found, counter, buf[i]); - prev_pulse_start = pulse_start; - print = 0; - print2 = 1; - } - } - counter++; - if (buf[i] < demod->level_limit) { - if (print2) { - pulse_avg += counter - pulse_start; - if (debug_output) fprintf(stderr, "pulse_end [%d] found at sample %d, pulse length = %d, pulse avg length = %d\n", - pulses_found, counter, counter - pulse_start, pulse_avg / pulses_found); - pulse_end = counter; - print2 = 0; - signal_pulse_data[signal_pulse_counter][1] = counter; - signal_pulse_data[signal_pulse_counter][2] = counter - pulse_start; - signal_pulse_counter++; - if (signal_pulse_counter >= 4000) { - signal_pulse_counter = 0; - goto err; - } - } - print = 1; - if (signal_start && (pulse_end + 50000 < counter)) { - signal_end = counter - 40000; - fprintf(stderr, "*** signal_start = %d, signal_end = %d\n", signal_start - 10000, signal_end); - fprintf(stderr, "signal_len = %d, pulses = %d\n", signal_end - (signal_start - 10000), pulses_found); - pulses_found = 0; - classify_signal(); - - signal_pulse_counter = 0; - if (demod->sg_buf) { - int start_pos, signal_bszie, wlen, wrest = 0, sg_idx, idx; - char sgf_name[256] = {0}; - FILE *sgfp; - - sprintf(sgf_name, "gfile%03d.data", demod->signal_grabber); - demod->signal_grabber++; - signal_bszie = 2 * (signal_end - (signal_start - 10000)); - signal_bszie = (131072 - (signal_bszie % 131072)) + signal_bszie; - sg_idx = demod->sg_index - demod->sg_len; - if (sg_idx < 0) - sg_idx = SIGNAL_GRABBER_BUFFER - demod->sg_len; - idx = (i - 40000)*2; - start_pos = sg_idx + idx - signal_bszie; - fprintf(stderr, "signal_bszie = %d - sg_index = %d\n", signal_bszie, demod->sg_index); - fprintf(stderr, "start_pos = %d - buffer_size = %d\n", start_pos, SIGNAL_GRABBER_BUFFER); - if (signal_bszie > SIGNAL_GRABBER_BUFFER) - fprintf(stderr, "Signal bigger then buffer, signal = %d > buffer %d !!\n", signal_bszie, SIGNAL_GRABBER_BUFFER); - - if (start_pos < 0) { - start_pos = SIGNAL_GRABBER_BUFFER + start_pos; - fprintf(stderr, "restart_pos = %d\n", start_pos); - } - - fprintf(stderr, "*** Saving signal to file %s\n", sgf_name); - sgfp = fopen(sgf_name, "wb"); - if (!sgfp) { - fprintf(stderr, "Failed to open %s\n", sgf_name); - } - wlen = signal_bszie; - if (start_pos + signal_bszie > SIGNAL_GRABBER_BUFFER) { - wlen = SIGNAL_GRABBER_BUFFER - start_pos; - wrest = signal_bszie - wlen; - } - fprintf(stderr, "*** Writing data from %d, len %d\n", start_pos, wlen); - fwrite(&demod->sg_buf[start_pos], 1, wlen, sgfp); - - if (wrest) { - fprintf(stderr, "*** Writing data from %d, len %d\n", 0, wrest); - fwrite(&demod->sg_buf[0], 1, wrest, sgfp); - } - - fclose(sgfp); - } - signal_start = 0; - } - } - - - } - return; - -err: - fprintf(stderr, "To many pulses detected, probably bad input data or input parameters\n"); - return; -} - -/* The distance between pulses decodes into bits */ - -static void pwm_d_decode(struct dm_state *demod, struct protocol_state* p, int16_t *buf, uint32_t len) { - unsigned int i; - - for (i = 0; i < len; i++) { - if (buf[i] > demod->level_limit) { - p->pulse_count = 1; - p->start_c = 1; - } - if (p->pulse_count && (buf[i] < demod->level_limit)) { - p->pulse_length = 0; - p->pulse_distance = 1; - p->sample_counter = 0; - p->pulse_count = 0; - } - if (p->start_c) p->sample_counter++; - if (p->pulse_distance && (buf[i] > demod->level_limit)) { - if (p->sample_counter < p->short_limit) { - demod_add_bit(p, 0); - } else if (p->sample_counter < p->long_limit) { - demod_add_bit(p, 1); - } else { - demod_next_bits_packet(p); - p->pulse_count = 0; - p->sample_counter = 0; - } - p->pulse_distance = 0; - } - if (p->sample_counter > p->reset_limit) { - p->start_c = 0; - p->sample_counter = 0; - p->pulse_distance = 0; - if (p->callback) - events += p->callback(p->bits_buffer, p->bits_per_row); - else - demod_print_bits_packet(p); - - demod_reset_bits_packet(p); - } - } -} - -/* The length of pulses decodes into bits */ - -static void pwm_p_decode(struct dm_state *demod, struct protocol_state* p, int16_t *buf, uint32_t len) { - unsigned int i; - - for (i = 0; i < len; i++) { - if (buf[i] > demod->level_limit && !p->start_bit) { - /* start bit detected */ - p->start_bit = 1; - p->start_c = 1; - p->sample_counter = 0; - // fprintf(stderr, "start bit pulse start detected\n"); - } - - if (!p->real_bits && p->start_bit && (buf[i] < demod->level_limit)) { - /* end of startbit */ - p->real_bits = 1; - p->pulse_length = 0; - p->sample_counter = 0; - // fprintf(stderr, "start bit pulse end detected\n"); - } - if (p->start_c) p->sample_counter++; - - - if (!p->pulse_start && p->real_bits && (buf[i] > demod->level_limit)) { - /* save the pulse start, it will never be zero */ - p->pulse_start = p->sample_counter; - // fprintf(stderr, "real bit pulse start detected\n"); - - } - - if (p->real_bits && p->pulse_start && (buf[i] < demod->level_limit)) { - /* end of pulse */ - - p->pulse_length = p->sample_counter - p->pulse_start; - // fprintf(stderr, "real bit pulse end detected %d\n", p->pulse_length); - // fprintf(stderr, "space duration %d\n", p->sample_counter); - - if (p->pulse_length <= p->short_limit) { - demod_add_bit(p, 1); - } else if (p->pulse_length > p->short_limit) { - demod_add_bit(p, 0); - } - p->sample_counter = 0; - p->pulse_start = 0; - } - - if (p->real_bits && (p->pulse_length > p->long_limit)) { - demod_next_bits_packet(p); - - p->start_bit = 0; - p->real_bits = 0; - } - - if (p->sample_counter > p->reset_limit) { - p->start_c = 0; - p->sample_counter = 0; - //demod_print_bits_packet(p); - if (p->callback) - events += p->callback(p->bits_buffer, p->bits_per_row); - else - demod_print_bits_packet(p); - demod_reset_bits_packet(p); - - p->start_bit = 0; - p->real_bits = 0; - } - } -} - -/* Machester Decode for Oregon Scientific Weather Sensors - Decode data streams sent by Oregon Scientific v2.1, and v3 weather sensors. - With manchester encoding, both the pulse width and pulse distance vary. Clock sync - is recovered from the data stream based on pulse widths and distances exceeding a - minimum threashold (short limit* 1.5). - */ -static void manchester_decode(struct dm_state *demod, struct protocol_state* p, int16_t *buf, uint32_t len) { - unsigned int i; - - if (p->sample_counter == 0) - p->sample_counter = p->short_limit*2; - - for (i=0 ; istart_c) - p->sample_counter++; /* For this decode type, sample counter is count since last data bit recorded */ - - if (!p->pulse_count && (buf[i] > demod->level_limit)) { /* Pulse start (rising edge) */ - p->pulse_count = 1; - if (p->sample_counter > (p->short_limit + (p->short_limit>>1))) { - /* Last bit was recorded more than short_limit*1.5 samples ago */ - /* so this pulse start must be a data edge (rising data edge means bit = 0) */ - demod_add_bit(p, 0); - p->sample_counter=1; - p->start_c++; // start_c counts number of bits received - } - } - if (p->pulse_count && (buf[i] <= demod->level_limit)) { /* Pulse end (falling edge) */ - if (p->sample_counter > (p->short_limit + (p->short_limit>>1))) { - /* Last bit was recorded more than "short_limit*1.5" samples ago */ - /* so this pulse end is a data edge (falling data edge means bit = 1) */ - demod_add_bit(p, 1); - p->sample_counter=1; - p->start_c++; - } - p->pulse_count = 0; - } - - if (p->sample_counter > p->reset_limit) { - //fprintf(stderr, "manchester_decode number of bits received=%d\n",p->start_c); - if (p->callback) - events+=p->callback(p->bits_buffer, p->bits_per_row); - else - demod_print_bits_packet(p); - demod_reset_bits_packet(p); - p->sample_counter = p->short_limit*2; - p->start_c = 0; - } - } -} - -/** Something that might look like a IIR lowpass filter - * - * [b,a] = butter(1, 0.01) -> quantizes nicely thus suitable for fixed point - * Q1.15*Q15.0 = Q16.15 - * Q16.15>>1 = Q15.14 - * Q15.14 + Q15.14 + Q15.14 could possibly overflow to 17.14 - * but the b coeffs are small so it wont happen - * Q15.14>>14 = Q15.0 \o/ - */ - -static uint16_t lp_xmem[FILTER_ORDER] = {0}; - -#define F_SCALE 15 -#define S_CONST (1<> 1) + (b[0] * x_buf[0] >> 1) + (b[1] * lp_xmem[0] >> 1)) >> (F_SCALE - 1); - for (i = 1; i < len; i++) { - y_buf[i] = ((a[1] * y_buf[i - 1] >> 1) + (b[0] * x_buf[i] >> 1) + (b[1] * x_buf[i - 1] >> 1)) >> (F_SCALE - 1); - } - - /* Save last sample */ - memcpy(lp_xmem, &x_buf[len - 1 - FILTER_ORDER], FILTER_ORDER * sizeof (int16_t)); - memcpy(&y_buf[-FILTER_ORDER], &y_buf[len - 1 - FILTER_ORDER], FILTER_ORDER * sizeof (int16_t)); - //fprintf(stderr, "%d\n", y_buf[0]); -} - -static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) { - struct dm_state *demod = ctx; - uint16_t* sbuf = (uint16_t*) buf; - int i; - if (demod->file || !demod->save_data) { - if (do_exit || do_exit_async) - return; - - if ((bytes_to_read > 0) && (bytes_to_read < len)) { - len = bytes_to_read; - do_exit = 1; - rtlsdr_cancel_async(dev); - } - - if (demod->signal_grabber) { - //fprintf(stderr, "[%d] sg_index - len %d\n", demod->sg_index, len ); - memcpy(&demod->sg_buf[demod->sg_index], buf, len); - demod->sg_len = len; - demod->sg_index += len; - if (demod->sg_index + len > SIGNAL_GRABBER_BUFFER) - demod->sg_index = 0; - } - - - if (demod->debug_mode == 0) { - envelope_detect(buf, len, demod->decimation_level); - low_pass_filter(sbuf, demod->f_buf, len >> (demod->decimation_level + 1)); - } else if (demod->debug_mode == 1) { - memcpy(demod->f_buf, buf, len); - } - if (demod->analyze) { - pwm_analyze(demod, demod->f_buf, len / 2); - } else { - for (i = 0; i < demod->r_dev_num; i++) { - switch (demod->r_devs[i]->modulation) { - case OOK_PWM_D: - pwm_d_decode(demod, demod->r_devs[i], demod->f_buf, len / 2); - break; - case OOK_PWM_P: - pwm_p_decode(demod, demod->r_devs[i], demod->f_buf, len / 2); - break; - case OOK_MANCHESTER: - manchester_decode(demod, demod->r_devs[i], demod->f_buf, len/2); - break; - default: - fprintf(stderr, "Unknown modulation %d in protocol!\n", demod->r_devs[i]->modulation); - } - } - fflush(stdout); - } - - if (demod->save_data) { - if (fwrite(demod->f_buf, 1, len >> demod->decimation_level, demod->file) != len >> demod->decimation_level) { - fprintf(stderr, "Short write, samples lost, exiting!\n"); - rtlsdr_cancel_async(dev); - } - } - - if (bytes_to_read > 0) - bytes_to_read -= len; - - if (frequencies > 1) { - time_t rawtime; - time(&rawtime); - if (difftime(rawtime, rawtime_old) > DEFAULT_HOP_TIME || events >= DEFAULT_HOP_EVENTS) { - rawtime_old = rawtime; - events = 0; - do_exit_async = 1; - rtlsdr_cancel_async(dev); - } - } - } -} - -int main(int argc, char **argv) { -#ifndef _WIN32 - struct sigaction sigact; -#endif - char *filename = NULL; - char *test_mode_file = NULL; - FILE *test_mode; - int n_read; - int r, opt; - int i, gain = 0; - int sync_mode = 0; - int ppm_error = 0; - struct dm_state* demod; - uint8_t *buffer; - uint32_t dev_index = 0; - int frequency_current = 0; - uint32_t out_block_size = DEFAULT_BUF_LENGTH; - int device_count; - char vendor[256], product[256], serial[256]; - - demod = malloc(sizeof (struct dm_state)); - memset(demod, 0, sizeof (struct dm_state)); - - /* initialize tables */ - calc_squares(); - - demod->f_buf = &demod->filter_buffer[FILTER_ORDER]; - demod->decimation_level = DEFAULT_DECIMATION_LEVEL; - demod->level_limit = DEFAULT_LEVEL_LIMIT; - - - while ((opt = getopt(argc, argv, "x:z:p:Dtam:r:c:l:d:f:g:s:b:n:S::")) != -1) { - switch (opt) { - case 'd': - dev_index = atoi(optarg); - break; - case 'f': - if (frequencies < MAX_PROTOCOLS) frequency[frequencies++] = (uint32_t) atof(optarg); - else fprintf(stderr, "Max number of frequencies reached %d\n", MAX_PROTOCOLS); - break; - case 'g': - gain = (int) (atof(optarg) * 10); /* tenths of a dB */ - break; - case 'p': - ppm_error = atoi(optarg); - break; - case 's': - samp_rate = (uint32_t) atof(optarg); - break; - case 'b': - out_block_size = (uint32_t) atof(optarg); - break; - case 'l': - demod->level_limit = (uint32_t) atof(optarg); - break; - case 'n': - bytes_to_read = (uint32_t) atof(optarg) * 2; - break; - case 'c': - demod->decimation_level = (uint32_t) atof(optarg); - break; - case 'a': - demod->analyze = 1; - break; - case 'r': - test_mode_file = optarg; - break; - case 't': - demod->signal_grabber = 1; - break; - case 'm': - demod->debug_mode = atoi(optarg); - break; - case 'S': - sync_mode = 1; - break; - case 'D': - debug_output = 1; - break; - case 'z': - override_short = atoi(optarg); - break; - case 'x': - override_long = atoi(optarg); - break; - default: - usage(); - break; - } - } - - /* init protocols somewhat ok */ - register_protocol(demod, &rubicson); - register_protocol(demod, &prologue); - register_protocol(demod, &silvercrest); - // register_protocol(demod, &generic_hx2262); - // register_protocol(demod, &technoline_ws9118); - register_protocol(demod, &elv_em1000); - register_protocol(demod, &elv_ws2000); - register_protocol(demod, &waveman); - register_protocol(demod, &steffen); - register_protocol(demod, &acurite5n1); - register_protocol(demod, &acurite_th); - register_protocol(demod, &acurite_rain_gauge); - register_protocol(demod, &lacrossetx); - register_protocol(demod, &oregon_scientific); - register_protocol(demod, &newkaku); - register_protocol(demod, &alectov1); - register_protocol(demod, &intertechno); - register_protocol(demod, &mebus433); - register_protocol(demod, &wh2); - - if (argc <= optind - 1) { - usage(); - } else { - filename = argv[optind]; - } - - if (out_block_size < MINIMAL_BUF_LENGTH || - out_block_size > MAXIMAL_BUF_LENGTH) { - fprintf(stderr, - "Output block size wrong value, falling back to default\n"); - fprintf(stderr, - "Minimal length: %u\n", MINIMAL_BUF_LENGTH); - fprintf(stderr, - "Maximal length: %u\n", MAXIMAL_BUF_LENGTH); - out_block_size = DEFAULT_BUF_LENGTH; - } - - buffer = malloc(out_block_size * sizeof (uint8_t)); - - device_count = rtlsdr_get_device_count(); - if (!device_count) { - fprintf(stderr, "No supported devices found.\n"); - if (!test_mode_file) - exit(1); - } - - fprintf(stderr, "Found %d device(s):\n", device_count); - for (i = 0; i < device_count; i++) { - rtlsdr_get_device_usb_strings(i, vendor, product, serial); - fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial); - } - fprintf(stderr, "\n"); - - fprintf(stderr, "Using device %d: %s\n", - dev_index, rtlsdr_get_device_name(dev_index)); - - r = rtlsdr_open(&dev, dev_index); - if (r < 0) { - fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); - if (!test_mode_file) - exit(1); - } -#ifndef _WIN32 - sigact.sa_handler = sighandler; - sigemptyset(&sigact.sa_mask); - sigact.sa_flags = 0; - sigaction(SIGINT, &sigact, NULL); - sigaction(SIGTERM, &sigact, NULL); - sigaction(SIGQUIT, &sigact, NULL); - sigaction(SIGPIPE, &sigact, NULL); -#else - SetConsoleCtrlHandler((PHANDLER_ROUTINE) sighandler, TRUE); -#endif - /* Set the sample rate */ - r = rtlsdr_set_sample_rate(dev, samp_rate); - if (r < 0) - fprintf(stderr, "WARNING: Failed to set sample rate.\n"); - else - fprintf(stderr, "Sample rate set to %d.\n", rtlsdr_get_sample_rate(dev)); // Unfortunately, doesn't return real rate - - fprintf(stderr, "Sample rate decimation set to %d. %d->%d\n", demod->decimation_level, samp_rate, samp_rate >> demod->decimation_level); - fprintf(stderr, "Bit detection level set to %d.\n", demod->level_limit); - - if (0 == gain) { - /* Enable automatic gain */ - r = rtlsdr_set_tuner_gain_mode(dev, 0); - if (r < 0) - fprintf(stderr, "WARNING: Failed to enable automatic gain.\n"); - else - fprintf(stderr, "Tuner gain set to Auto.\n"); - } else { - /* Enable manual gain */ - r = rtlsdr_set_tuner_gain_mode(dev, 1); - if (r < 0) - fprintf(stderr, "WARNING: Failed to enable manual gain.\n"); - - /* Set the tuner gain */ - r = rtlsdr_set_tuner_gain(dev, gain); - if (r < 0) - fprintf(stderr, "WARNING: Failed to set tuner gain.\n"); - else - fprintf(stderr, "Tuner gain set to %f dB.\n", gain / 10.0); - } - - r = rtlsdr_set_freq_correction(dev, ppm_error); - - demod->save_data = 1; - if (!filename) { - demod->save_data = 0; - } else if (strcmp(filename, "-") == 0) { /* Write samples to stdout */ - demod->file = stdout; -#ifdef _WIN32 - _setmode(_fileno(stdin), _O_BINARY); -#endif - } else { - demod->file = fopen(filename, "wb"); - if (!demod->file) { - fprintf(stderr, "Failed to open %s\n", filename); - goto out; - } - } - - if (demod->signal_grabber) - demod->sg_buf = malloc(SIGNAL_GRABBER_BUFFER); - - if (test_mode_file) { - int i = 0; - unsigned char test_mode_buf[DEFAULT_BUF_LENGTH]; - fprintf(stderr, "Test mode active. Reading samples from file: %s\n", test_mode_file); - test_mode = fopen(test_mode_file, "r"); - if (!test_mode) { - fprintf(stderr, "Opening file: %s failed!\n", test_mode_file); - goto out; - } - while (fread(test_mode_buf, 131072, 1, test_mode) != 0) { - rtlsdr_callback(test_mode_buf, 131072, demod); - i++; - } - //Always classify a signal at the end of the file - classify_signal(); - fprintf(stderr, "Test mode file issued %d packets\n", i); - fprintf(stderr, "Filter coeffs used:\n"); - fprintf(stderr, "a: %d %d\n", a[0], a[1]); - fprintf(stderr, "b: %d %d\n", b[0], b[1]); - exit(0); - } - - /* Reset endpoint before we start reading from it (mandatory) */ - r = rtlsdr_reset_buffer(dev); - if (r < 0) - fprintf(stderr, "WARNING: Failed to reset buffers.\n"); - - if (sync_mode) { - fprintf(stderr, "Reading samples in sync mode...\n"); - while (!do_exit) { - r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read); - if (r < 0) { - fprintf(stderr, "WARNING: sync read failed.\n"); - break; - } - - if ((bytes_to_read > 0) && (bytes_to_read < (uint32_t) n_read)) { - n_read = bytes_to_read; - do_exit = 1; - } - - if (fwrite(buffer, 1, n_read, demod->file) != (size_t) n_read) { - fprintf(stderr, "Short write, samples lost, exiting!\n"); - break; - } - - if ((uint32_t) n_read < out_block_size) { - fprintf(stderr, "Short read, samples lost, exiting!\n"); - break; - } - - if (bytes_to_read > 0) - bytes_to_read -= n_read; - } - } else { - if (frequencies == 0) { - frequency[0] = DEFAULT_FREQUENCY; - frequencies = 1; - } else { - time(&rawtime_old); - } - fprintf(stderr, "Reading samples in async mode...\n"); - while (!do_exit) { - /* Set the frequency */ - r = rtlsdr_set_center_freq(dev, frequency[frequency_current]); - if (r < 0) - fprintf(stderr, "WARNING: Failed to set center freq.\n"); - else - fprintf(stderr, "Tuned to %u Hz.\n", rtlsdr_get_center_freq(dev)); - r = rtlsdr_read_async(dev, rtlsdr_callback, (void *) demod, - DEFAULT_ASYNC_BUF_NUMBER, out_block_size); - do_exit_async = 0; - frequency_current++; - if (frequency_current > frequencies - 1) frequency_current = 0; - } - } - - if (do_exit) - fprintf(stderr, "\nUser cancel, exiting...\n"); - else - fprintf(stderr, "\nLibrary error %d, exiting...\n", r); - - if (demod->file && (demod->file != stdout)) - fclose(demod->file); - - for (i = 0; i < demod->r_dev_num; i++) - free(demod->r_devs[i]); - - if (demod->signal_grabber) - free(demod->sg_buf); - - if (demod) - free(demod); - - rtlsdr_close(dev); - free(buffer); -out: - return r >= 0 ? r : -r; -}