summaryrefslogtreecommitdiff
path: root/src/hw
diff options
context:
space:
mode:
Diffstat (limited to 'src/hw')
-rw-r--r--src/hw/Kconfig39
-rw-r--r--src/hw/aud.c77
-rw-r--r--src/hw/aud.h14
-rw-r--r--src/hw/hw.c285
-rw-r--r--src/hw/hw.h64
-rw-r--r--src/hw/hw_eeprom.c47
-rw-r--r--src/hw/hw_eeprom.h15
-rw-r--r--src/hw/make.mk12
-rw-r--r--src/hw/sdr.c315
-rw-r--r--src/hw/sdr.h99
10 files changed, 967 insertions, 0 deletions
diff --git a/src/hw/Kconfig b/src/hw/Kconfig
new file mode 100644
index 0000000..f95a0f5
--- /dev/null
+++ b/src/hw/Kconfig
@@ -0,0 +1,39 @@
+menuconfig HW
+ bool "Hardware support"
+ default y
+
+if HW
+ choice
+ prompt "RTLSDR library"
+ help
+ RTLSDR library
+
+ config HW_LIB_ORIG
+ bool "librtlsdr original version"
+ default y
+
+ config HW_LIB_R820T
+ bool "libr820t for of librtlsdr by radiola"
+ default n
+
+
+ endchoice
+
+ choice
+ prompt "Audio"
+
+ config HW_ALSA
+ bool "Linux ALSA"
+ default y
+ depends on OS_LINUX
+
+ config HW_NO_AUDIO
+ bool "No audio support"
+ default n
+
+ endchoice
+
+endif
+
+
+
diff --git a/src/hw/aud.c b/src/hw/aud.c
new file mode 100644
index 0000000..ade60cb
--- /dev/null
+++ b/src/hw/aud.c
@@ -0,0 +1,77 @@
+#include "aud.h"
+
+#if def(OS_LINUX)
+//harc-copy from aplay.c static void device_list(void)
+int audio_get_devices()
+{
+ snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
+
+ snd_ctl_t *handle;
+ int card, err, dev, idx;
+ snd_ctl_card_info_t *info;
+ snd_pcm_info_t *pcminfo;
+ snd_ctl_card_info_alloca(&info);
+ snd_pcm_info_alloca(&pcminfo);
+
+ card = -1;
+ if (snd_card_next(&card) < 0 || card < 0) {
+ printf("no soundcards found...\n");
+ return -1;
+ }
+ printf("**** List of %s Hardware Devices ****\n",
+ snd_pcm_stream_name(stream));
+ while (card >= 0) {
+ char name[32];
+ sprintf(name, "hw:%d", card);
+ if ((err = snd_ctl_open(&handle, name, 0)) < 0) {
+ printf("control open (%i): %s\n", card, snd_strerror(err));
+ goto next_card;
+ }
+ if ((err = snd_ctl_card_info(handle, info)) < 0) {
+ printf("control hardware info (%i): %s\n", card, snd_strerror(err));
+ snd_ctl_close(handle);
+ goto next_card;
+ }
+ dev = -1;
+ while (1) {
+ unsigned int count;
+ if (snd_ctl_pcm_next_device(handle, &dev)<0)
+ printf("snd_ctl_pcm_next_device\n");
+ if (dev < 0)
+ break;
+ snd_pcm_info_set_device(pcminfo, dev);
+ snd_pcm_info_set_subdevice(pcminfo, 0);
+ snd_pcm_info_set_stream(pcminfo, stream);
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+ if (err != -ENOENT)
+ printf("control digital audio info (%i): %s\n", card, snd_strerror(err));
+ continue;
+ }
+ printf("card %i: %s [%s], device %i: %s [%s]\n",
+ card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
+ dev,
+ snd_pcm_info_get_id(pcminfo),
+ snd_pcm_info_get_name(pcminfo));
+ count = snd_pcm_info_get_subdevices_count(pcminfo);
+ printf( " Subdevices: %i/%i\n",
+ snd_pcm_info_get_subdevices_avail(pcminfo), count);
+ for (idx = 0; idx < (int)count; idx++) {
+ snd_pcm_info_set_subdevice(pcminfo, idx);
+ if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
+ printf("control digital audio playback info (%i): %s\n", card, snd_strerror(err));
+ } else {
+ printf(" Subdevice #%d: %s\n",
+ idx, snd_pcm_info_get_subdevice_name(pcminfo));
+ }
+ }
+ }
+ snd_ctl_close(handle);
+ next_card:
+ if (snd_card_next(&card) < 0) {
+ printf("snd_card_next\n");
+ break;
+ }
+ }
+ return 0;
+}
+#endif
diff --git a/src/hw/aud.h b/src/hw/aud.h
new file mode 100644
index 0000000..974646a
--- /dev/null
+++ b/src/hw/aud.h
@@ -0,0 +1,14 @@
+#ifndef __RADIOLA_AUD_H
+#define __RADIOLA_AUD_H
+#include "../config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#if def(OS_LINUX)
+#include <alsa/asoundlib.h>
+#endif
+int audio_get_devices();
+
+#endif
diff --git a/src/hw/hw.c b/src/hw/hw.c
new file mode 100644
index 0000000..4496a51
--- /dev/null
+++ b/src/hw/hw.c
@@ -0,0 +1,285 @@
+#include "hw.h"
+
+uint32_t hw_get_device_count(void)
+{
+ uint32_t ret;
+ ret = rtlsdr_get_device_count();
+ return ret;
+}
+
+
+const char* hw_get_device_name(uint32_t index)
+{
+ const char *ret;
+ ret = rtlsdr_get_device_name( index );
+ return ret;
+}
+
+
+int hw_get_device_usb_strings(uint32_t index,
+ char *manufact,
+ char *product,
+ char *serial)
+{
+ int ret;
+ ret = rtlsdr_get_device_usb_strings( index, manufact, product, serial );
+ return ret;
+}
+
+
+int hw_get_index_by_serial(const char *serial)
+{
+ int ret;
+ rtlsdr_get_index_by_serial( serial );
+ return ret;
+}
+
+
+int hw_open(rtlsdr_dev_t **dev, uint32_t index)
+{
+ int ret;
+ ret = rtlsdr_open( dev, index );
+ return ret;
+}
+
+
+int hw_close(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_close( dev );
+ return ret;
+}
+
+
+int hw_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq,
+ uint32_t tuner_freq)
+{
+ int ret;
+ ret = rtlsdr_set_xtal_freq( dev, rtl_freq, tuner_freq );
+ return ret;
+}
+
+
+int hw_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq,
+ uint32_t *tuner_freq)
+{
+ int ret;
+ ret = rtlsdr_get_xtal_freq( dev, rtl_freq, tuner_freq );
+ return ret;
+}
+
+
+int hw_get_usb_strings(rtlsdr_dev_t *dev, char *manufact,
+ char *product, char *serial)
+{
+ int ret;
+ ret = rtlsdr_get_usb_strings( dev, manufact, product, serial );
+ return ret;
+}
+
+
+int hw_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+ uint8_t offset, uint16_t len)
+{
+ int ret;
+ ret = rtlsdr_write_eeprom( dev, data, offset, len );
+ return ret;
+}
+
+
+int hw_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+ uint8_t offset, uint16_t len)
+{
+ int ret;
+ ret = rtlsdr_read_eeprom( dev, data, offset, len );
+ return ret;
+}
+
+
+int hw_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
+{
+ int ret;
+ ret = rtlsdr_set_center_freq( dev, freq );
+ return ret;
+}
+
+
+uint32_t hw_get_center_freq(rtlsdr_dev_t *dev)
+{
+ uint32_t ret;
+ ret = rtlsdr_get_center_freq( dev );
+ return ret;
+}
+
+
+int hw_set_freq_correction(rtlsdr_dev_t *dev, int ppm)
+{
+ int ret;
+ ret = rtlsdr_set_freq_correction( dev, ppm );
+ return ret;
+}
+
+
+int hw_get_freq_correction(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_get_freq_correction( dev );
+ return ret;
+}
+
+
+enum rtlsdr_tuner hw_get_tuner_type(rtlsdr_dev_t *dev)
+{
+ enum rtlsdr_tuner ret;
+ ret = rtlsdr_get_tuner_type( dev );
+ return ret;
+}
+
+
+int hw_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
+{
+ int ret;
+ ret = rtlsdr_get_tuner_gains( dev, gains );
+ return ret;
+}
+
+
+int hw_set_tuner_gain(rtlsdr_dev_t *dev, int gain)
+{
+ int ret;
+ ret = rtlsdr_set_tuner_gain( dev, gain );
+ return ret;
+}
+
+
+int hw_get_tuner_gain(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_get_tuner_gain( dev );
+ return ret;
+}
+
+
+int hw_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain)
+{
+ int ret;
+ ret = rtlsdr_set_tuner_if_gain( dev, stage, gain );
+ return ret;
+}
+
+
+int hw_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual)
+{
+ int ret;
+ ret = rtlsdr_set_tuner_gain_mode( dev, manual );
+ return ret;
+}
+
+
+int hw_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate)
+{
+ int ret;
+ ret = rtlsdr_set_sample_rate( dev, rate );
+ return ret;
+}
+
+
+uint32_t hw_get_sample_rate(rtlsdr_dev_t *dev)
+{
+ uint32_t ret;
+ ret = rtlsdr_get_sample_rate( dev );
+ return ret;
+}
+
+
+int hw_set_testmode(rtlsdr_dev_t *dev, int on)
+{
+ int ret;
+ ret = rtlsdr_set_testmode( dev, on );
+ return ret;
+}
+
+
+int hw_set_agc_mode(rtlsdr_dev_t *dev, int on)
+{
+ int ret;
+ ret = rtlsdr_set_agc_mode( dev, on );
+ return ret;
+}
+
+
+int hw_set_direct_sampling(rtlsdr_dev_t *dev, int on)
+{
+ int ret;
+ ret = rtlsdr_set_direct_sampling( dev, on );
+ return ret;
+}
+
+
+int hw_get_direct_sampling(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_get_direct_sampling( dev );
+ return ret;
+}
+
+
+int hw_set_offset_tuning(rtlsdr_dev_t *dev, int on)
+{
+ int ret;
+ ret = rtlsdr_set_offset_tuning( dev, on );
+ return ret;
+}
+
+
+int hw_get_offset_tuning(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_get_offset_tuning( dev );
+ return ret;
+}
+
+
+
+int hw_reset_buffer(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_reset_buffer( dev );
+ return ret;
+}
+
+
+int hw_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read)
+{
+ int ret;
+ ret = rtlsdr_read_sync( dev, buf, len, n_read );
+ return ret;
+}
+
+
+int hw_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx)
+{
+ int ret;
+ ret = rtlsdr_wait_async( dev, cb, ctx );
+ return ret;
+}
+
+
+int hw_read_async(rtlsdr_dev_t *dev,
+ rtlsdr_read_async_cb_t cb,
+ void *ctx,
+ uint32_t buf_num,
+ uint32_t buf_len)
+{
+ int ret;
+ ret = rtlsdr_read_async( dev, cb, ctx, buf_num, buf_len );
+ return ret;
+}
+
+
+int hw_cancel_async(rtlsdr_dev_t *dev)
+{
+ int ret;
+ ret = rtlsdr_cancel_async( dev );
+ return ret;
+} \ No newline at end of file
diff --git a/src/hw/hw.h b/src/hw/hw.h
new file mode 100644
index 0000000..ac79431
--- /dev/null
+++ b/src/hw/hw.h
@@ -0,0 +1,64 @@
+#ifndef __RADIOLA_HW_H
+#define __RADIOLA_HW_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+//#include <r820t.h>
+#include <rtl-sdr.h>
+
+
+
+uint32_t hw_get_device_count(void);
+const char* hw_get_device_name(uint32_t index);
+int hw_get_device_usb_strings(uint32_t index,
+ char *manufact,
+ char *product,
+ char *serial);
+int hw_get_index_by_serial(const char *serial);
+int hw_open(rtlsdr_dev_t **dev, uint32_t index);
+int hw_close(rtlsdr_dev_t *dev);
+int hw_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq,
+ uint32_t tuner_freq);
+int hw_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq,
+ uint32_t *tuner_freq);
+int hw_get_usb_strings(rtlsdr_dev_t *dev, char *manufact,
+ char *product, char *serial);
+int hw_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+ uint8_t offset, uint16_t len);
+int hw_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
+ uint8_t offset, uint16_t len);
+int hw_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
+uint32_t hw_get_center_freq(rtlsdr_dev_t *dev);
+int hw_set_freq_correction(rtlsdr_dev_t *dev, int ppm);
+int hw_get_freq_correction(rtlsdr_dev_t *dev);
+enum rtlsdr_tuner hw_get_tuner_type(rtlsdr_dev_t *dev);
+int hw_get_tuner_gains(rtlsdr_dev_t *dev, int *gains);
+int hw_set_tuner_gain(rtlsdr_dev_t *dev, int gain);
+int hw_get_tuner_gain(rtlsdr_dev_t *dev);
+int hw_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain);
+int hw_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual);
+int hw_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate);
+uint32_t hw_get_sample_rate(rtlsdr_dev_t *dev);
+int hw_set_testmode(rtlsdr_dev_t *dev, int on);
+int hw_set_agc_mode(rtlsdr_dev_t *dev, int on);
+int hw_set_direct_sampling(rtlsdr_dev_t *dev, int on);
+int hw_get_direct_sampling(rtlsdr_dev_t *dev);
+int hw_set_offset_tuning(rtlsdr_dev_t *dev, int on);
+int hw_get_offset_tuning(rtlsdr_dev_t *dev);
+int hw_reset_buffer(rtlsdr_dev_t *dev);
+int hw_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read);
+int hw_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx);
+int hw_read_async(rtlsdr_dev_t *dev,
+ rtlsdr_read_async_cb_t cb,
+ void *ctx,
+ uint32_t buf_num,
+ uint32_t buf_len);
+int hw_cancel_async(rtlsdr_dev_t *dev);
+
+
+
+
+
+
+#endif \ No newline at end of file
diff --git a/src/hw/hw_eeprom.c b/src/hw/hw_eeprom.c
new file mode 100644
index 0000000..10ae817
--- /dev/null
+++ b/src/hw/hw_eeprom.c
@@ -0,0 +1,47 @@
+#include "hw_eeprom.h"
+
+
+
+int dump_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len )
+{
+ int fret = 0;
+
+ if ( len != EEPROM_SIZE )
+ {
+ printf("EEPROM sump size expected to be %d\n", EEPROM_SIZE);
+ return -1;
+ }
+
+ fret = hw_read_eeprom( dev, data, 0, len );
+ if ( fret != 0 )
+ {
+ printf("Cannot read eeprom rtlsdr err (%d)\n", fret);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int restore_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len )
+{
+ int fret = 0;
+
+ if ( len != EEPROM_SIZE )
+ {
+ printf("EEPROM sump size expected to be %d\n", EEPROM_SIZE);
+ return -1;
+ }
+
+ fret = hw_write_eeprom( dev, data, 0, len );
+ if ( fret != 0 )
+ {
+ printf("Cannot write eeprom rtlsdr err(%d)\n", fret);
+ return -1;
+ }
+
+
+ return 0;
+}
+
+
diff --git a/src/hw/hw_eeprom.h b/src/hw/hw_eeprom.h
new file mode 100644
index 0000000..ac3ec0a
--- /dev/null
+++ b/src/hw/hw_eeprom.h
@@ -0,0 +1,15 @@
+#ifndef __RADIOLA_HW_EEPROM_H
+#define __RADIOLA_HW_EEPROM_H
+
+#include "hw.h"
+
+#define EEPROM_SIZE 256
+
+int dump_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len );
+int restore_eeprom( rtlsdr_dev_t *dev, uint8_t *data, uint16_t len );
+
+//int eeprom_read_config();
+//int eeprom_write_config();
+
+
+#endif \ No newline at end of file
diff --git a/src/hw/make.mk b/src/hw/make.mk
new file mode 100644
index 0000000..34d3e6f
--- /dev/null
+++ b/src/hw/make.mk
@@ -0,0 +1,12 @@
+DIR_HW = hw/
+SOURCES_HW += $(SRC_DIR)hw/aud.c $(SRC_DIR)hw/hw.c $(SRC_DIR)hw/hw_eeprom.c \
+$(SRC_DIR)hw/sdr.c
+OBJECTS_HW += $(SOURCES_HW:.c=.o)
+LDFLAGS += -lrtlsdr -lasound
+LDFLAGS_BSD += -lrtlsdr
+
+
+OBJECTS_DIR_HW += $(subst $(SRC_DIR)$(DIR_HW),$(BUILD_DIR)$(SRC_DIR)$(DIR_HW),$(OBJECTS_HW))
+
+OBJECTS += $(OBJECTS_HW)
+OBJECTS_FINAL += $(OBJECTS_DIR_HW) \ No newline at end of file
diff --git a/src/hw/sdr.c b/src/hw/sdr.c
new file mode 100644
index 0000000..a9590da
--- /dev/null
+++ b/src/hw/sdr.c
@@ -0,0 +1,315 @@
+#include "sdr.h"
+
+sdr_t* sdr_init()
+{
+ sdr_t *sdr=NULL;
+
+ sdr = malloc( sizeof(sdr_t) );
+ if (sdr == NULL)
+ return NULL;
+
+ memset( sdr, 0, sizeof(sdr_t) );
+
+ return sdr;
+}
+
+
+//index of device in oter list
+//return inner device list
+int sdr_open_device( sdr_t *sdr, int dev_index )
+{
+ int ret;
+ dongle_t *dng=NULL;
+ rtlsdr_dev_t *rtl=NULL;
+
+ //for now only one device will be supported
+ if (sdr == NULL)
+ return -1;
+
+ if (sdr->dongle != NULL)
+ return -1;
+
+ dng = malloc(sizeof(dongle_t));
+ memset(dng, 0, sizeof(dongle_t));
+ //set default values for dongle_t
+ DEF_DONGLE_VALUES(dng);
+
+ ret = hw_open( &rtl, (uint32_t)dev_index );
+ if ( ret < 0 )
+ {
+ printf("Cannot open device %02d\n", dev_index );
+ goto exit_dng_err;
+ }
+
+ ret = hw_reset_buffer( rtl );
+ if ( ret < 0 )
+ {
+ printf("Couldnt reset buffer\n");
+ goto exit_dng_err;
+ }
+
+ ret = hw_set_sample_rate( rtl, dng->rate );
+ if ( ret < 0 )
+ {
+ printf("Couldnt set sample rate to %d\n", dng->rate);
+ goto exit_dng_err;
+ }
+
+ ret = hw_set_center_freq( rtl, dng->freq );
+ if ( ret < 0 )
+ {
+ printf("Couldnt set frequency %d\n", dng->freq );
+ goto exit_dng_err;
+ }
+
+ ret = hw_set_tuner_gain_mode( rtl, dng->gain );
+ if ( ret < 0 )
+ {
+ printf("Cannot set autogain mode\n");
+ goto exit_dng_err;
+ }
+
+ ret = hw_set_agc_mode( rtl, 1 );
+ if ( ret < 0 )
+ {
+ printf("Cannot set agc mode\n");
+ goto exit_dng_err;
+ }
+
+ dng->dev_index = dev_index;
+ dng->dev = rtl;
+ sdr->dongle = dng;
+
+ return 0;
+
+exit_dng_err:
+ free( dng );
+
+ return -1;
+}
+
+
+//associate audio device that going to be used
+//int sdr_open_audio( sdr_t *sdr, int dev_index );//?should be just device from list or device name?
+
+
+//get device structure from sdr manager by pluged device num
+//dont try to free it muahaha
+dongle_t* sdr_get_device_id( sdr_t *sdr, int dev_index)
+{
+ dongle_t *dng=NULL;
+
+ if ( sdr == NULL )
+ return NULL;
+
+ if (sdr->dongle == NULL)
+ return NULL;
+
+ if (sdr->dongle->dev_index != dev_index)
+ {
+ printf("Cannot find device with such device ID\n");
+ return NULL;
+ }
+
+ return sdr->dongle;
+}
+
+
+
+//get index in list of devices of structure from outer device index
+//? do we need?
+//int sdr_get_dongle_idx( sdr_t *sdr, int idx );
+//close device by internal list index
+int sdr_close_device( sdr_t *sdr, int dev_index )
+{
+ if ( sdr == NULL )
+ return -1;
+
+ if ( sdr->dongle == NULL )
+ {
+ return -1;
+ }
+
+ if ( sdr->dongle->dev == NULL )
+ return -1;
+
+ if ( sdr->dongle->dev_index != dev_index )
+ return -1;
+
+ hw_close( sdr->dongle->dev );
+ free( sdr->dongle->dev );
+ sdr->dongle->dev = NULL;
+
+ free( sdr->dongle );
+ sdr->dongle = NULL;
+
+ return 0;
+}
+
+
+
+//close sdr
+//if there is opened audios then close
+//if there is opened devices then close
+int sdr_close( sdr_t *sdr )
+{
+ if ( sdr != NULL )
+ {
+ if ( sdr->dongle != NULL )
+ {
+ if ( sdr->dongle->dev != NULL )
+ {
+ hw_close( sdr->dongle->dev );
+ //all ready free'd by rtlsdr
+ //free( sdr->dongle->dev );
+ sdr->dongle->dev = NULL;
+ }
+ free( sdr->dongle );
+ sdr->dongle = NULL;
+ }
+ free(sdr);
+ sdr = NULL;
+ return 0;
+ }
+ return -1;
+}
+
+
+
+//stop any action that associated with dongle
+//not yet implemented
+int dongle_stop( dongle_t *dongle )
+{
+ return -1;
+}
+
+
+//int dongle_open( sdr_t *);
+//set dongle frequency
+int dongle_set_freq( dongle_t *dongle, uint32_t freq)
+{
+ int ret = 0;
+ if ( dongle == NULL )
+ return -1;
+
+ if ( dongle->dev == NULL )
+ return -1;
+
+ ret = hw_set_center_freq( dongle->dev, freq );
+ if ( ret < 0 )
+ {
+ printf("Cannot set device frequency to %ud\n", freq);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+//set gain
+int dongle_set_gain( dongle_t *dongle, int gain)
+{
+
+ int ret;
+
+ if ( dongle == NULL )
+ return -1;
+
+ if ( dongle->dev == NULL )
+ return -1;
+
+ ret = hw_set_tuner_gain_mode( dongle->dev, gain );
+ if ( ret < 0 )
+ {
+ printf("Cannot set tunner gain level %d\n", gain );
+ return -1;
+ }
+
+ return 0;
+}
+
+
+//set dongle sample rate
+int dongle_set_sample_rate( dongle_t *dongle, uint32_t rate )
+{
+ int ret;
+
+ if ( dongle == NULL )
+ {
+ return -1;
+ }
+
+ if ( dongle->dev == NULL )
+ return -1;
+
+ ret = hw_set_sample_rate( dongle->dev, rate );
+ if ( ret < 0 )
+ {
+ printf("Cannot set sample rate to %uMsps\n", rate);
+ return -1;
+ }
+
+ return 0;
+}
+
+int dongle_set_agc( dongle_t *dongle, int mode)
+{
+ int ret;
+
+ if ( dongle == NULL )
+ return -1;
+
+ if ( dongle->dev == NULL )
+ return -1;
+
+ //need mode check things
+ ret = hw_set_agc_mode( dongle->dev, mode );
+ if ( ret < 0 )
+ {
+ printf("Cannot set agc gain mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+uint32_t dongle_get_freq( dongle_t *dongle )
+{
+ return dongle->freq;
+}
+
+
+int dongle_get_gain( dongle_t *dongle )
+{
+ return dongle->gain;
+}
+
+
+uint32_t dongle_get_sample_rate( dongle_t *dongle )
+{
+ return dongle->rate;
+}
+
+
+int dongle_read_samples( dongle_t *dongle, uint8_t *buf, int len )
+{
+ int ret, read_num;
+
+ if ( dongle == NULL )
+ return -1;
+
+ if ( dongle->dev == NULL )
+ return -1;
+
+
+
+ ret = hw_read_sync( dongle->dev, buf, len, &read_num );
+ if ( ret < 0 )
+ {
+ printf("Couldnt read samples\n");
+ return -1;
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/hw/sdr.h b/src/hw/sdr.h
new file mode 100644
index 0000000..ce4ef70
--- /dev/null
+++ b/src/hw/sdr.h
@@ -0,0 +1,99 @@
+#ifndef __RADIOLA_HW_SDR_H
+#define __RADIOLA_HW_SDR_H
+
+#include <string.h>
+
+#include "hw.h"
+
+
+//list of supported devices RTLSDR is rtlsdr tunners,
+//AUDIO is just used audio cards
+//NET get or send some info to server/client
+//PTT usb connected with audio link radios, trought PTT things
+typedef enum
+{
+ DEVICE_NONE=0,
+ DEVICE_RTLSDR,
+ DEVICE_AUDIO,
+ DEVICE_NET,
+ DEVICE_PTT
+} sdr_device;
+
+
+typedef struct dongle_t
+{
+ rtlsdr_dev_t *dev;
+ int dev_index;
+ uint32_t freq;
+ uint32_t rate;
+ int gain;
+} dongle_t;
+
+#define DONGLE_SAMPLE_RATE 2048000
+#define DONGLE_CENTER_FREQ 100000000
+#define DONGLE_GAIN 1
+
+//dongle pointer to dongle_t
+#define DEF_DONGLE_VALUES(DONGLE)\
+{\
+(DONGLE)->freq=DONGLE_CENTER_FREQ;\
+(DONGLE)->rate=DONGLE_SAMPLE_RATE;\
+(DONGLE)->gain=DONGLE_GAIN;\
+}
+
+
+typedef struct audio_t
+{
+} audio_t;
+
+
+typedef struct sdr_t
+{
+ dongle_t *dongle; //list of rtlsdr devices
+ uint32_t d_used; //not yes used
+ audio_t *audio; //audio devices used
+ uint32_t a_used; //not yet used
+} sdr_t;
+
+//init structure
+
+sdr_t* sdr_init();
+//index of device in oter list
+//return inner device list
+int sdr_open_device( sdr_t *sdr, int dev_index );
+//associate audio device that going to be used
+//int sdr_open_audio( sdr_t *sdr, int dev_index );//?should be just device from list or device name?
+
+
+//get device structure from sdr manager
+dongle_t* sdr_get_device_id( sdr_t *sdr, int dev_index);
+
+//get index in list of devices of structure from outer device index
+//? do we need?
+//int sdr_get_dongle_idx( sdr_t *sdr, int idx );
+//close device by internal list index
+int sdr_close_device( sdr_t *sdr, int idx );
+
+//close sdr
+//if there is opened audios then close
+//if there is opened devices then close
+int sdr_close( sdr_t *sdr );
+
+//stop any action that associated with dongle
+int dongle_stop( dongle_t *dongle );
+//int dongle_open( sdr_t *);
+//set dongle frequency
+int dongle_set_freq( dongle_t *dongle, uint32_t freq);
+//set gain
+int dongle_set_gain( dongle_t *dongle, int gain);
+int dongle_set_agc( dongle_t *dongle, int mode);
+//set dongle sample rate
+int dongle_set_sample_rate( dongle_t *dongle, uint32_t rate );
+
+uint32_t dongle_get_freq( dongle_t *dongle );
+int dongle_get_gain( dongle_t *dongle );
+uint32_t dongle_get_sample_rate( dongle_t *dongle );
+int dongle_read_samples( dongle_t *dongle, uint8_t *buf, int len );
+//int dongle_close();
+
+#endif \ No newline at end of file