├── packages.config ├── app.config ├── .gitattributes ├── README.md ├── Properties ├── DataSources │ ├── telive.usi.datasource │ ├── telive.tfreq.datasource │ └── telive.receiver.datasource ├── Resources.Designer.cs └── Resources.resx ├── frmSDS.cs ├── Program.cs ├── frmMain.cs ├── frmMode.cs ├── frmTune.cs ├── frmSDS.Designer.cs ├── frmMode.Designer.cs ├── wintelive.csproj ├── frmTune.Designer.cs ├── frmMain.resx ├── frmMode.resx ├── frmSDS.resx ├── frmTune.resx ├── .gitignore ├── frmFreq.resx ├── frmMain.Designer.cs ├── frmFreq.cs ├── frmFreq.Designer.cs └── wtl-structures.cs /packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WinTelive 2 | telive compatible frontend for Windows 3 | (similar to my other projects - this was abandoned once it was working 4 | enough for community to take over and fork/patch. i got out of the SDR 5 | scene so i don't have the motivation to maintain this) 6 | 7 | 8 | Still pretty much work in progress but more or less working Windows port of telive. 9 | You just feed it data from tetra-rx and connect it to running GNURadio companion 10 | project. Currently only working the the XMLRPC version of the projects, completely 11 | passive mode to come later. 12 | -------------------------------------------------------------------------------- /Properties/DataSources/telive.usi.datasource: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | wintelive.telive+usi, wintelive, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /Properties/DataSources/telive.tfreq.datasource: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | wintelive.telive+tfreq, wintelive, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /Properties/DataSources/telive.receiver.datasource: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | wintelive.telive+receiver, wintelive, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /frmSDS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace wintelive 12 | { 13 | public partial class frmSDS : Form 14 | { 15 | public frmSDS() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | public void addMsg(string data) 21 | { 22 | txtSDS.AppendText(string.Format("[{0:HH:mm:ss}] {1}{2}", DateTime.Now, data, Environment.NewLine)); 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using System.Net.Sockets; 6 | using System.Net; 7 | using System.Threading; 8 | using System.ComponentModel; 9 | using System.Data; 10 | using System.Drawing; 11 | using System.Text; 12 | using System.Globalization; 13 | using System.IO; 14 | 15 | namespace wintelive 16 | { 17 | static class Program 18 | { 19 | 20 | /// 21 | /// The main entry point for the application. 22 | /// 23 | [STAThread] 24 | static void Main() 25 | { 26 | Application.EnableVisualStyles(); 27 | Application.SetCompatibleTextRenderingDefault(false); 28 | //Application.Run(new frmMain()); 29 | telive.fmInit(); 30 | } 31 | 32 | 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /frmMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Threading; 4 | 5 | namespace wintelive 6 | { 7 | public partial class frmMain : Form 8 | { 9 | frmFreq ff = new frmFreq(); 10 | short verbosity = 0; 11 | 12 | public frmMain() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | private void frmMain_Load(object sender, EventArgs e) 18 | { 19 | 20 | 21 | } 22 | 23 | 24 | private void btnInitGNR_Click(object sender, EventArgs e) 25 | { 26 | settings.allScanLow = double.Parse(txtRangeLow.Text); 27 | settings.allScanHigh = double.Parse(txtRangeHigh.Text); 28 | 29 | gnuradio.init(txtHost.Text, ushort.Parse(txtPort.Text)); 30 | telive.startAll(); 31 | grpGnuradio.Enabled = false; 32 | telive.ffInit(this); 33 | telive.fsInit(); 34 | 35 | 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /frmMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace wintelive 11 | { 12 | public partial class frmMode : Form 13 | { 14 | public frmMode(ushort rxid) 15 | { 16 | InitializeComponent(); 17 | cmbRx.DataSource = telive.rxs; 18 | cmbRx.DisplayMember = "id"; 19 | cmbRx.ValueMember = "id"; 20 | if (rxid > 0) 21 | { 22 | cmbRx.SelectedValue = rxid; 23 | } 24 | cmbMode.DataSource = Enum.GetValues(typeof(telive.rx_mode)); 25 | telive.receiver rxo = telive.rxs.FirstOrDefault(w => w.id == rxid); 26 | if (rxo != null) 27 | cmbMode.SelectedItem = rxo.mode; 28 | } 29 | 30 | private void btnMode_Click(object sender, EventArgs e) 31 | { 32 | telive.receiver rx = (telive.receiver)cmbRx.SelectedItem; 33 | telive.rx_mode mode = (telive.rx_mode)cmbMode.SelectedItem; 34 | if (!telive.rxChangeMode(rx.id, mode)) 35 | { 36 | MessageBox.Show("Some receiver is already in band scanning mode."); 37 | } 38 | else 39 | { 40 | this.Close(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /frmTune.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace wintelive 11 | { 12 | public partial class frmTune : Form 13 | { 14 | public frmTune(ushort rxid, double freq) 15 | { 16 | InitializeComponent(); 17 | cmbRx.DataSource = telive.rxs; 18 | cmbRx.DisplayMember = "id"; 19 | cmbRx.ValueMember = "id"; 20 | if (rxid > 0) 21 | { 22 | cmbRx.SelectedValue = rxid; 23 | } 24 | if (freq > 0) 25 | { 26 | txtFreq.Text = string.Format("{0}", freq); 27 | } 28 | else 29 | { 30 | telive.receiver rxo = telive.rxs.FirstOrDefault(w => w.id == rxid); 31 | if (rxo != null) 32 | txtFreq.Text = string.Format("{0}", rxo.freq); 33 | } 34 | 35 | } 36 | 37 | private void btnTune_Click(object sender, EventArgs e) 38 | { 39 | telive.receiver rx = (telive.receiver)cmbRx.SelectedItem; 40 | if (telive.rxTuneSafe(rx.id, double.Parse(txtFreq.Text), chkForce.Checked)) 41 | { 42 | this.Close(); 43 | } 44 | else 45 | { 46 | MessageBox.Show("Cannot tune receiver!", "Receiver tune", MessageBoxButtons.OK, MessageBoxIcon.Error); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /frmSDS.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace wintelive 2 | { 3 | partial class frmSDS 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.txtSDS = new System.Windows.Forms.TextBox(); 32 | this.SuspendLayout(); 33 | // 34 | // txtSDS 35 | // 36 | this.txtSDS.Location = new System.Drawing.Point(12, 12); 37 | this.txtSDS.Multiline = true; 38 | this.txtSDS.Name = "txtSDS"; 39 | this.txtSDS.ReadOnly = true; 40 | this.txtSDS.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 41 | this.txtSDS.Size = new System.Drawing.Size(588, 356); 42 | this.txtSDS.TabIndex = 0; 43 | // 44 | // frmSDS 45 | // 46 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 47 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 48 | this.ClientSize = new System.Drawing.Size(612, 380); 49 | this.Controls.Add(this.txtSDS); 50 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 51 | this.MaximizeBox = false; 52 | this.MinimizeBox = false; 53 | this.Name = "frmSDS"; 54 | this.Text = "SDS Messages"; 55 | this.ResumeLayout(false); 56 | this.PerformLayout(); 57 | 58 | } 59 | 60 | #endregion 61 | 62 | private System.Windows.Forms.TextBox txtSDS; 63 | } 64 | } -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 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 wintelive.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", "4.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("wintelive.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 | -------------------------------------------------------------------------------- /frmMode.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace wintelive 2 | { 3 | partial class frmMode 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.btnMode = new System.Windows.Forms.Button(); 32 | this.cmbRx = new System.Windows.Forms.ComboBox(); 33 | this.lblMode = new System.Windows.Forms.Label(); 34 | this.lblRx = new System.Windows.Forms.Label(); 35 | this.cmbMode = new System.Windows.Forms.ComboBox(); 36 | this.SuspendLayout(); 37 | // 38 | // btnMode 39 | // 40 | this.btnMode.Location = new System.Drawing.Point(68, 87); 41 | this.btnMode.Name = "btnMode"; 42 | this.btnMode.Size = new System.Drawing.Size(80, 23); 43 | this.btnMode.TabIndex = 9; 44 | this.btnMode.Text = "Set!"; 45 | this.btnMode.UseVisualStyleBackColor = true; 46 | this.btnMode.Click += new System.EventHandler(this.btnMode_Click); 47 | // 48 | // cmbRx 49 | // 50 | this.cmbRx.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 51 | this.cmbRx.FormattingEnabled = true; 52 | this.cmbRx.Location = new System.Drawing.Point(84, 15); 53 | this.cmbRx.Name = "cmbRx"; 54 | this.cmbRx.Size = new System.Drawing.Size(121, 21); 55 | this.cmbRx.TabIndex = 8; 56 | // 57 | // lblMode 58 | // 59 | this.lblMode.AutoSize = true; 60 | this.lblMode.Location = new System.Drawing.Point(12, 45); 61 | this.lblMode.Name = "lblMode"; 62 | this.lblMode.Size = new System.Drawing.Size(34, 13); 63 | this.lblMode.TabIndex = 6; 64 | this.lblMode.Text = "Mode"; 65 | // 66 | // lblRx 67 | // 68 | this.lblRx.AutoSize = true; 69 | this.lblRx.Location = new System.Drawing.Point(12, 18); 70 | this.lblRx.Name = "lblRx"; 71 | this.lblRx.Size = new System.Drawing.Size(53, 13); 72 | this.lblRx.TabIndex = 5; 73 | this.lblRx.Text = "Receiver:"; 74 | // 75 | // cmbMode 76 | // 77 | this.cmbMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 78 | this.cmbMode.FormattingEnabled = true; 79 | this.cmbMode.Location = new System.Drawing.Point(84, 42); 80 | this.cmbMode.Name = "cmbMode"; 81 | this.cmbMode.Size = new System.Drawing.Size(121, 21); 82 | this.cmbMode.TabIndex = 10; 83 | // 84 | // frmMode 85 | // 86 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 87 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 88 | this.ClientSize = new System.Drawing.Size(226, 132); 89 | this.Controls.Add(this.cmbMode); 90 | this.Controls.Add(this.btnMode); 91 | this.Controls.Add(this.cmbRx); 92 | this.Controls.Add(this.lblMode); 93 | this.Controls.Add(this.lblRx); 94 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 95 | this.MaximizeBox = false; 96 | this.MinimizeBox = false; 97 | this.Name = "frmMode"; 98 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 99 | this.Text = "Switch receiver mode"; 100 | this.ResumeLayout(false); 101 | this.PerformLayout(); 102 | 103 | } 104 | 105 | #endregion 106 | 107 | private System.Windows.Forms.Button btnMode; 108 | private System.Windows.Forms.ComboBox cmbRx; 109 | private System.Windows.Forms.Label lblMode; 110 | private System.Windows.Forms.Label lblRx; 111 | private System.Windows.Forms.ComboBox cmbMode; 112 | } 113 | } -------------------------------------------------------------------------------- /wintelive.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {18FAE5BF-0CA2-477D-A42B-C0C1F09389F5} 8 | WinExe 9 | Properties 10 | wintelive 11 | wintelive 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | x86 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | wintelive.Program 39 | 40 | 41 | true 42 | 43 | 44 | 45 | packages\NAudio.1.7.3\lib\net35\NAudio.dll 46 | True 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Form 63 | 64 | 65 | frmFreq.cs 66 | 67 | 68 | Form 69 | 70 | 71 | frmMain.cs 72 | 73 | 74 | Form 75 | 76 | 77 | frmMode.cs 78 | 79 | 80 | Form 81 | 82 | 83 | frmSDS.cs 84 | 85 | 86 | Form 87 | 88 | 89 | frmTune.cs 90 | 91 | 92 | 93 | True 94 | True 95 | Resources.resx 96 | 97 | 98 | 99 | frmFreq.cs 100 | 101 | 102 | frmMain.cs 103 | 104 | 105 | frmMode.cs 106 | 107 | 108 | frmSDS.cs 109 | 110 | 111 | frmTune.cs 112 | 113 | 114 | ResXFileCodeGenerator 115 | Resources.Designer.cs 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 131 | -------------------------------------------------------------------------------- /frmTune.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace wintelive 2 | { 3 | partial class frmTune 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.lblRx = new System.Windows.Forms.Label(); 32 | this.lblFreq = new System.Windows.Forms.Label(); 33 | this.txtFreq = new System.Windows.Forms.TextBox(); 34 | this.cmbRx = new System.Windows.Forms.ComboBox(); 35 | this.btnTune = new System.Windows.Forms.Button(); 36 | this.lblHz = new System.Windows.Forms.Label(); 37 | this.chkForce = new System.Windows.Forms.CheckBox(); 38 | this.SuspendLayout(); 39 | // 40 | // lblRx 41 | // 42 | this.lblRx.AutoSize = true; 43 | this.lblRx.Location = new System.Drawing.Point(10, 18); 44 | this.lblRx.Name = "lblRx"; 45 | this.lblRx.Size = new System.Drawing.Size(53, 13); 46 | this.lblRx.TabIndex = 0; 47 | this.lblRx.Text = "Receiver:"; 48 | // 49 | // lblFreq 50 | // 51 | this.lblFreq.AutoSize = true; 52 | this.lblFreq.Location = new System.Drawing.Point(10, 45); 53 | this.lblFreq.Name = "lblFreq"; 54 | this.lblFreq.Size = new System.Drawing.Size(57, 13); 55 | this.lblFreq.TabIndex = 1; 56 | this.lblFreq.Text = "Frequency"; 57 | // 58 | // txtFreq 59 | // 60 | this.txtFreq.Location = new System.Drawing.Point(82, 42); 61 | this.txtFreq.Name = "txtFreq"; 62 | this.txtFreq.Size = new System.Drawing.Size(93, 20); 63 | this.txtFreq.TabIndex = 2; 64 | this.txtFreq.Text = ""; 65 | this.txtFreq.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 66 | // 67 | // cmbRx 68 | // 69 | this.cmbRx.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 70 | this.cmbRx.FormattingEnabled = true; 71 | this.cmbRx.Location = new System.Drawing.Point(82, 15); 72 | this.cmbRx.Name = "cmbRx"; 73 | this.cmbRx.Size = new System.Drawing.Size(121, 21); 74 | this.cmbRx.TabIndex = 3; 75 | // 76 | // btnTune 77 | // 78 | this.btnTune.Location = new System.Drawing.Point(73, 103); 79 | this.btnTune.Name = "btnTune"; 80 | this.btnTune.Size = new System.Drawing.Size(80, 23); 81 | this.btnTune.TabIndex = 4; 82 | this.btnTune.Text = "Tune!"; 83 | this.btnTune.UseVisualStyleBackColor = true; 84 | this.btnTune.Click += new System.EventHandler(this.btnTune_Click); 85 | // 86 | // lblHz 87 | // 88 | this.lblHz.AutoSize = true; 89 | this.lblHz.Location = new System.Drawing.Point(181, 45); 90 | this.lblHz.Name = "lblHz"; 91 | this.lblHz.Size = new System.Drawing.Size(20, 13); 92 | this.lblHz.TabIndex = 5; 93 | this.lblHz.Text = "Hz"; 94 | // 95 | // chkForce 96 | // 97 | this.chkForce.AutoSize = true; 98 | this.chkForce.Location = new System.Drawing.Point(13, 73); 99 | this.chkForce.Name = "chkForce"; 100 | this.chkForce.Size = new System.Drawing.Size(210, 17); 101 | this.chkForce.TabIndex = 6; 102 | this.chkForce.Text = "Tune even if baseband need changing"; 103 | this.chkForce.UseVisualStyleBackColor = true; 104 | // 105 | // frmTune 106 | // 107 | this.AcceptButton = this.btnTune; 108 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 109 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 110 | this.ClientSize = new System.Drawing.Size(228, 138); 111 | this.Controls.Add(this.chkForce); 112 | this.Controls.Add(this.lblHz); 113 | this.Controls.Add(this.btnTune); 114 | this.Controls.Add(this.cmbRx); 115 | this.Controls.Add(this.txtFreq); 116 | this.Controls.Add(this.lblFreq); 117 | this.Controls.Add(this.lblRx); 118 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 119 | this.MaximizeBox = false; 120 | this.MinimizeBox = false; 121 | this.Name = "frmTune"; 122 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 123 | this.Text = "Tune receiver"; 124 | this.ResumeLayout(false); 125 | this.PerformLayout(); 126 | 127 | } 128 | 129 | #endregion 130 | 131 | private System.Windows.Forms.Label lblRx; 132 | private System.Windows.Forms.Label lblFreq; 133 | private System.Windows.Forms.TextBox txtFreq; 134 | private System.Windows.Forms.ComboBox cmbRx; 135 | private System.Windows.Forms.Button btnTune; 136 | private System.Windows.Forms.Label lblHz; 137 | private System.Windows.Forms.CheckBox chkForce; 138 | } 139 | } -------------------------------------------------------------------------------- /frmMain.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 | -------------------------------------------------------------------------------- /frmMode.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 | -------------------------------------------------------------------------------- /frmSDS.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 | -------------------------------------------------------------------------------- /frmTune.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # ========================= 255 | # Operating System Files 256 | # ========================= 257 | 258 | # OSX 259 | # ========================= 260 | 261 | .DS_Store 262 | .AppleDouble 263 | .LSOverride 264 | 265 | # Thumbnails 266 | ._* 267 | 268 | # Files that might appear in the root of a volume 269 | .DocumentRevisions-V100 270 | .fseventsd 271 | .Spotlight-V100 272 | .TemporaryItems 273 | .Trashes 274 | .VolumeIcon.icns 275 | 276 | # Directories potentially created on remote AFP share 277 | .AppleDB 278 | .AppleDesktop 279 | Network Trash Folder 280 | Temporary Items 281 | .apdisk 282 | 283 | # Windows 284 | # ========================= 285 | 286 | # Windows image file caches 287 | Thumbs.db 288 | ehthumbs.db 289 | 290 | # Folder config file 291 | Desktop.ini 292 | 293 | # Recycle Bin used on file shares 294 | $RECYCLE.BIN/ 295 | 296 | # Windows Installer files 297 | *.cab 298 | *.msi 299 | *.msm 300 | *.msp 301 | 302 | # Windows shortcuts 303 | *.lnk 304 | *.sln 305 | -------------------------------------------------------------------------------- /frmFreq.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 | 121 | 461, 17 122 | 123 | 124 | 163, 17 125 | 126 | 127 | True 128 | 129 | 130 | 299, 17 131 | 132 | 133 | 617, 17 134 | 135 | 136 | 728, 17 137 | 138 | 139 | 56 140 | 141 | -------------------------------------------------------------------------------- /frmMain.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace wintelive 2 | { 3 | partial class frmMain 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.grpGnuradio = new System.Windows.Forms.GroupBox(); 32 | this.txtUdp = new System.Windows.Forms.TextBox(); 33 | this.lblUdp = new System.Windows.Forms.Label(); 34 | this.txtPort = new System.Windows.Forms.TextBox(); 35 | this.txtHost = new System.Windows.Forms.TextBox(); 36 | this.lblPort = new System.Windows.Forms.Label(); 37 | this.lblHost = new System.Windows.Forms.Label(); 38 | this.btnInitGNR = new System.Windows.Forms.Button(); 39 | this.txtRangeHigh = new System.Windows.Forms.TextBox(); 40 | this.txtRangeLow = new System.Windows.Forms.TextBox(); 41 | this.lblRange = new System.Windows.Forms.Label(); 42 | this.grpGnuradio.SuspendLayout(); 43 | this.SuspendLayout(); 44 | // 45 | // grpGnuradio 46 | // 47 | this.grpGnuradio.Controls.Add(this.txtRangeHigh); 48 | this.grpGnuradio.Controls.Add(this.txtRangeLow); 49 | this.grpGnuradio.Controls.Add(this.lblRange); 50 | this.grpGnuradio.Controls.Add(this.txtUdp); 51 | this.grpGnuradio.Controls.Add(this.lblUdp); 52 | this.grpGnuradio.Controls.Add(this.txtPort); 53 | this.grpGnuradio.Controls.Add(this.txtHost); 54 | this.grpGnuradio.Controls.Add(this.lblPort); 55 | this.grpGnuradio.Controls.Add(this.lblHost); 56 | this.grpGnuradio.Controls.Add(this.btnInitGNR); 57 | this.grpGnuradio.Location = new System.Drawing.Point(12, 12); 58 | this.grpGnuradio.Name = "grpGnuradio"; 59 | this.grpGnuradio.Size = new System.Drawing.Size(231, 221); 60 | this.grpGnuradio.TabIndex = 16; 61 | this.grpGnuradio.TabStop = false; 62 | this.grpGnuradio.Text = "GNU Radio"; 63 | // 64 | // txtUdp 65 | // 66 | this.txtUdp.Location = new System.Drawing.Point(109, 72); 67 | this.txtUdp.Name = "txtUdp"; 68 | this.txtUdp.Size = new System.Drawing.Size(100, 20); 69 | this.txtUdp.TabIndex = 22; 70 | this.txtUdp.Text = "7379"; 71 | this.txtUdp.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 72 | // 73 | // lblUdp 74 | // 75 | this.lblUdp.AutoSize = true; 76 | this.lblUdp.Location = new System.Drawing.Point(18, 75); 77 | this.lblUdp.Name = "lblUdp"; 78 | this.lblUdp.Size = new System.Drawing.Size(78, 13); 79 | this.lblUdp.TabIndex = 21; 80 | this.lblUdp.Text = "UDP listen port"; 81 | // 82 | // txtPort 83 | // 84 | this.txtPort.Location = new System.Drawing.Point(109, 46); 85 | this.txtPort.Name = "txtPort"; 86 | this.txtPort.Size = new System.Drawing.Size(100, 20); 87 | this.txtPort.TabIndex = 20; 88 | this.txtPort.Text = "42000"; 89 | this.txtPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 90 | // 91 | // txtHost 92 | // 93 | this.txtHost.Location = new System.Drawing.Point(109, 20); 94 | this.txtHost.Name = "txtHost"; 95 | this.txtHost.Size = new System.Drawing.Size(100, 20); 96 | this.txtHost.TabIndex = 19; 97 | this.txtHost.Text = "127.0.0.1"; 98 | // 99 | // lblPort 100 | // 101 | this.lblPort.AutoSize = true; 102 | this.lblPort.Location = new System.Drawing.Point(18, 49); 103 | this.lblPort.Name = "lblPort"; 104 | this.lblPort.Size = new System.Drawing.Size(75, 13); 105 | this.lblPort.TabIndex = 18; 106 | this.lblPort.Text = "XML RPC port"; 107 | // 108 | // lblHost 109 | // 110 | this.lblHost.AutoSize = true; 111 | this.lblHost.Location = new System.Drawing.Point(18, 23); 112 | this.lblHost.Name = "lblHost"; 113 | this.lblHost.Size = new System.Drawing.Size(77, 13); 114 | this.lblHost.TabIndex = 17; 115 | this.lblHost.Text = "XML RPC host"; 116 | // 117 | // btnInitGNR 118 | // 119 | this.btnInitGNR.Location = new System.Drawing.Point(149, 172); 120 | this.btnInitGNR.Name = "btnInitGNR"; 121 | this.btnInitGNR.Size = new System.Drawing.Size(60, 28); 122 | this.btnInitGNR.TabIndex = 16; 123 | this.btnInitGNR.Text = "Connect"; 124 | this.btnInitGNR.UseVisualStyleBackColor = true; 125 | this.btnInitGNR.Click += new System.EventHandler(this.btnInitGNR_Click); 126 | // 127 | // txtRangeHigh 128 | // 129 | this.txtRangeHigh.Location = new System.Drawing.Point(109, 137); 130 | this.txtRangeHigh.Name = "txtRangeHigh"; 131 | this.txtRangeHigh.Size = new System.Drawing.Size(100, 20); 132 | this.txtRangeHigh.TabIndex = 25; 133 | this.txtRangeHigh.Text = "430000000"; 134 | this.txtRangeHigh.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 135 | // 136 | // txtRangeLow 137 | // 138 | this.txtRangeLow.Location = new System.Drawing.Point(109, 111); 139 | this.txtRangeLow.Name = "txtRangeLow"; 140 | this.txtRangeLow.Size = new System.Drawing.Size(100, 20); 141 | this.txtRangeLow.TabIndex = 24; 142 | this.txtRangeLow.Text = "420000000"; 143 | this.txtRangeLow.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 144 | // 145 | // lblRange 146 | // 147 | this.lblRange.AutoSize = true; 148 | this.lblRange.Location = new System.Drawing.Point(18, 114); 149 | this.lblRange.Name = "lblRange"; 150 | this.lblRange.Size = new System.Drawing.Size(90, 13); 151 | this.lblRange.TabIndex = 23; 152 | this.lblRange.Text = "Frequency range:"; 153 | // 154 | // frmMain 155 | // 156 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 157 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 158 | this.ClientSize = new System.Drawing.Size(260, 248); 159 | this.Controls.Add(this.grpGnuradio); 160 | this.Name = "frmMain"; 161 | this.Text = "WinTelive"; 162 | this.Load += new System.EventHandler(this.frmMain_Load); 163 | this.grpGnuradio.ResumeLayout(false); 164 | this.grpGnuradio.PerformLayout(); 165 | this.ResumeLayout(false); 166 | 167 | } 168 | 169 | #endregion 170 | private System.Windows.Forms.GroupBox grpGnuradio; 171 | private System.Windows.Forms.TextBox txtUdp; 172 | private System.Windows.Forms.Label lblUdp; 173 | private System.Windows.Forms.TextBox txtPort; 174 | private System.Windows.Forms.TextBox txtHost; 175 | private System.Windows.Forms.Label lblPort; 176 | private System.Windows.Forms.Label lblHost; 177 | private System.Windows.Forms.Button btnInitGNR; 178 | private System.Windows.Forms.TextBox txtRangeHigh; 179 | private System.Windows.Forms.TextBox txtRangeLow; 180 | private System.Windows.Forms.Label lblRange; 181 | } 182 | } 183 | 184 | -------------------------------------------------------------------------------- /frmFreq.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Windows.Forms; 10 | using wintelive; 11 | 12 | namespace wintelive 13 | { 14 | public partial class frmFreq : Form 15 | { 16 | 17 | public frmFreq() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | public void bindFreqs() 23 | { 24 | BindingSource bs = new BindingSource(telive.freqs.OrderBy(w => w.dl_freq), null); 25 | grdFreqs.DataSource = bs; 26 | } 27 | 28 | public void rebindFreqs() 29 | { 30 | int rScroll = grdFreqs.FirstDisplayedScrollingRowIndex; 31 | 32 | int rSel = -1; 33 | if (grdFreqs.SelectedRows.Count > 0) 34 | rSel = grdFreqs.SelectedRows[0].Index; 35 | 36 | bindFreqs(); 37 | 38 | if (rSel != -1) 39 | { 40 | rSel = Math.Min(rSel, grdFreqs.Rows.Count - 1); 41 | grdFreqs.Rows[rSel].Selected = true; 42 | 43 | } 44 | 45 | rScroll = Math.Min(rScroll, grdFreqs.Rows.Count - 1); 46 | grdFreqs.FirstDisplayedScrollingRowIndex = rScroll; 47 | 48 | } 49 | 50 | public void bindUSIs() 51 | { 52 | BindingSource bs = new BindingSource(telive.usis.OrderBy(w => w.id), null); 53 | grdUSIs.DataSource = bs; 54 | } 55 | 56 | public void bindRXs() 57 | { 58 | BindingSource bs = new BindingSource(telive.rxs.OrderBy(w => w.id), null); 59 | grdRXs.DataSource = bs; 60 | } 61 | 62 | private void frmFreq_Load(object sender, EventArgs e) 63 | { 64 | bindFreqs(); 65 | bindRXs(); 66 | bindUSIs(); 67 | tmrRefresh.Enabled = true; 68 | } 69 | 70 | private void grdRXs_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 71 | { 72 | ushort rxid = 0; 73 | if (e.RowIndex != -1) 74 | { 75 | rxid = (ushort)grdRXs[0, e.RowIndex].Value; 76 | } 77 | switch (e.ColumnIndex) 78 | { 79 | case 2: 80 | frmTune ft = new frmTune(rxid, 0); 81 | ft.Show(); 82 | break; 83 | 84 | case 5: 85 | frmMode fm = new frmMode(rxid); 86 | fm.Show(); 87 | break; 88 | } 89 | 90 | } 91 | 92 | private void grdFreqs_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 93 | { 94 | double nfreq = (double)grdFreqs[2, e.RowIndex].Value; 95 | telive.receiver rx = telive.rxs.FirstOrDefault(w => w.mode == telive.rx_mode.OFF); 96 | ushort rxid = (rx != null ? rx.id : (ushort)0); 97 | frmTune ft = new frmTune(rxid, nfreq); 98 | ft.Show(); 99 | } 100 | 101 | private void txtBase_KeyDown(object sender, KeyEventArgs e) 102 | { 103 | if (e.KeyCode == Keys.Enter) 104 | { 105 | double nfreq = double.Parse(txtBase.Text); 106 | if (!telive.baseSetSafe(nfreq)) 107 | { 108 | MessageBox.Show("Baseband frequency could not be changed!", "Baseband change", MessageBoxButtons.OK, MessageBoxIcon.Error); 109 | } 110 | e.Handled = true; 111 | e.SuppressKeyPress = true; 112 | } 113 | 114 | } 115 | 116 | private void chkLockBase_CheckedChanged(object sender, EventArgs e) 117 | { 118 | txtBase.Enabled = !chkLockBase.Checked; 119 | } 120 | 121 | private void lblBasefreq_Doubleclick(object sender, EventArgs e) 122 | { 123 | DialogResult drs = MessageBox.Show("Center baseband frequency?", "Center baseband", MessageBoxButtons.YesNo); 124 | if (drs == DialogResult.Yes) 125 | { 126 | telive.baseCenter(); 127 | } 128 | } 129 | 130 | private void btnTuneNew_Click(object sender, EventArgs e) 131 | { 132 | telive.tuneAllFree(); 133 | } 134 | 135 | public void grdFreqSelect(double freq) 136 | { 137 | grdFreqs.ClearSelection(); 138 | foreach (DataGridViewRow radek in grdFreqs.Rows) 139 | { 140 | if ((double)radek.Cells[2].Value == freq) 141 | { 142 | radek.Selected = true; 143 | grdFreqs.FirstDisplayedScrollingRowIndex = radek.Index; 144 | } 145 | } 146 | } 147 | 148 | public void grdRXsSelect(ushort rxid) 149 | { 150 | grdRXs.ClearSelection(); 151 | grdRXs.Rows[rxid].Selected = true; 152 | grdRXs.FirstDisplayedScrollingRowIndex = rxid; 153 | } 154 | 155 | private void tmrRefresh_Tick(object sender, EventArgs e) 156 | { 157 | if (!txtBase.Focused) 158 | txtBase.Text = gnuradio.basefreq.ToString(); 159 | 160 | rebindFreqs(); 161 | grdRXs.Invalidate(); 162 | bindUSIs(); 163 | guiDrawGraph(); 164 | 165 | } 166 | 167 | private void guiDrawGraph() 168 | { 169 | int ix = picFreqGraph.Width; 170 | int iy = picFreqGraph.Height; 171 | Bitmap bmp = new Bitmap(ix, iy); 172 | Graphics gr = Graphics.FromImage(bmp); 173 | gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 174 | int x1, x2; 175 | 176 | Brush bandBrush = new SolidBrush(Color.LightYellow); 177 | Pen bandCenterPen = new Pen(Color.Orange); 178 | Brush freqBrush = new SolidBrush(Color.Blue); 179 | Brush freqSlaveBrush = new SolidBrush(Color.LightBlue); 180 | Brush rxOffBrush = new SolidBrush(Color.FromArgb(128, 128, 128, 128)); 181 | Brush rxTunedBrush = new SolidBrush(Color.Cyan); 182 | Brush rxScanBrush = new SolidBrush(Color.FromArgb(128, 255, 0, 0)); 183 | Brush textBrush = new SolidBrush(Color.Black); 184 | Font rxFont = new Font(FontFamily.GenericSansSerif, 7); 185 | 186 | // baseband rect 187 | x1 = telive.guiFreqToX(gnuradio.lowRange()); 188 | x2 = telive.guiFreqToX(gnuradio.HighRange()) - x1; 189 | Rectangle bandRect = new Rectangle(x1, 0, x2, iy - 1); 190 | gr.FillRectangle(bandBrush, bandRect); 191 | gr.DrawRectangle(bandCenterPen, bandRect); 192 | x1 = telive.guiFreqToX(gnuradio.basefreq); 193 | gr.DrawLine(bandCenterPen, x1, 1, x1, iy - 2); 194 | 195 | // frequencies 196 | foreach (telive.frequency fre in telive.freqs) 197 | { 198 | x1 = telive.guiFreqToX(fre.dl_freq - gnuradio.cbw / 2); 199 | x2 = telive.guiFreqToX(fre.dl_freq + gnuradio.cbw / 2) - x1; 200 | Rectangle freqRect = new Rectangle(x1, 10, x2, iy - 12); 201 | gr.FillRectangle((fre.mcc != 0 && fre.mnc != 0 ? freqBrush : freqSlaveBrush), freqRect); 202 | } 203 | 204 | // receivers 205 | foreach (telive.receiver rx in telive.rxs) 206 | { 207 | x1 = telive.guiFreqToX(rx.freq - gnuradio.cbw / 2); 208 | x2 = telive.guiFreqToX(rx.freq + gnuradio.cbw / 2) - x1; 209 | Rectangle rxRect = new Rectangle(x1, 20, x2, iy - 22); 210 | Brush thisbrush; 211 | switch (rx.mode) 212 | { 213 | case telive.rx_mode.OFF: thisbrush = rxOffBrush; break; 214 | case telive.rx_mode.TUNED: thisbrush = rxTunedBrush; break; 215 | default: thisbrush = rxScanBrush; break; 216 | } 217 | gr.FillRectangle(thisbrush, rxRect); 218 | if (rx.mode == telive.rx_mode.TUNED || rx.mode == telive.rx_mode.BANDSCAN) 219 | { 220 | x1 = telive.guiFreqToX(rx.freq); 221 | gr.DrawString(rx.id.ToString(), rxFont, textBrush, x1 - 5, -1); 222 | } 223 | } 224 | 225 | picFreqGraph.Image = bmp; 226 | } 227 | 228 | private void tmrAutotune_Tick(object sender, EventArgs e) 229 | { 230 | telive.tuneAllFree(); 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /frmFreq.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace wintelive 2 | { 3 | partial class frmFreq 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 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); 33 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); 34 | this.grdFreqs = new System.Windows.Forms.DataGridView(); 35 | this.mccDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 36 | this.mncDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 37 | this.dlfreqDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 38 | this.ulfreqDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 39 | this.lalistDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 40 | this.cclistDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 41 | this.tunedrxDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 42 | this.tfreqBindingSource = new System.Windows.Forms.BindingSource(this.components); 43 | this.grdUSIs = new System.Windows.Forms.DataGridView(); 44 | this.idDataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); 45 | this.ssilistDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 46 | this.encrDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); 47 | this.activeDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); 48 | this.playingDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); 49 | this.cidDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 50 | this.lastrxDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 51 | this.usiBindingSource = new System.Windows.Forms.BindingSource(this.components); 52 | this.grdRXs = new System.Windows.Forms.DataGridView(); 53 | this.idDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 54 | this.afcDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 55 | this.freqDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 56 | this.lastseenDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 57 | this.lastburstDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); 58 | this.state = new System.Windows.Forms.DataGridViewTextBoxColumn(); 59 | this.receiverBindingSource = new System.Windows.Forms.BindingSource(this.components); 60 | this.lblUSIs = new System.Windows.Forms.Label(); 61 | this.lblRX = new System.Windows.Forms.Label(); 62 | this.lblFreqs = new System.Windows.Forms.Label(); 63 | this.lblHz = new System.Windows.Forms.Label(); 64 | this.lblBasefreq = new System.Windows.Forms.Label(); 65 | this.chkLockBase = new System.Windows.Forms.CheckBox(); 66 | this.chkTuneNew = new System.Windows.Forms.CheckBox(); 67 | this.txtBase = new System.Windows.Forms.TextBox(); 68 | this.btnTuneNew = new System.Windows.Forms.Button(); 69 | this.picFreqGraph = new System.Windows.Forms.PictureBox(); 70 | this.tmrRefresh = new System.Windows.Forms.Timer(this.components); 71 | this.tmrAutotune = new System.Windows.Forms.Timer(this.components); 72 | ((System.ComponentModel.ISupportInitialize)(this.grdFreqs)).BeginInit(); 73 | ((System.ComponentModel.ISupportInitialize)(this.tfreqBindingSource)).BeginInit(); 74 | ((System.ComponentModel.ISupportInitialize)(this.grdUSIs)).BeginInit(); 75 | ((System.ComponentModel.ISupportInitialize)(this.usiBindingSource)).BeginInit(); 76 | ((System.ComponentModel.ISupportInitialize)(this.grdRXs)).BeginInit(); 77 | ((System.ComponentModel.ISupportInitialize)(this.receiverBindingSource)).BeginInit(); 78 | ((System.ComponentModel.ISupportInitialize)(this.picFreqGraph)).BeginInit(); 79 | this.SuspendLayout(); 80 | // 81 | // grdFreqs 82 | // 83 | this.grdFreqs.AllowUserToAddRows = false; 84 | this.grdFreqs.AllowUserToDeleteRows = false; 85 | this.grdFreqs.AllowUserToResizeRows = false; 86 | this.grdFreqs.AutoGenerateColumns = false; 87 | this.grdFreqs.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 88 | this.grdFreqs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 89 | this.grdFreqs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 90 | this.mccDataGridViewTextBoxColumn, 91 | this.mncDataGridViewTextBoxColumn, 92 | this.dlfreqDataGridViewTextBoxColumn, 93 | this.ulfreqDataGridViewTextBoxColumn, 94 | this.lalistDataGridViewTextBoxColumn, 95 | this.cclistDataGridViewTextBoxColumn, 96 | this.tunedrxDataGridViewTextBoxColumn}); 97 | this.grdFreqs.DataSource = this.tfreqBindingSource; 98 | this.grdFreqs.Location = new System.Drawing.Point(465, 327); 99 | this.grdFreqs.MultiSelect = false; 100 | this.grdFreqs.Name = "grdFreqs"; 101 | this.grdFreqs.ReadOnly = true; 102 | this.grdFreqs.RowHeadersVisible = false; 103 | this.grdFreqs.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 104 | this.grdFreqs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 105 | this.grdFreqs.Size = new System.Drawing.Size(403, 191); 106 | this.grdFreqs.TabIndex = 2; 107 | this.grdFreqs.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.grdFreqs_CellDoubleClick); 108 | // 109 | // mccDataGridViewTextBoxColumn 110 | // 111 | this.mccDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 112 | this.mccDataGridViewTextBoxColumn.DataPropertyName = "mcc"; 113 | this.mccDataGridViewTextBoxColumn.HeaderText = "MCC"; 114 | this.mccDataGridViewTextBoxColumn.Name = "mccDataGridViewTextBoxColumn"; 115 | this.mccDataGridViewTextBoxColumn.ReadOnly = true; 116 | this.mccDataGridViewTextBoxColumn.Width = 55; 117 | // 118 | // mncDataGridViewTextBoxColumn 119 | // 120 | this.mncDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 121 | this.mncDataGridViewTextBoxColumn.DataPropertyName = "mnc"; 122 | this.mncDataGridViewTextBoxColumn.HeaderText = "MNC"; 123 | this.mncDataGridViewTextBoxColumn.Name = "mncDataGridViewTextBoxColumn"; 124 | this.mncDataGridViewTextBoxColumn.ReadOnly = true; 125 | this.mncDataGridViewTextBoxColumn.Width = 56; 126 | // 127 | // dlfreqDataGridViewTextBoxColumn 128 | // 129 | this.dlfreqDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 130 | this.dlfreqDataGridViewTextBoxColumn.DataPropertyName = "dl_freq"; 131 | this.dlfreqDataGridViewTextBoxColumn.HeaderText = "DLF"; 132 | this.dlfreqDataGridViewTextBoxColumn.Name = "dlfreqDataGridViewTextBoxColumn"; 133 | this.dlfreqDataGridViewTextBoxColumn.ReadOnly = true; 134 | this.dlfreqDataGridViewTextBoxColumn.Width = 52; 135 | // 136 | // ulfreqDataGridViewTextBoxColumn 137 | // 138 | this.ulfreqDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 139 | this.ulfreqDataGridViewTextBoxColumn.DataPropertyName = "ul_freq"; 140 | this.ulfreqDataGridViewTextBoxColumn.HeaderText = "ULF"; 141 | this.ulfreqDataGridViewTextBoxColumn.Name = "ulfreqDataGridViewTextBoxColumn"; 142 | this.ulfreqDataGridViewTextBoxColumn.ReadOnly = true; 143 | this.ulfreqDataGridViewTextBoxColumn.Width = 52; 144 | // 145 | // lalistDataGridViewTextBoxColumn 146 | // 147 | this.lalistDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 148 | this.lalistDataGridViewTextBoxColumn.DataPropertyName = "lalist"; 149 | this.lalistDataGridViewTextBoxColumn.HeaderText = "LAs"; 150 | this.lalistDataGridViewTextBoxColumn.Name = "lalistDataGridViewTextBoxColumn"; 151 | this.lalistDataGridViewTextBoxColumn.ReadOnly = true; 152 | // 153 | // cclistDataGridViewTextBoxColumn 154 | // 155 | this.cclistDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 156 | this.cclistDataGridViewTextBoxColumn.DataPropertyName = "cclist"; 157 | this.cclistDataGridViewTextBoxColumn.HeaderText = "CCs"; 158 | this.cclistDataGridViewTextBoxColumn.Name = "cclistDataGridViewTextBoxColumn"; 159 | this.cclistDataGridViewTextBoxColumn.ReadOnly = true; 160 | // 161 | // tunedrxDataGridViewTextBoxColumn 162 | // 163 | this.tunedrxDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 164 | this.tunedrxDataGridViewTextBoxColumn.DataPropertyName = "tunedrx"; 165 | this.tunedrxDataGridViewTextBoxColumn.HeaderText = "RX"; 166 | this.tunedrxDataGridViewTextBoxColumn.Name = "tunedrxDataGridViewTextBoxColumn"; 167 | this.tunedrxDataGridViewTextBoxColumn.ReadOnly = true; 168 | this.tunedrxDataGridViewTextBoxColumn.Width = 47; 169 | // 170 | // tfreqBindingSource 171 | // 172 | this.tfreqBindingSource.DataSource = typeof(wintelive.telive.frequency); 173 | // 174 | // grdUSIs 175 | // 176 | this.grdUSIs.AllowUserToAddRows = false; 177 | this.grdUSIs.AllowUserToDeleteRows = false; 178 | this.grdUSIs.AllowUserToResizeRows = false; 179 | this.grdUSIs.AutoGenerateColumns = false; 180 | this.grdUSIs.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 181 | this.grdUSIs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 182 | this.grdUSIs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 183 | this.idDataGridViewTextBoxColumn1, 184 | this.ssilistDataGridViewTextBoxColumn, 185 | this.encrDataGridViewCheckBoxColumn, 186 | this.activeDataGridViewCheckBoxColumn, 187 | this.playingDataGridViewCheckBoxColumn, 188 | this.cidDataGridViewTextBoxColumn, 189 | this.lastrxDataGridViewTextBoxColumn}); 190 | this.grdUSIs.DataSource = this.usiBindingSource; 191 | this.grdUSIs.Location = new System.Drawing.Point(12, 31); 192 | this.grdUSIs.MultiSelect = false; 193 | this.grdUSIs.Name = "grdUSIs"; 194 | this.grdUSIs.ReadOnly = true; 195 | this.grdUSIs.RowHeadersVisible = false; 196 | this.grdUSIs.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 197 | this.grdUSIs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 198 | this.grdUSIs.Size = new System.Drawing.Size(438, 487); 199 | this.grdUSIs.TabIndex = 0; 200 | // 201 | // idDataGridViewTextBoxColumn1 202 | // 203 | this.idDataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 204 | this.idDataGridViewTextBoxColumn1.DataPropertyName = "id"; 205 | this.idDataGridViewTextBoxColumn1.HeaderText = "ID"; 206 | this.idDataGridViewTextBoxColumn1.Name = "idDataGridViewTextBoxColumn1"; 207 | this.idDataGridViewTextBoxColumn1.ReadOnly = true; 208 | this.idDataGridViewTextBoxColumn1.Width = 43; 209 | // 210 | // ssilistDataGridViewTextBoxColumn 211 | // 212 | this.ssilistDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 213 | this.ssilistDataGridViewTextBoxColumn.DataPropertyName = "ssilist"; 214 | this.ssilistDataGridViewTextBoxColumn.HeaderText = "SSIs"; 215 | this.ssilistDataGridViewTextBoxColumn.Name = "ssilistDataGridViewTextBoxColumn"; 216 | this.ssilistDataGridViewTextBoxColumn.ReadOnly = true; 217 | // 218 | // encrDataGridViewCheckBoxColumn 219 | // 220 | this.encrDataGridViewCheckBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 221 | this.encrDataGridViewCheckBoxColumn.DataPropertyName = "encr"; 222 | this.encrDataGridViewCheckBoxColumn.HeaderText = "Encr"; 223 | this.encrDataGridViewCheckBoxColumn.Name = "encrDataGridViewCheckBoxColumn"; 224 | this.encrDataGridViewCheckBoxColumn.ReadOnly = true; 225 | this.encrDataGridViewCheckBoxColumn.Width = 35; 226 | // 227 | // activeDataGridViewCheckBoxColumn 228 | // 229 | this.activeDataGridViewCheckBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 230 | this.activeDataGridViewCheckBoxColumn.DataPropertyName = "active"; 231 | this.activeDataGridViewCheckBoxColumn.HeaderText = "Active"; 232 | this.activeDataGridViewCheckBoxColumn.Name = "activeDataGridViewCheckBoxColumn"; 233 | this.activeDataGridViewCheckBoxColumn.ReadOnly = true; 234 | this.activeDataGridViewCheckBoxColumn.Width = 43; 235 | // 236 | // playingDataGridViewCheckBoxColumn 237 | // 238 | this.playingDataGridViewCheckBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 239 | this.playingDataGridViewCheckBoxColumn.DataPropertyName = "playing"; 240 | this.playingDataGridViewCheckBoxColumn.HeaderText = "Playing"; 241 | this.playingDataGridViewCheckBoxColumn.Name = "playingDataGridViewCheckBoxColumn"; 242 | this.playingDataGridViewCheckBoxColumn.ReadOnly = true; 243 | this.playingDataGridViewCheckBoxColumn.Width = 47; 244 | // 245 | // cidDataGridViewTextBoxColumn 246 | // 247 | this.cidDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 248 | this.cidDataGridViewTextBoxColumn.DataPropertyName = "cid"; 249 | this.cidDataGridViewTextBoxColumn.HeaderText = "CalledID"; 250 | this.cidDataGridViewTextBoxColumn.Name = "cidDataGridViewTextBoxColumn"; 251 | this.cidDataGridViewTextBoxColumn.ReadOnly = true; 252 | this.cidDataGridViewTextBoxColumn.Width = 72; 253 | // 254 | // lastrxDataGridViewTextBoxColumn 255 | // 256 | this.lastrxDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 257 | this.lastrxDataGridViewTextBoxColumn.DataPropertyName = "lastrx"; 258 | this.lastrxDataGridViewTextBoxColumn.HeaderText = "RX"; 259 | this.lastrxDataGridViewTextBoxColumn.Name = "lastrxDataGridViewTextBoxColumn"; 260 | this.lastrxDataGridViewTextBoxColumn.ReadOnly = true; 261 | this.lastrxDataGridViewTextBoxColumn.Width = 47; 262 | // 263 | // usiBindingSource 264 | // 265 | this.usiBindingSource.DataSource = typeof(wintelive.telive.usi); 266 | // 267 | // grdRXs 268 | // 269 | this.grdRXs.AllowUserToAddRows = false; 270 | this.grdRXs.AllowUserToDeleteRows = false; 271 | this.grdRXs.AllowUserToResizeRows = false; 272 | this.grdRXs.AutoGenerateColumns = false; 273 | this.grdRXs.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 274 | this.grdRXs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 275 | this.grdRXs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 276 | this.idDataGridViewTextBoxColumn, 277 | this.afcDataGridViewTextBoxColumn, 278 | this.freqDataGridViewTextBoxColumn, 279 | this.lastseenDataGridViewTextBoxColumn, 280 | this.lastburstDataGridViewTextBoxColumn, 281 | this.state}); 282 | this.grdRXs.DataSource = this.receiverBindingSource; 283 | this.grdRXs.Location = new System.Drawing.Point(465, 31); 284 | this.grdRXs.MultiSelect = false; 285 | this.grdRXs.Name = "grdRXs"; 286 | this.grdRXs.ReadOnly = true; 287 | this.grdRXs.RowHeadersVisible = false; 288 | this.grdRXs.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 289 | this.grdRXs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 290 | this.grdRXs.Size = new System.Drawing.Size(403, 252); 291 | this.grdRXs.TabIndex = 1; 292 | this.grdRXs.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.grdRXs_CellDoubleClick); 293 | // 294 | // idDataGridViewTextBoxColumn 295 | // 296 | this.idDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 297 | this.idDataGridViewTextBoxColumn.DataPropertyName = "id"; 298 | this.idDataGridViewTextBoxColumn.HeaderText = "ID"; 299 | this.idDataGridViewTextBoxColumn.Name = "idDataGridViewTextBoxColumn"; 300 | this.idDataGridViewTextBoxColumn.ReadOnly = true; 301 | this.idDataGridViewTextBoxColumn.Width = 43; 302 | // 303 | // afcDataGridViewTextBoxColumn 304 | // 305 | this.afcDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 306 | this.afcDataGridViewTextBoxColumn.DataPropertyName = "afc"; 307 | this.afcDataGridViewTextBoxColumn.HeaderText = "AFC"; 308 | this.afcDataGridViewTextBoxColumn.Name = "afcDataGridViewTextBoxColumn"; 309 | this.afcDataGridViewTextBoxColumn.ReadOnly = true; 310 | this.afcDataGridViewTextBoxColumn.Width = 52; 311 | // 312 | // freqDataGridViewTextBoxColumn 313 | // 314 | this.freqDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 315 | this.freqDataGridViewTextBoxColumn.DataPropertyName = "freq"; 316 | this.freqDataGridViewTextBoxColumn.HeaderText = "Frequency"; 317 | this.freqDataGridViewTextBoxColumn.Name = "freqDataGridViewTextBoxColumn"; 318 | this.freqDataGridViewTextBoxColumn.ReadOnly = true; 319 | // 320 | // lastseenDataGridViewTextBoxColumn 321 | // 322 | this.lastseenDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 323 | this.lastseenDataGridViewTextBoxColumn.DataPropertyName = "lastseen"; 324 | dataGridViewCellStyle1.Format = "HH:mm:ss"; 325 | this.lastseenDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle1; 326 | this.lastseenDataGridViewTextBoxColumn.HeaderText = "Seen"; 327 | this.lastseenDataGridViewTextBoxColumn.Name = "lastseenDataGridViewTextBoxColumn"; 328 | this.lastseenDataGridViewTextBoxColumn.ReadOnly = true; 329 | this.lastseenDataGridViewTextBoxColumn.Width = 57; 330 | // 331 | // lastburstDataGridViewTextBoxColumn 332 | // 333 | this.lastburstDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 334 | this.lastburstDataGridViewTextBoxColumn.DataPropertyName = "lastburst"; 335 | dataGridViewCellStyle2.Format = "HH:mm:ss"; 336 | this.lastburstDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle2; 337 | this.lastburstDataGridViewTextBoxColumn.HeaderText = "Burst"; 338 | this.lastburstDataGridViewTextBoxColumn.Name = "lastburstDataGridViewTextBoxColumn"; 339 | this.lastburstDataGridViewTextBoxColumn.ReadOnly = true; 340 | this.lastburstDataGridViewTextBoxColumn.Width = 56; 341 | // 342 | // state 343 | // 344 | this.state.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; 345 | this.state.DataPropertyName = "state"; 346 | this.state.HeaderText = "State"; 347 | this.state.Name = "state"; 348 | this.state.ReadOnly = true; 349 | this.state.Width = 57; 350 | // 351 | // receiverBindingSource 352 | // 353 | this.receiverBindingSource.DataSource = typeof(wintelive.telive.receiver); 354 | // 355 | // lblUSIs 356 | // 357 | this.lblUSIs.AutoSize = true; 358 | this.lblUSIs.Location = new System.Drawing.Point(9, 9); 359 | this.lblUSIs.Name = "lblUSIs"; 360 | this.lblUSIs.Size = new System.Drawing.Size(89, 13); 361 | this.lblUSIs.TabIndex = 3; 362 | this.lblUSIs.Text = "Usage Identifiers:"; 363 | // 364 | // lblRX 365 | // 366 | this.lblRX.AutoSize = true; 367 | this.lblRX.Location = new System.Drawing.Point(462, 9); 368 | this.lblRX.Name = "lblRX"; 369 | this.lblRX.Size = new System.Drawing.Size(58, 13); 370 | this.lblRX.TabIndex = 4; 371 | this.lblRX.Text = "Receivers:"; 372 | // 373 | // lblFreqs 374 | // 375 | this.lblFreqs.AutoSize = true; 376 | this.lblFreqs.Location = new System.Drawing.Point(462, 305); 377 | this.lblFreqs.Name = "lblFreqs"; 378 | this.lblFreqs.Size = new System.Drawing.Size(122, 13); 379 | this.lblFreqs.TabIndex = 5; 380 | this.lblFreqs.Text = "Discovered frequencies:"; 381 | // 382 | // lblHz 383 | // 384 | this.lblHz.Location = new System.Drawing.Point(792, 9); 385 | this.lblHz.Name = "lblHz"; 386 | this.lblHz.Size = new System.Drawing.Size(23, 13); 387 | this.lblHz.TabIndex = 6; 388 | this.lblHz.Text = "Hz"; 389 | this.lblHz.TextAlign = System.Drawing.ContentAlignment.TopRight; 390 | // 391 | // lblBasefreq 392 | // 393 | this.lblBasefreq.AutoSize = true; 394 | this.lblBasefreq.Location = new System.Drawing.Point(604, 9); 395 | this.lblBasefreq.Name = "lblBasefreq"; 396 | this.lblBasefreq.Size = new System.Drawing.Size(108, 13); 397 | this.lblBasefreq.TabIndex = 7; 398 | this.lblBasefreq.Text = "Baseband frequency:"; 399 | this.lblBasefreq.DoubleClick += new System.EventHandler(this.lblBasefreq_Doubleclick); 400 | // 401 | // chkLockBase 402 | // 403 | this.chkLockBase.AutoSize = true; 404 | this.chkLockBase.Location = new System.Drawing.Point(821, 8); 405 | this.chkLockBase.Name = "chkLockBase"; 406 | this.chkLockBase.Size = new System.Drawing.Size(50, 17); 407 | this.chkLockBase.TabIndex = 8; 408 | this.chkLockBase.Text = "Lock"; 409 | this.chkLockBase.UseVisualStyleBackColor = true; 410 | this.chkLockBase.CheckedChanged += new System.EventHandler(this.chkLockBase_CheckedChanged); 411 | // 412 | // chkTuneNew 413 | // 414 | this.chkTuneNew.AutoSize = true; 415 | this.chkTuneNew.Location = new System.Drawing.Point(776, 304); 416 | this.chkTuneNew.Name = "chkTuneNew"; 417 | this.chkTuneNew.Size = new System.Drawing.Size(92, 17); 418 | this.chkTuneNew.TabIndex = 9; 419 | this.chkTuneNew.Text = "Autotune new"; 420 | this.chkTuneNew.UseVisualStyleBackColor = true; 421 | // 422 | // txtBase 423 | // 424 | this.txtBase.Location = new System.Drawing.Point(718, 6); 425 | this.txtBase.Name = "txtBase"; 426 | this.txtBase.Size = new System.Drawing.Size(75, 20); 427 | this.txtBase.TabIndex = 10; 428 | this.txtBase.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; 429 | this.txtBase.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtBase_KeyDown); 430 | // 431 | // btnTuneNew 432 | // 433 | this.btnTuneNew.Location = new System.Drawing.Point(695, 300); 434 | this.btnTuneNew.Name = "btnTuneNew"; 435 | this.btnTuneNew.Size = new System.Drawing.Size(75, 23); 436 | this.btnTuneNew.TabIndex = 11; 437 | this.btnTuneNew.Text = "Tune new"; 438 | this.btnTuneNew.UseVisualStyleBackColor = true; 439 | this.btnTuneNew.Click += new System.EventHandler(this.btnTuneNew_Click); 440 | // 441 | // picFreqGraph 442 | // 443 | this.picFreqGraph.Location = new System.Drawing.Point(12, 535); 444 | this.picFreqGraph.Name = "picFreqGraph"; 445 | this.picFreqGraph.Size = new System.Drawing.Size(856, 50); 446 | this.picFreqGraph.TabIndex = 12; 447 | this.picFreqGraph.TabStop = false; 448 | // 449 | // tmrRefresh 450 | // 451 | this.tmrRefresh.Interval = 500; 452 | this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); 453 | // 454 | // tmrAutotune 455 | // 456 | this.tmrAutotune.Interval = 10000; 457 | this.tmrAutotune.Tick += new System.EventHandler(this.tmrAutotune_Tick); 458 | // 459 | // frmFreq 460 | // 461 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 462 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 463 | this.ClientSize = new System.Drawing.Size(881, 597); 464 | this.Controls.Add(this.picFreqGraph); 465 | this.Controls.Add(this.btnTuneNew); 466 | this.Controls.Add(this.txtBase); 467 | this.Controls.Add(this.chkTuneNew); 468 | this.Controls.Add(this.chkLockBase); 469 | this.Controls.Add(this.lblBasefreq); 470 | this.Controls.Add(this.lblHz); 471 | this.Controls.Add(this.lblFreqs); 472 | this.Controls.Add(this.lblRX); 473 | this.Controls.Add(this.lblUSIs); 474 | this.Controls.Add(this.grdRXs); 475 | this.Controls.Add(this.grdUSIs); 476 | this.Controls.Add(this.grdFreqs); 477 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 478 | this.MaximizeBox = false; 479 | this.Name = "frmFreq"; 480 | this.Text = "WinTelive monitor"; 481 | this.Load += new System.EventHandler(this.frmFreq_Load); 482 | ((System.ComponentModel.ISupportInitialize)(this.grdFreqs)).EndInit(); 483 | ((System.ComponentModel.ISupportInitialize)(this.tfreqBindingSource)).EndInit(); 484 | ((System.ComponentModel.ISupportInitialize)(this.grdUSIs)).EndInit(); 485 | ((System.ComponentModel.ISupportInitialize)(this.usiBindingSource)).EndInit(); 486 | ((System.ComponentModel.ISupportInitialize)(this.grdRXs)).EndInit(); 487 | ((System.ComponentModel.ISupportInitialize)(this.receiverBindingSource)).EndInit(); 488 | ((System.ComponentModel.ISupportInitialize)(this.picFreqGraph)).EndInit(); 489 | this.ResumeLayout(false); 490 | this.PerformLayout(); 491 | 492 | } 493 | 494 | #endregion 495 | 496 | private System.Windows.Forms.DataGridView grdFreqs; 497 | private System.Windows.Forms.DataGridView grdUSIs; 498 | private System.Windows.Forms.BindingSource usiBindingSource; 499 | private System.Windows.Forms.DataGridView grdRXs; 500 | private System.Windows.Forms.BindingSource receiverBindingSource; 501 | private System.Windows.Forms.DataGridViewTextBoxColumn idDataGridViewTextBoxColumn1; 502 | private System.Windows.Forms.DataGridViewTextBoxColumn ssilistDataGridViewTextBoxColumn; 503 | private System.Windows.Forms.DataGridViewCheckBoxColumn encrDataGridViewCheckBoxColumn; 504 | private System.Windows.Forms.DataGridViewCheckBoxColumn activeDataGridViewCheckBoxColumn; 505 | private System.Windows.Forms.DataGridViewCheckBoxColumn playingDataGridViewCheckBoxColumn; 506 | private System.Windows.Forms.DataGridViewTextBoxColumn cidDataGridViewTextBoxColumn; 507 | private System.Windows.Forms.DataGridViewTextBoxColumn lastrxDataGridViewTextBoxColumn; 508 | private System.Windows.Forms.BindingSource tfreqBindingSource; 509 | private System.Windows.Forms.Label lblUSIs; 510 | private System.Windows.Forms.Label lblRX; 511 | private System.Windows.Forms.Label lblFreqs; 512 | private System.Windows.Forms.DataGridViewTextBoxColumn mccDataGridViewTextBoxColumn; 513 | private System.Windows.Forms.DataGridViewTextBoxColumn mncDataGridViewTextBoxColumn; 514 | private System.Windows.Forms.DataGridViewTextBoxColumn dlfreqDataGridViewTextBoxColumn; 515 | private System.Windows.Forms.DataGridViewTextBoxColumn ulfreqDataGridViewTextBoxColumn; 516 | private System.Windows.Forms.DataGridViewTextBoxColumn lalistDataGridViewTextBoxColumn; 517 | private System.Windows.Forms.DataGridViewTextBoxColumn cclistDataGridViewTextBoxColumn; 518 | private System.Windows.Forms.DataGridViewTextBoxColumn tunedrxDataGridViewTextBoxColumn; 519 | private System.Windows.Forms.Label lblBasefreq; 520 | private System.Windows.Forms.CheckBox chkLockBase; 521 | public System.Windows.Forms.TextBox txtBase; 522 | private System.Windows.Forms.Label lblHz; 523 | public System.Windows.Forms.CheckBox chkTuneNew; 524 | private System.Windows.Forms.DataGridViewTextBoxColumn idDataGridViewTextBoxColumn; 525 | private System.Windows.Forms.DataGridViewTextBoxColumn afcDataGridViewTextBoxColumn; 526 | private System.Windows.Forms.DataGridViewTextBoxColumn freqDataGridViewTextBoxColumn; 527 | private System.Windows.Forms.DataGridViewTextBoxColumn lastseenDataGridViewTextBoxColumn; 528 | private System.Windows.Forms.DataGridViewTextBoxColumn lastburstDataGridViewTextBoxColumn; 529 | private System.Windows.Forms.DataGridViewTextBoxColumn state; 530 | private System.Windows.Forms.Button btnTuneNew; 531 | private System.Windows.Forms.Timer tmrRefresh; 532 | private System.Windows.Forms.PictureBox picFreqGraph; 533 | private System.Windows.Forms.Timer tmrAutotune; 534 | } 535 | } -------------------------------------------------------------------------------- /wtl-structures.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Globalization; 6 | using System.Net; 7 | using System.IO; 8 | using System.Xml; 9 | using System.Runtime.InteropServices; 10 | using System.Net.Sockets; 11 | using System.Threading; 12 | using System.Timers; 13 | using NAudio.Wave; 14 | using NAudio.Wave.SampleProviders; 15 | using System.Windows.Forms; 16 | 17 | namespace wintelive 18 | { 19 | public static class tetraRx 20 | { 21 | // interface to listen for UDP packets from tetra-rx instances 22 | 23 | public static UdpClient udpCli = new UdpClient(7379); 24 | 25 | public static void Recv(IAsyncResult ar) 26 | { 27 | IPEndPoint e = new IPEndPoint(IPAddress.Any, 0); 28 | byte[] prebuf = udpCli.EndReceive(ar, ref e); 29 | 30 | telive.parseUdp(prebuf); 31 | if (udpCli.Client!=null) 32 | { 33 | Start(); 34 | } 35 | 36 | } 37 | 38 | public static void Start() 39 | { 40 | udpCli.BeginReceive(new AsyncCallback(Recv), null); 41 | } 42 | 43 | public static void Stop() 44 | { 45 | udpCli.Close(); 46 | } 47 | } 48 | 49 | public class acelp 50 | { 51 | 52 | BufferedWaveProvider wp; 53 | FileStream fs; 54 | 55 | int fpass = 1; 56 | public bool listenOpen = false; 57 | public bool recordOpen = false; 58 | DateTime lastData; 59 | private telive.receiver parentRx; 60 | 61 | 62 | object listenLock, recordLock; 63 | 64 | 65 | [DllImport("libtetradec.dll", CallingConvention = CallingConvention.Cdecl)] 66 | public static extern void tetra_decode_init(); 67 | [DllImport("libtetradec.dll", CallingConvention = CallingConvention.Cdecl)] 68 | public static extern int tetra_cdec(int fp, short[] inp, short[] outp); 69 | [DllImport("libtetradec.dll", CallingConvention = CallingConvention.Cdecl)] 70 | public static extern int tetra_sdec(short[] inp, short[] outp); 71 | 72 | public acelp(telive.receiver myParent) 73 | { 74 | listenLock = new object(); 75 | recordLock = new object(); 76 | parentRx = myParent; 77 | initDll(); 78 | } 79 | 80 | public void initDll() 81 | { 82 | fpass = 1; 83 | tetra_decode_init(); 84 | } 85 | 86 | public static byte[] s2b(short[] shorts) 87 | { 88 | int len = shorts.Length * 2; 89 | byte[] nbytes = new byte[len]; 90 | Buffer.BlockCopy(shorts, 0, nbytes, 0, len); 91 | return nbytes; 92 | } 93 | 94 | public static short[] b2s(byte[] bytes) 95 | { 96 | int len = (int)Math.Ceiling((double)(bytes.Length / 2)); 97 | short[] nshorts = new short[len]; 98 | Buffer.BlockCopy(bytes, 0, nshorts, 0, bytes.Length); 99 | return nshorts; 100 | } 101 | 102 | public byte[] acelp2pcm(byte[] acdata) 103 | { 104 | short[] sh = b2s(acdata); 105 | 106 | short[] cdc = new short[276]; 107 | tetra_cdec(fpass, sh, cdc); 108 | fpass = 0; 109 | 110 | short[] sdc = new short[480]; 111 | tetra_sdec(cdc, sdc); 112 | 113 | return s2b(sdc); 114 | 115 | } 116 | 117 | public void processAcelp(byte[] audio) 118 | { 119 | byte[] pcmaudio = acelp2pcm(audio); 120 | if (pcmaudio.Any(w => w != 0)) 121 | { 122 | lastData = DateTime.Now; 123 | listenInit(); 124 | listen(pcmaudio); 125 | 126 | recordInit(); 127 | record(pcmaudio); 128 | } 129 | } 130 | 131 | public void listenInit() 132 | { 133 | lock (listenLock) 134 | { 135 | if (listenOpen) return; 136 | wp = new BufferedWaveProvider(new WaveFormat(8000, 16, 1)); 137 | // i know, i know... but the discard effectively prevents crashing on full buffer forever... 138 | wp.DiscardOnBufferOverflow = true; 139 | telive.msp.AddMixerInput(wp); 140 | listenOpen = true; 141 | } 142 | } 143 | 144 | public void listen(byte[] pcm) 145 | { 146 | if (wp.BufferedBytes + pcm.Length >= wp.BufferLength || telive.wout.PlaybackState != PlaybackState.Playing) 147 | telive.wout.Play(); 148 | wp.AddSamples(pcm, 0, pcm.Length); 149 | } 150 | 151 | public void listenClose() 152 | { 153 | lock (listenLock) 154 | { 155 | if (!listenOpen) return; 156 | telive.msp.RemoveMixerInput(wp.ToSampleProvider()); 157 | 158 | wp = null; 159 | listenOpen = false; 160 | } 161 | } 162 | 163 | public void timeout() 164 | { 165 | TimeSpan kdy = DateTime.Now - lastData; 166 | if (kdy.TotalMilliseconds > settings.timeoutUsiPlay) 167 | { 168 | listenClose(); 169 | } 170 | 171 | if (kdy.TotalMilliseconds > settings.timeoutUsiActive) 172 | { 173 | recordClose(); 174 | } 175 | 176 | } 177 | 178 | public void recordInit() 179 | { 180 | 181 | lock (recordLock) 182 | { 183 | if (recordOpen) return; 184 | string recpath = string.Format(@"tetra_{0:yyyyMMdd}_{0:HHmmss}_{1}.wav", DateTime.Now, parentRx.freq); 185 | bool writeHead = true; 186 | if (File.Exists(recpath)) 187 | { 188 | writeHead = false; 189 | } 190 | fs = new FileStream(recpath, FileMode.Append); 191 | if (writeHead) 192 | { 193 | byte[] wavhead = new byte[] { 0x52, 0x49, 0x46, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x80, 0x3E, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0xFF, 0xFF, 0xFF, 0xFF }; 194 | fs.Write(wavhead, 0, wavhead.Length); 195 | } 196 | recordOpen = true; 197 | } 198 | } 199 | 200 | public void record(byte[] pcm) 201 | { 202 | fs.Write(pcm, 0, pcm.Length); 203 | } 204 | 205 | public void recordClose() 206 | { 207 | lock (recordLock) 208 | { 209 | if (!recordOpen) return; 210 | fs.Close(); 211 | recordOpen = false; 212 | } 213 | } 214 | 215 | } 216 | 217 | public static class gnuradio 218 | { 219 | public static string addr; 220 | public static double basefreq; 221 | public static double ppm_corr; 222 | public static double samp_rate; 223 | public static double sdr_gain; 224 | public static double sdr_ifgain; 225 | public static int receivers; 226 | public static string title; 227 | public static double cbw = 12500; 228 | public static bool baselock = false; 229 | 230 | private static object sendreq(bool method, string varname, object value = null) 231 | { 232 | // send XML RPC request 233 | string kver; 234 | if (method) 235 | { 236 | string typ; 237 | switch (Type.GetTypeCode(value.GetType())) 238 | { 239 | case TypeCode.Int16: 240 | case TypeCode.Int32: 241 | case TypeCode.Int64: 242 | case TypeCode.UInt16: 243 | case TypeCode.UInt32: 244 | case TypeCode.UInt64: 245 | typ = "int"; 246 | break; 247 | 248 | case TypeCode.Double: 249 | typ = "double"; 250 | break; 251 | 252 | case TypeCode.Boolean: 253 | typ = "boolean"; 254 | break; 255 | 256 | default: 257 | typ = "string"; 258 | value = value.ToString(); 259 | break; 260 | } 261 | kver = string.Format(" set_{0}<{1}>{2}\n", varname, typ, value); 262 | } 263 | else 264 | { 265 | kver = string.Format(" get_{0}\n", varname); 266 | } 267 | 268 | WebClient wc = new WebClient(); 269 | wc.Headers.Add("Content-Type", "text/xml"); 270 | string vystup = Encoding.ASCII.GetString(wc.UploadData(addr, Encoding.ASCII.GetBytes(kver))); 271 | 272 | XmlDocument xd = new XmlDocument(); 273 | xd.LoadXml(vystup); 274 | XmlNode chyba = xd.SelectSingleNode("/methodResponse/fault"); 275 | object oval = null; 276 | if (chyba == null) 277 | { 278 | // no problem 279 | if (method) 280 | return true; 281 | 282 | XmlNode respn = xd.SelectSingleNode("/methodResponse/params/param/value"); 283 | XmlNode respt = respn.FirstChild; 284 | string otyp = respt.Name; 285 | string cont = respt.InnerText; 286 | switch (otyp) 287 | { 288 | case "string": 289 | oval = cont; 290 | break; 291 | 292 | case "int": 293 | oval = int.Parse(cont); 294 | break; 295 | 296 | case "double": 297 | oval = double.Parse(cont, CultureInfo.InvariantCulture); 298 | break; 299 | 300 | case "boolean": 301 | oval = bool.Parse(cont); 302 | break; 303 | 304 | } 305 | } 306 | else 307 | { 308 | if (method) 309 | return false; 310 | } 311 | return oval; 312 | 313 | } 314 | 315 | public static bool setval(string varname, object varvalue) 316 | { 317 | // set GNU Radio value 318 | return (bool)sendreq(true, varname, varvalue); 319 | } 320 | 321 | public static object getval(string varname) 322 | { 323 | // Read GNU Radio value 324 | return sendreq(false, varname); 325 | } 326 | 327 | public static bool baseSet(double nfreq) 328 | { 329 | // Set baseband frequency 330 | bool vysl = setval("freq", nfreq); 331 | if (vysl) 332 | { 333 | basefreq = nfreq; 334 | } 335 | return vysl; 336 | } 337 | 338 | public static bool getSampRate() 339 | { 340 | // Get tuner sample rate 341 | object srate = getval("samp_rate"); 342 | if (srate != null) 343 | { 344 | samp_rate = Convert.ToDouble(srate); 345 | return true; 346 | } 347 | else 348 | { 349 | return false; 350 | } 351 | } 352 | 353 | public static bool getBaseFreq() 354 | { 355 | // Get tuner baseband frequency 356 | object freqval = getval("freq"); 357 | if (freqval != null) 358 | { 359 | basefreq = Convert.ToDouble(freqval); 360 | return true; 361 | } 362 | else 363 | { 364 | return false; 365 | } 366 | } 367 | 368 | public static bool getReceivers() 369 | { 370 | // Get receiver count 371 | object rxcount = getval("telive_receiver_channels"); 372 | if (rxcount != null) 373 | { 374 | receivers = (int)rxcount; 375 | return true; 376 | } 377 | else 378 | { 379 | return false; 380 | } 381 | } 382 | 383 | public static bool getTitle() 384 | { 385 | // Get project title 386 | object titl = getval("telive_receiver_name"); 387 | if (titl != null) 388 | { 389 | title = (string)titl; 390 | return true; 391 | } 392 | else 393 | { 394 | return false; 395 | } 396 | } 397 | 398 | public static void init(string naddr, ushort nport) 399 | { 400 | // Initialize GNU Radio URL and some data structures 401 | addr = string.Format("http://{0}:{1}/", naddr, nport); 402 | getTitle(); 403 | getBaseFreq(); 404 | getSampRate(); 405 | getReceivers(); 406 | } 407 | 408 | public static bool freqIsOver(double qfreq, IEnumerable oldfreqs) 409 | { 410 | return (qfreq > oldfreqs.Max()); 411 | } 412 | 413 | public static bool freqIsUnder(double qfreq, IEnumerable oldfreqs) 414 | { 415 | return (qfreq < oldfreqs.Min()); 416 | } 417 | 418 | public static bool freqFitsToBase(double nfreq) 419 | { 420 | // Does frequency fit into currently tuned baseband? 421 | // (i.e. can we listen to it without changing the base frequency?) 422 | double noff = nfreq - basefreq; 423 | double maxdiff = (samp_rate / 2) - cbw; 424 | return (Math.Abs(noff) <= maxdiff); 425 | } 426 | 427 | public static bool freqsFitToBandwidth(IEnumerable freqs) 428 | { 429 | // Are all specified frequencies within single bandwidth? 430 | // (i.e. can we tune them all together?) 431 | bool fits = false; 432 | if (freqs.Count() > 0) 433 | { 434 | double min = freqs.Min(); 435 | double max = freqs.Max(); 436 | double range = max - min; 437 | 438 | fits = range <= samp_rate - 2 * cbw; 439 | } 440 | return fits; 441 | } 442 | 443 | public static double freqsCenter(IEnumerable freqs) 444 | { 445 | // Return exact center of specified frequencies 446 | if (freqs.Count() > 0) 447 | { 448 | return (freqs.Max() + freqs.Min()) / 2; 449 | } 450 | // Or nothing if there are none 451 | return -1; 452 | 453 | } 454 | 455 | public static double baseCalc(double nfreq, IEnumerable neededfreqs, bool allowRxLoss) 456 | { 457 | // Calculate new baseband frequency that covers all specified frequencies optimally 458 | // Will return -1 if that's not possible (all freqs don't fit bandwidth) 459 | double nbase = 0; 460 | if (neededfreqs.Count() > 0) 461 | { 462 | sbyte newpos = 0; 463 | if (freqIsOver(nfreq, neededfreqs)) 464 | newpos = 1; 465 | if (freqIsUnder(nfreq, neededfreqs)) 466 | newpos = -1; 467 | 468 | neededfreqs = neededfreqs.Concat(new double[] { nfreq }); 469 | 470 | // check the list 471 | if (freqsFitToBandwidth(neededfreqs)) 472 | { 473 | // it fits 474 | nbase = freqsCenter(neededfreqs); 475 | // this also means that newpos = 0, just sayin... :D 476 | } 477 | else 478 | { 479 | // not possible without losing some channels 480 | if (allowRxLoss) 481 | { 482 | // this will cut the currently used freuqencies list until 483 | // the list + the new freq fit within one baseband 484 | do 485 | { 486 | 487 | if (newpos == 1) 488 | { 489 | double fmin = neededfreqs.Min(); 490 | neededfreqs = neededfreqs.Where(w => w != fmin); 491 | } 492 | else 493 | if (newpos == -1) 494 | { 495 | double fmax = neededfreqs.Max(); 496 | neededfreqs = neededfreqs.Where(w => w != fmax); 497 | } 498 | 499 | } while (!freqsFitToBandwidth(neededfreqs)); 500 | 501 | // ok, now we have a frequency list that was stripped of some border freqencies 502 | // and contains the rest AND the new frequency 503 | 504 | nbase = freqsCenter(neededfreqs); 505 | 506 | } 507 | else 508 | { 509 | // just return that it's impossible 510 | nbase = -1; 511 | } 512 | } 513 | } 514 | else 515 | { 516 | // spot on the new freq 517 | nbase = nfreq; 518 | } 519 | return nbase; 520 | } 521 | 522 | public static double lowestValidFreq() 523 | { 524 | // gets the lower tunable frequency of current baseband 525 | // (with proper rounding to 100KHz's) 526 | double lvf = basefreq - (samp_rate / 2); 527 | int roundbase = 100000; 528 | long rnd = (long)lvf / roundbase; 529 | lvf = rnd * roundbase; 530 | 531 | while (!freqFitsToBase(lvf)) 532 | { 533 | lvf += cbw; 534 | } 535 | return lvf; 536 | } 537 | 538 | public static double lowRange() 539 | { 540 | return basefreq - samp_rate / 2; 541 | } 542 | 543 | public static double HighRange() 544 | { 545 | return basefreq + samp_rate / 2; 546 | } 547 | 548 | } 549 | 550 | public static class settings 551 | { 552 | public static double allScanLow = 424000000; 553 | public static double allScanHigh = 428000000; 554 | public static int allScanTime = 500; 555 | 556 | public static int bandScanTime = 1000; 557 | 558 | public static int timeoutUsiExist = 30000; 559 | public static int timeoutUsiActive = 10000; 560 | public static int timeoutUsiPlay = 2000; 561 | 562 | public static int timeoutSsiExist = 20000; 563 | 564 | public static int timeoutRxTuned = 60000; 565 | 566 | } 567 | 568 | public static class telive 569 | { 570 | public enum addr_type : ushort 571 | { 572 | NULL = 0, 573 | SSI = 1, 574 | EVENT_LABEL = 2, 575 | USSI = 3, 576 | SMI = 4, 577 | SSI_EVENT = 5, 578 | SSI_USAGE = 6, 579 | SMI_EVENT = 7, 580 | }; 581 | public enum freq_reason : ushort 582 | { 583 | NETINFO = 0, 584 | FREQINFO = 1, 585 | DLFREQ = 2, 586 | SCANNED = 3, 587 | UNKNOWN = 99 588 | } 589 | public enum rx_mode : ushort 590 | { 591 | OFF = 0, // receiver is considered disabled 592 | TUNED = 1, // receiver is tunned to a channel 593 | ALLSCAN = 2, // ALL receivers are progressively scanning defined range 594 | BANDSCAN = 3 // receiver is loop-scanning within currently tuned baseband 595 | } 596 | 597 | public class receiver 598 | { 599 | public ushort id { get; } 600 | public int afc { get; set; } 601 | public double freq { get { return gnuradio.basefreq + offset; } } 602 | public double freqFix; 603 | public double offset; 604 | public DateTime lastseen { get; set; } 605 | public DateTime lastburst { get; set; } 606 | public DateTime firstTuned; 607 | public rx_mode mode; 608 | public string state 609 | { 610 | get 611 | { 612 | switch (mode) 613 | { 614 | case rx_mode.OFF: 615 | return "OFF"; 616 | 617 | case rx_mode.TUNED: 618 | return "tuned"; 619 | 620 | case rx_mode.ALLSCAN: 621 | return "scan"; 622 | 623 | case rx_mode.BANDSCAN: 624 | return "band scan"; 625 | 626 | default: 627 | return "unknown"; 628 | } 629 | 630 | } 631 | } 632 | public uint master; 633 | 634 | public acelp spl; 635 | 636 | 637 | public receiver(ushort newid) 638 | { 639 | id = newid; 640 | mode = rx_mode.OFF; 641 | spl = new acelp(this); 642 | } 643 | 644 | public bool getOffset() 645 | { 646 | // get current offset against baseband 647 | object offval = gnuradio.getval(string.Format("xlate_offset{0}", id)); 648 | if (offval != null) 649 | { 650 | double boffs = Convert.ToDouble(offval); 651 | offset = boffs; 652 | return true; 653 | } 654 | else 655 | { 656 | return false; 657 | } 658 | } 659 | 660 | public bool setOffset(double noff) 661 | { 662 | // set current offset against baseband 663 | bool vysl = gnuradio.setval(string.Format("xlate_offset{0}", id), noff); 664 | if (vysl) 665 | { 666 | offset = noff; 667 | freqRefDel(); 668 | if (mode == rx_mode.TUNED) 669 | { 670 | firstTuned = DateTime.Now; 671 | freqRefAdd(); 672 | } 673 | } 674 | return vysl; 675 | } 676 | 677 | public void setAfc(int newafc) 678 | { 679 | // just log AFC value 680 | afc = newafc; 681 | } 682 | 683 | public void seenBurst() 684 | { 685 | // a burst has been received on the receiver 686 | lastburst = DateTime.Now; 687 | } 688 | 689 | public void seen() 690 | { 691 | // receiver is seen alive (whether tuned to a signal or not) 692 | lastseen = DateTime.Now; 693 | } 694 | 695 | public bool tuneOOR() 696 | { 697 | // make the receiver quiet by tuning it out of receiving range 698 | return setOffset(gnuradio.samp_rate); 699 | } 700 | 701 | public void setMode(rx_mode nmode) 702 | { 703 | // set mode of receiver 704 | mode = nmode; 705 | switch (mode) 706 | { 707 | case rx_mode.OFF: 708 | firstTuned = default(DateTime); 709 | freqRefDel(); 710 | break; 711 | 712 | case rx_mode.TUNED: 713 | firstTuned = DateTime.Now; 714 | freqRefAdd(); 715 | break; 716 | } 717 | } 718 | 719 | public void freqRefAdd() 720 | { 721 | foreach (frequency fr in freqs.Where(w => w.dl_freq == freq)) 722 | { 723 | fr.tuned(id); 724 | } 725 | 726 | } 727 | 728 | public void freqRefDel() 729 | { 730 | lastburst = default(DateTime); 731 | foreach (frequency fr in freqs.Where(w => w.tunedrx == id).ToList()) 732 | { 733 | fr.detuned(); 734 | } 735 | } 736 | 737 | public bool setFreq(double nfreq) 738 | { 739 | // just overlay method for setting offset 740 | double noff = nfreq - gnuradio.basefreq; 741 | bool vysledek = setOffset(noff); 742 | if (vysledek) 743 | { 744 | updateFix(); 745 | } 746 | return vysledek; 747 | } 748 | 749 | public void updateFix() 750 | { 751 | // what we have is what we want 752 | freqFix = freq; 753 | } 754 | 755 | public bool applyFix() 756 | { 757 | // tune receiver to what we want 758 | bool vysledek = true; 759 | if (freq != freqFix) 760 | { 761 | vysledek = setFreq(freqFix); 762 | } 763 | return vysledek; 764 | } 765 | 766 | } 767 | public class usi 768 | { 769 | public ushort id { get; } 770 | public List ssis; 771 | public string ssilist { get { return string.Join(", ", ssis.Select(w => w.id).ToArray()); } } 772 | public bool encr { get; set; } 773 | public bool active { get; set; } 774 | public bool playing { get; set; } 775 | public DateTime lastseen { get; set; } 776 | public DateTime lastplay { get; set; } 777 | public ushort cid { get; set; } 778 | public ushort lastrx { get; set; } 779 | 780 | public usi(ushort newid) 781 | { 782 | id = newid; 783 | ssis = new List(); 784 | encr = false; 785 | active = false; 786 | playing = false; 787 | } 788 | 789 | public void seen(ushort rx) 790 | { 791 | // this USI has been seen on receiver rx 792 | lastseen = DateTime.Now; 793 | lastrx = rx; 794 | activate(); 795 | } 796 | 797 | public void addssi(uint nssi) 798 | { 799 | // a SSI has been seen 800 | if (nssi == 0) return; 801 | 802 | if (!ssis.Any(w => w.id == nssi)) 803 | { 804 | ssi nsio = new ssi(nssi); 805 | nsio.seen(); 806 | ssis.Add(nsio); 807 | } 808 | } 809 | 810 | public void removessi(uint ossi) 811 | { 812 | // ssi is being forgotten 813 | ssis.RemoveAll(w => w.id == ossi); 814 | } 815 | 816 | public void addcid(ushort ncid) 817 | { 818 | // calledid has been seen 819 | if (ncid == 0) return; 820 | 821 | cid = ncid; 822 | } 823 | 824 | public void activate() 825 | { 826 | // there is an activity on this USI 827 | active = true; 828 | } 829 | 830 | public void play(ushort rxid) 831 | { 832 | // there is a voice comming from this USI 833 | playing = true; 834 | lastplay = DateTime.Now; 835 | } 836 | 837 | public void stop() 838 | { 839 | // voice ceased 840 | playing = false; 841 | } 842 | 843 | public void deactivate() 844 | { 845 | // USI forgotten 846 | active = false; 847 | } 848 | 849 | } 850 | public class ssi 851 | { 852 | public uint id; 853 | public DateTime lastseen; 854 | public ssi(uint nid) 855 | { 856 | id = nid; 857 | } 858 | 859 | public void seen() 860 | { 861 | // SSI activity 862 | lastseen = DateTime.Now; 863 | } 864 | } 865 | public class frequency 866 | { 867 | public uint mcc { get; set; } 868 | public uint mnc { get; set; } 869 | public double dl_freq { get; } 870 | public double ul_freq { get; } 871 | public List la; 872 | public string lalist { get { return string.Join(", ", la.ToArray()); } } 873 | public List ccode; 874 | public string cclist { get { return string.Join(", ", ccode.ToArray()); } } 875 | public freq_reason reason; 876 | public ushort tunedrx { get; set; } 877 | public DateTime lastuned; 878 | 879 | public frequency(uint nmcc, uint nmnc, double dlf, double ulf, uint nla, ushort ncc, freq_reason nreason) 880 | { 881 | mcc = nmcc; 882 | mnc = nmnc; 883 | dl_freq = dlf; 884 | ul_freq = ulf; 885 | la = new List { nla }; 886 | ccode = new List { ncc }; 887 | reason = nreason; 888 | tunedrx = 0; 889 | } 890 | 891 | public void tuned(ushort rx) 892 | { 893 | // frequency has been tuned on receiver 894 | tunedrx = rx; 895 | lastuned = DateTime.Now; 896 | } 897 | 898 | public void detuned() 899 | { 900 | // frequency has been detuned form receiver 901 | tunedrx = 0; 902 | } 903 | 904 | public void addla(uint nla) 905 | { 906 | // detected new LA for this frequency 907 | if (!la.Contains(nla)) 908 | la.Add(nla); 909 | } 910 | 911 | public void addcc(ushort ncc) 912 | { 913 | // detected new CCODE for this frequency 914 | if (!ccode.Contains(ncc)) 915 | ccode.Add(ncc); 916 | } 917 | 918 | } 919 | public class allScanner 920 | { 921 | // all receivers scanning defined range 922 | public double startfreq; 923 | public double stopfreq; 924 | private System.Timers.Timer tmrScan = new System.Timers.Timer(settings.allScanTime); 925 | private object scanLock; 926 | 927 | public allScanner(double lf, double uf) 928 | { 929 | startfreq = lf; 930 | stopfreq = uf; 931 | scanLock = new object(); 932 | } 933 | 934 | public void start() 935 | { 936 | lock (scanLock) 937 | { 938 | for (ushort i = 1; i <= gnuradio.receivers; i++) 939 | { 940 | receiver rx = rxs.FirstOrDefault(w => w.id == i); 941 | rx.setMode(rx_mode.OFF); 942 | } 943 | double nbase = startfreq + (gnuradio.receivers / 2) * gnuradio.cbw; 944 | 945 | baseSetSafe(nbase); 946 | 947 | for (ushort i = 1; i <= gnuradio.receivers; i++) 948 | { 949 | if (rxTune(i, nbase + (i - 6) * gnuradio.cbw)) 950 | rxs.FirstOrDefault(w => w.id == i).setMode(rx_mode.ALLSCAN); 951 | } 952 | } 953 | tmrScan.Elapsed += new ElapsedEventHandler(tmrScan_tick); 954 | tmrScan.Enabled = true; 955 | 956 | } 957 | 958 | public void step() 959 | { 960 | double nbase; 961 | lock (scanLock) 962 | { 963 | nbase = gnuradio.basefreq + gnuradio.receivers * gnuradio.cbw; 964 | baseSetSafe(nbase); 965 | } 966 | 967 | if (nbase + (gnuradio.receivers / 2) * gnuradio.cbw > stopfreq) 968 | { 969 | stop(); 970 | } 971 | } 972 | 973 | public void stop() 974 | { 975 | lock (scanLock) 976 | { 977 | tmrScan.Enabled = false; 978 | foreach (receiver rx in rxs.Where(w => w.mode == rx_mode.ALLSCAN)) 979 | { 980 | rx.setMode(rx_mode.OFF); 981 | } 982 | } 983 | } 984 | 985 | public void tmrScan_tick(object source, ElapsedEventArgs e) 986 | { 987 | step(); 988 | } 989 | } 990 | public class bandScanner 991 | { 992 | public ushort scanRx; 993 | private System.Timers.Timer tmrScan = new System.Timers.Timer(settings.bandScanTime); 994 | private object scanLock; 995 | 996 | public bandScanner(ushort rx) 997 | { 998 | scanRx = rx; 999 | scanLock = new object(); 1000 | } 1001 | 1002 | public void start() 1003 | { 1004 | lock (scanLock) 1005 | { 1006 | receiver scanner = rxs.FirstOrDefault(w => w.id == scanRx); 1007 | scanner.setMode(rx_mode.BANDSCAN); 1008 | double startf = gnuradio.lowestValidFreq(); 1009 | rxTune(scanner.id, startf); 1010 | 1011 | tmrScan.Elapsed += new ElapsedEventHandler(tmrScan_tick); 1012 | tmrScan.Enabled = true; 1013 | } 1014 | } 1015 | 1016 | public void stop() 1017 | { 1018 | lock (scanLock) 1019 | { 1020 | tmrScan.Enabled = false; 1021 | } 1022 | rxs.FirstOrDefault(w => w.id == scanRx).setMode(rx_mode.OFF); 1023 | } 1024 | 1025 | public void step() 1026 | { 1027 | lock (scanLock) 1028 | { 1029 | receiver scanner = rxs.FirstOrDefault(w => w.id == scanRx); 1030 | 1031 | double nf = scanner.freq + gnuradio.cbw; 1032 | 1033 | if (!gnuradio.freqFitsToBase(nf)) 1034 | { 1035 | nf = gnuradio.lowestValidFreq(); 1036 | } 1037 | rxTune(scanner.id, nf); 1038 | 1039 | } 1040 | } 1041 | 1042 | public void tmrScan_tick(object source, ElapsedEventArgs e) 1043 | { 1044 | step(); 1045 | } 1046 | } 1047 | 1048 | public static List rxs = new List(); 1049 | public static List usis = new List(); 1050 | public static List freqs = new List(); 1051 | public static bandScanner bas; 1052 | public static allScanner als; 1053 | public static System.Timers.Timer janitor = new System.Timers.Timer(500); 1054 | public static frmFreq ff; 1055 | public static frmMain fm; 1056 | public static frmSDS fs; 1057 | public static WaveFormat wf; 1058 | public static MixingSampleProvider msp; 1059 | public static IWavePlayer wout; 1060 | 1061 | public static void fmInit() 1062 | { 1063 | fm = new frmMain(); 1064 | fm.ShowDialog(); 1065 | 1066 | } 1067 | 1068 | public static void ffInit(frmMain orig) 1069 | { 1070 | 1071 | ff = new frmFreq(); 1072 | ff.Show(); 1073 | } 1074 | 1075 | public static void fsInit() 1076 | { 1077 | fs = new frmSDS(); 1078 | fs.Show(); 1079 | } 1080 | 1081 | public static void startAll() 1082 | { 1083 | rxEnumAll(); 1084 | tetraRx.Start(); 1085 | 1086 | janitorStart(); 1087 | 1088 | audioInit(); 1089 | } 1090 | 1091 | public static void audioInit() 1092 | { 1093 | wf = WaveFormat.CreateIeeeFloatWaveFormat(8000, 1); 1094 | msp = new MixingSampleProvider(wf); 1095 | wout = new WaveOutEvent(); 1096 | msp.ReadFully = true; 1097 | wout.Init(msp); 1098 | wout.Play(); 1099 | } 1100 | 1101 | public static void janitorStart() 1102 | { 1103 | janitor.SynchronizingObject = fm; 1104 | janitor.Elapsed += new ElapsedEventHandler(janitorCall); 1105 | janitor.Enabled = true; 1106 | } 1107 | 1108 | public static void janitorCall(object source, ElapsedEventArgs e) 1109 | { 1110 | // internal structures cleanup 1111 | timeoutUsi(); 1112 | timeoutRx(); 1113 | timeoutSsi(); 1114 | timeoutMixer(); 1115 | } 1116 | 1117 | public static void rxEnumAll() 1118 | { 1119 | for (ushort i = 1; i <= gnuradio.receivers; i++) 1120 | { 1121 | receiver newrx = new receiver(i); 1122 | newrx.getOffset(); 1123 | rxs.Add(newrx); 1124 | } 1125 | } 1126 | 1127 | public static void timeoutUsi() 1128 | { 1129 | DateTime ted = DateTime.Now; 1130 | 1131 | List delQue = new List(); 1132 | foreach (usi ucho in usis) 1133 | { 1134 | if (ucho.playing) 1135 | { 1136 | // stop anything playing more than 2s without audio signal 1137 | TimeSpan splay = ted - ucho.lastplay; 1138 | if (splay.TotalMilliseconds > settings.timeoutUsiPlay) 1139 | ucho.stop(); 1140 | } 1141 | 1142 | TimeSpan sping = ted - ucho.lastseen; 1143 | if (ucho.active) 1144 | { 1145 | // deactivate anything without SSI activity for more than 10s 1146 | if (sping.TotalMilliseconds > settings.timeoutUsiActive) 1147 | ucho.deactivate(); 1148 | } 1149 | else 1150 | { 1151 | // destroy anything with inactivity for more than 30s 1152 | if (sping.TotalMilliseconds > settings.timeoutUsiExist) 1153 | { 1154 | delQue.Add(ucho); 1155 | } 1156 | 1157 | } 1158 | } 1159 | 1160 | foreach (usi ucho in delQue) 1161 | { 1162 | usis.Remove(ucho); 1163 | } 1164 | 1165 | 1166 | } 1167 | 1168 | public static void timeoutSsi() 1169 | { 1170 | DateTime ted = DateTime.Now; 1171 | 1172 | foreach (usi ucho in usis.Where(w => !w.active)) 1173 | { 1174 | ucho.ssis.RemoveAll(w => (ted - w.lastseen).TotalMilliseconds > settings.timeoutSsiExist); 1175 | } 1176 | } 1177 | 1178 | public static void timeoutRx() 1179 | { 1180 | DateTime ted = DateTime.Now; 1181 | 1182 | foreach (receiver rx in rxs.Where(w => w.mode == rx_mode.TUNED)) 1183 | { 1184 | rx.spl.timeout(); 1185 | 1186 | if (rx.lastburst == default(DateTime)) 1187 | { 1188 | TimeSpan sburst = ted - rx.firstTuned; 1189 | if (sburst.TotalMilliseconds > settings.timeoutRxTuned) 1190 | { 1191 | List deadFreqs = freqs.Where(w => w.dl_freq == rx.freq).ToList(); 1192 | rx.setMode(rx_mode.OFF); 1193 | // if we didnt hear anything on that frequency, we might as well forget it 1194 | deadFreqs.ForEach(w => freqs.Remove(w)); 1195 | 1196 | } 1197 | } 1198 | } 1199 | } 1200 | 1201 | public static void timeoutMixer() 1202 | { 1203 | // clear mixer if nothing is playing 1204 | if (!rxs.Any(w => w.spl.listenOpen)) 1205 | { 1206 | msp.RemoveAllMixerInputs(); 1207 | } 1208 | } 1209 | 1210 | public static void tuneAllFree() 1211 | { 1212 | // first only frequencies that do not require baseband change 1213 | do 1214 | { 1215 | receiver freeRx = rxs.Where(w => w.mode == rx_mode.OFF).OrderBy(w => w.id).FirstOrDefault(); 1216 | // ha! this mighty query first selects freqs with known MCC and MNC, and then orders them by the ascending freq 1217 | frequency freeFr = freqs.Where(w => w.tunedrx == 0 && gnuradio.freqFitsToBase(w.dl_freq)).OrderByDescending(w => Math.Sign(w.mcc) * Math.Sign(w.mnc)).ThenBy(w => w.dl_freq).FirstOrDefault(); 1218 | if (freeRx == null || freeFr == null) 1219 | break; 1220 | rxTune(freeRx.id, freeFr.dl_freq); 1221 | freeRx.setMode(rx_mode.TUNED); 1222 | } while (true); 1223 | 1224 | // then those, that WILL change baseband, but not so much that we lose other active channels 1225 | do 1226 | { 1227 | receiver freeRx = rxs.Where(w => w.mode == rx_mode.OFF).OrderBy(w => w.id).FirstOrDefault(); 1228 | frequency freeFr = freqs.Where(w => w.tunedrx == 0 && gnuradio.baseCalc(w.dl_freq, rxs.Where(y => y.mode == rx_mode.TUNED).Select(y => y.freq), false) != -1).OrderBy(w => Math.Abs(gnuradio.basefreq - w.dl_freq)).FirstOrDefault(); 1229 | if (freeRx == null || freeFr == null) 1230 | break; 1231 | rxTuneSafe(freeRx.id, freeFr.dl_freq, false); 1232 | } while (true); 1233 | 1234 | } 1235 | 1236 | public static bool rxTune(ushort rxid, double nfreq) 1237 | { 1238 | receiver trx = rxs.FirstOrDefault(w => w.id == rxid); 1239 | return trx.setFreq(nfreq); 1240 | } 1241 | 1242 | public static bool rxTuneSafe(ushort rxid, double nfreq, bool force = false) 1243 | { 1244 | receiver trx = rxs.FirstOrDefault(w => w.id == rxid); 1245 | bool vysledek = false; 1246 | if (!gnuradio.freqFitsToBase(nfreq)) 1247 | { 1248 | // find other active receivers (except the one we are tuning) 1249 | IEnumerable used = rxs.Where(w => w.mode == rx_mode.TUNED && w.id != rxid); 1250 | IEnumerable needed = used.Select(w => w.freq).Distinct(); 1251 | 1252 | // calculate new base that includes everything (or at least as much as possible) 1253 | double nbase = gnuradio.baseCalc(nfreq, needed, force); 1254 | 1255 | if (nbase != -1) 1256 | { 1257 | // turn the rx off temporarily 1258 | //trx.setMode(rx_mode.OFF); 1259 | // set the new base 1260 | vysledek = baseSetSafe(nbase); 1261 | // set new rx freq 1262 | vysledek &= rxTune(rxid, nfreq); 1263 | // turn it on again 1264 | trx.setMode(rx_mode.TUNED); 1265 | } 1266 | } 1267 | else 1268 | { 1269 | // the required frequency is withing the baseband, just tune it 1270 | vysledek = rxTune(rxid, nfreq); 1271 | // turn on the rx 1272 | trx.setMode(rx_mode.TUNED); 1273 | } 1274 | return vysledek; 1275 | 1276 | } 1277 | 1278 | public static bool rxApplyFix(IEnumerable rtr) 1279 | { 1280 | // alter receivers so they stay on their declared freq 1281 | bool vysledek = true; 1282 | foreach (receiver rtrx in rtr) 1283 | { 1284 | // if the receiver is close enough to base then just re-apply the freq 1285 | vysledek &= rtrx.applyFix(); 1286 | } 1287 | return vysledek; 1288 | } 1289 | 1290 | public static void rxUpdateFix(IEnumerable rtr) 1291 | { 1292 | // alter receivers so they stay on their declared freq 1293 | foreach (receiver rtrx in rtr) 1294 | { 1295 | // if the receiver is close enough to base then just re-apply the freq 1296 | rtrx.updateFix(); 1297 | } 1298 | } 1299 | 1300 | public static bool baseCenter() 1301 | { 1302 | bool vysledek = true; 1303 | 1304 | IEnumerable used = rxs.Where(w => w.mode == rx_mode.TUNED); 1305 | IEnumerable usedfr = used.Select(w => w.freq).Distinct(); 1306 | 1307 | // calc new optimal frequency 1308 | double optim = gnuradio.freqsCenter(usedfr); 1309 | if (optim != -1 && optim != gnuradio.basefreq) 1310 | { 1311 | // if we got some and it's different from current 1312 | vysledek = baseSetSafe(optim); 1313 | } 1314 | 1315 | return vysledek; 1316 | } 1317 | 1318 | public static bool baseSetSafe(double nbase) 1319 | { 1320 | bool vysledek = true; 1321 | // set the new base 1322 | vysledek &= gnuradio.baseSet(nbase); 1323 | // switch off all channels that won't fit after the baseband shift 1324 | foreach (receiver rx in rxs.Where(w => w.mode == rx_mode.TUNED && !gnuradio.freqFitsToBase(w.freq))) 1325 | { 1326 | rx.setMode(rx_mode.OFF); 1327 | } 1328 | // change all online channels 1329 | vysledek &= rxApplyFix(rxs.Where(w => w.mode == rx_mode.TUNED)); 1330 | // calculate all offline/scanning channels 1331 | rxUpdateFix(rxs.Where(w => w.mode != rx_mode.TUNED)); 1332 | 1333 | 1334 | return true; 1335 | } 1336 | 1337 | public static bool rxChangeMode(ushort rxid, rx_mode newmode) 1338 | { 1339 | if (rxs.Any(w => w.mode == rx_mode.ALLSCAN)) 1340 | { 1341 | als.stop(); 1342 | als = null; 1343 | } 1344 | 1345 | receiver rxo = rxs.FirstOrDefault(w => w.id == rxid); 1346 | 1347 | if (rxo.mode == rx_mode.BANDSCAN) 1348 | { 1349 | bas.stop(); 1350 | bas = null; 1351 | } 1352 | 1353 | if (rxo.mode == rx_mode.TUNED) 1354 | rxo.setMode(rx_mode.OFF); 1355 | 1356 | //at this moment, the receiver should be in OFF mode with all frequencies unlinked 1357 | 1358 | switch (newmode) 1359 | { 1360 | case rx_mode.ALLSCAN: 1361 | // use all receivers for full scan 1362 | als = new allScanner(settings.allScanLow, settings.allScanHigh); 1363 | als.start(); 1364 | break; 1365 | 1366 | case rx_mode.BANDSCAN: 1367 | // use this receiver for scanning the band 1368 | if (rxs.Any(w => w.mode == rx_mode.BANDSCAN)) 1369 | { 1370 | // we only need one bandscan 1371 | return false; 1372 | } 1373 | else 1374 | { 1375 | bas = new bandScanner(rxid); 1376 | bas.start(); 1377 | } 1378 | break; 1379 | 1380 | case rx_mode.TUNED: 1381 | // update the fixed frequency to match reality 1382 | rxo.updateFix(); 1383 | rxo.setMode(rx_mode.TUNED); 1384 | break; 1385 | } 1386 | return true; 1387 | 1388 | } 1389 | 1390 | public static int guiFreqToX(double freq) 1391 | { 1392 | double fLen = settings.allScanHigh - settings.allScanLow; 1393 | double pLen = 850; 1394 | double ratio = fLen / pLen; 1395 | double min = freq - settings.allScanLow; 1396 | 1397 | // if the user enter a little too small number, we drop the 0 1398 | if (min < 0) min = 0; 1399 | 1400 | return Convert.ToInt16(min / ratio); 1401 | } 1402 | 1403 | private static void cidaddssi(ushort cid, uint ssi) 1404 | { 1405 | foreach (usi usak in usis.Where(w => w.cid == cid)) 1406 | { 1407 | usak.addssi(ssi); 1408 | } 1409 | } 1410 | 1411 | private static usi findOrCreateUsi(ushort id) 1412 | { 1413 | usi ucho = usis.FirstOrDefault(w => w.id == id); 1414 | if (ucho == null) 1415 | { 1416 | ucho = new usi(id); 1417 | usis.Add(ucho); 1418 | } 1419 | return ucho; 1420 | } 1421 | 1422 | private static Dictionary TETelements(string buf) 1423 | { 1424 | string[] slova = buf.Split(' '); 1425 | Dictionary TETstat = new Dictionary(); 1426 | foreach (string slovo in slova) 1427 | { 1428 | if (slovo.Contains(":")) 1429 | { 1430 | int dvojtec = slovo.IndexOf(':'); 1431 | string parametr = slovo.Substring(0, dvojtec); 1432 | string hodnota = slovo.Substring(dvojtec + 1); 1433 | 1434 | TETstat.Add(parametr, hodnota); 1435 | } 1436 | } 1437 | return TETstat; 1438 | 1439 | } 1440 | 1441 | public static void parseUdp(byte[] prebuf) 1442 | { 1443 | // this gets executed in gui thread 1444 | string buf = Encoding.ASCII.GetString(prebuf); 1445 | 1446 | if (buf.Contains("TETMON_begin")) 1447 | { 1448 | // control message 1449 | if (buf.Contains("TETMON_end")) 1450 | { 1451 | parseStat(buf); 1452 | } 1453 | else 1454 | { 1455 | // error: line starts but doesnt end 1456 | } 1457 | } 1458 | else 1459 | { 1460 | // data payload 1461 | if (buf.Length == 1393) 1462 | { 1463 | parseTraffic(prebuf); 1464 | } 1465 | else 1466 | { 1467 | // error: small frame 1468 | } 1469 | } 1470 | 1471 | } 1472 | 1473 | private static void parseStat(string buf) 1474 | { 1475 | Dictionary TETstat = TETelements(buf); 1476 | 1477 | ushort rx = 0; 1478 | receiver rxo = null; 1479 | if (TETstat.ContainsKey("RX")) 1480 | { 1481 | rx = ushort.Parse(TETstat["RX"]); 1482 | rxo = rxs.FirstOrDefault(w => w.id == rx); 1483 | } 1484 | if (rxo == null) return; 1485 | 1486 | rxo.seen(); 1487 | 1488 | string func = (TETstat.ContainsKey("FUNC") ? TETstat["FUNC"] : ""); 1489 | 1490 | Dictionary> allowed = new Dictionary>(); 1491 | allowed.Add(rx_mode.OFF, new List { "AFCVAL" }); 1492 | allowed.Add(rx_mode.ALLSCAN, new List { "BURST", "AFCVAL", "NETINFO1", "FREQINFO1", "FREQINFO2" }); 1493 | allowed.Add(rx_mode.BANDSCAN, new List { "BURST", "AFCVAL", "NETINFO1", "FREQINFO1", "FREQINFO2" }); 1494 | allowed.Add(rx_mode.TUNED, new List { "BURST", "AFCVAL", "NETINFO1", "FREQINFO1", "FREQINFO2", "DSETUPDEC", "DCONNECTDEC", "DTXGRANTDEC", "SDSDEC", "D-SETUP", "D-CONNECT", "D-RELEASE" }); 1495 | 1496 | if (!allowed[rxo.mode].Contains(func)) 1497 | return; 1498 | 1499 | ushort idx; 1500 | usi idxo = null; 1501 | if (TETstat.ContainsKey("IDX")) 1502 | { 1503 | idx = ushort.Parse(TETstat["IDX"]); 1504 | idxo = findOrCreateUsi(idx); 1505 | if (rxo.mode == rx_mode.TUNED) 1506 | { 1507 | idxo.seen(rx); 1508 | } 1509 | } 1510 | 1511 | uint ssi1 = (TETstat.ContainsKey("SSI") ? uint.Parse(TETstat["SSI"]) : 0); 1512 | uint ssi2 = (TETstat.ContainsKey("SSI2") ? uint.Parse(TETstat["SSI2"]) : 0); 1513 | ushort cid = (TETstat.ContainsKey("CID") ? ushort.Parse(TETstat["CID"]) : (ushort)0); 1514 | addr_type idt = (TETstat.ContainsKey("IDT") ? (addr_type)ushort.Parse(TETstat["IDT"]) : addr_type.NULL); 1515 | uint mcc = (TETstat.ContainsKey("MCC") ? uint.Parse(TETstat["MCC"], NumberStyles.HexNumber) : 0); 1516 | uint mnc = (TETstat.ContainsKey("MNC") ? uint.Parse(TETstat["MNC"], NumberStyles.HexNumber) : 0); 1517 | double dl_freq = (TETstat.ContainsKey("DLF") ? double.Parse(TETstat["DLF"]) : 0); 1518 | double ul_freq = (TETstat.ContainsKey("ULF") ? double.Parse(TETstat["ULF"]) : 0); 1519 | uint la = (TETstat.ContainsKey("LA") ? uint.Parse(TETstat["LA"], NumberStyles.HexNumber) : 0); 1520 | ushort ccode = (TETstat.ContainsKey("CCODE") ? ushort.Parse(TETstat["CCODE"], NumberStyles.HexNumber) : (ushort)0); 1521 | int afc = (TETstat.ContainsKey("AFC") ? int.Parse(TETstat["AFC"]) : 0); 1522 | 1523 | switch (func) 1524 | { 1525 | case "BURST": 1526 | rxo.seenBurst(); 1527 | break; 1528 | 1529 | case "AFCVAL": 1530 | rxo.setAfc(afc); 1531 | break; 1532 | 1533 | case "NETINFO1": 1534 | case "FREQINFO1": 1535 | case "FREQINFO2": 1536 | if (dl_freq == 0) break; 1537 | freq_reason fr = freq_reason.UNKNOWN; 1538 | switch(func) 1539 | { 1540 | case "NETINFO1": fr = freq_reason.NETINFO; break; 1541 | case "FREQINFO1": fr = freq_reason.FREQINFO; break; 1542 | case "FREQINFO2": fr = freq_reason.DLFREQ; break; 1543 | } 1544 | if (rxo.mode == rx_mode.ALLSCAN || rxo.mode == rx_mode.BANDSCAN) 1545 | { 1546 | // note that the channel was discovered during scanning 1547 | fr = freq_reason.SCANNED; 1548 | } 1549 | 1550 | frequency newfreq = new frequency(mcc, mnc, dl_freq, ul_freq, la, ccode, fr); 1551 | 1552 | frequency oldfreq = freqs.FirstOrDefault(w => w.dl_freq == dl_freq); 1553 | 1554 | if (oldfreq == null) 1555 | { 1556 | freqs.Add(newfreq); 1557 | } 1558 | else 1559 | { 1560 | if (oldfreq.mcc == 0 || oldfreq.mnc == 0) 1561 | { 1562 | oldfreq.mcc = mcc; 1563 | oldfreq.mnc = mnc; 1564 | } 1565 | oldfreq.addla(la); 1566 | oldfreq.addcc(ccode); 1567 | oldfreq.reason = fr; 1568 | } 1569 | break; 1570 | 1571 | case "DSETUPDEC": 1572 | if (idxo != null) 1573 | { 1574 | idxo.addssi(ssi1); 1575 | idxo.addssi(ssi2); 1576 | } 1577 | 1578 | if (cid > 0) 1579 | { 1580 | cidaddssi(cid, ssi1); 1581 | cidaddssi(cid, ssi2); 1582 | } 1583 | break; 1584 | 1585 | case "DCONNECTDEC": 1586 | if (idxo != null) 1587 | { 1588 | idxo.addssi(ssi1); 1589 | idxo.addssi(ssi2); 1590 | if (cid > 0) 1591 | { 1592 | idxo.addcid(cid); 1593 | } 1594 | } 1595 | 1596 | break; 1597 | 1598 | case "DTXGRANTDEC": 1599 | string txgr = TETstat["TXGRANT"]; 1600 | if (cid > 0 && (txgr == "1" || txgr == "3")) 1601 | { 1602 | cidaddssi(cid, ssi1); 1603 | cidaddssi(cid, ssi2); 1604 | } 1605 | break; 1606 | 1607 | case "SDSDEC": 1608 | string ssisrc = TETstat["CallingSSI"]; 1609 | string ssitrg = TETstat["CalledSSI"]; 1610 | if (buf.Contains("DATA:")) 1611 | { 1612 | int poz = buf.IndexOf("DATA:[")+6; 1613 | string dat = buf.Substring(poz); 1614 | poz = dat.IndexOf("]"); 1615 | dat = dat.Substring(0, poz); 1616 | fs.BeginInvoke((MethodInvoker)delegate 1617 | { 1618 | fs.addMsg(dat); 1619 | }); 1620 | 1621 | 1622 | } 1623 | //string data = TETstat["DATA"]; 1624 | //string lat = TETstat["lat"]; 1625 | //string lon = TETstat["lon"]; 1626 | // pokud contains Test. posli DATA 1627 | break; 1628 | 1629 | case "D-SETUP": 1630 | case "D-CONNECT": 1631 | if (idt == addr_type.SSI_USAGE) 1632 | { 1633 | if (idxo != null) 1634 | idxo.addssi(ssi1); 1635 | } 1636 | break; 1637 | 1638 | case "D-RELEASE": 1639 | if (idxo != null) 1640 | idxo.removessi(ssi1); 1641 | break; 1642 | 1643 | default: 1644 | return; 1645 | } 1646 | 1647 | } 1648 | 1649 | private static void parseTraffic(byte[] buf) 1650 | { 1651 | byte[] controlb = new byte[12]; 1652 | byte[] payload = new byte[1380]; 1653 | Array.Copy(buf, 0, controlb, 0, controlb.Length); 1654 | Array.Copy(buf, 13, payload, 0, payload.Length); 1655 | 1656 | string control = Encoding.ASCII.GetString(controlb); 1657 | 1658 | 1659 | Dictionary TETstat = TETelements(control); 1660 | ushort rx; 1661 | receiver rxo = null; 1662 | if (TETstat.ContainsKey("RX")) 1663 | { 1664 | rx = ushort.Parse(TETstat["RX"], NumberStyles.HexNumber); 1665 | rxo = rxs.FirstOrDefault(w => w.id == rx); 1666 | if (rxo == null) 1667 | // rx received but not exists 1668 | return; 1669 | if (rxo.mode != rx_mode.TUNED) 1670 | // rx is muted or scanning 1671 | return; 1672 | } 1673 | else 1674 | { 1675 | // RX not received 1676 | return; 1677 | } 1678 | 1679 | rxo.seen(); 1680 | 1681 | ushort idx; 1682 | usi idxo = null; 1683 | if (TETstat.ContainsKey("TRA")) 1684 | { 1685 | idx = ushort.Parse(TETstat["TRA"], NumberStyles.HexNumber); 1686 | idxo = findOrCreateUsi(idx); 1687 | idxo.seen(rx); 1688 | } 1689 | else 1690 | { 1691 | // no idx at all 1692 | return; 1693 | } 1694 | 1695 | idxo.play(rx); 1696 | rxo.spl.processAcelp(payload); 1697 | 1698 | // if ssis !encr 1699 | 1700 | } 1701 | 1702 | } 1703 | 1704 | } 1705 | --------------------------------------------------------------------------------