Wrapper DLL RTL-SDR
Publié : mer. 24/janv./2024 18:12
Bonjour,
J'essaie de réaliser un wrapper de librtlsdr.dll pour contrôler un récepteur radio de type dongle USB SDR (Software Defined Radio)
De nombreuses applications open source existent concernant l'utilisation de ce type de récepteur, mais pour le moment je n'en ai pas encore vu en Purebasic.
J'ai pu tester avec succès un récepteur ADSB (réception mode synchrone, type terminal) en Free Pascal, initialement développé en Delphi XE, après la conversion des fichiers dans l'IDE Lazarus 3.0.
Ce projet intègre un fichier wrapper relativement simple concernant la dll d'accès au matériel. Cette DLL principale, associée à deux autres dépendantes (libusb-1.0.dll, libwinpthread-1.dll), est utilisée pour la majorité des applications SDR utilisant des récepteurs de type RTL-SDR.
Je souhaite réaliser un wrapper similaire pour Purebasic.
. Information sur RTL-SDR: https://www.rtl-sdr.com/about-rtl-sdr/
. Projet Osmocom: https://osmocom.org/projects/rtl-sdr/wiki
. Github sources des drivers: https://github.com/osmocom/rtl-sdr
. Exemple de récepteur ADSB en DELPHI/PASCAL: https://sourceforge.net/projects/rtl-ad ... -xe8-port/
. Dernières versions de drivers pour Windows: https://ftp.osmocom.org/binaries/windows/rtl-sdr/
A partir de plusieurs posts, lus dans les forums français et anglais, j'ai pu réalisé un framework de wrapper, mais je bute principalement sur l'usage des pointeurs pour avoir un ensemble fonctionnel.
D'autre part, j'ai pu tester et utiliser un wrapper pour la DLL de VLC dans une application de player simplifié Purebasic, mais ma compréhension des fichiers sources reste problèmatique ...
Voici le développement actuel pour matériel SDR. Le wrapper compile sans anomalie, mais il ne permet de traiter que 2 fonctions de la DLL, un comptage des clefs RTL-SDR insérées sur ports USB et la récupération du nom de clef.
Je suis preneur de toute information pour avancer sur ce sujet afin de débloquer les fonctions principales de contrôle SDR (fréquence, bande passante, gain, buffer de données,...).
Source wrapper Libsdr.pbi
Programme de test: FunctionCall.pb
J'essaie de réaliser un wrapper de librtlsdr.dll pour contrôler un récepteur radio de type dongle USB SDR (Software Defined Radio)
De nombreuses applications open source existent concernant l'utilisation de ce type de récepteur, mais pour le moment je n'en ai pas encore vu en Purebasic.
J'ai pu tester avec succès un récepteur ADSB (réception mode synchrone, type terminal) en Free Pascal, initialement développé en Delphi XE, après la conversion des fichiers dans l'IDE Lazarus 3.0.
Ce projet intègre un fichier wrapper relativement simple concernant la dll d'accès au matériel. Cette DLL principale, associée à deux autres dépendantes (libusb-1.0.dll, libwinpthread-1.dll), est utilisée pour la majorité des applications SDR utilisant des récepteurs de type RTL-SDR.
Je souhaite réaliser un wrapper similaire pour Purebasic.
. Information sur RTL-SDR: https://www.rtl-sdr.com/about-rtl-sdr/
. Projet Osmocom: https://osmocom.org/projects/rtl-sdr/wiki
. Github sources des drivers: https://github.com/osmocom/rtl-sdr
. Exemple de récepteur ADSB en DELPHI/PASCAL: https://sourceforge.net/projects/rtl-ad ... -xe8-port/
. Dernières versions de drivers pour Windows: https://ftp.osmocom.org/binaries/windows/rtl-sdr/
A partir de plusieurs posts, lus dans les forums français et anglais, j'ai pu réalisé un framework de wrapper, mais je bute principalement sur l'usage des pointeurs pour avoir un ensemble fonctionnel.
D'autre part, j'ai pu tester et utiliser un wrapper pour la DLL de VLC dans une application de player simplifié Purebasic, mais ma compréhension des fichiers sources reste problèmatique ...
Voici le développement actuel pour matériel SDR. Le wrapper compile sans anomalie, mais il ne permet de traiter que 2 fonctions de la DLL, un comptage des clefs RTL-SDR insérées sur ports USB et la récupération du nom de clef.
Je suis preneur de toute information pour avancer sur ce sujet afin de débloquer les fonctions principales de contrôle SDR (fréquence, bande passante, gain, buffer de données,...).
Source wrapper Libsdr.pbi
Code : Tout sélectionner
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 : Tout sélectionner
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