I am trying to create a librtlsdr.dll wrapper to control a USB SDR (Software Defined Radio) dongle radio receiver
Many open source applications exist regarding the use of this type of receiver, but for the moment I have not yet seen any in Purebasic.
I was able to successfully test an ADSB receiver (synchronous mode reception, terminal type) in Free Pascal, initially developed in Delphi XE, after converting the files in the Lazarus 3.0 IDE.
This project includes a relatively simple wrapper file for the hardware access dll. This main DLL, associated with two other dependent ones (libusb-1.0.dll, libwinpthread-1.dll), is used for the majority of SDR applications using RTL-SDR receivers.
I want to make a similar wrapper for Purebasic.
. RTL-SDR information: https://www.rtl-sdr.com/about-rtl-sdr/
. Osmocom project: https://osmocom.org/projects/rtl-sdr/wiki
. Github driver sources: https://github.com/osmocom/rtl-sdr
. ADSB receiver example in DELPHI/PASCAL: https://sourceforge.net/projects/rtl-ad ... -xe8-port/
. Last Windows drivers builds: https://ftp.osmocom.org/binaries/windows/rtl-sdr/
From several posts, read in the French and English forums, I was able to create a wrapper framework, but I mainly stumble on the use of pointers to have a functional set.
On the other hand, I was able to test and use a wrapper for the VLC DLL in a simplified Purebasic player application, but my understanding of the source files remains problematic...
Here is the current development for SDR hardware. The wrapper compiles without anomaly, but it only allows processing 2 functions of the DLL, counting the RTL-SDR keys inserted on USB ports and retrieving the key name.
I welcome any information to move forward on this subject in order to unlock the main SDR control functions (frequency, bandwidth, gain, data buffer, etc.).
Libsdr.pbi wrapper file
Code: Select all
EnableExplicit
; ------- Structure for SDR device from C header rtlsdr.h
; 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;
; int use_zerocopy;
; /* 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;
; char manufact[256];
; char product[256];
; };
Structure rtlsdr_dev_t
; content
EndStructure
Structure rtlsdr_read_async_cb_t
; content
EndStructure
Enumeration rtlsdr_tuner_t
#RTLSDR_TUNER_UNKNOWN = 0
#RTLSDR_TUNER_E4000 = 1
#RTLSDR_TUNER_FC0012 = 2
#RTLSDR_TUNER_FC0013 = 3
#RTLSDR_TUNER_FC2580 = 4
#RTLSDR_TUNER_R820T = 5
#RTLSDR_TUNER_R828D = 6
EndEnumeration
; ------- Variable definitions
Global dev.rtlsdr_dev_t
Global *dev
Global cb.rtlsdr_read_async_cb_t
Global manufact.s
Global *manufact
Global product.s
Global *product
Global serial.s
Global *serial
Global *gains
Global *rtl_freq
Global *tuner_freq
Global *data
Global *ctx
Global index.l=0
Global freq.l=0
Global on.i=0
Global buf_num.l=0
Global buf_len.l=0
Global *data=0
Global offset.l=0
Global len.i=0
Global gpio.i=0
Global ppm.i=0
Global rate.l=0
Global bw.l=0
Global gain.i=0
Global manual.i=0
Global stage.i=0
Global rtl_freq.i=0
Global tuner_freq.i=0
Global n_read.i=0
; ------- Prototype parameters specifications
; RTLSDR_API int rtlsdr_cancel_async(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_cancel_async(*dev)
; RTLSDR_API int rtlsdr_close(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_close(*dev)
; RTLSDR_API uint32_t rtlsdr_get_center_freq(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_get_center_freq(*dev)
; RTLSDR_API uint32_t rtlsdr_get_device_count(void);
Prototype.l proto_rtlsdr_get_device_count()
; RTLSDR_API const char* rtlsdr_get_device_name(uint32_t index);
Prototype proto_rtlsdr_get_device_name(index.l)
; RTLSDR_API int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, char *product, char *serial);
Prototype.l proto_rtlsdr_get_device_usb_strings(index.l, *manufact, *product, *serial)
; RTLSDR_API int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_get_direct_sampling(*dev, on.i)
; RTLSDR_API int rtlsdr_get_freq_correction(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_get_freq_correction(*dev)
; RTLSDR_API int rtlsdr_get_index_by_serial(const char *serial);
Prototype.l proto_rtlsdr_get_index_by_serial(*serial)
; RTLSDR_API int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_get_offset_tuning(*dev, on.i)
; RTLSDR_API uint32_t rtlsdr_get_sample_rate(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_get_sample_rate(*dev)
; RTLSDR_API int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_get_tuner_gain(*dev)
; RTLSDR_API int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains);
Prototype.l proto_rtlsdr_get_tuner_gains(*dev, *gains)
; RTLSDR_API enum rtlsdr_tuner rtlsdr_get_tuner_type(rtlsdr_dev_t *dev);
Prototype proto_rtlsdr_get_tuner_type(*dev)
; RTLSDR_API int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, char *serial);
Prototype.l proto_rtlsdr_get_usb_strings(*dev, *manufact, *product, *serial)
; RTLSDR_API int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_freq);
Prototype.l proto_rtlsdr_get_xtal_freq(*dev, *rtl_freq, *tuner_freq)
; RTLSDR_API int rtlsdr_open(rtlsdr_dev_t **dev, uint32_t index);
Prototype.l proto_rtlsdr_open(*dev, index.l)
; RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len);
Prototype.l proto_rtlsdr_read_async(*dev, cb, *ctx, buf_num.l, buf_len.i)
; RTLSDR_API int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len);
Prototype.l proto_rtlsdr_read_eeprom(*dev, *data, offset.l, len.i)
; RTLSDR_API int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read);
Prototype.l proto_rtlsdr_read_sync(*dev, *buf, len.i, *n_read)
; RTLSDR_API int rtlsdr_reset_buffer(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_reset_buffer(*dev)
; RTLSDR_API int rtlsdr_set_agc_mode(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_set_agc_mode(*dev, on.i)
; RTLSDR_API int rtlsdr_set_bias_tee(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_set_bias_tee(*dev, on.i)
; RTLSDR_API int rtlsdr_set_bias_tee_gpio(rtlsdr_dev_t *dev, int gpio, int on);
Prototype.l proto_rtlsdr_set_bias_tee_gpio(*dev, gpio.i, on.i)
; RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
Prototype.l proto_rtlsdr_set_center_freq(*dev, freq.l)
; RTLSDR_API int rtlsdr_get_direct_sampling(rtlsdr_dev_t *dev);
Prototype.l proto_rtlsdr_set_direct_sampling(*dev)
; RTLSDR_API int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm);
Prototype.l proto_rtlsdr_set_freq_correction(*dev, ppm.i)
; RTLSDR_API int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_set_offset_tuning(*dev, on.i)
; RTLSDR_API int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t rate);
Prototype.l proto_rtlsdr_set_sample_rate(*dev, rate.l)
; RTLSDR_API int rtlsdr_set_testmode(rtlsdr_dev_t *dev, int on);
Prototype.l proto_rtlsdr_set_testmode(*dev, on.i)
; RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw);
Prototype.l proto_rtlsdr_set_tuner_bandwidth(*dev, bw.l)
; RTLSDR_API int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain);
Prototype.l proto_rtlsdr_set_tuner_gain(*dev, gain.i)
; RTLSDR_API int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int manual);
Prototype.l proto_rtlsdr_set_tuner_gain_mode(*dev, manual.i)
; RTLSDR_API int rtlsdr_set_tuner_if_gain(rtlsdr_dev_t *dev, int stage, int gain);
Prototype.l proto_rtlsdr_set_tuner_if_gain(*dev, stage.i, gain.i)
; RTLSDR_API int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_freq);
Prototype.l proto_rtlsdr_set_xtal_freq(*dev, rtl_freq.l, tuner_freq.l)
; RTLSDR_API int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx);
Prototype.l proto_rtlsdr_wait_async(*dev, cb, *ctx)
; RTLSDR_API int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data, uint8_t offset, uint16_t len);
Prototype.l proto_rtlsdr_write_eeprom(*dev, *data, offset.l, len.i)
; ------- Function pointer declaration with prototype type specification
Global rtlsdr_cancel_async.proto_rtlsdr_cancel_async
Global rtlsdr_close.proto_rtlsdr_close
Global rtlsdr_get_center_freq.proto_rtlsdr_get_center_freq
Global rtlsdr_get_device_count.proto_rtlsdr_get_device_count
Global rtlsdr_get_device_name.proto_rtlsdr_get_device_name
Global rtlsdr_get_device_usb_strings.proto_rtlsdr_get_device_usb_strings
Global rtlsdr_get_direct_sampling.proto_rtlsdr_get_direct_sampling
Global rtlsdr_get_freq_correction.proto_rtlsdr_get_freq_correction
Global rtlsdr_get_index_by_serial.proto_rtlsdr_get_index_by_serial
Global rtlsdr_get_offset_tuning.proto_rtlsdr_get_offset_tuning
Global rtlsdr_get_sample_rate.proto_rtlsdr_get_sample_rate
Global rtlsdr_get_tuner_gain.proto_rtlsdr_get_tuner_gain
Global rtlsdr_get_tuner_gains.proto_rtlsdr_get_tuner_gains
Global rtlsdr_get_tuner_type.proto_rtlsdr_get_tuner_type
Global rtlsdr_get_usb_strings.proto_rtlsdr_get_usb_strings
Global rtlsdr_get_xtal_freq.proto_rtlsdr_get_xtal_freq
Global rtlsdr_open.proto_rtlsdr_open
Global rtlsdr_read_async.proto_rtlsdr_read_async
Global rtlsdr_read_eeprom.proto_rtlsdr_read_eeprom
Global rtlsdr_read_sync.proto_rtlsdr_read_sync
Global rtlsdr_reset_buffer.proto_rtlsdr_reset_buffer
Global rtlsdr_set_agc_mode.proto_rtlsdr_set_agc_mode
Global rtlsdr_set_bias_tee.proto_rtlsdr_set_bias_tee
Global rtlsdr_set_bias_tee_gpio.proto_rtlsdr_set_bias_tee_gpio
Global rtlsdr_set_center_freq.proto_rtlsdr_set_center_freq
Global rtlsdr_set_direct_sampling.proto_rtlsdr_set_direct_sampling
Global rtlsdr_set_freq_correction.proto_rtlsdr_set_freq_correction
Global rtlsdr_set_offset_tuning.proto_rtlsdr_set_offset_tuning
Global rtlsdr_set_sample_rate.proto_rtlsdr_set_sample_rate
Global rtlsdr_set_testmode.proto_rtlsdr_set_testmode
Global rtlsdr_set_tuner_bandwidth.proto_rtlsdr_set_tuner_bandwidth
Global rtlsdr_set_tuner_gain.proto_rtlsdr_set_tuner_gain
Global rtlsdr_set_tuner_gain_mode.proto_rtlsdr_set_tuner_gain_mode
Global rtlsdr_set_tuner_if_gain.proto_rtlsdr_set_tuner_if_gain
Global rtlsdr_set_xtal_freq.proto_rtlsdr_set_xtal_freq
Global rtlsdr_wait_async.proto_rtlsdr_wait_async
Global rtlsdr_write_eeprom.proto_rtlsdr_write_eeprom
; ------- DLL Loading with functions pointers
Procedure.i rtlsdr_LoadDLL()
Protected hDLL.i
hDLL = OpenLibrary(#PB_Any, "librtlsdr.dll")
If hDLL <> 0
rtlsdr_cancel_async = GetFunction(hDLL, "rtlsdr_cancel_async")
rtlsdr_close = GetFunction(hDLL, "rtlsdr_close")
rtlsdr_get_center_freq = GetFunction(hDLL, "rtlsdr_get_center_freq")
rtlsdr_get_device_count = GetFunction(hDLL, "rtlsdr_get_device_count")
rtlsdr_get_device_name = GetFunction(hDLL, "rtlsdr_get_device_name")
rtlsdr_get_device_usb_strings = GetFunction(hDLL, "rtlsdr_get_device_usb_strings")
rtlsdr_get_direct_sampling = GetFunction(hDLL, "rtlsdr_get_direct_sampling")
rtlsdr_get_freq_correction = GetFunction(hDLL, "rtlsdr_get_freq_correction")
rtlsdr_get_index_by_serial = GetFunction(hDLL, "rtlsdr_get_index_by_serial")
rtlsdr_get_offset_tuning = GetFunction(hDLL, "rtlsdr_get_offset_tuning")
rtlsdr_get_sample_rate = GetFunction(hDLL, "rtlsdr_get_sample_rate")
rtlsdr_get_tuner_gain = GetFunction(hDLL, "rtlsdr_get_tuner_gain")
rtlsdr_get_tuner_gains = GetFunction(hDLL, "rtlsdr_get_tuner_gains")
rtlsdr_get_tuner_type = GetFunction(hDLL, "rtlsdr_get_tuner_type")
rtlsdr_get_usb_strings = GetFunction(hDLL, "rtlsdr_get_usb_strings")
rtlsdr_get_xtal_freq = GetFunction(hDLL, "rtlsdr_get_xtal_freq")
rtlsdr_open = GetFunction(hDLL, "rtlsdr_open")
rtlsdr_read_async = GetFunction(hDLL, "rtlsdr_read_async")
rtlsdr_read_eeprom = GetFunction(hDLL, "rtlsdr_read_eeprom")
rtlsdr_read_sync = GetFunction(hDLL, "rtlsdr_read_sync")
rtlsdr_reset_buffer = GetFunction(hDLL, "rtlsdr_reset_buffer")
rtlsdr_set_agc_mode = GetFunction(hDLL, "rtlsdr_set_agc_mode")
rtlsdr_set_bias_tee = GetFunction(hDLL, "rtlsdr_set_bias_tee")
rtlsdr_set_bias_tee_gpio = GetFunction(hDLL, "rtlsdr_set_bias_tee_gpio")
rtlsdr_set_center_freq = GetFunction(hDLL, "rtlsdr_set_center_freq")
rtlsdr_set_direct_sampling = GetFunction(hDLL, "rtlsdr_set_direct_sampling")
rtlsdr_set_freq_correction = GetFunction(hDLL, "rtlsdr_set_freq_correction")
rtlsdr_set_offset_tuning = GetFunction(hDLL, "rtlsdr_set_offset_tuning")
rtlsdr_set_sample_rate = GetFunction(hDLL, "rtlsdr_set_sample_rate")
rtlsdr_set_testmode = GetFunction(hDLL, "rtlsdr_set_testmode")
rtlsdr_set_tuner_bandwidth = GetFunction(hDLL, "rtlsdr_set_tuner_bandwidth")
rtlsdr_set_tuner_gain = GetFunction(hDLL, "rtlsdr_set_tuner_gain")
rtlsdr_set_tuner_gain_mode = GetFunction(hDLL, "rtlsdr_set_tuner_gain_mode")
rtlsdr_set_tuner_if_gain = GetFunction(hDLL, "rtlsdr_set_tuner_if_gain")
rtlsdr_set_xtal_freq = GetFunction(hDLL, "rtlsdr_set_xtal_freq")
rtlsdr_wait_async = GetFunction(hDLL, "rtlsdr_wait_async")
rtlsdr_write_eeprom = GetFunction(hDLL, "rtlsdr_write_eeprom")
ProcedureReturn hDLL
EndIf
ProcedureReturn #False
EndProcedure
Code: Select all
IncludeFile "libsdr.pbi"
EnableExplicit
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
CompilerError "Windows only compilation"
CompilerEndIf
; ------- Structures
Structure info_tuner_t
manufact.s
Product.s
serial.s
EndStructure
; ------- Variable definitions
Global counter.l=0
Global sdr_Name.s=""
Global myfreq.l
Global rtl_sdr_tuner.s
Global mytuner.info_tuner_t
Global tuner_type.l=0
; ------- Functions list inside DLL
; If OpenLibrary(1,"librtlsdr.dll")
; ExamineLibraryFunctions(1)
; While NextLibraryFunction()
; Debug LibraryFunctionName()
; Wend
; EndIf
; ------- SDR Helpers procedures
Procedure.s safePeekS(ps, len=-1)
If ps:ProcedureReturn PeekS(ps, len, #PB_UTF8):EndIf
EndProcedure
Procedure.l open_sdr(index.l)
rtlsdr_open(dev, index.l)
EndProcedure
Procedure.l get_device_count()
counter.l=rtlsdr_get_device_count()
EndProcedure
Procedure.s get_device_name(index.l)
sdr_name.s=safePeekS(rtlsdr_get_device_name(index.l), -1)
EndProcedure
Procedure.l get_tuner_type()
tuner_type.l=rtlsdr_get_tuner_type(*dev)
EndProcedure
Procedure set_center_frequency(freq.l)
rtlsdr_set_center_freq(*dev, freq.l)
EndProcedure
Procedure.l get_center_frequency()
myfreq.l=rtlsdr_get_center_freq(*dev)
EndProcedure
Procedure close_sdr()
rtlsdr_close(*dev)
EndProcedure
Procedure get_usb_strings(index.l)
rtlsdr_get_device_usb_strings(index.l, *manufact, *product, *serial)
manufact.s=safePeekS(*manufact, -1)
product.s=safePeekS(*product, -1)
serial.s=safePeekS(*serial, -1)
EndProcedure
; ------- SDR Tests access
If rtlsdr_LoadDll()
open_sdr(0)
get_device_count()
get_device_name(0)
get_tuner_type()
set_center_frequency(92200000)
get_center_frequency()
get_usb_strings(0)
MessageRequester ("SDR Info", "SDR Count: "+ Str(counter.l) + Chr(10) + Chr(13) + "SDR Name: " + sdr_name.s, #PB_MessageRequester_Ok)
MessageRequester ("SDR Info", "SDR Type: "+ tuner_type.l, #PB_MessageRequester_Ok)
MessageRequester ("SDR Info", "Frequency: "+ myfreq.l +Chr(10) + Chr(13) + "Device: " + manufact.s + "/" + product.s + "/" + serial.s, #PB_MessageRequester_Ok)
close_sdr()
EndIf
End