summaryrefslogtreecommitdiff
path: root/Radio/Utils/AirSpyIQ/main.swift
blob: a643d5fd1b92f47e8c8e4370f44661ee2b10a9d2 (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
//
//  main.swift
//  AirSpyIQ
//
//  Created by Jacky Jack on 02/12/2024.
//

import Foundation
import ArgumentParser
import libairspy

//set the command line arguments
struct CommandLineArgs: ParsableCommand {
    @Argument var file:String = ""
    @Option() var serial: UInt64 = 0
    @Option(name:.shortAndLong) var samplerate: Int = 3000000
    @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)
}

var libersion:airspy_lib_version_t = airspy_lib_version_t()

airspy_lib_version(&libersion)
print("libairspy \(libersion.major_version).\(libersion.minor_version).\(libersion.revision)")

//detect number of devices
var dev:UnsafeMutablePointer<airspy_device_t>? = .allocate(capacity: 1)

var ret:Int32
ret = airspy_init()
if (ret != AIRSPY_SUCCESS.rawValue) {
    print("Couldnt init library")
    exit(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()
}

var device:AirSpy?
do {
    device = try AirSpy()
} catch {
    print("Cant attach to device")
}

let sample_rates = device?.getSampleRates()

let _ = device?.setSampleRate(sample_rates![0])
print("sample rate \(sample_rates![0])")

var sdr_run = true
var total_samples:Int32=0
func rf_callback(_ transffer: UnsafeMutablePointer<airspy_transfer_t>?) -> Int32 {
    let t = transffer!.pointee
    let rx_bufffer = t.samples
    let sample_count = t.sample_count
    //default value
    
    if (t.sample_type != AIRSPY_SAMPLE_FLOAT32_IQ) {
        print("Unsupported sample type to write")
    }
    let bytes_to_write = sample_count*2*4 //IQ*float
    
    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")
        }
    }
    
    print("Got \(sample_count) samples")
    
    return 0
}

let _ = device?.VGAGain(5)
let _ = device?.mixerGain(5)
let _ = device?.lnaGain(1)

let _ = device?.startRx(rf_callback)

let _ = device?.setFrequency(UInt32(args.frequency))

sleep(1)
var count = 10
while ((device?.isStreaming() != AIRSPY_TRUE.rawValue)
&& (count>0) && (sdr_run)) {
    print("Streaming")
    sleep(1)
    count -= 1
}

let _ = device?.stopRx()

let _ = device?.close()

airspy_exit()