├── README.md ├── SDRSharp.HRFTCP.dll ├── SDRSharp.HackRF.dll ├── how-to-install.txt └── src ├── HRFTCP ├── HRFTCPIO.cs ├── HRFTCPSettings.Designer.cs ├── HRFTCPSettings.cs ├── HRFTCPSettings.resx ├── Properties │ └── AssemblyInfo.cs └── SDRSharp.HRFTCP.csproj └── HackRF ├── HackRFControllerDialog.Designer.cs ├── HackRFControllerDialog.cs ├── HackRFControllerDialog.resx ├── HackRFDevice.cs ├── HackRFIO.cs ├── NativeMethods.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx └── SDRSharp.HackRF.csproj /README.md: -------------------------------------------------------------------------------- 1 | sdrsharp_hackrf 2 | =============== 3 | 4 | SDR# HackRF plugin beta 5 | 6 | SDR# is developped by Youssef Touil and available on 7 | http://sdrsharp.com 8 | 9 | SDR# Source code: 10 | http://sdrsharp.com/index.php/source-code 11 | 12 | https://subversion.assembla.com/svn/sdrsharp 13 | 14 | 15 | Required libs: 16 | 17 | 1) LibusbX 1.0.15 (or later but tested only with this one) 18 | http://sourceforge.net/projects/libusbx/files/releases/1.0.15/binaries/libusbx-1.0.15-win.7z/download 19 | Use the file libusbx-1.0.15-win.7z\libusbx-1.0.15\MinGW32\dll\libusb-1.0.dll 20 | 21 | 2) Install MinGW (especially to rebuild libhackrf and for pthreadGC2.dll) 22 | 23 | 3) libhackrf.dll (from https://github.com/mossmann/hackrf/tree/master/host/libhackrf) 24 | To be built in directory hackrf/host/libhackrf/src 25 | 26 | 4) Install SDRSharp latest trunk from http://sdrsharp.com/downloads/sdr-install.zip 27 | Install it in for example sdrsharp_hackrf\bin\sdrsharp directory 28 | 29 | How to build and use SDR# + HackRF plugin: 30 | 31 | 1) Checkout sdrsharp from https://subversion.assembla.com/svn/sdrsharp 32 | 33 | 2) Copy sdrsharp_hackrf\src\HackRF directory and files to sdrsharp_hackrf\bin\sdrsharp\ 34 | 35 | 3) Launch SDRSharp.sln and add project HackRF 36 | 37 | 4) Choose Release and x86 and Clean Solution then Rebuild Solution 38 | -> Now all is built in directory sdrsharp\trunk\Release 39 | 40 | 5) Copy sdrsharp\trunk\Release\* (except *.pdb/manifest) to sdrsharp_hackrf\bin\sdrsharp\* (from Install SDRSharp) 41 | 42 | 6) Edit file sdrsharp_hackrf\bin\sdrsharp\SDRSharp.exe.config and add the following line after line frontendPlugins: ``` 43 | ``` 44 | 45 | 7) Extract libusbx-1.0.15-win.7z\libusbx-1.0.15\MinGW32\dll\libusb-1.0.dll to sdrsharp_hackrf\bin\sdrsharp\ 46 | 47 | 8) Copy hackrf/host/libhackrf/src/libhackrf.dll to sdrsharp_hackrf\bin\sdrsharp\ 48 | 49 | 9) Copy from mingw/bin/pthreadGC2.dll to sdrsharp_hackrf\bin\sdrsharp\ 50 | 51 | -------------------------------------------------------------------------------- /SDRSharp.HRFTCP.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zefie/sdrsharp_hackrf/094211279223427ac52850941115519a36e1a092/SDRSharp.HRFTCP.dll -------------------------------------------------------------------------------- /SDRSharp.HackRF.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zefie/sdrsharp_hackrf/094211279223427ac52850941115519a36e1a092/SDRSharp.HackRF.dll -------------------------------------------------------------------------------- /how-to-install.txt: -------------------------------------------------------------------------------- 1 | 1) Extract SDRSharp.HackRF.dll and SDRSharp.HRFTCP.dll to your SDRSharp install folder 2 | 3 | 2) Open SDRSharp.exe.Config and find the line "" 4 | 5 | 3) After the line "", but before "", add this line: 6 | 7 | 8 | 9 | 4) Save and close SDRSharp.exe.Config 10 | 11 | Notes: 12 | 1) You need to have compiled hackrf-tools for windows, or you can download my compiled copy from my website. 13 | http://the.midnightchannel.net/sdr/SDRSharp_Plugins/zefie/SDRSharp.HackRF.ZefieMod/hackrf-tools.zip 14 | 15 | 2) You will need to copy the 32-bit versions of libhackrf.dll and pthreadVC2.dll into the SDRSharp Program Folder. 16 | You can obtain these from either my copy of the hackrf-tools above, or, if you compiled it yourself, you 17 | should have both files in your development folder. libhackrf.dll may have been compiled as "hackrf.dll", 18 | you can simply rename it. 19 | 20 | 3) If you are using my copy of hackrf-tools above, you may need to install the 21 | Microsoft Visual C++ 2012 Redistributable, which you can get from Microsoft here: 22 | http://www.microsoft.com/en-us/download/details.aspx?id=30679 -------------------------------------------------------------------------------- /src/HRFTCP/HRFTCPIO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Net.Sockets; 4 | using System.Threading; 5 | using SDRSharp.Radio; 6 | 7 | namespace SDRSharp.HRFTCP 8 | { 9 | public unsafe class HRFTCPIO : IFrontendController, IDisposable 10 | { 11 | private const int DongleInfoLength = 12; 12 | private const string DefaultHost = "127.0.0.1"; 13 | private const short DefaultPort = 1234; 14 | private const uint DefaultFrequency = 100000000; 15 | private readonly static int _bufferSize = Utils.GetIntSetting("HRFTCPBufferLength", 32 * 1024); 16 | 17 | #region Native rtl_tcp Commands 18 | 19 | private const byte CMD_SET_FREQ = 0x1; 20 | private const byte CMD_SET_SAMPLE_RATE = 0x2; 21 | private const byte CMD_SET_TUNER_GAIN_MODE = 0x3; 22 | private const byte CMD_SET_GAIN = 0x4; 23 | private const byte CMD_SET_FREQ_COR = 0x5; 24 | private const byte CMD_SET_AGC_MODE = 0x8; 25 | private const byte CMD_SET_TUNER_GAIN_INDEX = 0xd; 26 | private const byte CMD_SET_TUNER_AMP = 0xb0; 27 | private const byte CMD_SET_TUNER_VGA_GAIN = 0xb1; 28 | private const byte CMD_SET_TUNER_LNA_GAIN = 0xb2; 29 | private const byte CMD_SET_TUNER_IF = 0xb3; 30 | 31 | #endregion 32 | 33 | private static readonly float* _lutPtr; 34 | private static readonly UnsafeBuffer _lutBuffer = UnsafeBuffer.Create(256, sizeof(float)); 35 | 36 | private long _frequency = DefaultFrequency; 37 | private double _sampleRate; 38 | private string _host; 39 | private int _port; 40 | private bool _useTunerAMP; 41 | private int _tunerGainLNA; 42 | private int _tunerGainVGA; 43 | private int _tunerIF; 44 | private SamplesAvailableDelegate _callback; 45 | private Thread _sampleThread; 46 | private UnsafeBuffer _iqBuffer; 47 | private Complex* _iqBufferPtr; 48 | private Socket _s; 49 | private readonly byte [] _cmdBuffer = new byte[5]; 50 | private readonly HRFTCPSettings _gui; 51 | 52 | #region Public Properties 53 | 54 | public bool IsStreaming 55 | { 56 | get { return _sampleThread != null; } 57 | } 58 | 59 | public bool IsSoundCardBased 60 | { 61 | get { return false; } 62 | } 63 | 64 | public string SoundCardHint 65 | { 66 | get { return string.Empty; } 67 | } 68 | 69 | public void ShowSettingGUI(IWin32Window parent) 70 | { 71 | _gui.Show(); 72 | } 73 | 74 | public void HideSettingGUI() 75 | { 76 | _gui.Hide(); 77 | } 78 | 79 | public double Samplerate 80 | { 81 | get { return _sampleRate; } 82 | set 83 | { 84 | _sampleRate = value; 85 | SendCommand(CMD_SET_SAMPLE_RATE, (uint) _sampleRate); 86 | } 87 | } 88 | 89 | public long Frequency 90 | { 91 | get { return _frequency; } 92 | set 93 | { 94 | _frequency = value; 95 | SendCommand(CMD_SET_FREQ, (ulong)_frequency); 96 | } 97 | } 98 | 99 | public bool UseTunerAMP 100 | { 101 | get { return _useTunerAMP; } 102 | set 103 | { 104 | _useTunerAMP = value; 105 | if (IsStreaming) 106 | { 107 | SendCommand(CMD_SET_TUNER_AMP, _useTunerAMP ? 1 : 0); 108 | } 109 | } 110 | } 111 | 112 | public int tunerGainVGA 113 | { 114 | get { return _tunerGainVGA; } 115 | set 116 | { 117 | _tunerGainVGA = value; 118 | if (IsStreaming) 119 | { 120 | SendCommand(CMD_SET_TUNER_VGA_GAIN, (uint)_tunerGainVGA); 121 | } 122 | } 123 | } 124 | public int tunerGainLNA 125 | { 126 | get { return _tunerGainLNA; } 127 | set 128 | { 129 | _tunerGainLNA = value; 130 | if (IsStreaming) 131 | { 132 | SendCommand(CMD_SET_TUNER_LNA_GAIN, (uint)_tunerGainLNA); 133 | } 134 | } 135 | } 136 | public int tunerIF 137 | { 138 | get { return _tunerIF; } 139 | set 140 | { 141 | _tunerIF = value; 142 | if (IsStreaming) 143 | { 144 | SendCommand(CMD_SET_TUNER_IF, (ulong)_tunerIF); 145 | } 146 | } 147 | } 148 | 149 | #endregion 150 | 151 | static HRFTCPIO() 152 | { 153 | _lutPtr = (float*) _lutBuffer; 154 | 155 | const float scale = 1.0f / 127.5f; 156 | for (var i = 0; i < 256; i++) 157 | { 158 | _lutPtr[i] = (i - 127.5f) * scale; 159 | } 160 | } 161 | 162 | public HRFTCPIO() 163 | { 164 | _gui = new HRFTCPSettings(this); 165 | _gui.Hostname = Utils.GetStringSetting("HRFTCPHost", DefaultHost); 166 | _gui.Port = Utils.GetIntSetting("HRFTCPPort", DefaultPort); 167 | _frequency = DefaultFrequency; 168 | } 169 | 170 | ~HRFTCPIO() 171 | { 172 | Dispose(); 173 | } 174 | 175 | public void Dispose() 176 | { 177 | if (_iqBuffer != null) 178 | { 179 | _iqBuffer.Dispose(); 180 | _iqBuffer = null; 181 | _iqBufferPtr = null; 182 | } 183 | if (_gui != null) 184 | { 185 | _gui.Dispose(); 186 | } 187 | GC.SuppressFinalize(this); 188 | } 189 | 190 | public void Open() 191 | { 192 | } 193 | 194 | public void Close() 195 | { 196 | if (_s != null) 197 | { 198 | _s.Close(); 199 | _s = null; 200 | } 201 | } 202 | 203 | public void Start(SamplesAvailableDelegate callback) 204 | { 205 | _callback = callback; 206 | _host = _gui.Hostname; 207 | _port = _gui.Port; 208 | _s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 209 | _s.NoDelay = true; 210 | _s.Connect(_host, _port); 211 | 212 | var dongleInfo = new byte[DongleInfoLength]; 213 | 214 | var length = _s.Receive(dongleInfo, 0, DongleInfoLength, SocketFlags.None); 215 | if (length > 0) 216 | { 217 | ParseDongleInfo(dongleInfo); 218 | } 219 | 220 | SendCommand(CMD_SET_SAMPLE_RATE, (uint)_sampleRate); 221 | SendCommand(CMD_SET_FREQ, (uint)_frequency); 222 | SendCommand(CMD_SET_TUNER_AMP, (uint)(_useTunerAMP ? 1 : 0)); 223 | SendCommand(CMD_SET_TUNER_VGA_GAIN, _tunerGainVGA); 224 | SendCommand(CMD_SET_TUNER_LNA_GAIN, _tunerGainLNA); 225 | SendCommand(CMD_SET_TUNER_IF, _tunerIF); 226 | 227 | _sampleThread = new Thread(RecieveSamples); 228 | _sampleThread.Start(); 229 | 230 | Utils.SaveSetting("HRFTCPHost", _host); 231 | Utils.SaveSetting("HRFTCPPort", _port); 232 | } 233 | 234 | public void Stop() 235 | { 236 | Close(); 237 | if (_sampleThread != null) 238 | { 239 | _sampleThread.Join(); 240 | _sampleThread = null; 241 | } 242 | _callback = null; 243 | } 244 | 245 | #region Private Methods 246 | 247 | private void ParseDongleInfo(byte[] buffer) 248 | { 249 | return; 250 | } 251 | 252 | public bool SendCommand(byte cmd, byte[] val) 253 | { 254 | if (_s == null || val.Length < 4) 255 | { 256 | return false; 257 | } 258 | 259 | _cmdBuffer[0] = cmd; 260 | _cmdBuffer[1] = val[3]; //Network byte order 261 | _cmdBuffer[2] = val[2]; 262 | _cmdBuffer[3] = val[1]; 263 | _cmdBuffer[4] = val[0]; 264 | try 265 | { 266 | _s.Send(_cmdBuffer); 267 | } 268 | catch 269 | { 270 | return false; 271 | } 272 | return true; 273 | } 274 | 275 | private void SendCommand(byte cmd, UInt64 val) 276 | { 277 | var valBytes = BitConverter.GetBytes(val); 278 | SendCommand(cmd, valBytes); 279 | } 280 | 281 | private void SendCommand(byte cmd, UInt32 val) 282 | { 283 | var valBytes = BitConverter.GetBytes(val); 284 | SendCommand(cmd, valBytes); 285 | } 286 | 287 | private void SendCommand(byte cmd, Int32 val) 288 | { 289 | var valBytes = BitConverter.GetBytes(val); 290 | SendCommand(cmd, valBytes); 291 | } 292 | 293 | #endregion 294 | 295 | #region Worker Thread 296 | 297 | private void RecieveSamples() 298 | { 299 | var recBuffer = new byte[_bufferSize]; 300 | var recUnsafeBuffer = UnsafeBuffer.Create(recBuffer); 301 | var recPtr = (byte*) recUnsafeBuffer; 302 | _iqBuffer = UnsafeBuffer.Create(_bufferSize / 2, sizeof(Complex)); 303 | _iqBufferPtr = (Complex*) _iqBuffer; 304 | var offs = 0; 305 | while (_s != null && _s.Connected) 306 | { 307 | try 308 | { 309 | var bytesRec = _s.Receive(recBuffer, offs, _bufferSize - offs, SocketFlags.None); 310 | var totalBytes = offs + bytesRec; 311 | offs = totalBytes % 2; //Need to correctly handle the hypothetical case where we somehow get an odd number of bytes 312 | ProcessSamples(recPtr, totalBytes - offs); //This might work. 313 | if (offs == 1) 314 | { 315 | recPtr[0] = recPtr[totalBytes - 1]; 316 | } 317 | } 318 | catch 319 | { 320 | Close(); 321 | break; 322 | } 323 | } 324 | } 325 | 326 | private void ProcessSamples(byte* rawPtr, int len) 327 | { 328 | var sampleCount = len / 2; 329 | 330 | var ptr = _iqBufferPtr; 331 | for (var i = 0; i < sampleCount; i++) 332 | { 333 | ptr->Imag = _lutPtr[*rawPtr++]; 334 | ptr->Real = _lutPtr[*rawPtr++]; 335 | ptr++; 336 | } 337 | if (_callback != null) 338 | { 339 | _callback(this, _iqBufferPtr, sampleCount); 340 | } 341 | } 342 | 343 | #endregion 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /src/HRFTCP/HRFTCPSettings.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SDRSharp.HRFTCP 2 | { 3 | partial class HRFTCPSettings 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.hostBox = new System.Windows.Forms.TextBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.tunerAmpCheckBox = new System.Windows.Forms.CheckBox(); 36 | this.label8 = new System.Windows.Forms.Label(); 37 | this.samplerateComboBox = new System.Windows.Forms.ComboBox(); 38 | this.refreshTimer = new System.Windows.Forms.Timer(this.components); 39 | this.portNumberUpDown = new System.Windows.Forms.NumericUpDown(); 40 | this.IFLabel = new System.Windows.Forms.Label(); 41 | this.label5 = new System.Windows.Forms.Label(); 42 | this.tunerIFFreq = new System.Windows.Forms.TrackBar(); 43 | this.gainVGALabel = new System.Windows.Forms.Label(); 44 | this.label6 = new System.Windows.Forms.Label(); 45 | this.tunerVGAGainTrackBar = new System.Windows.Forms.TrackBar(); 46 | this.gainLNALabel = new System.Windows.Forms.Label(); 47 | this.label3 = new System.Windows.Forms.Label(); 48 | this.tunerLNAGainTrackBar = new System.Windows.Forms.TrackBar(); 49 | ((System.ComponentModel.ISupportInitialize)(this.portNumberUpDown)).BeginInit(); 50 | ((System.ComponentModel.ISupportInitialize)(this.tunerIFFreq)).BeginInit(); 51 | ((System.ComponentModel.ISupportInitialize)(this.tunerVGAGainTrackBar)).BeginInit(); 52 | ((System.ComponentModel.ISupportInitialize)(this.tunerLNAGainTrackBar)).BeginInit(); 53 | this.SuspendLayout(); 54 | // 55 | // hostBox 56 | // 57 | this.hostBox.Location = new System.Drawing.Point(119, 12); 58 | this.hostBox.Name = "hostBox"; 59 | this.hostBox.Size = new System.Drawing.Size(138, 20); 60 | this.hostBox.TabIndex = 0; 61 | this.hostBox.Text = "127.0.0.1"; 62 | // 63 | // label1 64 | // 65 | this.label1.AutoSize = true; 66 | this.label1.Location = new System.Drawing.Point(7, 12); 67 | this.label1.Name = "label1"; 68 | this.label1.Size = new System.Drawing.Size(29, 13); 69 | this.label1.TabIndex = 4; 70 | this.label1.Text = "Host"; 71 | // 72 | // label2 73 | // 74 | this.label2.AutoSize = true; 75 | this.label2.Location = new System.Drawing.Point(7, 38); 76 | this.label2.Name = "label2"; 77 | this.label2.Size = new System.Drawing.Size(26, 13); 78 | this.label2.TabIndex = 5; 79 | this.label2.Text = "Port"; 80 | // 81 | // tunerAmpCheckBox 82 | // 83 | this.tunerAmpCheckBox.AutoSize = true; 84 | this.tunerAmpCheckBox.Checked = true; 85 | this.tunerAmpCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 86 | this.tunerAmpCheckBox.Location = new System.Drawing.Point(10, 111); 87 | this.tunerAmpCheckBox.Name = "tunerAmpCheckBox"; 88 | this.tunerAmpCheckBox.Size = new System.Drawing.Size(78, 17); 89 | this.tunerAmpCheckBox.TabIndex = 5; 90 | this.tunerAmpCheckBox.Text = "Tuner Amp"; 91 | this.tunerAmpCheckBox.UseVisualStyleBackColor = true; 92 | this.tunerAmpCheckBox.CheckedChanged += new System.EventHandler(this.tunerAmpCheckBox_CheckedChanged); 93 | // 94 | // label8 95 | // 96 | this.label8.AutoSize = true; 97 | this.label8.Location = new System.Drawing.Point(7, 66); 98 | this.label8.Name = "label8"; 99 | this.label8.Size = new System.Drawing.Size(68, 13); 100 | this.label8.TabIndex = 37; 101 | this.label8.Text = "Sample Rate"; 102 | // 103 | // samplerateComboBox 104 | // 105 | this.samplerateComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 106 | this.samplerateComboBox.FormattingEnabled = true; 107 | this.samplerateComboBox.Items.AddRange(new object[] { 108 | "20.0 MSPS (334mbps, USB upper limit)", 109 | "19.5 MSPS (325mbps)", 110 | "19.0 MSPS (317mbps)", 111 | "18.5 MSPS (308mbps)", 112 | "18.0 MSPS (300mbps)", 113 | "17.5 MSPS (292mbps)", 114 | "17.0 MSPS (284mbps)", 115 | "16.0 MSPS (267mbps)", 116 | "14.0 MSPS (234mbps)", 117 | "12.0 MSPS (200mbps)", 118 | "10.0 MSPS (167mbps)", 119 | "8.0 MSPS (134mbps)", 120 | "6.0 MSPS (100mbps)", 121 | "5.8 MSPS ( 97mbps)", 122 | "5.0 MSPS ( 84mbps)", 123 | "4.0 MSPS ( 67mbps)", 124 | "3.2 MSPS ( 54mbps)", 125 | "2.8 MSPS ( 47mbps)", 126 | "2.4 MSPS ( 40mbps)", 127 | "2.048 MSPS ( 34mbps)", 128 | "1.92 MSPS ( 32mbps)", 129 | "1.8 MSPS ( 30mbps)", 130 | "1.4 MSPS ( 24mbps)", 131 | "0.6 MSPS ( 10mbps)", 132 | "0.3 MSPS ( 5mbps)"}); 133 | this.samplerateComboBox.Location = new System.Drawing.Point(10, 84); 134 | this.samplerateComboBox.Name = "samplerateComboBox"; 135 | this.samplerateComboBox.Size = new System.Drawing.Size(247, 21); 136 | this.samplerateComboBox.TabIndex = 3; 137 | this.samplerateComboBox.SelectedIndexChanged += new System.EventHandler(this.samplerateComboBox_SelectedIndexChanged); 138 | // 139 | // refreshTimer 140 | // 141 | this.refreshTimer.Interval = 1000; 142 | this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick); 143 | // 144 | // portNumberUpDown 145 | // 146 | this.portNumberUpDown.Location = new System.Drawing.Point(119, 38); 147 | this.portNumberUpDown.Maximum = new decimal(new int[] { 148 | 65535, 149 | 0, 150 | 0, 151 | 0}); 152 | this.portNumberUpDown.Name = "portNumberUpDown"; 153 | this.portNumberUpDown.Size = new System.Drawing.Size(138, 20); 154 | this.portNumberUpDown.TabIndex = 2; 155 | this.portNumberUpDown.Value = new decimal(new int[] { 156 | 1234, 157 | 0, 158 | 0, 159 | 0}); 160 | // 161 | // IFLabel 162 | // 163 | this.IFLabel.Location = new System.Drawing.Point(188, 232); 164 | this.IFLabel.Name = "IFLabel"; 165 | this.IFLabel.Size = new System.Drawing.Size(68, 14); 166 | this.IFLabel.TabIndex = 47; 167 | this.IFLabel.Text = "2400MHz"; 168 | this.IFLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 169 | // 170 | // label5 171 | // 172 | this.label5.AutoSize = true; 173 | this.label5.Location = new System.Drawing.Point(9, 232); 174 | this.label5.Name = "label5"; 175 | this.label5.Size = new System.Drawing.Size(118, 13); 176 | this.label5.TabIndex = 46; 177 | this.label5.Text = "Intermediate Frequency"; 178 | // 179 | // tunerIFFreq 180 | // 181 | this.tunerIFFreq.Location = new System.Drawing.Point(0, 248); 182 | this.tunerIFFreq.Maximum = 300; 183 | this.tunerIFFreq.Name = "tunerIFFreq"; 184 | this.tunerIFFreq.Size = new System.Drawing.Size(267, 45); 185 | this.tunerIFFreq.TabIndex = 45; 186 | this.tunerIFFreq.Scroll += new System.EventHandler(this.tunerIFFreq_Scroll); 187 | // 188 | // gainVGALabel 189 | // 190 | this.gainVGALabel.Location = new System.Drawing.Point(188, 181); 191 | this.gainVGALabel.Name = "gainVGALabel"; 192 | this.gainVGALabel.Size = new System.Drawing.Size(68, 14); 193 | this.gainVGALabel.TabIndex = 44; 194 | this.gainVGALabel.Text = "1000dB"; 195 | this.gainVGALabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 196 | // 197 | // label6 198 | // 199 | this.label6.AutoSize = true; 200 | this.label6.Location = new System.Drawing.Point(9, 181); 201 | this.label6.Name = "label6"; 202 | this.label6.Size = new System.Drawing.Size(54, 13); 203 | this.label6.TabIndex = 43; 204 | this.label6.Text = "VGA Gain"; 205 | // 206 | // tunerVGAGainTrackBar 207 | // 208 | this.tunerVGAGainTrackBar.Location = new System.Drawing.Point(0, 197); 209 | this.tunerVGAGainTrackBar.Maximum = 31; 210 | this.tunerVGAGainTrackBar.Name = "tunerVGAGainTrackBar"; 211 | this.tunerVGAGainTrackBar.Size = new System.Drawing.Size(267, 45); 212 | this.tunerVGAGainTrackBar.TabIndex = 42; 213 | this.tunerVGAGainTrackBar.Scroll += new System.EventHandler(this.tunerVGAGainTrackBar_Scroll); 214 | // 215 | // gainLNALabel 216 | // 217 | this.gainLNALabel.Location = new System.Drawing.Point(188, 130); 218 | this.gainLNALabel.Name = "gainLNALabel"; 219 | this.gainLNALabel.Size = new System.Drawing.Size(68, 14); 220 | this.gainLNALabel.TabIndex = 41; 221 | this.gainLNALabel.Text = "1000dB"; 222 | this.gainLNALabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 223 | // 224 | // label3 225 | // 226 | this.label3.AutoSize = true; 227 | this.label3.Location = new System.Drawing.Point(9, 130); 228 | this.label3.Name = "label3"; 229 | this.label3.Size = new System.Drawing.Size(53, 13); 230 | this.label3.TabIndex = 40; 231 | this.label3.Text = "LNA Gain"; 232 | // 233 | // tunerLNAGainTrackBar 234 | // 235 | this.tunerLNAGainTrackBar.Location = new System.Drawing.Point(0, 146); 236 | this.tunerLNAGainTrackBar.Maximum = 5; 237 | this.tunerLNAGainTrackBar.Name = "tunerLNAGainTrackBar"; 238 | this.tunerLNAGainTrackBar.Size = new System.Drawing.Size(267, 45); 239 | this.tunerLNAGainTrackBar.TabIndex = 39; 240 | this.tunerLNAGainTrackBar.Scroll += new System.EventHandler(this.tunerLNAGainTrackBar_Scroll); 241 | // 242 | // HRFTCPSettings 243 | // 244 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 245 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 246 | this.ClientSize = new System.Drawing.Size(266, 288); 247 | this.Controls.Add(this.IFLabel); 248 | this.Controls.Add(this.label5); 249 | this.Controls.Add(this.tunerIFFreq); 250 | this.Controls.Add(this.gainVGALabel); 251 | this.Controls.Add(this.label6); 252 | this.Controls.Add(this.tunerVGAGainTrackBar); 253 | this.Controls.Add(this.gainLNALabel); 254 | this.Controls.Add(this.label3); 255 | this.Controls.Add(this.tunerLNAGainTrackBar); 256 | this.Controls.Add(this.portNumberUpDown); 257 | this.Controls.Add(this.label8); 258 | this.Controls.Add(this.samplerateComboBox); 259 | this.Controls.Add(this.tunerAmpCheckBox); 260 | this.Controls.Add(this.label2); 261 | this.Controls.Add(this.label1); 262 | this.Controls.Add(this.hostBox); 263 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 264 | this.MaximizeBox = false; 265 | this.MinimizeBox = false; 266 | this.Name = "HRFTCPSettings"; 267 | this.ShowInTaskbar = false; 268 | this.Text = "HackRF-TCP Settings"; 269 | this.TopMost = true; 270 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HRFTCPSettings_FormClosing); 271 | this.VisibleChanged += new System.EventHandler(this.HRFTCPSettings_VisibleChanged); 272 | ((System.ComponentModel.ISupportInitialize)(this.portNumberUpDown)).EndInit(); 273 | ((System.ComponentModel.ISupportInitialize)(this.tunerIFFreq)).EndInit(); 274 | ((System.ComponentModel.ISupportInitialize)(this.tunerVGAGainTrackBar)).EndInit(); 275 | ((System.ComponentModel.ISupportInitialize)(this.tunerLNAGainTrackBar)).EndInit(); 276 | this.ResumeLayout(false); 277 | this.PerformLayout(); 278 | 279 | } 280 | 281 | #endregion 282 | 283 | private System.Windows.Forms.TextBox hostBox; 284 | private System.Windows.Forms.Label label1; 285 | private System.Windows.Forms.Label label2; 286 | private System.Windows.Forms.CheckBox tunerAmpCheckBox; 287 | private System.Windows.Forms.Label label8; 288 | private System.Windows.Forms.ComboBox samplerateComboBox; 289 | private System.Windows.Forms.Timer refreshTimer; 290 | private System.Windows.Forms.NumericUpDown portNumberUpDown; 291 | private System.Windows.Forms.Label IFLabel; 292 | private System.Windows.Forms.Label label5; 293 | private System.Windows.Forms.TrackBar tunerIFFreq; 294 | private System.Windows.Forms.Label gainVGALabel; 295 | private System.Windows.Forms.Label label6; 296 | private System.Windows.Forms.TrackBar tunerVGAGainTrackBar; 297 | private System.Windows.Forms.Label gainLNALabel; 298 | private System.Windows.Forms.Label label3; 299 | private System.Windows.Forms.TrackBar tunerLNAGainTrackBar; 300 | } 301 | } -------------------------------------------------------------------------------- /src/HRFTCP/HRFTCPSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Forms; 4 | using SDRSharp.Radio; 5 | 6 | namespace SDRSharp.HRFTCP 7 | { 8 | public partial class HRFTCPSettings : Form 9 | { 10 | private const int LNAGainStep = 8; 11 | private const int VGAGainStep = 2; 12 | private const int IFFreqOffset = 2400; 13 | private readonly HRFTCPIO _owner; 14 | 15 | public string Hostname 16 | { 17 | get { return hostBox.Text; } 18 | set { hostBox.Text = value; } 19 | } 20 | 21 | public int Port 22 | { 23 | get { return (int)portNumberUpDown.Value; } 24 | set { portNumberUpDown.Value = value; } 25 | } 26 | 27 | public HRFTCPSettings(HRFTCPIO owner) 28 | { 29 | _owner = owner; 30 | InitializeComponent(); 31 | 32 | samplerateComboBox.SelectedIndex = Utils.GetIntSetting("HRFTCPSampleRate", 18); 33 | tunerAmpCheckBox.Checked = Utils.GetBooleanSetting("HRFTCPTunerAmp"); 34 | tunerLNAGainTrackBar.Value = Utils.GetIntSetting("HRFTCPTunerLNAGain", 3); 35 | tunerVGAGainTrackBar.Value = Utils.GetIntSetting("HRFTCPTunerVGAGain", 12); 36 | tunerIFFreq.Value = Utils.GetIntSetting("HRFTCPTunerIFFreq", 0); 37 | gainLNALabel.Text = (tunerLNAGainTrackBar.Value * LNAGainStep) + " dB"; 38 | gainVGALabel.Text = (tunerVGAGainTrackBar.Value * VGAGainStep) + " dB"; 39 | IFLabel.Text = (tunerIFFreq.Value + IFFreqOffset) + " MHz"; 40 | 41 | tunerVGAGainTrackBar_Scroll(null, null); 42 | tunerLNAGainTrackBar_Scroll(null, null); 43 | tunerIFFreq_Scroll(null, null); 44 | samplerateComboBox_SelectedIndexChanged(null, null); 45 | tunerAmpCheckBox_CheckedChanged(null, null); 46 | 47 | UpdateGuiState(); 48 | } 49 | 50 | private void refreshTimer_Tick(object sender, EventArgs e) 51 | { 52 | UpdateGuiState(); 53 | } 54 | 55 | private void UpdateGuiState() 56 | { 57 | samplerateComboBox.Enabled = !_owner.IsStreaming; 58 | hostBox.Enabled = !_owner.IsStreaming; 59 | portNumberUpDown.Enabled = !_owner.IsStreaming; 60 | } 61 | 62 | private void HRFTCPSettings_VisibleChanged(object sender, EventArgs e) 63 | { 64 | refreshTimer.Enabled = Visible; 65 | UpdateGuiState(); 66 | } 67 | 68 | private void HRFTCPSettings_FormClosing(object sender, FormClosingEventArgs e) 69 | { 70 | e.Cancel = true; 71 | Hide(); 72 | } 73 | 74 | private void samplerateComboBox_SelectedIndexChanged(object sender, EventArgs e) 75 | { 76 | var samplerateString = samplerateComboBox.Items[samplerateComboBox.SelectedIndex].ToString().Split(' ')[0]; 77 | var sampleRate = double.Parse(samplerateString, CultureInfo.InvariantCulture); 78 | _owner.Samplerate = (uint)(sampleRate * 1000000.0); 79 | Utils.SaveSetting("HRFTCPSampleRate", samplerateComboBox.SelectedIndex); 80 | } 81 | 82 | private void tunerAmpCheckBox_CheckedChanged(object sender, EventArgs e) 83 | { 84 | _owner.UseTunerAMP = tunerAmpCheckBox.Checked; 85 | Utils.SaveSetting("HRFTCPTunerAmp", tunerAmpCheckBox.Checked); 86 | } 87 | 88 | private void tunerVGAGainTrackBar_Scroll(object sender, EventArgs e) 89 | { 90 | _owner.tunerGainVGA = (tunerVGAGainTrackBar.Value * VGAGainStep); 91 | gainVGALabel.Text = _owner.tunerGainVGA + " dB"; 92 | Utils.SaveSetting("HRFTCPTunerVGAGain", tunerVGAGainTrackBar.Value); 93 | } 94 | 95 | private void tunerLNAGainTrackBar_Scroll(object sender, EventArgs e) 96 | { 97 | _owner.tunerGainLNA = (tunerLNAGainTrackBar.Value * LNAGainStep); 98 | gainLNALabel.Text = _owner.tunerGainLNA + " dB"; 99 | Utils.SaveSetting("HRFTCPTunerLNAGain", tunerLNAGainTrackBar.Value); 100 | } 101 | 102 | private void tunerIFFreq_Scroll(object sender, EventArgs e) 103 | { 104 | _owner.tunerIF = (tunerIFFreq.Value + IFFreqOffset); 105 | IFLabel.Text = _owner.tunerIF + " MHz"; 106 | Utils.SaveSetting("HRFTCPTunerIFFreq", tunerIFFreq.Value); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/HRFTCP/HRFTCPSettings.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /src/HRFTCP/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SDRSharp.HRFTCP")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SDRSharp.HRFTCP")] 13 | [assembly: AssemblyCopyright("Copyright © Ian Gilmour 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dcea766b-9806-49dc-97dd-f9ed391d3ba5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/HRFTCP/SDRSharp.HRFTCP.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {A69AD350-B79C-4F42-9A3E-D41F1DA44C35} 9 | Library 10 | Properties 11 | SDRSharp.HRFTCP 12 | SDRSharp.HRFTCP 13 | v3.5 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | pdbonly 28 | true 29 | ..\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Form 50 | 51 | 52 | HRFTCPSettings.cs 53 | 54 | 55 | 56 | 57 | {1E08E7FD-5A13-454D-ADBD-C1A0B75ECF2D} 58 | SDRSharp.Radio 59 | 60 | 61 | 62 | 63 | HRFTCPSettings.cs 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /src/HackRF/HackRFControllerDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace SDRSharp.HackRF 2 | { 3 | partial class HackRFControllerDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.refreshTimer = new System.Windows.Forms.Timer(this.components); 33 | this.closeButton = new System.Windows.Forms.Button(); 34 | this.deviceComboBox = new System.Windows.Forms.ComboBox(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.tunerLNAGainTrackBar = new System.Windows.Forms.TrackBar(); 37 | this.label2 = new System.Windows.Forms.Label(); 38 | this.label3 = new System.Windows.Forms.Label(); 39 | this.samplerateComboBox = new System.Windows.Forms.ComboBox(); 40 | this.tunerAmpCheckBox = new System.Windows.Forms.CheckBox(); 41 | this.gainLNALabel = new System.Windows.Forms.Label(); 42 | this.tunerTypeLabel = new System.Windows.Forms.Label(); 43 | this.gainVGALabel = new System.Windows.Forms.Label(); 44 | this.label6 = new System.Windows.Forms.Label(); 45 | this.tunerVGAGainTrackBar = new System.Windows.Forms.TrackBar(); 46 | this.IFLabel = new System.Windows.Forms.Label(); 47 | this.label5 = new System.Windows.Forms.Label(); 48 | this.tunerIFFreq = new System.Windows.Forms.TrackBar(); 49 | ((System.ComponentModel.ISupportInitialize)(this.tunerLNAGainTrackBar)).BeginInit(); 50 | ((System.ComponentModel.ISupportInitialize)(this.tunerVGAGainTrackBar)).BeginInit(); 51 | ((System.ComponentModel.ISupportInitialize)(this.tunerIFFreq)).BeginInit(); 52 | this.SuspendLayout(); 53 | // 54 | // refreshTimer 55 | // 56 | this.refreshTimer.Interval = 1000; 57 | this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick); 58 | // 59 | // closeButton 60 | // 61 | this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 62 | this.closeButton.Location = new System.Drawing.Point(184, 282); 63 | this.closeButton.Name = "closeButton"; 64 | this.closeButton.Size = new System.Drawing.Size(75, 23); 65 | this.closeButton.TabIndex = 8; 66 | this.closeButton.Text = "Close"; 67 | this.closeButton.UseVisualStyleBackColor = true; 68 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click); 69 | // 70 | // deviceComboBox 71 | // 72 | this.deviceComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 73 | this.deviceComboBox.FormattingEnabled = true; 74 | this.deviceComboBox.Location = new System.Drawing.Point(12, 26); 75 | this.deviceComboBox.Name = "deviceComboBox"; 76 | this.deviceComboBox.Size = new System.Drawing.Size(247, 21); 77 | this.deviceComboBox.TabIndex = 0; 78 | this.deviceComboBox.SelectedIndexChanged += new System.EventHandler(this.deviceComboBox_SelectedIndexChanged); 79 | // 80 | // label1 81 | // 82 | this.label1.AutoSize = true; 83 | this.label1.Location = new System.Drawing.Point(12, 9); 84 | this.label1.Name = "label1"; 85 | this.label1.Size = new System.Drawing.Size(41, 13); 86 | this.label1.TabIndex = 20; 87 | this.label1.Text = "Device"; 88 | // 89 | // tunerLNAGainTrackBar 90 | // 91 | this.tunerLNAGainTrackBar.Location = new System.Drawing.Point(3, 135); 92 | this.tunerLNAGainTrackBar.Maximum = 5; 93 | this.tunerLNAGainTrackBar.Name = "tunerLNAGainTrackBar"; 94 | this.tunerLNAGainTrackBar.Size = new System.Drawing.Size(267, 45); 95 | this.tunerLNAGainTrackBar.TabIndex = 6; 96 | this.tunerLNAGainTrackBar.Scroll += new System.EventHandler(this.tunerLNAGainTrackBar_Scroll); 97 | // 98 | // label2 99 | // 100 | this.label2.AutoSize = true; 101 | this.label2.Location = new System.Drawing.Point(12, 119); 102 | this.label2.Name = "label2"; 103 | this.label2.Size = new System.Drawing.Size(53, 13); 104 | this.label2.TabIndex = 22; 105 | this.label2.Text = "LNA Gain"; 106 | // 107 | // label3 108 | // 109 | this.label3.AutoSize = true; 110 | this.label3.Location = new System.Drawing.Point(12, 53); 111 | this.label3.Name = "label3"; 112 | this.label3.Size = new System.Drawing.Size(68, 13); 113 | this.label3.TabIndex = 24; 114 | this.label3.Text = "Sample Rate"; 115 | // 116 | // samplerateComboBox 117 | // 118 | this.samplerateComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 119 | this.samplerateComboBox.FormattingEnabled = true; 120 | this.samplerateComboBox.Items.AddRange(new object[] { 121 | "20 MSPS (Slight Sample Loss)", 122 | "16 MSPS ", 123 | "12.5 MSPS ", 124 | "10 MSPS ", 125 | "8 MSPS (Zefie Recommended)", 126 | "4 MSPS ", 127 | "3.2 MSPS (Slower PCs)", 128 | "2 MSPS (RTLSDR Compatible)", 129 | "1 MSPS (RTLSDR Compatible)"}); 130 | this.samplerateComboBox.Location = new System.Drawing.Point(12, 70); 131 | this.samplerateComboBox.Name = "samplerateComboBox"; 132 | this.samplerateComboBox.Size = new System.Drawing.Size(247, 21); 133 | this.samplerateComboBox.TabIndex = 1; 134 | this.samplerateComboBox.SelectedIndexChanged += new System.EventHandler(this.samplerateComboBox_SelectedIndexChanged); 135 | // 136 | // tunerAmpCheckBox 137 | // 138 | this.tunerAmpCheckBox.AutoSize = true; 139 | this.tunerAmpCheckBox.Checked = true; 140 | this.tunerAmpCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 141 | this.tunerAmpCheckBox.Enabled = false; 142 | this.tunerAmpCheckBox.Location = new System.Drawing.Point(12, 99); 143 | this.tunerAmpCheckBox.Name = "tunerAmpCheckBox"; 144 | this.tunerAmpCheckBox.Size = new System.Drawing.Size(166, 17); 145 | this.tunerAmpCheckBox.TabIndex = 5; 146 | this.tunerAmpCheckBox.Text = "Enable HackRF Internal AMP"; 147 | this.tunerAmpCheckBox.UseVisualStyleBackColor = true; 148 | this.tunerAmpCheckBox.CheckedChanged += new System.EventHandler(this.tunerAmpCheckBox_CheckedChanged); 149 | // 150 | // gainLNALabel 151 | // 152 | this.gainLNALabel.Location = new System.Drawing.Point(191, 119); 153 | this.gainLNALabel.Name = "gainLNALabel"; 154 | this.gainLNALabel.Size = new System.Drawing.Size(68, 13); 155 | this.gainLNALabel.TabIndex = 26; 156 | this.gainLNALabel.Text = "1000dB"; 157 | this.gainLNALabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 158 | this.gainLNALabel.Visible = false; 159 | // 160 | // tunerTypeLabel 161 | // 162 | this.tunerTypeLabel.Location = new System.Drawing.Point(166, 9); 163 | this.tunerTypeLabel.Name = "tunerTypeLabel"; 164 | this.tunerTypeLabel.Size = new System.Drawing.Size(93, 13); 165 | this.tunerTypeLabel.TabIndex = 29; 166 | this.tunerTypeLabel.Text = "HackRF"; 167 | this.tunerTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 168 | // 169 | // gainVGALabel 170 | // 171 | this.gainVGALabel.Location = new System.Drawing.Point(191, 170); 172 | this.gainVGALabel.Name = "gainVGALabel"; 173 | this.gainVGALabel.Size = new System.Drawing.Size(68, 13); 174 | this.gainVGALabel.TabIndex = 34; 175 | this.gainVGALabel.Text = "1000dB"; 176 | this.gainVGALabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 177 | this.gainVGALabel.Visible = false; 178 | // 179 | // label6 180 | // 181 | this.label6.AutoSize = true; 182 | this.label6.Location = new System.Drawing.Point(12, 170); 183 | this.label6.Name = "label6"; 184 | this.label6.Size = new System.Drawing.Size(54, 13); 185 | this.label6.TabIndex = 33; 186 | this.label6.Text = "VGA Gain"; 187 | // 188 | // tunerVGAGainTrackBar 189 | // 190 | this.tunerVGAGainTrackBar.Location = new System.Drawing.Point(3, 186); 191 | this.tunerVGAGainTrackBar.Maximum = 31; 192 | this.tunerVGAGainTrackBar.Name = "tunerVGAGainTrackBar"; 193 | this.tunerVGAGainTrackBar.Size = new System.Drawing.Size(267, 45); 194 | this.tunerVGAGainTrackBar.TabIndex = 32; 195 | this.tunerVGAGainTrackBar.Scroll += new System.EventHandler(this.tunerVGAGainTrackBar_Scroll); 196 | // 197 | // IFLabel 198 | // 199 | this.IFLabel.Location = new System.Drawing.Point(191, 221); 200 | this.IFLabel.Name = "IFLabel"; 201 | this.IFLabel.Size = new System.Drawing.Size(68, 13); 202 | this.IFLabel.TabIndex = 38; 203 | this.IFLabel.Text = "2400MHz"; 204 | this.IFLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; 205 | this.IFLabel.Visible = false; 206 | // 207 | // label5 208 | // 209 | this.label5.AutoSize = true; 210 | this.label5.Location = new System.Drawing.Point(12, 221); 211 | this.label5.Name = "label5"; 212 | this.label5.Size = new System.Drawing.Size(118, 13); 213 | this.label5.TabIndex = 37; 214 | this.label5.Text = "Intermediate Frequency"; 215 | // 216 | // tunerIFFreq 217 | // 218 | this.tunerIFFreq.Location = new System.Drawing.Point(3, 237); 219 | this.tunerIFFreq.Maximum = 300; 220 | this.tunerIFFreq.Name = "tunerIFFreq"; 221 | this.tunerIFFreq.Size = new System.Drawing.Size(267, 45); 222 | this.tunerIFFreq.TabIndex = 36; 223 | this.tunerIFFreq.Scroll += new System.EventHandler(this.tunerIFFreq_Scroll); 224 | // 225 | // HackRFControllerDialog 226 | // 227 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 228 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 229 | this.CancelButton = this.closeButton; 230 | this.ClientSize = new System.Drawing.Size(271, 315); 231 | this.Controls.Add(this.IFLabel); 232 | this.Controls.Add(this.label5); 233 | this.Controls.Add(this.tunerIFFreq); 234 | this.Controls.Add(this.gainVGALabel); 235 | this.Controls.Add(this.label6); 236 | this.Controls.Add(this.tunerVGAGainTrackBar); 237 | this.Controls.Add(this.tunerTypeLabel); 238 | this.Controls.Add(this.gainLNALabel); 239 | this.Controls.Add(this.tunerAmpCheckBox); 240 | this.Controls.Add(this.label3); 241 | this.Controls.Add(this.samplerateComboBox); 242 | this.Controls.Add(this.label2); 243 | this.Controls.Add(this.tunerLNAGainTrackBar); 244 | this.Controls.Add(this.label1); 245 | this.Controls.Add(this.deviceComboBox); 246 | this.Controls.Add(this.closeButton); 247 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 248 | this.MaximizeBox = false; 249 | this.MinimizeBox = false; 250 | this.Name = "HackRFControllerDialog"; 251 | this.ShowIcon = false; 252 | this.ShowInTaskbar = false; 253 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 254 | this.Text = "HackRF Controller"; 255 | this.TopMost = true; 256 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HackRFControllerDialog_FormClosing); 257 | this.VisibleChanged += new System.EventHandler(this.HackRFControllerDialog_VisibleChanged); 258 | ((System.ComponentModel.ISupportInitialize)(this.tunerLNAGainTrackBar)).EndInit(); 259 | ((System.ComponentModel.ISupportInitialize)(this.tunerVGAGainTrackBar)).EndInit(); 260 | ((System.ComponentModel.ISupportInitialize)(this.tunerIFFreq)).EndInit(); 261 | this.ResumeLayout(false); 262 | this.PerformLayout(); 263 | 264 | } 265 | 266 | #endregion 267 | 268 | private System.Windows.Forms.Timer refreshTimer; 269 | private System.Windows.Forms.Button closeButton; 270 | private System.Windows.Forms.ComboBox deviceComboBox; 271 | private System.Windows.Forms.Label label1; 272 | private System.Windows.Forms.TrackBar tunerLNAGainTrackBar; 273 | private System.Windows.Forms.Label label2; 274 | private System.Windows.Forms.Label label3; 275 | private System.Windows.Forms.ComboBox samplerateComboBox; 276 | private System.Windows.Forms.CheckBox tunerAmpCheckBox; 277 | private System.Windows.Forms.Label gainLNALabel; 278 | private System.Windows.Forms.Label tunerTypeLabel; 279 | private System.Windows.Forms.Label gainVGALabel; 280 | private System.Windows.Forms.Label label6; 281 | private System.Windows.Forms.TrackBar tunerVGAGainTrackBar; 282 | private System.Windows.Forms.Label IFLabel; 283 | private System.Windows.Forms.Label label5; 284 | private System.Windows.Forms.TrackBar tunerIFFreq; 285 | } 286 | } 287 | 288 | -------------------------------------------------------------------------------- /src/HackRF/HackRFControllerDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Forms; 4 | using SDRSharp.Radio; 5 | using System.Timers; 6 | 7 | namespace SDRSharp.HackRF 8 | { 9 | public partial class HackRFControllerDialog : Form 10 | { 11 | private readonly HackRFIO _owner; 12 | private bool _initialized; 13 | private const int LNAGainStep = 8; 14 | private const int VGAGainStep = 2; 15 | private const int IFFreqOffset = 2400; 16 | private static System.Timers.Timer configureDelay = new System.Timers.Timer(); 17 | 18 | public HackRFControllerDialog(HackRFIO owner) 19 | { 20 | InitializeComponent(); 21 | 22 | _owner = owner; 23 | var devices = DeviceDisplay.GetActiveDevices(); 24 | deviceComboBox.Items.Clear(); 25 | deviceComboBox.Items.AddRange(devices); 26 | 27 | samplerateComboBox.SelectedIndex = Utils.GetIntSetting("HackRFSampleRate", 3); 28 | tunerAmpCheckBox.Checked = Utils.GetBooleanSetting("HackRFTunerAmp"); 29 | tunerLNAGainTrackBar.Value = Utils.GetIntSetting("LNATunerGain", 3); 30 | tunerVGAGainTrackBar.Value = Utils.GetIntSetting("VGATunerGain", 12); 31 | tunerIFFreq.Value = Utils.GetIntSetting("HackRFIFFreq", 0); 32 | gainLNALabel.Text = (tunerLNAGainTrackBar.Value * LNAGainStep) + " dB"; 33 | gainVGALabel.Text = (tunerVGAGainTrackBar.Value * VGAGainStep) + " dB"; 34 | IFLabel.Text = (tunerIFFreq.Value + IFFreqOffset) + " MHz"; 35 | 36 | //gainLabel.Visible = tunerAmpCheckBox.Enabled && !tunerAmpCheckBox.Checked; 37 | //tunerGainTrackBar.Enabled = tunerAmpCheckBox.Enabled && !tunerAmpCheckBox.Checked; 38 | gainLNALabel.Visible = tunerLNAGainTrackBar.Enabled = true; 39 | gainVGALabel.Visible = tunerVGAGainTrackBar.Enabled = true; 40 | IFLabel.Visible = tunerIFFreq.Enabled = true; 41 | tunerAmpCheckBox.Enabled = true; 42 | 43 | _initialized = true; 44 | } 45 | 46 | private void closeButton_Click(object sender, EventArgs e) 47 | { 48 | Close(); 49 | } 50 | 51 | private void HackRFControllerDialog_FormClosing(object sender, FormClosingEventArgs e) 52 | { 53 | e.Cancel = true; 54 | Hide(); 55 | } 56 | 57 | private void HackRFControllerDialog_VisibleChanged(object sender, EventArgs e) 58 | { 59 | refreshTimer.Enabled = Visible; 60 | if (Visible) 61 | { 62 | samplerateComboBox.Enabled = !_owner.Device.IsStreaming; 63 | deviceComboBox.Enabled = !_owner.Device.IsStreaming; 64 | 65 | if (!_owner.Device.IsStreaming) 66 | { 67 | var devices = DeviceDisplay.GetActiveDevices(); 68 | deviceComboBox.Items.Clear(); 69 | deviceComboBox.Items.AddRange(devices); 70 | 71 | for (var i = 0; i < devices.Length; i++) 72 | { 73 | if (devices[i].Index == ((DeviceDisplay) deviceComboBox.Items[i]).Index) 74 | { 75 | _initialized = false; 76 | deviceComboBox.SelectedIndex = i; 77 | _initialized = true; 78 | break; 79 | } 80 | } 81 | } 82 | } 83 | } 84 | 85 | private void refreshTimer_Tick(object sender, EventArgs e) 86 | { 87 | samplerateComboBox.Enabled = !_owner.Device.IsStreaming; 88 | deviceComboBox.Enabled = !_owner.Device.IsStreaming; 89 | } 90 | 91 | private void deviceComboBox_SelectedIndexChanged(object sender, EventArgs e) 92 | { 93 | if (!_initialized) 94 | { 95 | return; 96 | } 97 | var deviceDisplay = (DeviceDisplay) deviceComboBox.SelectedItem; 98 | if (deviceDisplay != null) 99 | { 100 | try 101 | { 102 | _owner.SelectDevice(deviceDisplay.Index); 103 | } 104 | catch (Exception ex) 105 | { 106 | deviceComboBox.SelectedIndex = -1; 107 | MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 108 | } 109 | } 110 | } 111 | 112 | private void samplerateComboBox_SelectedIndexChanged(object sender, EventArgs e) 113 | { 114 | if (!_initialized) 115 | { 116 | return; 117 | } 118 | var samplerateString = samplerateComboBox.Items[samplerateComboBox.SelectedIndex].ToString().Split(' ')[0]; 119 | var sampleRate = double.Parse(samplerateString, CultureInfo.InvariantCulture); 120 | _owner.Device.Samplerate = (uint) (sampleRate * 1000000.0); 121 | Utils.SaveSetting("HackRFSampleRate", samplerateComboBox.SelectedIndex); 122 | } 123 | 124 | public void ConfigureGUI() 125 | { 126 | for (var i = 0; i < deviceComboBox.Items.Count; i++) 127 | { 128 | var deviceDisplay = (DeviceDisplay) deviceComboBox.Items[i]; 129 | if (deviceDisplay.Index == _owner.Device.Index) 130 | { 131 | deviceComboBox.SelectedIndex = i; 132 | break; 133 | } 134 | } 135 | } 136 | 137 | public void ConfigureDevice() 138 | { 139 | tunerVGAGainTrackBar_Scroll(null, null); 140 | tunerLNAGainTrackBar_Scroll(null, null); 141 | tunerIFFreq_Scroll(null, null); 142 | samplerateComboBox_SelectedIndexChanged(null, null); 143 | tunerAmpCheckBox_CheckedChanged(null, null); 144 | if (!_owner.Device.IsStreaming) 145 | { 146 | // A timer is required since for whatever reason, the amp (and assumingly other settings) 147 | // are not properly applied when ConfigureDevice() is called by SDRSharp 148 | configureDelay.Interval = 10; 149 | configureDelay.Elapsed += new ElapsedEventHandler(configureDelayHandler); 150 | configureDelay.Start(); 151 | } 152 | /* 153 | tunerAgcCheckBox_CheckedChanged(null, null); 154 | if (!tunerAgcCheckBox.Checked) 155 | { 156 | tunerGainTrackBar_Scroll(null, null); 157 | } 158 | */ 159 | } 160 | 161 | private void configureDelayHandler(object source, ElapsedEventArgs e) 162 | { 163 | if (_owner.Device.IsStreaming) 164 | { 165 | configureDelay.Interval = 10000; 166 | configureDelay.Stop(); 167 | ConfigureDevice(); 168 | } 169 | } 170 | 171 | private void tunerAmpCheckBox_CheckedChanged(object sender, EventArgs e) 172 | { 173 | if (!_initialized) 174 | { 175 | return; 176 | } 177 | _owner.Device.UseTunerAMP = tunerAmpCheckBox.Checked; 178 | Utils.SaveSetting("HackRFTunerAmp", tunerAmpCheckBox.Checked); 179 | } 180 | 181 | private void tunerVGAGainTrackBar_Scroll(object sender, EventArgs e) 182 | { 183 | if (!_initialized) 184 | { 185 | return; 186 | } 187 | 188 | _owner.Device.VGAGain = (tunerVGAGainTrackBar.Value * VGAGainStep); 189 | gainVGALabel.Text = _owner.Device.VGAGain + " dB"; 190 | Utils.SaveSetting("VGATunerGain", tunerVGAGainTrackBar.Value); 191 | } 192 | 193 | private void tunerLNAGainTrackBar_Scroll(object sender, EventArgs e) 194 | { 195 | if (!_initialized) 196 | { 197 | return; 198 | } 199 | _owner.Device.LNAGain = (tunerLNAGainTrackBar.Value * LNAGainStep); 200 | gainLNALabel.Text = _owner.Device.LNAGain + " dB"; 201 | Utils.SaveSetting("LNATunerGain", tunerLNAGainTrackBar.Value); 202 | } 203 | 204 | private void tunerIFFreq_Scroll(object sender, EventArgs e) 205 | { 206 | if (!_initialized) 207 | { 208 | return; 209 | } 210 | _owner.Device.IFFreq = (tunerIFFreq.Value + IFFreqOffset); 211 | IFLabel.Text = _owner.Device.IFFreq + " MHz"; 212 | Utils.SaveSetting("HackRFIFFreq", tunerIFFreq.Value); 213 | } 214 | } 215 | 216 | public class DeviceDisplay 217 | { 218 | public uint Index { get; private set; } 219 | public string Name { get; set; } 220 | 221 | public static DeviceDisplay[] GetActiveDevices() 222 | { 223 | /* 224 | var count = NativeMethods.rtlsdr_get_device_count(); 225 | */ 226 | //string namestr = "HackRF Device"; 227 | var count = 1; 228 | var result = new DeviceDisplay[count]; 229 | 230 | var name = NativeMethods.hackrf_board_id_name(1); 231 | result[0] = new DeviceDisplay { Index = 0, Name = name }; 232 | /* 233 | for (var i = 0u; i < count; i++) 234 | { 235 | var name = NativeMethods.rtlsdr_get_device_name(i); 236 | result[i] = new DeviceDisplay { Index = i, Name = name }; 237 | } 238 | */ 239 | return result; 240 | } 241 | 242 | public override string ToString() 243 | { 244 | return Name; 245 | } 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /src/HackRF/HackRFControllerDialog.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /src/HackRF/HackRFDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Threading; 4 | using SDRSharp.Radio; 5 | 6 | namespace SDRSharp.HackRF 7 | { 8 | public enum SamplingMode 9 | { 10 | Quadrature = 0, 11 | DirectSamplingI, 12 | DirectSamplingQ 13 | } 14 | 15 | public unsafe sealed class HackRFDevice : IDisposable 16 | { 17 | private const uint DefaultFrequency = 105500000; 18 | private const int DefaultSamplerate = 8000000; /* 8MHz */ 19 | 20 | private static readonly float* _lutPtr; 21 | private static readonly UnsafeBuffer _lutBuffer = UnsafeBuffer.Create(256, sizeof(float)); 22 | 23 | private IntPtr _dev; 24 | private readonly string _name; 25 | private readonly int[] _supportedVGAGains; 26 | private bool _useTunerAMP = true; 27 | private bool _useHackRFAGC; 28 | public int _initialLNAGain = -1; 29 | public int _initialVGAGain = -1; 30 | private int _tunerLNAGain; 31 | private int _tunerVGAGain; 32 | private int _IFFreq; 33 | private long _centerFrequency = DefaultFrequency; 34 | private uint _sampleRate = DefaultSamplerate; 35 | private int _frequencyCorrection; 36 | private SamplingMode _samplingMode; 37 | private bool _useOffsetTuning; 38 | private readonly bool _supportsOffsetTuning; 39 | 40 | private GCHandle _gcHandle; 41 | private UnsafeBuffer _iqBuffer; 42 | private Complex* _iqPtr; 43 | private bool _rxIsRunning; 44 | private readonly SamplesAvailableEventArgs _eventArgs = new SamplesAvailableEventArgs(); 45 | private static readonly hackrf_sample_block_cb_fn _HackRFCallback = HackRFSamplesAvailable; 46 | private static readonly uint _readLength = (uint)Utils.GetIntSetting("HackRFBufferLength", 16 * 1024); 47 | 48 | static HackRFDevice() 49 | { 50 | _lutPtr = (float*)_lutBuffer; 51 | 52 | const float scale = 1.0f / 127.0f; 53 | for (var i = 0; i < 256; i++) 54 | { 55 | _lutPtr[i] = (i - 128) * scale; 56 | } 57 | } 58 | 59 | public HackRFDevice() 60 | { 61 | var r = NativeMethods.hackrf_init(); 62 | if (r != 0) 63 | { 64 | throw new ApplicationException("Cannot init HackRF device. Is the device locked somewhere?"); 65 | } 66 | 67 | r = NativeMethods.hackrf_open(out _dev); 68 | if (r != 0) 69 | { 70 | throw new ApplicationException("Cannot open HackRF device. Is the device locked somewhere?"); 71 | } 72 | /* 73 | var count = _dev == IntPtr.Zero ? 0 : NativeMethods.rtlsdr_get_tuner_gains(_dev, null); 74 | if (count < 0) 75 | { 76 | count = 0; 77 | } 78 | */ 79 | var count = 62; 80 | 81 | //_supportsOffsetTuning = NativeMethods.rtlsdr_set_offset_tuning(_dev, 0) != -2; 82 | _supportsOffsetTuning = false; 83 | _supportedVGAGains = new int[count]; 84 | /* 85 | if (count >= 0) 86 | { 87 | NativeMethods.rtlsdr_get_tuner_gains(_dev, _supportedGains); 88 | } 89 | */ 90 | _name = "HackRF Jawbreaker"; // NativeMethods.rtlsdr_get_device_name(_index); 91 | _gcHandle = GCHandle.Alloc(this); 92 | } 93 | 94 | ~HackRFDevice() 95 | { 96 | Dispose(); 97 | } 98 | 99 | public void Dispose() 100 | { 101 | Stop(); 102 | var r = NativeMethods.hackrf_close(_dev); 103 | if (r != 0) 104 | { 105 | //throw new ApplicationException("Cannot close HackRF device."); 106 | } 107 | NativeMethods.hackrf_exit(); 108 | if (_gcHandle.IsAllocated) 109 | { 110 | _gcHandle.Free(); 111 | } 112 | _dev = IntPtr.Zero; 113 | GC.SuppressFinalize(this); 114 | } 115 | 116 | public event SamplesAvailableDelegate SamplesAvailable; 117 | 118 | public void Start() 119 | { 120 | uint baseband_filter_bw_hz; 121 | var r = 0; 122 | 123 | if (_rxIsRunning) 124 | { 125 | throw new ApplicationException("Start() Already running"); 126 | } 127 | 128 | r = NativeMethods.hackrf_set_sample_rate(_dev, _sampleRate); 129 | if (r != 0) 130 | { 131 | throw new ApplicationException("hackrf_sample_rate_set error"); 132 | } 133 | 134 | r = NativeMethods.hackrf_set_amp_enable(_dev, 1); /* 0 = OFF, 1= ON */ 135 | if (r != 0) 136 | { 137 | throw new ApplicationException("hackrf_set_amp_enable error"); 138 | } 139 | 140 | baseband_filter_bw_hz = NativeMethods.hackrf_compute_baseband_filter_bw_round_down_lt(_sampleRate); 141 | //baseband_filter_bw_hz = 5000000; /* Force 5MHz */ 142 | r = NativeMethods.hackrf_set_baseband_filter_bandwidth(_dev, baseband_filter_bw_hz); 143 | if (r != 0) 144 | { 145 | throw new ApplicationException("hackrf_baseband_filter_bandwidth_set error"); 146 | } 147 | 148 | r = NativeMethods.hackrf_start_rx(_dev, _HackRFCallback, (IntPtr)_gcHandle); 149 | if (r != 0) 150 | { 151 | throw new ApplicationException("hackrf_start_rx error"); 152 | } 153 | 154 | r = NativeMethods.hackrf_is_streaming(_dev); 155 | if (r != 1) 156 | { 157 | throw new ApplicationException("hackrf_is_streaming() Error"); 158 | } 159 | 160 | _rxIsRunning = true; 161 | } 162 | 163 | public void Stop() 164 | { 165 | if (!_rxIsRunning) 166 | { 167 | return; 168 | } 169 | 170 | var r = NativeMethods.hackrf_stop_rx(_dev); 171 | if (r != 0) 172 | { 173 | //throw new ApplicationException("hackrf_stop_rx error"); 174 | } 175 | 176 | _rxIsRunning = false; 177 | } 178 | 179 | public uint Index 180 | { 181 | get { return 0; } 182 | } 183 | 184 | public string Name 185 | { 186 | get { return _name; } 187 | } 188 | 189 | public int InitialLNAGain 190 | { 191 | get { return _initialLNAGain; } 192 | set { _initialLNAGain = value; } 193 | } 194 | 195 | public int InitialVGAGain 196 | { 197 | get { return _initialVGAGain; } 198 | set { _initialVGAGain = value; } 199 | } 200 | 201 | 202 | public uint Samplerate 203 | { 204 | get 205 | { 206 | return _sampleRate; 207 | } 208 | set 209 | { 210 | _sampleRate = value; 211 | if (_dev != IntPtr.Zero) 212 | { 213 | NativeMethods.hackrf_set_sample_rate(_dev, _sampleRate); 214 | } 215 | } 216 | } 217 | 218 | public long Frequency 219 | { 220 | get 221 | { 222 | return _centerFrequency; 223 | } 224 | set 225 | { 226 | _centerFrequency = value; 227 | if (_dev != IntPtr.Zero) 228 | { 229 | NativeMethods.hackrf_set_freq(_dev, _centerFrequency); 230 | } 231 | } 232 | } 233 | 234 | public bool UseHackRFAGC 235 | { 236 | get { return _useHackRFAGC; } 237 | set 238 | { 239 | _useHackRFAGC = value; 240 | /* TODO code HackRF AGC */ 241 | /* 242 | if (_dev != IntPtr.Zero) 243 | { 244 | NativeMethods.rtlsdr_set_agc_mode(_dev, _useHackRFAGC ? 1 : 0); 245 | } 246 | */ 247 | } 248 | } 249 | 250 | public bool UseTunerAMP 251 | { 252 | get { return _useTunerAMP; } 253 | set 254 | { 255 | _useTunerAMP = value; 256 | if (_dev != IntPtr.Zero) 257 | { 258 | NativeMethods.hackrf_set_amp_enable(_dev, (uint)(_useTunerAMP ? 1 : 0)); 259 | } 260 | 261 | } 262 | } 263 | 264 | public SamplingMode SamplingMode 265 | { 266 | get { return _samplingMode; } 267 | set 268 | { 269 | _samplingMode = value; 270 | /* TODO code HackRF Direct Sampling TBD */ 271 | /* 272 | if (_dev != IntPtr.Zero) 273 | { 274 | NativeMethods.rtlsdr_set_direct_sampling(_dev, (int) _samplingMode); 275 | } 276 | */ 277 | } 278 | } 279 | 280 | public bool SupportsOffsetTuning 281 | { 282 | get { return _supportsOffsetTuning; } 283 | } 284 | 285 | public bool UseOffsetTuning 286 | { 287 | get { return _useOffsetTuning; } 288 | set 289 | { 290 | _useOffsetTuning = value; 291 | /* TODO code HackRF Offset Tuning TBD */ 292 | /* 293 | if (_dev != IntPtr.Zero) 294 | { 295 | NativeMethods.rtlsdr_set_offset_tuning(_dev, _useOffsetTuning ? 1 : 0); 296 | } 297 | */ 298 | } 299 | } 300 | 301 | public int[] SupportedGains 302 | { 303 | get { return _supportedVGAGains; } 304 | } 305 | 306 | public int LNAGain 307 | { 308 | get { return _tunerLNAGain; } 309 | set 310 | { 311 | _tunerLNAGain = value; 312 | 313 | if (_dev != IntPtr.Zero) 314 | { 315 | NativeMethods.hackrf_set_lna_gain(_dev, Convert.ToUInt32(_tunerLNAGain)); 316 | } 317 | 318 | } 319 | } 320 | 321 | public int VGAGain 322 | { 323 | get { return _tunerVGAGain; } 324 | set 325 | { 326 | _tunerVGAGain = value; 327 | 328 | if (_dev != IntPtr.Zero) 329 | { 330 | NativeMethods.hackrf_set_vga_gain(_dev, Convert.ToUInt32(_tunerVGAGain)); 331 | } 332 | 333 | } 334 | } 335 | 336 | public int IFFreq 337 | { 338 | get { return _IFFreq; } 339 | set 340 | { 341 | _IFFreq = value; 342 | 343 | if (_dev != IntPtr.Zero) 344 | { 345 | NativeMethods.hackrf_set_if_freq(_dev, Convert.ToUInt32(_IFFreq)); 346 | } 347 | 348 | } 349 | } 350 | 351 | public int FrequencyCorrection 352 | { 353 | get 354 | { 355 | return _frequencyCorrection; 356 | } 357 | set 358 | { 359 | _frequencyCorrection = value; 360 | /* TODO code HackRF Freq Correction TBD */ 361 | /* 362 | if (_dev != IntPtr.Zero) 363 | { 364 | NativeMethods.rtlsdr_set_freq_correction(_dev, _frequencyCorrection); 365 | } 366 | */ 367 | } 368 | } 369 | /* 370 | public RtlSdrTunerType TunerType 371 | { 372 | get 373 | { 374 | return _dev == IntPtr.Zero ? RtlSdrTunerType.Unknown : NativeMethods.rtlsdr_get_tuner_type(_dev); 375 | } 376 | } 377 | */ 378 | 379 | public bool IsStreaming 380 | { 381 | get 382 | { 383 | return _rxIsRunning; 384 | } 385 | } 386 | 387 | #region Streaming methods 388 | 389 | private void ComplexSamplesAvailable(Complex* buffer, int length) 390 | { 391 | if (SamplesAvailable != null) 392 | { 393 | _eventArgs.Buffer = buffer; 394 | _eventArgs.Length = length; 395 | SamplesAvailable(this, _eventArgs); 396 | } 397 | } 398 | 399 | private static int HackRFSamplesAvailable(hackrf_transfer* ptr) 400 | { 401 | byte* buf = ptr->buffer; 402 | int len = ptr->buffer_length; 403 | IntPtr ctx = ptr->rx_ctx; 404 | 405 | var gcHandle = GCHandle.FromIntPtr(ctx); 406 | if (!gcHandle.IsAllocated) 407 | { 408 | return -1; 409 | } 410 | var instance = (HackRFDevice)gcHandle.Target; 411 | 412 | var sampleCount = (int)len / 2; 413 | if (instance._iqBuffer == null || instance._iqBuffer.Length != sampleCount) 414 | { 415 | instance._iqBuffer = UnsafeBuffer.Create(sampleCount, sizeof(Complex)); 416 | instance._iqPtr = (Complex*)instance._iqBuffer; 417 | } 418 | 419 | var ptrIq = instance._iqPtr; 420 | for (var i = 0; i < sampleCount; i++) 421 | { 422 | ptrIq->Imag = _lutPtr[*buf++]; 423 | ptrIq->Real = _lutPtr[*buf++]; 424 | ptrIq++; 425 | } 426 | 427 | instance.ComplexSamplesAvailable(instance._iqPtr, instance._iqBuffer.Length); 428 | return 0; 429 | } 430 | 431 | #endregion 432 | } 433 | 434 | public delegate void SamplesAvailableDelegate(object sender, SamplesAvailableEventArgs e); 435 | 436 | public unsafe sealed class SamplesAvailableEventArgs : EventArgs 437 | { 438 | public int Length { get; set; } 439 | public Complex* Buffer { get; set; } 440 | } 441 | } 442 | -------------------------------------------------------------------------------- /src/HackRF/HackRFIO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using SDRSharp.Radio; 4 | 5 | namespace SDRSharp.HackRF 6 | { 7 | public unsafe class HackRFIO : IFrontendController, IDisposable 8 | { 9 | private readonly HackRFControllerDialog _gui; 10 | private HackRFDevice _HackRFDevice; 11 | private long _frequency = 105500000; 12 | private Radio.SamplesAvailableDelegate _callback; 13 | 14 | public HackRFIO() 15 | { 16 | _gui = new HackRFControllerDialog(this); 17 | } 18 | 19 | ~HackRFIO() 20 | { 21 | Dispose(); 22 | } 23 | 24 | public void Dispose() 25 | { 26 | if (_gui != null) 27 | { 28 | _gui.Dispose(); 29 | } 30 | GC.SuppressFinalize(this); 31 | } 32 | 33 | public void SelectDevice(uint index) 34 | { 35 | Close(); 36 | _HackRFDevice = new HackRFDevice(); 37 | _HackRFDevice.SamplesAvailable += HackRFDevice_SamplesAvailable; 38 | _HackRFDevice.Frequency = _frequency; 39 | _gui.ConfigureGUI(); 40 | _gui.ConfigureDevice(); 41 | } 42 | 43 | public HackRFDevice Device 44 | { 45 | get { return _HackRFDevice; } 46 | } 47 | 48 | public void Open() 49 | { 50 | var devices = DeviceDisplay.GetActiveDevices(); 51 | foreach (var device in devices) 52 | { 53 | try 54 | { 55 | SelectDevice(device.Index); 56 | return; 57 | } 58 | catch (ApplicationException) 59 | { 60 | // Just ignore it 61 | } 62 | } 63 | if (devices.Length > 0) 64 | { 65 | throw new ApplicationException(devices.Length + " compatible devices have been found but are all busy"); 66 | } 67 | throw new ApplicationException("No compatible devices found"); 68 | } 69 | 70 | public void Close() 71 | { 72 | if (_HackRFDevice != null) 73 | { 74 | _HackRFDevice.SamplesAvailable -= HackRFDevice_SamplesAvailable; 75 | _HackRFDevice.Dispose(); 76 | _HackRFDevice = null; 77 | } 78 | } 79 | 80 | public void Start(Radio.SamplesAvailableDelegate callback) 81 | { 82 | if (_HackRFDevice == null) 83 | { 84 | throw new ApplicationException("No device selected"); 85 | } 86 | _callback = callback; 87 | try 88 | { 89 | _HackRFDevice.Start(); 90 | } 91 | catch 92 | { 93 | Open(); 94 | _HackRFDevice.Start(); 95 | } 96 | } 97 | 98 | public void Stop() 99 | { 100 | _HackRFDevice.Stop(); 101 | } 102 | 103 | public bool IsSoundCardBased 104 | { 105 | get { return false; } 106 | } 107 | 108 | public string SoundCardHint 109 | { 110 | get { return string.Empty; } 111 | } 112 | 113 | public void ShowSettingGUI(IWin32Window parent) 114 | { 115 | _gui.Show(); 116 | } 117 | 118 | public void HideSettingGUI() 119 | { 120 | _gui.Hide(); 121 | } 122 | 123 | public double Samplerate 124 | { 125 | get { return _HackRFDevice == null ? 0.0 : _HackRFDevice.Samplerate; } 126 | } 127 | 128 | public long Frequency 129 | { 130 | get { return _frequency; } 131 | set 132 | { 133 | _frequency = value; 134 | if (_HackRFDevice != null) 135 | { 136 | _HackRFDevice.Frequency = _frequency; 137 | } 138 | } 139 | } 140 | 141 | private void HackRFDevice_SamplesAvailable(object sender, SamplesAvailableEventArgs e) 142 | { 143 | _callback(this, e.Buffer, e.Length); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/HackRF/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace SDRSharp.HackRF 6 | { 7 | [StructLayout(LayoutKind.Sequential)] 8 | public unsafe struct hackrf_transfer 9 | { 10 | public IntPtr device; 11 | public byte* buffer; /* Source buffer */ 12 | public int buffer_length; 13 | public int valid_length; 14 | public IntPtr rx_ctx; 15 | public IntPtr tx_ctx; 16 | } 17 | 18 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 19 | public unsafe delegate int hackrf_sample_block_cb_fn(hackrf_transfer* ptr); /* Return 0 if OK or -1 if error to stop */ 20 | 21 | public class NativeMethods 22 | { 23 | private const string LibHackRF = "libhackrf"; 24 | 25 | [DllImport(LibHackRF, EntryPoint = "hackrf_init", CallingConvention = CallingConvention.StdCall)] 26 | public static extern int hackrf_init(); 27 | 28 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_if_freq", CallingConvention = CallingConvention.StdCall)] 29 | public static extern int hackrf_set_if_freq(IntPtr dev, UInt32 value); 30 | 31 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_vga_gain", CallingConvention = CallingConvention.StdCall)] 32 | public static extern int hackrf_set_vga_gain(IntPtr dev, UInt32 value); 33 | 34 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_lna_gain", CallingConvention = CallingConvention.StdCall)] 35 | public static extern int hackrf_set_lna_gain(IntPtr dev, UInt32 value); 36 | 37 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_amp_enable", CallingConvention = CallingConvention.StdCall)] 38 | public static extern int hackrf_set_amp_enable(IntPtr dev, uint value); 39 | 40 | [DllImport(LibHackRF, EntryPoint = "hackrf_exit", CallingConvention = CallingConvention.StdCall)] 41 | public static extern int hackrf_exit(); 42 | 43 | [DllImport(LibHackRF, EntryPoint = "hackrf_open", CallingConvention = CallingConvention.StdCall)] 44 | public static extern int hackrf_open(out IntPtr dev); 45 | 46 | [DllImport(LibHackRF, EntryPoint = "hackrf_close", CallingConvention = CallingConvention.StdCall)] 47 | public static extern int hackrf_close(IntPtr dev); 48 | 49 | [DllImport(LibHackRF, EntryPoint = "hackrf_start_rx", CallingConvention = CallingConvention.StdCall)] 50 | public static extern int hackrf_start_rx(IntPtr dev, hackrf_sample_block_cb_fn cb, IntPtr rx_ctx); 51 | 52 | [DllImport(LibHackRF, EntryPoint = "hackrf_stop_rx", CallingConvention = CallingConvention.StdCall)] 53 | public static extern int hackrf_stop_rx(IntPtr dev); 54 | 55 | [DllImport(LibHackRF, EntryPoint = "hackrf_is_streaming", CallingConvention = CallingConvention.StdCall)] 56 | public static extern int hackrf_is_streaming(IntPtr dev); 57 | 58 | [DllImport(LibHackRF, EntryPoint = "hackrf_board_id_name", CallingConvention = CallingConvention.StdCall)] 59 | private static extern IntPtr hackrf_board_id_name_native(uint index); 60 | 61 | public static string hackrf_board_id_name(uint index) 62 | { 63 | try 64 | { 65 | var strptr = hackrf_board_id_name_native(index); 66 | return Marshal.PtrToStringAnsi(strptr); 67 | } 68 | catch (EntryPointNotFoundException e) 69 | { 70 | Console.WriteLine("{0}:\n {1}", e.GetType().Name, e.Message); 71 | return "HackRF"; 72 | } 73 | } 74 | 75 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_sample_rate", CallingConvention = CallingConvention.StdCall)] 76 | public static extern int hackrf_set_sample_rate(IntPtr dev, double rate); 77 | 78 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_freq", CallingConvention = CallingConvention.StdCall)] 79 | public static extern int hackrf_set_freq(IntPtr dev, long freq); 80 | 81 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_amp_enable", CallingConvention = CallingConvention.StdCall)] 82 | public static extern int hackrf_set_amp_enable(IntPtr dev, byte value); 83 | 84 | [DllImport(LibHackRF, EntryPoint = "hackrf_set_baseband_filter_bandwidth", CallingConvention = CallingConvention.StdCall)] 85 | public static extern int hackrf_set_baseband_filter_bandwidth(IntPtr dev, uint bandwidth_hz); 86 | 87 | [DllImport(LibHackRF, EntryPoint = "hackrf_compute_baseband_filter_bw_round_down_lt", CallingConvention = CallingConvention.StdCall)] 88 | public static extern uint hackrf_compute_baseband_filter_bw_round_down_lt(uint bandwidth_hz); 89 | 90 | [DllImport(LibHackRF, EntryPoint = "hackrf_compute_baseband_filter_bw", CallingConvention = CallingConvention.StdCall)] 91 | public static extern uint hackrf_compute_baseband_filter_bw(uint bandwidth_hz); 92 | 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/HackRF/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // General Information about an assembly is controlled through the following 4 | // set of attributes. Change these attribute values to modify the information 5 | // associated with an assembly. 6 | [assembly: AssemblyTitle("HackRF Controller")] 7 | [assembly: AssemblyDescription("USB interface for HackRF")] 8 | [assembly: AssemblyProduct("SDR#")] 9 | [assembly: AssemblyCopyright("Copyright © Youssef TOUIL 2012")] 10 | -------------------------------------------------------------------------------- /src/HackRF/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:2.0.50727.3603 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SDRSharp.HackRF.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SDRSharp.HackRF.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/HackRF/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /src/HackRF/SDRSharp.HackRF.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {4B73C0E7-E153-4B28-AC50-C4EAB3973DFB} 9 | Library 10 | Properties 11 | SDRSharp.HackRF 12 | SDRSharp.HackRF 13 | v3.5 14 | 512 15 | Always 16 | False 17 | 18 | 19 | 20 | 21 | 3.5 22 | 23 | 24 | true 25 | full 26 | false 27 | ..\Debug\ 28 | TRACE;DEBUG;MANAGED_ONLY 29 | prompt 30 | 4 31 | true 32 | 33 | 34 | pdbonly 35 | true 36 | ..\Release\ 37 | TRACE;MANAGED_ONLY 38 | prompt 39 | 4 40 | true 41 | 42 | 43 | true 44 | ..\Debug\ 45 | DEBUG;TRACE 46 | full 47 | x86 48 | prompt 49 | true 50 | 51 | 52 | ..\Release\ 53 | 54 | 55 | true 56 | pdbonly 57 | x86 58 | prompt 59 | true 60 | 61 | 62 | 63 | 64 | 3.5 65 | 66 | 67 | 68 | 69 | 3.5 70 | 71 | 72 | 3.5 73 | 74 | 75 | 76 | 77 | 78 | 79 | Resources.resx 80 | True 81 | True 82 | 83 | 84 | Form 85 | 86 | 87 | HackRFControllerDialog.cs 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | {1E08E7FD-5A13-454D-ADBD-C1A0B75ECF2D} 97 | SDRSharp.Radio 98 | 99 | 100 | 101 | 102 | ResXFileCodeGenerator 103 | Resources.Designer.cs 104 | Designer 105 | 106 | 107 | HackRFControllerDialog.cs 108 | Designer 109 | 110 | 111 | 112 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | --------------------------------------------------------------------------------