blob: 6fc75013a96c943be44bf76053a983ba640ee14e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
//
// main.swift
// AirSpyHFIQ
//
// Created by Jacky Jack on 02/12/2024.
//
import Foundation
import ArgumentParser
import libairspyhf
//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 = 192000
@Option(name:.shortAndLong) var gain: Int = 0
@Option(name:.shortAndLong) var frequency: Int = 100000000
@Option(name:.shortAndLong) var nsamples: Int = 1024
@Flag(help:"Version \(software_version)") var version: Bool = false
@Flag(name: .shortAndLong) var verbose: Bool = false
}
let args = CommandLineArgs.parseOrExit()
if (args.version) {
print("AirSpyHFIQ version \(software_version)")
exit(0)
}
var libersion:airspyhf_lib_version_t = airspyhf_lib_version_t()
airspyhf_lib_version(&libersion)
print("libairspyhf \(libersion.major_version).\(libersion.minor_version).\(libersion.revision)")
let ndev = airspyhf_list_devices(nil, 0)
print("Found \(ndev) AirSpyHF devices")
if ndev < 0 {
exit(0)
}
//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()
}
//will try the first one first
var device:AirSpyHF?
do {
device = try AirSpyHF(idx: 0)
} catch {
print("Cant attach to device")
}
let samplerates = device!.getSampleRates()
print(samplerates)
if (!samplerates.contains(UInt32(args.samplerate))) {
print("Unsupported sample rate")
exit(0)
}
//set sample rate
var fret:Int32 = -1
fret = device!.setSampleRate(UInt32(args.samplerate))
print("samplerate err=\(fret)")
fret = device!.setFreq(UInt32(args.frequency))
print("setfreq err=\(fret)")
fret = device!.setHfAgc(1)
print("sethfagc err=\(fret)")
fret = device!.setHfAgcThreshold(0)
print("agcthreshold err=\(fret)")
fret = device!.setHfLNA(1)
print("hflna err=\(fret)")
var sdr_run = true
var total_samples:Int32=0
func rf_callback(_ transffer: UnsafeMutablePointer<airspyhf_transfer_t>?) -> Int32 {
let sample_count = transffer?.pointee.sample_count
let rx_bufffer = transffer?.pointee.samples
// samples are = float * IQ (I and Q)
let bytes_to_write = sample_count! * 4 * 2
total_samples += sample_count!
if total_samples > args.nsamples {
sdr_run = false
return 0
}
if let file = fileHandle {
let convertedData = Data(bytes: rx_bufffer!, count: Int(bytes_to_write))
do {
try file.write(contentsOf: convertedData)
} catch {
print("Cant dump data to file")
}
}
return 0
}
let _ = device!.start(rf_callback)
let _ = device!.setFreq(UInt32(args.frequency))
var count=3
var old_total:Int32=1
while ((device!.isStreaming() == 1) && (sdr_run == true)) {
//print("Streaming ... total \(total_samples) bytes")
//check till the number of samples are written to file or aquired
sleep(1)
if (old_total == total_samples) {
count += 1
} else {
count = 0
}
old_total = total_samples
if (count > 10) {
break
}
}
let _ = device!.stop()
print("Closing device. Read \(total_samples) samples")
device!.close()
|