-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathNetSdrClient.cs
More file actions
165 lines (129 loc) · 5.47 KB
/
NetSdrClient.cs
File metadata and controls
165 lines (129 loc) · 5.47 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
using NetSdrClientApp.Messages;
using NetSdrClientApp.Networking;
using System;
//using System.Collections.Generic;
using System.Linq;
//using System.Text;
//using System.Threading;
//using System.Threading.Channels;
using System.Threading.Tasks;
using static NetSdrClientApp.Messages.NetSdrMessageHelper;
//using static System.Runtime.InteropServices.JavaScript.JSType;
namespace NetSdrClientApp
{
public class NetSdrClient
{
private readonly ITcpClient _tcpClient;
private readonly IUdpClient _udpClient;
public bool IQStarted { get; set; }
public NetSdrClient(ITcpClient tcpClient, IUdpClient udpClient)
{
_tcpClient = tcpClient;
_udpClient = udpClient;
_tcpClient.MessageReceived += _tcpClient_MessageReceived;
_udpClient.MessageReceived += _udpClient_MessageReceived;
}
public async Task ConnectAsync()
{
if (!_tcpClient.Connected)
{
_tcpClient.Connect();
var sampleRate = BitConverter.GetBytes((long)100000).Take(5).ToArray();
var automaticFilterMode = BitConverter.GetBytes((ushort)0).ToArray();
var adMode = new byte[] { 0x00, 0x03 };
//Host pre setup
var msgs = new List<byte[]>
{
NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.IQOutputDataSampleRate, sampleRate),
NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.RFFilter, automaticFilterMode),
NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.ADModes, adMode),
};
foreach (var msg in msgs)
{
await SendTcpRequest(msg);
}
}
}
public void Disconect()
{
_tcpClient.Disconnect();
}
public async Task StartIQAsync()
{
if (!_tcpClient.Connected)
{
Console.WriteLine("No active connection.");
return;
}
; var iqDataMode = (byte)0x80;
var start = (byte)0x02;
var fifo16bitCaptureMode = (byte)0x01;
var n = (byte)1;
var args = new[] { iqDataMode, start, fifo16bitCaptureMode, n };
var msg = NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.ReceiverState, args);
await SendTcpRequest(msg);
IQStarted = true;
_ = _udpClient.StartListeningAsync();
}
public async Task StopIQAsync()
{
if (!_tcpClient.Connected)
{
Console.WriteLine("No active connection.");
return;
}
var stop = (byte)0x01;
var args = new byte[] { 0, stop, 0, 0 };
var msg = NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.ReceiverState, args);
await SendTcpRequest(msg);
IQStarted = false;
_udpClient.StopListening();
}
public async Task ChangeFrequencyAsync(long hz, int channel)
{
var channelArg = (byte)channel;
var frequencyArg = BitConverter.GetBytes(hz).Take(5);
var args = new[] { channelArg }.Concat(frequencyArg).ToArray();
var msg = NetSdrMessageHelper.GetControlItemMessage(MsgTypes.SetControlItem, ControlItemCodes.ReceiverFrequency, args);
await SendTcpRequest(msg);
}
private void _udpClient_MessageReceived(object? sender, byte[] e)
{
NetSdrMessageHelper.TranslateMessage(e, out MsgTypes type, out ControlItemCodes code, out ushort sequenceNum, out byte[] body);
var samples = NetSdrMessageHelper.GetSamples(16, body);
Console.WriteLine($"Samples recieved: " + body.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}"));
using (FileStream fs = new FileStream("samples.bin", FileMode.Append, FileAccess.Write, FileShare.Read))
using (BinaryWriter sw = new BinaryWriter(fs))
{
foreach (var sample in samples)
{
sw.Write((short)sample); //write 16 bit per sample as configured
}
}
}
private TaskCompletionSource<byte[]>? responseTaskSource;
private async Task<byte[]?> SendTcpRequest(byte[] msg)
{
if (!_tcpClient.Connected)
{
Console.WriteLine("No active connection.");
return null;
}
responseTaskSource = new TaskCompletionSource<byte[]>(TaskCreationOptions.RunContinuationsAsynchronously);
var responseTask = responseTaskSource.Task;
await _tcpClient.SendMessageAsync(msg);
var resp = await responseTask;
return resp;
}
private void _tcpClient_MessageReceived(object? sender, byte[] e)
{
//TODO: add Unsolicited messages handling here
if (responseTaskSource != null)
{
responseTaskSource.SetResult(e);
responseTaskSource = null;
}
Console.WriteLine("Response recieved: " + e.Select(b => Convert.ToString(b, toBase: 16)).Aggregate((l, r) => $"{l} {r}"));
}
}
}