diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2013-01-27 23:33:58 +0200 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2013-01-27 23:33:58 +0200 |
| commit | 18d67880cbc09256f37c8257a9635c3d3f98ad73 (patch) | |
| tree | 085b52ff2162514f49c4e0d1c6a0e148301bd6fc /gascop.c | |
| parent | 9b7da31e44dcfa01ee65ce13de993c7c46828b45 (diff) | |
Rename, add data processing thread and internal state
Diffstat (limited to 'gascop.c')
| -rw-r--r-- | gascop.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/gascop.c b/gascop.c new file mode 100644 index 0000000..b50929a --- /dev/null +++ b/gascop.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <pthread.h> +#include <stdint.h> +#include <errno.h> +#include <unistd.h> +#include <math.h> +#include <sys/time.h> +#include <signal.h> +#include <fcntl.h> +#include <ctype.h> +#include "rtl-sdr.h" + +/* POCSAG parameters */ +#define POCSAG_ID "POCSAG" +#define POCSAG_SYM_RATE 1200 +#define POCSAG_FM_DEV 4500 +#define POCSAG_SPS 8 +#define POCSAG_STD_SYNC 0x7cd215d8 +#define POCSAG_STD_IDLE 0x7a89c197 +#define POCSAG_WORDSIZE 32 +#define POCSAG_SOFTTHRESHOLD 2 +#define POCSAG_MAXWORD 16 + +#define POCSAG_ASYNC_BUF_NUMBER 12 +#define POCSAG_DATA_LEN (16*16384) /* 256K */ +#define POCSAG_AUTO_GAIN -100 /* Use automatic gain. */ +#define POCSAG_MAX_GAIN 999999 /* Use max available gain. */ + +/* BCH parameters */ +#define POCSAG_BCH_POLY 0x769 +#define POCSAG_BCH_N 31 +#define POCSAG_BCH_K 21 + +/* POCASG states */ +#define POCSAG_SEARCH_PREAMBLE_START 0 +#define POCSAG_SEARCH_PREAMBLE_END 1 +#define POCSAG_SYNC 2 +#define POCSAG_SEARCH_SYNC 3 +#define POCSAG_SYNCHED 4 + +#define IGNORE(V) ((void) V) + +struct { + pthread_t reader_thread; + pthread_mutex_t data_mutex; /* Mutex to synchronize buffer access. */ + pthread_cond_t data_cond; /* Conditional variable associated. */ + unsigned char *data; /* Raw IQ samples buffer */ + uint16_t *magnitude; /* Magnitude vector */ + uint32_t data_len; /* Buffer length. */ + int data_ready; /* Data ready to be processed. */ + uint16_t *maglut; /* I/Q -> Magnitude lookup table. */ + int exit; + + /* rtlsdr */ + int dev_index; + int gain; + int enable_agc; + rtlsdr_dev_t *dev; + int freq; +} Gascop; + +int hammingWeight(uint32_t n) { + unsigned int c; + for (c = 0; n; c++) + n &= n - 1; + return c; +} + +int evenParity(int n) { + return hammingWeight(n) & 1; +} + +int bchSyndrome(int data, int poly, int n, int k) { + int mask = 1 << (n - 1); + int coeff = poly << (k - 1); + n = k; + + int s = data >> 1; + while (n > 0) { + if (s & mask) + s ^= coeff; + n -= 1; + mask >>= 1; + coeff >>= 1; + } + + if (evenParity(data)) + s |= 1 << (n - k); + + return s; +} + +int bchFix(int data, int poly, int n, int k) { + int i, j; + for (i=0; i<32; i++) { + int t = data ^ (1 << i); + if (!bchSyndrome(t, poly, n, k)) + return t; + } + for (i=0; i<32; i++) { + for (j=i+1; j<32; j++) { + int t = data ^ ((1 << i) | (1 << j)); + if (!bchSyndrome(t, poly, n, k)) + return t; + } + } + return data; +} + +void rtlsdrCallback(unsigned char *buf, uint32_t len, void *ctx) { + IGNORE(ctx); + + pthread_mutex_lock(&Gascop.data_mutex); + if (len > Gascop.data_len) len = Gascop.data_len; + memcpy(Gascop.data, buf, len); + Gascop.data_ready = 1; + pthread_cond_signal(&Gascop.data_cond); + pthread_mutex_unlock(&Gascop.data_mutex); +} + +void *readerThreadEntryPoint(void *arg) { + IGNORE(arg); + + rtlsdr_read_async(Gascop.dev, rtlsdrCallback, NULL, + POCSAG_ASYNC_BUF_NUMBER, Gascop.data_len); + return NULL; +} + +int main(int argc, char **argv) { + IGNORE(argc); + IGNORE(argv); + + printf("Dumpocsag v0.1\n"); + exit(0); +} |
