diff --git a/moc_test/Makefile b/moc_test/Makefile new file mode 100644 index 0000000..5aeb65f --- /dev/null +++ b/moc_test/Makefile @@ -0,0 +1,14 @@ +# + + +all: + gcc -Wall -c librtlsdr_moc.c -o librtlsdr_moc.o + ar rcs librtlsdr_moc.a librtlsdr_moc.o + CC="gcc -DMOCK_TEST" go build --ldflags '-extldflags "-static"' -o gortlsdr_moc.a ../rtlsdr.go ../exports.go + go build main_moc.go + +clean: + rm -f *.o *.a + + + diff --git a/moc_test/librtlsdr_moc.c b/moc_test/librtlsdr_moc.c new file mode 100644 index 0000000..f67c30d --- /dev/null +++ b/moc_test/librtlsdr_moc.c @@ -0,0 +1,655 @@ +/* + * Copyright (c) 2015-2016 Joseph D Poirier + * Distributable under the terms of The New BSD License + * that can be found in the LICENSE file. + * + * $ gcc -Wall -c librtlsdr_moc.c -o librtlsdr_moc.o + * $ ar rcs librtlsdr_moc.a librtlsdr_moc.o + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "rtl-sdr_moc.h" + +#define DEBVICE_CNT (3) + +// struct rtlsdr_dev { +// libusb_context *ctx; +// struct libusb_device_handle *devh; +// uint32_t xfer_buf_num; +// uint32_t xfer_buf_len; +// struct libusb_transfer **xfer; +// unsigned char **xfer_buf; +// rtlsdr_read_async_cb_t cb; +// void *cb_ctx; +// enum rtlsdr_async_status async_status; +// int async_cancel; +// /* rtl demod context */ +// uint32_t rate; /* Hz */ +// uint32_t rtl_xtal; /* Hz */ +// int fir[FIR_LEN]; +// int direct_sampling; +// /* tuner context */ +// enum rtlsdr_tuner tuner_type; +// rtlsdr_tuner_iface_t *tuner; +// uint32_t tun_xtal; /* Hz */ +// uint32_t freq; /* Hz */ +// uint32_t bw; +// uint32_t offs_freq; /* Hz */ +// int corr; /* ppm */ +// int gain; /* tenth dB */ +// struct e4k_state e4k_s; +// struct r82xx_config r82xx_c; +// struct r82xx_priv r82xx_p; +// /* status */ +// int dev_lost; +// int driver_active; +// unsigned int xfer_errors; +// }; + +struct rtlsdr_dev { + bool status; + int ppm; + uint32_t tuner_freq; + uint32_t rtl_freq; + uint32_t center_freq; + uint32_t tuner_bandwidth; + int if_gain; + int gain; + int gain_mode; + uint32_t sample_rate; + int test_mode; + int agc_mode; + int direct_sampling_mode; + int offset_tuning; + enum rtlsdr_tuner type; + char eeprom_buffer[256]; + int gains[29]; +}; + +/* + 0 | 1 | 2(L) 3(U) | 4(L) 5(U) | 6 (0xA5) | 7 (|0x01) | 7 (|0x02) | + 0x28 | 0x32 | Vendor ID | Product ID | Have Serial | Remote Wakeup | Enable IR | + +string start offset index is 9 and it indicates the string size in bytes +max string length is: 35 * 2 + 2 header bytes = 72 bytes +header byte [0] = total string length <= 72 (info string length <= 72 - 2 header bytes) +header byte [1] = 0x03 +Manufact info string start [3], info string end [header byte [0] - 2] +Product info string start [], info string end [header byte [] - 2] +Serial info string start [], info string end [header byte [] - 2] + +string are written as "char, 0x00" pairs +*/ + +static int device_count = DEBVICE_CNT; + +struct rtlsdr_dev s0 = {0}; +struct rtlsdr_dev s1 = {0}; +struct rtlsdr_dev s2 = {0}; + +struct rtlsdr_dev *rtlsdr_devs[DEBVICE_CNT] = {&s0, &s1, &s2}; + +static bool is_initialized = false; + +void do_init(void) { + if (is_initialized) + return; + + s0 = (struct rtlsdr_dev){ + .status = false, + .ppm = 50, + .tuner_freq = 1700000, + .rtl_freq = 1700000, + .center_freq = 1700000, + .tuner_bandwidth = 1000000, + .if_gain = 50, + .gain = 100, + .gain_mode = 1, + .sample_rate = 3200000, + .test_mode = 0, + .agc_mode = 0, + .direct_sampling_mode = 1, + .offset_tuning =1000, + .type = RTLSDR_TUNER_R828D, + .eeprom_buffer = {0x28, 0x32, 0x09, 0x01, 0x01, 0x01, 0xA5, 0x03, + 0x1F, 0x03, 'R', 0x00, 'E', 0x00, 'A', 0x00, 'L', 0x00, 'T', 0x00, 'E', 0x00, 'K', 0x00, + 0x1F, 0x03, 'N', 0x00, 'O', 0x00, 'O', 0x00, 'E', 0x00, 'L', 0x00, 'E', 0x00, 'C', 0x00, + 0x0A, 0x03, '1', 0x00, '9', 0x00, '9', 0x00, '1', 0x00}, + .gains = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496} + }; + s1 = (struct rtlsdr_dev){ + .status = false, + .ppm = 51, + .tuner_freq = 1700001, + .rtl_freq = 1700001, + .center_freq = 1700001, + .tuner_bandwidth = 1000001, + .if_gain = 51, + .gain = 101, + .gain_mode = 0, + .sample_rate = 3200000, + .test_mode = 1, + .agc_mode = 1, + .direct_sampling_mode = 0, + .offset_tuning =1001, + .type = RTLSDR_TUNER_R820T, + .eeprom_buffer = {0x28, 0x32, 0x09, 0x01, 0x01, 0x01, 0xA5, 0x03, + 0x1F, 0x03, 'R', 0x00, 'E', 0x00, 'A', 0x00, 'L', 0x00, 'T', 0x00, 'E', 0x00, 'K', 0x00, + 0x1F, 0x03, 'N', 0x00, 'O', 0x00, 'O', 0x00, 'E', 0x00, 'L', 0x00, 'E', 0x00, 'C', 0x00, + 0x0A, 0x03, '2', 0x00, '9', 0x00, '9', 0x00, '2', 0x00}, + .gains = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496} + }; + s2 = (struct rtlsdr_dev){ + .status = false, + .ppm = 52, + .tuner_freq = 1700002, + .rtl_freq = 1700002, + .center_freq = 1700002, + .tuner_bandwidth = 1000002, + .if_gain = 52, + .gain = 102, + .gain_mode = 1, + .sample_rate = 3200000, + .test_mode = 0, + .agc_mode = 1, + .direct_sampling_mode = 1, + .offset_tuning =1002, + .type = RTLSDR_TUNER_E4000, + .eeprom_buffer = {0x28, 0x32, 0x09, 0x01, 0x01, 0x01, 0xA5, 0x03, + 0x1F, 0x03, 'R', 0x00, 'E', 0x00, 'A', 0x00, 'L', 0x00, 'T', 0x00, 'E', 0x00, 'K', 0x00, + 0x1F, 0x03, 'N', 0x00, 'O', 0x00, 'O', 0x00, 'E', 0x00, 'L', 0x00, 'E', 0x00, 'C', 0x00, + 0x0A, 0x03, '1', 0x00, '9', 0x00, '9', 0x00, '1', 0x00}, + .gains = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, + 166, 197, 207, 229, 254, 280, 297, 328, + 338, 364, 372, 386, 402, 421, 434, 439, + 445, 480, 496 } + }; + is_initialized = true; +} + +bool dev_valid(rtlsdr_dev_t *dev) { + if (dev == &s0 || dev == &s1 || dev == &s2) { + return true; + } + return false; +} + +int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->ppm = ppm; + return 0; +} + +int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_freq) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->tuner_freq = tuner_freq; + dev->rtl_freq = rtl_freq; + return 0; +} + +int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_freq) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + *rtl_freq = dev->rtl_freq; + *tuner_freq = dev->tuner_freq; + return 0; +} + +// TODO: +int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, char *serial) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + // strcpy(manufact, "Manufacturer"); + // strcpy(product, "Product"); + // strcpy(serial, "Serial"); + return 0; +} + +// TODO: +int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + // if ((len + offset) > 256) + // return -2; + // int i; + // for (i = 0; i < len; i++) + // eeprom_buffer[i+offset] = data[i]; + return 0; +} + +// TODO: +int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + // if ((len + offset) > 256) + // return -2; + // int i; + // for (i = 0; i < len; i++) + // data[i] = eeprom_buffer[i+offset]; + + return 0; +} + +int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->center_freq = freq; + return 0; +} + +uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->center_freq; +} + +int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->ppm; +} + +enum rtlsdr_tuner rtlsdr_get_tuner_type(rtlsdr_dev_t *dev){ + if (!dev) + return RTLSDR_TUNER_UNKNOWN; + if (!dev_valid(dev)) + return -2; + + return dev->type; +} + +int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + gains = &(dev->gains[0]); + return (29 / sizeof(int)); +} + +int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->tuner_bandwidth = bw; + return 0; +} + +int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->gain = gain; + return 0; +} + +int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->gain; +} + +int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->gain = gain; + return 0; +} + +int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int mode) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->gain_mode = mode; + return 0; +} + +int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + /* check if the rate is supported by the resampler */ + if ((samp_rate <= 225000) || (samp_rate > 3200000) || + ((samp_rate > 300000) && (samp_rate <= 900000))) { + fprintf(stderr, "Invalid sample rate: %u Hz\n", samp_rate); + return -EINVAL; + } + dev->sample_rate = samp_rate; + return 0; +} + +uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->sample_rate; +} + +int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->test_mode = on; + return 0; +} + +int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->agc_mode = on; + return 0; +} + +int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->direct_sampling_mode = on; + return 0; +} + +int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev){ + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->direct_sampling_mode; +} + +int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->offset_tuning = on; + return 0; +} + +int rtlsdr_get_offset_tuning(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return dev->offset_tuning; +} + +uint32_t rtlsdr_get_device_count(void) { + return device_count; +} + +// TODO: +const char *rtlsdr_get_device_name(uint32_t index) { + do_init(); + return 0; +} + +// TODO: +int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, char *product, char *serial) { + do_init(); + // strcpy(manufact, "Manufacturer"); + // strcpy(manufact, "Product"); + // strcpy(manufact, "Serial"); + return 0; +} + +// TODO: +int rtlsdr_get_index_by_serial(const char *serial) { + do_init(); + + if (!serial) + return -1; + + // if (!strcmp(serial, )) + // return 0; + + return -3; +} + +int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) { + do_init(); + + if (!out_dev) + return -1; + + int status = 1; + switch(index) { + case 0: + *out_dev = &s0; + s0.status = true; + status = 0; + break; + case 1: + *out_dev = &s1; + s1.status = true; + status = 0; + break; + case 2: + *out_dev = &s1; + s2.status = true; + status = 0; + break; + } + + return status; +} + +int rtlsdr_close(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + dev->status = false; + return 0; +} + +// TODO: +int rtlsdr_reset_buffer(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return 0; +} + +// TODO: +int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + return 0; +} + +// TODO: +int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, + uint32_t buf_num, uint32_t buf_len) { + // unsigned int i; + // int r = 0; + // struct timeval tv = { 1, 0 }; + // struct timeval zerotv = { 0, 0 }; + // enum rtlsdr_async_status next_status = RTLSDR_INACTIVE; + + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + // if (RTLSDR_INACTIVE != dev->async_status) + // return -2; + + // dev->async_status = RTLSDR_RUNNING; + // dev->async_cancel = 0; + + // dev->cb = cb; + // dev->cb_ctx = ctx; + + // if (buf_num > 0) + // dev->xfer_buf_num = buf_num; + // else + // dev->xfer_buf_num = DEFAULT_BUF_NUMBER; + + // if (buf_len > 0 && buf_len % 512 == 0) /* len must be multiple of 512 */ + // dev->xfer_buf_len = buf_len; + // else + // dev->xfer_buf_len = DEFAULT_BUF_LENGTH; + + // _rtlsdr_alloc_async_buffers(dev); + + // for(i = 0; i < dev->xfer_buf_num; ++i) { + // libusb_fill_bulk_transfer(dev->xfer[i], + // dev->devh, + // 0x81, + // dev->xfer_buf[i], + // dev->xfer_buf_len, + // _libusb_callback, + // (void *)dev, + // BULK_TIMEOUT); + + // r = libusb_submit_transfer(dev->xfer[i]); + // if (r < 0) { + // fprintf(stderr, "Failed to submit transfer %i!\n", i); + // dev->async_status = RTLSDR_CANCELING; + // break; + // } + // } + + // while (RTLSDR_INACTIVE != dev->async_status) { + // r = libusb_handle_events_timeout_completed(dev->ctx, &tv, + // &dev->async_cancel); + // if (r < 0) { + // /*fprintf(stderr, "handle_events returned: %d\n", r);*/ + // if (r == LIBUSB_ERROR_INTERRUPTED) /* stray signal */ + // continue; + // break; + // } + + // if (RTLSDR_CANCELING == dev->async_status) { + // next_status = RTLSDR_INACTIVE; + + // if (!dev->xfer) + // break; + + // for(i = 0; i < dev->xfer_buf_num; ++i) { + // if (!dev->xfer[i]) + // continue; + + // if (LIBUSB_TRANSFER_CANCELLED != + // dev->xfer[i]->status) { + // r = libusb_cancel_transfer(dev->xfer[i]); + // /* handle events after canceling + // * to allow transfer status to + // * propagate */ + // libusb_handle_events_timeout_completed(dev->ctx, + // &zerotv, NULL); + // if (r < 0) + // continue; + + // next_status = RTLSDR_CANCELING; + // } + // } + + // if (dev->dev_lost || RTLSDR_INACTIVE == next_status) { + // /* handle any events that still need to + // * be handled before exiting after we + // * just cancelled all transfers */ + // libusb_handle_events_timeout_completed(dev->ctx, + // &zerotv, NULL); + // break; + // } + // } + // } + + // _rtlsdr_free_async_buffers(dev); + + // dev->async_status = next_status; + + return 0; +} + +// TODO: +int rtlsdr_cancel_async(rtlsdr_dev_t *dev) { + if (!dev) + return -1; + if (!dev_valid(dev)) + return -2; + + // /* if streaming, try to cancel gracefully */ + // if (RTLSDR_RUNNING == dev->async_status) { + // dev->async_status = RTLSDR_CANCELING; + // dev->async_cancel = 1; + // return 0; + // } + return 0; +} diff --git a/moc_test/main_moc.go b/moc_test/main_moc.go new file mode 100644 index 0000000..2c82b35 --- /dev/null +++ b/moc_test/main_moc.go @@ -0,0 +1,174 @@ +// Copyright (c) 2015-2016 Joseph D Poirier +// Distributable under the terms of The New BSD License +// that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "errors" + "log" + + rtl "./gortlsdr_moc" +) + +func GetDeviceCount() int { + return rtl.GetDeviceCount() +} + +func GetDeviceName(i int) string { + return rtl.GetDeviceName(i) +} + +func GetDeviceUsbStrings(i int) (m, p, s string, err error) { + return rtl.GetDeviceUsbStrings(i) +} + +func GetIndexBySerial(s string) (i int, err error) { + return rtl.GetIndexBySerial(i) +} + +func Open(i int) (*rtl.Context, error){ + return rtl.Open(i) +} + +func Close(d *rtl.Context) error { + return d.Close() +} + +func SetXtalFreq(d *rtl.Context) { + +} + +func GetXtalFreq(d *rtl.Context) { + +} + +func GetUsbStrings(d *rtl.Context) { + +} + +func WriteEeprom(d *rtl.Context) { + +} + +func ReadEeprom(d *rtl.Context) { + +} + +func SetCenterFreq(d *rtl.Context) { + +} + +func GetCenterFreq(d *rtl.Context) { + +} + +func SetFreqCorrection(d *rtl.Context) { + +} + +func GetFreqCorrection(d *rtl.Context) { + +} + +func GetTunerType(d *rtl.Context) { + +} + +func GetTunerGains(d *rtl.Context) { + +} + +func SetTunerGains(d *rtl.Context) { + +} + +func SetTunerBw(d *rtl.Context) { + +} + +func GetTunerBw(d *rtl.Context) { + +} + +func GetTunerGain(d *rtl.Context) { + +} + +func SetTunerIfGain(d *rtl.Context) { + +} + +func SetTunerGainMode(d *rtl.Context) { + +} + +func SetSampleRate(d *rtl.Context) { + +} + +func GetSampleRate(d *rtl.Context) { + +} + +func SetTestMode(d *rtl.Context) { + +} + +func SetAgcMode(d *rtl.Context) { + +} + +func SetDirectSampling(d *rtl.Context) { + +} + +func GetDirectSampling(d *rtl.Context) { + +} + +func SetOffsetTuning(d *rtl.Context) { + +} + +func GetOffsetTuning(d *rtl.Context) { + +} + +func ResetBuffer(d *rtl.Context) { + +} + +func ReadSync(d *rtl.Context) { + +} + +func ReadAsync(d *rtl.Context) { + +} + +func CancelAsync(d *rtl.Context) { + +} + +func GetHwInfo(d *rtl.Context) { +} + +func SetHwInfo(d *rtl.Context) { +} + +func main() { + //---------- Device Check ---------- + if c := GetDeviceCount(); c == 0 { + log.Fatal("No devices found, exiting.\n") + } + for i := 0; i < c; i++ { + if m, p, s, err := GetDeviceUsbStrings(i); if err == nil { + err = errors.New("") + log.Printf("GetDeviceUsbStrings %s - %s %s %s\n", err, m, p, s) + } + } + +} diff --git a/moc_test/rtl-sdr_moc.h b/moc_test/rtl-sdr_moc.h new file mode 100644 index 0000000..121c0ab --- /dev/null +++ b/moc_test/rtl-sdr_moc.h @@ -0,0 +1,438 @@ +/* + * rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver + * Copyright (C) 2012-2013 by Steve Markgraf + * Copyright (C) 2012 by Dimitri Stolnikov + * + * 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 . + */ +#ifndef __RTL_SDR_H +#define __RTL_SDR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rtlsdr_dev rtlsdr_dev_t; + +// returns: 0 ... n +extern uint32_t rtlsdr_get_device_count(void); + +// returns "" or "some name" +extern const char* rtlsdr_get_device_name(uint32_t index); + + +// enum libusb_error { +// /** Success (no error) */ +// LIBUSB_SUCCESS = 0, + +// /** Input/output error */ +// LIBUSB_ERROR_IO = -1, + +// /** Invalid parameter */ +// LIBUSB_ERROR_INVALID_PARAM = -2, + +// /** Access denied (insufficient permissions) */ +// LIBUSB_ERROR_ACCESS = -3, + +// /** No such device (it may have been disconnected) */ +// LIBUSB_ERROR_NO_DEVICE = -4, + +// /** Entity not found */ +// LIBUSB_ERROR_NOT_FOUND = -5, + +// /** Resource busy */ +// LIBUSB_ERROR_BUSY = -6, + +// /** Operation timed out */ +// LIBUSB_ERROR_TIMEOUT = -7, + +// * Overflow +// LIBUSB_ERROR_OVERFLOW = -8, + +// /** Pipe error */ +// LIBUSB_ERROR_PIPE = -9, + +// /** System call interrupted (perhaps due to signal) */ +// LIBUSB_ERROR_INTERRUPTED = -10, + +// /** Insufficient memory */ +// LIBUSB_ERROR_NO_MEM = -11, + +// /** Operation not supported or unimplemented on this platform */ +// LIBUSB_ERROR_NOT_SUPPORTED = -12, + +// /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the +// message strings in strerror.c when adding new error codes here. */ + +// /** Other error */ +// LIBUSB_ERROR_OTHER = -99, +// }; +// returns -2, LIBUSB_ERROR_NO_MEM, LIBUSB_ERROR_ACCESS, +// LIBUSB_ERROR_NO_DEVICE, LIBUSB_ERROR +/*! + * Get USB device strings. + * + * NOTE: The string arguments must provide space for up to 256 bytes. + * + * \param index the device index + * \param manufact manufacturer name, may be NULL + * \param product product name, may be NULL + * \param serial serial number, may be NULL + * \return 0 on success + */ +extern int rtlsdr_get_device_usb_strings(uint32_t index, + char *manufact, + char *product, + char *serial); + +/*! + * Get device index by USB serial string descriptor. + * + * \param serial serial string of the device + * \return device index of first device where the name matched + * \return -1 if name is NULL + * \return -2 if no devices were found at all + * \return -3 if devices were found, but none with matching name + */ +extern int rtlsdr_get_index_by_serial(const char *serial); + +// returns -1 no device, some libusb_error value, also write_regs +// returns 0 or -1 +extern int rtlsdr_open(rtlsdr_dev_t **dev, uint32_t index); + +// returns -1 no device or 0 +extern int rtlsdr_close(rtlsdr_dev_t *dev); + +/* configuration functions */ + +/*! + * Set crystal oscillator frequencies used for the RTL2832 and the tuner IC. + * + * Usually both ICs use the same clock. Changing the clock may make sense if + * you are applying an external clock to the tuner or to compensate the + * frequency (and samplerate) error caused by the original (cheap) crystal. + * + * NOTE: Call this function only if you fully understand the implications. + * + * \param dev the device handle given by rtlsdr_open() + * \param rtl_freq frequency value used to clock the RTL2832 in Hz + * \param tuner_freq frequency value used to clock the tuner IC in Hz + * \return 0 on success + */ +extern int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, + uint32_t tuner_freq); + +/*! + * Get crystal oscillator frequencies used for the RTL2832 and the tuner IC. + * + * Usually both ICs use the same clock. + * + * \param dev the device handle given by rtlsdr_open() + * \param rtl_freq frequency value used to clock the RTL2832 in Hz + * \param tuner_freq frequency value used to clock the tuner IC in Hz + * \return 0 on success + */ +extern int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, + uint32_t *tuner_freq); + +/*! + * Get USB device strings. + * + * NOTE: The string arguments must provide space for up to 256 bytes. + * + * \param dev the device handle given by rtlsdr_open() + * \param manufact manufacturer name, may be NULL + * \param product product name, may be NULL + * \param serial serial number, may be NULL + * \return 0 on success + */ +extern int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, + char *product, char *serial); + +/*! + * Write the device EEPROM + * + * \param dev the device handle given by rtlsdr_open() + * \param data buffer of data to be written + * \param offset address where the data should be written + * \param len length of the data + * \return 0 on success + * \return -1 if device handle is invalid + * \return -2 if EEPROM size is exceeded + * \return -3 if no EEPROM was found + */ +extern int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, + uint8_t offset, uint16_t len); + +/*! + * Read the device EEPROM + * + * \param dev the device handle given by rtlsdr_open() + * \param data buffer where the data should be written + * \param offset address where the data should be read from + * \param len length of the data + * \return 0 on success + * \return -1 if device handle is invalid + * \return -2 if EEPROM size is exceeded + * \return -3 if no EEPROM was found + */ +extern int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, + uint8_t offset, uint16_t len); + +extern int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq); + +/*! + * Get actual frequency the device is tuned to. + * + * \param dev the device handle given by rtlsdr_open() + * \return 0 on error, frequency in Hz otherwise + */ +extern uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev); + +/*! + * Set the frequency correction value for the device. + * + * \param dev the device handle given by rtlsdr_open() + * \param ppm correction value in parts per million (ppm) + * \return 0 on success + */ +extern int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm); + +/*! + * Get actual frequency correction value of the device. + * + * \param dev the device handle given by rtlsdr_open() + * \return correction value in parts per million (ppm) + */ +extern int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev); + +// XXX: for enum returns there should be a NO_DEVICE = -1 +enum rtlsdr_tuner { + RTLSDR_TUNER_UNKNOWN = 0, + RTLSDR_TUNER_E4000, + RTLSDR_TUNER_FC0012, + RTLSDR_TUNER_FC0013, + RTLSDR_TUNER_FC2580, + RTLSDR_TUNER_R820T, + RTLSDR_TUNER_R828D +}; + +/*! + * Get the tuner type. + * + * \param dev the device handle given by rtlsdr_open() + * \return RTLSDR_TUNER_UNKNOWN on error, tuner type otherwise + */ +extern enum rtlsdr_tuner rtlsdr_get_tuner_type(rtlsdr_dev_t *dev); + +/*! + * Get a list of gains supported by the tuner. + * + * NOTE: The gains argument must be preallocated by the caller. If NULL is + * being given instead, the number of available gain values will be returned. + * + * \param dev the device handle given by rtlsdr_open() + * \param gains array of gain values. In tenths of a dB, 115 means 11.5 dB. + * \return <= 0 on error, number of available (returned) gain values otherwise + */ +extern int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains); + +/*! + * Set the gain for the device. + * Manual gain mode must be enabled for this to work. + * + * Valid gain values (in tenths of a dB) for the E4000 tuner: + * -10, 15, 40, 65, 90, 115, 140, 165, 190, + * 215, 240, 290, 340, 420, 430, 450, 470, 490 + * + * Valid gain values may be queried with \ref rtlsdr_get_tuner_gains function. + * + * \param dev the device handle given by rtlsdr_open() + * \param gain in tenths of a dB, 115 means 11.5 dB. + * \return 0 on success + */ +extern int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain); + +/*! + * Set the bandwidth for the device. + * + * \param dev the device handle given by rtlsdr_open() + * \param bw bandwidth in Hz. Zero means automatic BW selection. + * \return 0 on success + */ +extern int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw); + +/*! + * Get actual gain the device is configured to. + * + * \param dev the device handle given by rtlsdr_open() + * \return 0 on error, gain in tenths of a dB, 115 means 11.5 dB. + */ +extern int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev); + +/*! + * Set the intermediate frequency gain for the device. + * + * \param dev the device handle given by rtlsdr_open() + * \param stage intermediate frequency gain stage number (1 to 6 for E4000) + * \param gain in tenths of a dB, -30 means -3.0 dB. + * \return 0 on success + */ +extern int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain); + +/*! + * Set the gain mode (automatic/manual) for the device. + * Manual gain mode must be enabled for the gain setter function to work. + * + * \param dev the device handle given by rtlsdr_open() + * \param manual gain mode, 1 means manual gain mode shall be enabled. + * \return 0 on success + */ +extern int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual); + +/*! + * Set the sample rate for the device, also selects the baseband filters + * according to the requested sample rate for tuners where this is possible. + * + * \param dev the device handle given by rtlsdr_open() + * \param samp_rate the sample rate to be set, possible values are: + * 225001 - 300000 Hz + * 900001 - 3200000 Hz + * sample loss is to be expected for rates > 2400000 + * \return 0 on success, -EINVAL on invalid rate + */ +extern int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate); + +/*! + * Get actual sample rate the device is configured to. + * + * \param dev the device handle given by rtlsdr_open() + * \return 0 on error, sample rate in Hz otherwise + */ +extern uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev); + +/*! + * Enable test mode that returns an 8 bit counter instead of the samples. + * The counter is generated inside the RTL2832. + * + * \param dev the device handle given by rtlsdr_open() + * \param test mode, 1 means enabled, 0 disabled + * \return 0 on success + */ +extern int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on); + +/*! + * Enable or disable the internal digital AGC of the RTL2832. + * + * \param dev the device handle given by rtlsdr_open() + * \param digital AGC mode, 1 means enabled, 0 disabled + * \return 0 on success + */ +extern int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on); + +/*! + * Enable or disable the direct sampling mode. When enabled, the IF mode + * of the RTL2832 is activated, and rtlsdr_set_center_freq() will control + * the IF-frequency of the DDC, which can be used to tune from 0 to 28.8 MHz + * (xtal frequency of the RTL2832). + * + * \param dev the device handle given by rtlsdr_open() + * \param on 0 means disabled, 1 I-ADC input enabled, 2 Q-ADC input enabled + * \return 0 on success + */ +extern int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on); + +/*! + * Get state of the direct sampling mode + * + * \param dev the device handle given by rtlsdr_open() + * \return -1 on error, 0 means disabled, 1 I-ADC input enabled + * 2 Q-ADC input enabled + */ +extern int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev); + +/*! + * Enable or disable offset tuning for zero-IF tuners, which allows to avoid + * problems caused by the DC offset of the ADCs and 1/f noise. + * + * \param dev the device handle given by rtlsdr_open() + * \param on 0 means disabled, 1 enabled + * \return 0 on success + */ +extern int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on); + +/*! + * Get state of the offset tuning mode + * + * \param dev the device handle given by rtlsdr_open() + * \return -1 on error, 0 means disabled, 1 enabled + */ +extern int rtlsdr_get_offset_tuning(rtlsdr_dev_t *dev); + +/* streaming functions */ + +extern int rtlsdr_reset_buffer(rtlsdr_dev_t *dev); + +extern int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read); + +typedef void(*rtlsdr_read_async_cb_t)(unsigned char *buf, uint32_t len, void *ctx); + +/*! + * Read samples from the device asynchronously. This function will block until + * it is being canceled using rtlsdr_cancel_async() + * + * NOTE: This function is deprecated and is subject for removal. + * + * \param dev the device handle given by rtlsdr_open() + * \param cb callback function to return received samples + * \param ctx user specific context to pass via the callback function + * \return 0 on success + */ +extern int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx); + +/*! + * Read samples from the device asynchronously. This function will block until + * it is being canceled using rtlsdr_cancel_async() + * + * \param dev the device handle given by rtlsdr_open() + * \param cb callback function to return received samples + * \param ctx user specific context to pass via the callback function + * \param buf_num optional buffer count, buf_num * buf_len = overall buffer size + * set to 0 for default buffer count (15) + * \param buf_len optional buffer length, must be multiple of 512, + * should be a multiple of 16384 (URB size), set to 0 + * for default buffer length (16 * 32 * 512) + * \return 0 on success + */ +extern int rtlsdr_read_async(rtlsdr_dev_t *dev, + rtlsdr_read_async_cb_t cb, + void *ctx, + uint32_t buf_num, + uint32_t buf_len); + +/*! + * Cancel all pending asynchronous operations on the device. + * + * \param dev the device handle given by rtlsdr_open() + * \return 0 on success + */ +extern int rtlsdr_cancel_async(rtlsdr_dev_t *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* __RTL_SDR_H */