summaryrefslogtreecommitdiff
path: root/Radio
diff options
context:
space:
mode:
authorArturs Artamonovs <arturs.artamonovs@protonmail.com>2024-11-29 11:28:01 +0000
committerArturs Artamonovs <arturs.artamonovs@protonmail.com>2024-11-29 11:28:01 +0000
commit23fc08c8798d7c325a72fbee4175813efe4fe70f (patch)
tree0521f11441d267e60f7b9aa574c0defd43148b45 /Radio
parent77d1cfc27fb72e442b8d8e5cbe2be143723724e5 (diff)
downloadPrySDR-23fc08c8798d7c325a72fbee4175813efe4fe70f.tar.gz
PrySDR-23fc08c8798d7c325a72fbee4175813efe4fe70f.zip
RtlSdrIQ: can read samples from rtlsdr and dump those to file
Diffstat (limited to 'Radio')
-rw-r--r--Radio/HW/RtlSdr/r820/r820.swift9
-rw-r--r--Radio/Utils/RtlSdrIQ/main.swift77
2 files changed, 76 insertions, 10 deletions
diff --git a/Radio/HW/RtlSdr/r820/r820.swift b/Radio/HW/RtlSdr/r820/r820.swift
index 3f6d4a9..4c8859f 100644
--- a/Radio/HW/RtlSdr/r820/r820.swift
+++ b/Radio/HW/RtlSdr/r820/r820.swift
@@ -189,8 +189,13 @@ public class R820Tuner {
/// - len: input buffer length
/// - n_read: number of bytes received
/// - Returns: -1 if there is no device, 0 on success or one of LIBUSB error
- /// LIBUSB_ERROR_TIMEOUT, LIBUSB_ERROR_PIPE,LIBUSB_ERROR_OVERFLOW
- /// LIBUSB_ERROR_NO_DEVICE, LIBUSB_ERROR_BUSY LIBUSB_ERROR_INVALID_PARAM
+ /// on success, the number of bytes actually transferred
+ /// LIBUSB_ERROR_TIMEOUT if the transfer timed out
+ /// LIBUSB_ERROR_PIPE if the control request was not supported by the device
+ /// LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ /// LIBUSB_ERROR_BUSY if called from event handling context
+ /// LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than the operating system and/or hardware can support (see Transfer length limitations)
+ /// another LIBUSB_ERROR code on other failures
///
func readSync(buf:UnsafeMutableRawPointer?,len: Int32,n_read:UnsafeMutablePointer<Int32>?) -> Int32 {
return rtlsdr_read_sync(dev, buf, len, n_read);
diff --git a/Radio/Utils/RtlSdrIQ/main.swift b/Radio/Utils/RtlSdrIQ/main.swift
index 20573a9..c3d5732 100644
--- a/Radio/Utils/RtlSdrIQ/main.swift
+++ b/Radio/Utils/RtlSdrIQ/main.swift
@@ -9,13 +9,15 @@ import Foundation
import libr820
import ArgumentParser
+let NUM_SAMPLES=1024
+
//set the command line arguments
struct CommandLineArgs: ParsableCommand {
@Argument var file:String = ""
@Option(name:.shortAndLong) var device_idx: Int = 0
@Option(name:.shortAndLong) var samplerate: Int = 2048000
@Option(name:.shortAndLong) var gain: Int = 0
- @Option(name: .shortAndLong) var frequency: Int = 100000000
+ @Option(name:.shortAndLong) var frequency: Int = 100000000
@Option(name:.shortAndLong) var nsamples: Int = 1024
@Flag(name: .shortAndLong) var verbose: Bool = false
@Flag(name: .shortAndLong) var async: Bool = false
@@ -40,6 +42,7 @@ if (args.device_idx < 0) || (args.device_idx > count-1) {
let device = R820Tuner()
device.open(index: UInt32(args.device_idx))
+//prepare dongle to receive some data
let _ = device.setSampleRate(samplerate: UInt32(args.samplerate))
let _ = device.setCenterFreq(freq: UInt32(args.frequency))
if args.gain == 0 {
@@ -48,15 +51,73 @@ if args.gain == 0 {
let _ = device.setTunerGain(gain: Int32(args.gain))
}
let _ = device.resetBuffer()
-let buf_ptr = UnsafeMutableRawPointer.allocate(byteCount: args.nsamples, alignment: 1)
+
+//prepare file descriptor if args specify that
+let currentExePath = Process().currentDirectoryPath
+var fileDescriptor = FileManager.default
+var fileArgUrl:URL?
+var fileHandle:FileHandle?
+if args.file != "" {
+ fileArgUrl = URL(fileURLWithFileSystemRepresentation: args.file, isDirectory: false, relativeTo: nil)
+ if (checkIfFileExists(args.file)) {
+ //remove file
+ do {
+ try fileDescriptor.removeItem(atPath: fileArgUrl!.path())
+ } catch {
+ print("Couldn't delete file that exists \(fileArgUrl!.path())")
+ }
+ }
+
+ //create file
+ fileDescriptor.createFile(atPath: fileArgUrl!.path(), contents: nil)
+ try fileHandle = FileHandle(forWritingTo: fileArgUrl!)
+ try fileHandle?.seekToEnd()
+}
+
+//prepare loop buffers to process data
+let buf_ptr = UnsafeMutableRawPointer.allocate(byteCount: NUM_SAMPLES, alignment: 1)
var nbytes:Int32 = 0
-let r = device.readSync(buf: buf_ptr, len: Int32(args.nsamples), n_read: &nbytes)
-print("Reading samples return code (\(r)) read \(nbytes) bytes\n")
-for i in 0..<args.nsamples {
- let offsetByte = buf_ptr + i
- print("\(String(format:"%02hhX ",offsetByte.load(as: UInt8.self)))",terminator: "")
+var total_bytes:Int32 = 0
+if (args.async == false) {
+ while (total_bytes < args.nsamples) {
+ let ret = device.readSync(buf: buf_ptr, len: Int32(NUM_SAMPLES), n_read: &nbytes)
+ if ret<0 {
+ print("data read sync returned <0 = \(ret)")
+ break;
+ }
+ print("Reading samples read \(nbytes) bytes")
+ total_bytes += nbytes
+
+ let dataU8 = buf_ptr.bindMemory(to: UInt8.self, capacity: NUM_SAMPLES)
+ let bufferU8 = UnsafeBufferPointer(start: dataU8, count: NUM_SAMPLES)
+ let convertedData = Data(bufferU8)
+ /*for i in 0..<Int(nbytes) {
+ let offsetByte = buf_ptr + i
+ print("\(String(format:"%02hhX ",offsetByte.load(as: UInt8.self)))",terminator: "")
+ }*/
+ if (args.verbose) {
+ for i in 0..<bufferU8.count {
+ print("\(String(format: "%02hhX", bufferU8[i]))", terminator: "")
+ }
+ }
+
+ //dump data to file
+
+ if let file = fileHandle {
+ //print(convertedData)
+ do {
+ //try convertedData.write(to: fileUrl)
+ try file.write(contentsOf: convertedData)
+ } catch {
+ print("Cant dump data to file")
+ }
+ }
+ }
+} else {
+ print("ASYNC not implemented")
}
-device.close()
+//clean after use all structures
+device.close()
buf_ptr.deallocate()