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
|
//
// main.swift
// BladeRFIQ
//
// Created by Jacky Jack on 12/12/2024.
//
import Foundation
import ArgumentParser
import libbladerf
//set the command line arguments
struct CommandLineArgs: ParsableCommand {
@Argument var file:String = ""
@Option() var serial: UInt64 = 0
@Option(name:.shortAndLong) var samplerate: Int = 200000
@Option(name:.shortAndLong) var gain: Int = 0
@Option(name:.shortAndLong) var frequency: Int = 100000000
@Option(name:.shortAndLong) var nsamples: Int = 65536
@Flag(help:"Version \(software_version)") var version: Bool = false
@Flag(name: .shortAndLong) var verbose: Bool = false
}
let args = CommandLineArgs.parseOrExit()
if (args.version) {
print("AirSpyIQ version \(software_version)")
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()
}
var version: bladerf_version = bladerf_version()
bladerf_version(&version)
print(version.describe!)
var device: OpaquePointer?
var ret: Int32
ret = bladerf_open(&device,nil)
print("ret=\(ret)")
var actual_samplerate: UnsafeMutablePointer<bladerf_sample_rate> = .allocate(capacity: 1)
ret = bladerf_set_sample_rate(device, 0, UInt32(args.samplerate), actual_samplerate)
print("ret=\(ret)")
ret = bladerf_set_frequency(device, 0, UInt64(args.frequency))
print("ret=\(ret)")
let NUM_SAMPLES=8192
let SYNC_TIMEOUT=500
ret = bladerf_sync_config(device, bladerf_channel_layout(0), BLADERF_FORMAT_SC16_Q11, 16, UInt32(NUM_SAMPLES), 8, UInt32(SYNC_TIMEOUT))
print("ret=\(ret)")
ret = bladerf_enable_module(device, 0, true)
print("ret=\(ret)")
let buf_ptr = UnsafeMutableRawPointer.allocate(byteCount: NUM_SAMPLES, alignment: 1)
var total_samples:Int32=0
//var count=100
var done=false
while (!done) {
ret = bladerf_sync_rx(device, buf_ptr, UInt32(NUM_SAMPLES), nil, UInt32(SYNC_TIMEOUT))
if (ret != 0) {
print("RX failed: \(ret)")
done=true
} else {
print("Received \(NUM_SAMPLES) bytes")
if let file = fileHandle {
let convertedData = Data(bytes: buf_ptr, count: NUM_SAMPLES)
do {
try file.write(contentsOf: convertedData)
} catch {
print("Cant dump data to file")
}
}
total_samples += Int32(NUM_SAMPLES)
if total_samples > args.nsamples {
done=true
}
}
//count -= 1
print("ret=\(ret)")
}
ret = bladerf_enable_module(device, 0, false)
print("bladerf_enable_module ret=\(ret)")
bladerf_close(device)
|