|
|
|
@ -1,18 +1,11 @@
|
|
|
|
/*
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
* WhackerLink - WhackerLinkConsoleV2
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Digital Voice Modem - DVMConsole
|
|
|
|
|
|
|
|
* AGPLv3 Open Source. Use is subject to license terms.
|
|
|
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* @package DVM / DVM Console
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* @license AGPLv3 License (https://opensource.org/licenses/AGPL-3.0)
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Copyright (C) 2024-2025 Caleb, K4PHP
|
|
|
|
* Copyright (C) 2024-2025 Caleb, K4PHP
|
|
|
|
* Copyright (C) 2025 J. Dean
|
|
|
|
* Copyright (C) 2025 J. Dean
|
|
|
|
@ -26,32 +19,19 @@ using System.IO;
|
|
|
|
using System.Windows;
|
|
|
|
using System.Windows;
|
|
|
|
using System.Windows.Controls;
|
|
|
|
using System.Windows.Controls;
|
|
|
|
using System.Windows.Input;
|
|
|
|
using System.Windows.Input;
|
|
|
|
using WhackerLinkLib.Models.Radio;
|
|
|
|
|
|
|
|
using YamlDotNet.Serialization;
|
|
|
|
using YamlDotNet.Serialization;
|
|
|
|
using YamlDotNet.Serialization.NamingConventions;
|
|
|
|
using YamlDotNet.Serialization.NamingConventions;
|
|
|
|
using WhackerLinkConsoleV2.Controls;
|
|
|
|
using DVMConsole.Controls;
|
|
|
|
using WebSocketManager = WhackerLinkLib.Managers.WebSocketManager;
|
|
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
using System.Windows.Media;
|
|
|
|
using WhackerLinkLib.Utils;
|
|
|
|
|
|
|
|
using WhackerLinkLib.Models;
|
|
|
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
|
|
using NAudio.Wave;
|
|
|
|
using NAudio.Wave;
|
|
|
|
using WhackerLinkLib.Interfaces;
|
|
|
|
|
|
|
|
using WhackerLinkLib.Models.IOSP;
|
|
|
|
|
|
|
|
using fnecore.P25;
|
|
|
|
using fnecore.P25;
|
|
|
|
using fnecore;
|
|
|
|
using fnecore;
|
|
|
|
using Microsoft.VisualBasic;
|
|
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
using Nancy;
|
|
|
|
|
|
|
|
using Constants = fnecore.Constants;
|
|
|
|
using Constants = fnecore.Constants;
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
|
|
|
using fnecore.P25.LC.TSBK;
|
|
|
|
using fnecore.P25.LC.TSBK;
|
|
|
|
using WebSocketSharp;
|
|
|
|
|
|
|
|
using NWaves.Signals;
|
|
|
|
using NWaves.Signals;
|
|
|
|
using static WhackerLinkConsoleV2.P25Crypto;
|
|
|
|
using static DVMConsole.P25Crypto;
|
|
|
|
using static WhackerLinkLib.Models.Radio.Codeplug;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace WhackerLinkConsoleV2
|
|
|
|
namespace DVMConsole
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public partial class MainWindow : Window
|
|
|
|
public partial class MainWindow : Window
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -60,6 +40,8 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
private bool globalPttState = false;
|
|
|
|
private bool globalPttState = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private const int GridSize = 5;
|
|
|
|
|
|
|
|
|
|
|
|
private UIElement _draggedElement;
|
|
|
|
private UIElement _draggedElement;
|
|
|
|
private Point _startPoint;
|
|
|
|
private Point _startPoint;
|
|
|
|
private double _offsetX;
|
|
|
|
private double _offsetX;
|
|
|
|
@ -70,7 +52,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
private SelectedChannelsManager _selectedChannelsManager;
|
|
|
|
private SelectedChannelsManager _selectedChannelsManager;
|
|
|
|
private FlashingBackgroundManager _flashingManager;
|
|
|
|
private FlashingBackgroundManager _flashingManager;
|
|
|
|
private WaveFilePlaybackManager _emergencyAlertPlayback;
|
|
|
|
private WaveFilePlaybackManager _emergencyAlertPlayback;
|
|
|
|
private WebSocketManager _webSocketManager = new WebSocketManager();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ChannelBox playbackChannelBox;
|
|
|
|
private ChannelBox playbackChannelBox;
|
|
|
|
|
|
|
|
|
|
|
|
@ -88,12 +69,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
private Dictionary<string, SlotStatus> systemStatuses = new Dictionary<string, SlotStatus>();
|
|
|
|
private Dictionary<string, SlotStatus> systemStatuses = new Dictionary<string, SlotStatus>();
|
|
|
|
private FneSystemManager _fneSystemManager = new FneSystemManager();
|
|
|
|
private FneSystemManager _fneSystemManager = new FneSystemManager();
|
|
|
|
|
|
|
|
|
|
|
|
private bool cryptodev = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static HashSet<uint> usedRids = new HashSet<uint>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Tuple<uint, uint>> fneAffs = new List<Tuple<uint, uint>>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public MainWindow()
|
|
|
|
public MainWindow()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#if !DEBUG
|
|
|
|
#if !DEBUG
|
|
|
|
@ -206,77 +181,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
if (File.Exists(system.AliasPath))
|
|
|
|
if (File.Exists(system.AliasPath))
|
|
|
|
system.RidAlias = AliasTools.LoadAliases(system.AliasPath);
|
|
|
|
system.RidAlias = AliasTools.LoadAliases(system.AliasPath);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_webSocketManager.AddWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
handler.OnVoiceChannelResponse += HandleVoiceResponse;
|
|
|
|
|
|
|
|
handler.OnVoiceChannelRelease += HandleVoiceRelease;
|
|
|
|
|
|
|
|
handler.OnEmergencyAlarmResponse += HandleEmergencyAlarmResponse;
|
|
|
|
|
|
|
|
handler.OnAudioData += HandleReceivedAudio;
|
|
|
|
|
|
|
|
handler.OnAffiliationUpdate += HandleAffiliationUpdate;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.OnUnitRegistrationResponse += (response) =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (response.Status == (int)ResponseType.GRANT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
systemStatusBox.Background = (Brush)new BrushConverter().ConvertFrom("#FF00BC48");
|
|
|
|
|
|
|
|
systemStatusBox.ConnectionState = "Connected";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
systemStatusBox.Background = new SolidColorBrush(Colors.Red);
|
|
|
|
|
|
|
|
systemStatusBox.ConnectionState = "Disconnected";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.OnClose += () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
systemStatusBox.Background = new SolidColorBrush(Colors.Red);
|
|
|
|
|
|
|
|
systemStatusBox.ConnectionState = "Disconnected";
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.OnOpen += () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Console.WriteLine("Peer connected");
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.OnReconnecting += () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Console.WriteLine("Peer reconnecting");
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
handler.Connect(system.Address, system.Port, system.AuthKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.OnGroupAffiliationResponse += (response) => { /* TODO */ };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (handler.IsConnected)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
U_REG_REQ release = new U_REG_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
systemStatusBox.Background = new SolidColorBrush(Colors.Red);
|
|
|
|
|
|
|
|
systemStatusBox.ConnectionState = "Disconnected";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
_fneSystemManager.AddFneSystem(system.Name, system, this);
|
|
|
|
_fneSystemManager.AddFneSystem(system.Name, system, this);
|
|
|
|
|
|
|
|
|
|
|
|
PeerSystem peer = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem peer = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
@ -308,7 +212,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
{
|
|
|
|
{
|
|
|
|
peer.Start();
|
|
|
|
peer.Start();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!_settingsManager.ShowSystemStatus)
|
|
|
|
if (!_settingsManager.ShowSystemStatus)
|
|
|
|
systemStatusBox.Visibility = Visibility.Collapsed;
|
|
|
|
systemStatusBox.Visibility = Visibility.Collapsed;
|
|
|
|
@ -441,37 +344,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
Task.Run(() =>
|
|
|
|
Task.Run(() =>
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.IsSelected && channel.VoiceChannel != null && channel.PttState)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
isAnyTgOn = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
object voicePaket = new
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type = PacketType.AUDIO_DATA,
|
|
|
|
|
|
|
|
data = new
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Data = e.Buffer,
|
|
|
|
|
|
|
|
VoiceChannel = new VoiceChannel
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Frequency = channel.VoiceChannel,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(voicePaket);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
@ -495,7 +367,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -513,55 +384,14 @@ namespace WhackerLinkConsoleV2
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm) {
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.IsSelected && handler.IsConnected)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Console.WriteLine("sending WLINK master aff");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_AFF_REQ release = new GRP_AFF_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem fne = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem fne = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.IsSelected)
|
|
|
|
if (channel.IsSelected)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint newTgid = UInt32.Parse(cpgChannel.Tgid);
|
|
|
|
uint newTgid = UInt32.Parse(cpgChannel.Tgid);
|
|
|
|
bool exists = fneAffs.Any(aff => aff.Item2 == newTgid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cpgChannel.GetAlgoId() != 0 && cpgChannel.GetKeyId() != 0)
|
|
|
|
if (cpgChannel.GetAlgoId() != 0 && cpgChannel.GetKeyId() != 0)
|
|
|
|
fne.peer.SendMasterKeyRequest(cpgChannel.GetAlgoId(), cpgChannel.GetKeyId());
|
|
|
|
fne.peer.SendMasterKeyRequest(cpgChannel.GetAlgoId(), cpgChannel.GetKeyId());
|
|
|
|
|
|
|
|
|
|
|
|
if (!exists)
|
|
|
|
|
|
|
|
fneAffs.Add(new Tuple<uint, uint>(GetUniqueRid(system.Rid), newTgid));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Console.WriteLine("FNE Affiliations:");
|
|
|
|
|
|
|
|
//foreach (var aff in fneAffs)
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// Console.WriteLine($" RID: {aff.Item1}, TGID: {aff.Item2}");
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Codeplug.System system in Codeplug.Systems)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem fne = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
//fne.peer.SendMasterAffiliationUpdate(fneAffs);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -579,20 +409,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
|
|
|
|
DigitalPageWindow pageWindow = new DigitalPageWindow(Codeplug.Systems);
|
|
|
|
pageWindow.Owner = this;
|
|
|
|
pageWindow.Owner = this;
|
|
|
|
if (pageWindow.ShowDialog() == true)
|
|
|
|
if (pageWindow.ShowDialog() == true)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!pageWindow.RadioSystem.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(pageWindow.RadioSystem.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CALL_ALRT_REQ callAlert = new CALL_ALRT_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = pageWindow.RadioSystem.Rid,
|
|
|
|
|
|
|
|
DstId = pageWindow.DstId
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(callAlert.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(pageWindow.RadioSystem.Name);
|
|
|
|
IOSP_CALL_ALRT callAlert = new IOSP_CALL_ALRT(UInt32.Parse(pageWindow.DstId), UInt32.Parse(pageWindow.RadioSystem.Rid));
|
|
|
|
IOSP_CALL_ALRT callAlert = new IOSP_CALL_ALRT(UInt32.Parse(pageWindow.DstId), UInt32.Parse(pageWindow.RadioSystem.Rid));
|
|
|
|
@ -614,7 +430,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
Console.WriteLine("sent page");
|
|
|
|
Console.WriteLine("sent page");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async void ManualPage_Click(object sender, RoutedEventArgs e)
|
|
|
|
private async void ManualPage_Click(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -626,6 +441,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.PageState)
|
|
|
|
if (channel.PageState)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -641,10 +457,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
Buffer.BlockCopy(toneA, 0, combinedAudio, 0, toneA.Length);
|
|
|
|
Buffer.BlockCopy(toneA, 0, combinedAudio, 0, toneA.Length);
|
|
|
|
Buffer.BlockCopy(toneB, 0, combinedAudio, toneA.Length, toneB.Length);
|
|
|
|
Buffer.BlockCopy(toneB, 0, combinedAudio, toneA.Length, toneB.Length);
|
|
|
|
|
|
|
|
|
|
|
|
int chunkSize = 1600;
|
|
|
|
int chunkSize = 320;
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
chunkSize = 320;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int totalChunks = (combinedAudio.Length + chunkSize - 1) / chunkSize;
|
|
|
|
int totalChunks = (combinedAudio.Length + chunkSize - 1) / chunkSize;
|
|
|
|
|
|
|
|
|
|
|
|
@ -664,61 +477,17 @@ namespace WhackerLinkConsoleV2
|
|
|
|
byte[] chunk = new byte[chunkSize];
|
|
|
|
byte[] chunk = new byte[chunkSize];
|
|
|
|
Buffer.BlockCopy(combinedAudio, offset, chunk, 0, size);
|
|
|
|
Buffer.BlockCopy(combinedAudio, offset, chunk, 0, size);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AudioPacket voicePacket = new AudioPacket
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Data = chunk,
|
|
|
|
|
|
|
|
VoiceChannel = new VoiceChannel
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Frequency = channel.VoiceChannel,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Site = system.Site,
|
|
|
|
|
|
|
|
LopServerVocode = true
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(voicePacket.GetData());
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (chunk.Length == 320)
|
|
|
|
if (chunk.Length == 320)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
P25EncodeAudioFrame(chunk, handler, channel, cpgChannel, system);
|
|
|
|
P25EncodeAudioFrame(chunk, handler, channel, cpgChannel, system);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
double totalDurationMs = (toneADuration + toneBDuration) * 1000 + 750;
|
|
|
|
double totalDurationMs = (toneADuration + toneBDuration) * 1000 + 750;
|
|
|
|
await Task.Delay((int)totalDurationMs);
|
|
|
|
await Task.Delay((int)totalDurationMs + 4000);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRP_VCH_RLS release = new GRP_VCH_RLS
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Channel = channel.VoiceChannel,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Delay(4000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -748,6 +517,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.PageState || (forHold && channel.HoldState))
|
|
|
|
if (channel.PageState || (forHold && channel.HoldState))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -795,28 +565,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
byte[] chunk = new byte[chunkSize];
|
|
|
|
byte[] chunk = new byte[chunkSize];
|
|
|
|
Buffer.BlockCopy(pcmData, offset, chunk, 0, chunkSize);
|
|
|
|
Buffer.BlockCopy(pcmData, offset, chunk, 0, chunkSize);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AudioPacket voicePacket = new AudioPacket
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Data = chunk,
|
|
|
|
|
|
|
|
VoiceChannel = new VoiceChannel
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Frequency = channel.VoiceChannel,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
Site = system.Site,
|
|
|
|
|
|
|
|
LopServerVocode = true
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(voicePacket.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
channel.chunkedPcm = AudioConverter.SplitToChunks(chunk);
|
|
|
|
channel.chunkedPcm = AudioConverter.SplitToChunks(chunk);
|
|
|
|
@ -828,7 +576,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
P25EncodeAudioFrame(smallchunk, handler, channel, cpgChannel, system);
|
|
|
|
P25EncodeAudioFrame(smallchunk, handler, channel, cpgChannel, system);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DateTime nextPacketTime = startTime.AddMilliseconds((i + 1) * 100);
|
|
|
|
DateTime nextPacketTime = startTime.AddMilliseconds((i + 1) * 100);
|
|
|
|
TimeSpan waitTime = nextPacketTime - DateTime.UtcNow;
|
|
|
|
TimeSpan waitTime = nextPacketTime - DateTime.UtcNow;
|
|
|
|
@ -840,34 +587,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double totalDurationMs = ((double)pcmData.Length / 16000) + 250;
|
|
|
|
double totalDurationMs = ((double)pcmData.Length / 16000) + 250;
|
|
|
|
await Task.Delay((int)totalDurationMs);
|
|
|
|
await Task.Delay((int)totalDurationMs + 3000);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRP_VCH_RLS release = new GRP_VCH_RLS
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Channel = channel.VoiceChannel,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (forHold)
|
|
|
|
|
|
|
|
channel.PttButton.Background = channel.grayGradient;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
channel.PageState = false;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Delay(3000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
|
|
|
|
|
|
|
|
@ -878,7 +598,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
else
|
|
|
|
else
|
|
|
|
channel.PageState = false;
|
|
|
|
channel.PageState = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -909,7 +628,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void HandleEmergencyAlarmResponse(EMRG_ALRM_RSP response)
|
|
|
|
private void HandleEmergency(string dstId, string srcId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
bool forUs = false;
|
|
|
|
bool forUs = false;
|
|
|
|
|
|
|
|
|
|
|
|
@ -918,11 +637,11 @@ namespace WhackerLinkConsoleV2
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (response.DstId == cpgChannel.Tgid)
|
|
|
|
if (dstId == cpgChannel.Tgid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
forUs = true;
|
|
|
|
forUs = true;
|
|
|
|
channel.Emergency = true;
|
|
|
|
channel.Emergency = true;
|
|
|
|
channel.LastSrcId = response.SrcId;
|
|
|
|
channel.LastSrcId = srcId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -936,180 +655,10 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void HandleReceivedAudio(AudioPacket audioPacket)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
bool shouldReceive = false;
|
|
|
|
|
|
|
|
string talkgroupId = audioPacket.VoiceChannel.DstId;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (audioPacket.VoiceChannel.SrcId != system.Rid && audioPacket.VoiceChannel.Frequency == channel.VoiceChannel && audioPacket.VoiceChannel.DstId == cpgChannel.Tgid)
|
|
|
|
|
|
|
|
shouldReceive = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (shouldReceive)
|
|
|
|
|
|
|
|
_audioManager.AddTalkgroupStream(talkgroupId, audioPacket.Data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void HandleAffiliationUpdate(AFF_UPDATE affUpdate)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ridExists = affUpdate.Affiliations.Any(aff => aff.SrcId == system.Rid);
|
|
|
|
|
|
|
|
bool tgidExists = affUpdate.Affiliations.Any(aff => aff.DstId == cpgChannel.Tgid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ridExists && tgidExists)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//Console.WriteLine("rid aff'ed");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//Console.WriteLine("rid not aff'ed");
|
|
|
|
|
|
|
|
Task.Run(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_AFF_REQ affReq = new GRP_AFF_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(affReq.GetData());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void HandleVoiceRelease(GRP_VCH_RLS response)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (response.DstId == cpgChannel.Tgid && response.SrcId != system.Rid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (channel.IsSelected)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.Background = (Brush)new BrushConverter().ConvertFrom("#FF0B004B");
|
|
|
|
|
|
|
|
channel.IsReceiving = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.Background = new SolidColorBrush(Colors.DarkGray);
|
|
|
|
|
|
|
|
channel.IsReceiving = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel.VoiceChannel = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void HandleVoiceResponse(GRP_VCH_RSP response)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
foreach (ChannelBox channel in _selectedChannelsManager.GetSelectedChannels())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.PttState && response.Status == (int)ResponseType.GRANT && response.Channel != null && response.SrcId == system.Rid && response.DstId == cpgChannel.Tgid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.VoiceChannel = response.Channel;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (response.Status == (int)ResponseType.GRANT && response.SrcId != system.Rid && response.DstId == cpgChannel.Tgid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.VoiceChannel = response.Channel;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string alias = string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
alias = AliasTools.GetAliasByRid(system.RidAlias, int.Parse(response.SrcId));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (Exception) { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alias.IsNullOrEmpty())
|
|
|
|
|
|
|
|
channel.LastSrcId = "Last SRC: " + response.SrcId;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
channel.LastSrcId = "Last: " + alias;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.Background = (Brush)new BrushConverter().ConvertFrom("#FF00BC48");
|
|
|
|
|
|
|
|
channel.IsReceiving = true;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if ((channel.HoldState || channel.PageState) && response.Status == (int)ResponseType.GRANT && response.Channel != null && response.SrcId == system.Rid && response.DstId == cpgChannel.Tgid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
channel.VoiceChannel = response.Channel;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// if (channel.IsSelected)
|
|
|
|
|
|
|
|
// channel.Background = new SolidColorBrush(Colors.DodgerBlue);
|
|
|
|
|
|
|
|
// else
|
|
|
|
|
|
|
|
// channel.Background = new SolidColorBrush(Colors.Gray);
|
|
|
|
|
|
|
|
//});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//channel.VoiceChannel = null;
|
|
|
|
|
|
|
|
//_stopSending = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void ChannelBox_HoldChannelButtonClicked(object sender, ChannelBox e)
|
|
|
|
private void ChannelBox_HoldChannelButtonClicked(object sender, ChannelBox e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (e.SystemName == PLAYBACKSYS || e.ChannelName == PLAYBACKCHNAME || e.DstId == PLAYBACKTG)
|
|
|
|
if (e.SystemName == PLAYBACKSYS || e.ChannelName == PLAYBACKCHNAME || e.DstId == PLAYBACKTG)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(e.ChannelName);
|
|
|
|
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(e.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (system.IsDvm)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ChannelBox_PageButtonClicked(object sender, ChannelBox e)
|
|
|
|
private void ChannelBox_PageButtonClicked(object sender, ChannelBox e)
|
|
|
|
@ -1119,40 +668,8 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(e.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(e.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(e.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(e.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (e.PageState)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_VCH_REQ request = new GRP_VCH_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(request.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_VCH_RLS release = new GRP_VCH_RLS
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Channel = e.VoiceChannel,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
e.VoiceChannel = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (e.PageState)
|
|
|
|
if (e.PageState)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), true);
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), true);
|
|
|
|
@ -1162,7 +679,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
handler.SendP25TDU(UInt32.Parse(system.Rid), UInt32.Parse(cpgChannel.Tgid), false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void ChannelBox_PTTButtonClicked(object sender, ChannelBox e)
|
|
|
|
private void ChannelBox_PTTButtonClicked(object sender, ChannelBox e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -1171,40 +687,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(e.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(e.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(e.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(e.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!e.IsSelected)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (e.PttState)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_VCH_REQ request = new GRP_VCH_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(request.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
GRP_VCH_RLS release = new GRP_VCH_RLS
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Channel = e.VoiceChannel,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
e.VoiceChannel = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (!e.IsSelected)
|
|
|
|
if (!e.IsSelected)
|
|
|
|
@ -1219,16 +701,13 @@ namespace WhackerLinkConsoleV2
|
|
|
|
{
|
|
|
|
{
|
|
|
|
e.txStreamId = handler.NewStreamId();
|
|
|
|
e.txStreamId = handler.NewStreamId();
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("sending grant demand " + dstId);
|
|
|
|
|
|
|
|
handler.SendP25TDU(srcId, dstId, true);
|
|
|
|
handler.SendP25TDU(srcId, dstId, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Console.WriteLine("sending terminator " + dstId);
|
|
|
|
|
|
|
|
handler.SendP25TDU(srcId, dstId, false);
|
|
|
|
handler.SendP25TDU(srcId, dstId, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void ChannelBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
|
|
private void ChannelBox_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -1243,8 +722,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
element.CaptureMouse();
|
|
|
|
element.CaptureMouse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private const int GridSize = 5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
private void ChannelBox_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!isEditMode || !_isDragging || _draggedElement == null) return;
|
|
|
|
if (!isEditMode || !_isDragging || _draggedElement == null) return;
|
|
|
|
@ -1413,36 +890,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.HoldState && !channel.IsReceiving && !channel.PttState && !channel.PageState)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(async () =>
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
Console.WriteLine("Sending channel hold beep");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() => { channel.PttButton.Background = channel.redGradient; });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRP_VCH_REQ req = new GRP_VCH_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(req.GetData());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Delay(1000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SendAlertTone("hold.wav", true);
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (channel.HoldState && !channel.IsReceiving && !channel.PttState && !channel.PageState)
|
|
|
|
if (channel.HoldState && !channel.IsReceiving && !channel.PttState && !channel.PageState)
|
|
|
|
@ -1454,7 +901,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
|
|
|
|
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -1511,53 +957,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
|
|
|
|
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
IPeer handler = _webSocketManager.GetWebSocketHandler(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!channel.IsSelected)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (globalPttState)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
btnGlobalPtt.Background = channel.redGradient;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRP_VCH_REQ request = new GRP_VCH_REQ
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel.PttState = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(request.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
btnGlobalPtt.Background = channel.grayGradient;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRP_VCH_RLS release = new GRP_VCH_RLS
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = system.Rid,
|
|
|
|
|
|
|
|
DstId = cpgChannel.Tgid,
|
|
|
|
|
|
|
|
Site = system.Site
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel.PttState = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler.SendMessage(release.GetData());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
channel.txStreamId = handler.NewStreamId();
|
|
|
|
channel.txStreamId = handler.NewStreamId();
|
|
|
|
@ -1584,9 +983,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click(object sender, RoutedEventArgs e) { /* sub */ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void SelectAll_Click(object sender, RoutedEventArgs e)
|
|
|
|
private void SelectAll_Click(object sender, RoutedEventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -1892,19 +1288,12 @@ namespace WhackerLinkConsoleV2
|
|
|
|
channel.p25Errs = channel.decoder.decode(imbe, samples);
|
|
|
|
channel.p25Errs = channel.decoder.decode(imbe, samples);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (emergency)
|
|
|
|
if (emergency && !channel.Emergency)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!channel.Emergency)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Task.Run(() =>
|
|
|
|
Task.Run(() =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
HandleEmergencyAlarmResponse(new EMRG_ALRM_RSP
|
|
|
|
HandleEmergency(e.SrcId.ToString(), e.DstId.ToString());
|
|
|
|
{
|
|
|
|
|
|
|
|
SrcId = e.SrcId.ToString(),
|
|
|
|
|
|
|
|
DstId = e.DstId.ToString()
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (samples != null)
|
|
|
|
if (samples != null)
|
|
|
|
@ -1932,28 +1321,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private uint GetUniqueRid(string ridString)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint rid;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Try to parse the RID, default to 1000 if parsing fails
|
|
|
|
|
|
|
|
if (!UInt32.TryParse(ridString, out rid))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rid = 1000;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure uniqueness by incrementing if needed
|
|
|
|
|
|
|
|
while (usedRids.Contains(rid))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
rid++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Store the new unique RID
|
|
|
|
|
|
|
|
usedRids.Add(rid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rid;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
@ -1982,10 +1349,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (cpgChannel.GetKeyId() != 0 && cpgChannel.GetAlgoId() != 0)
|
|
|
|
if (cpgChannel.GetKeyId() != 0 && cpgChannel.GetAlgoId() != 0)
|
|
|
|
@ -2027,9 +1390,6 @@ namespace WhackerLinkConsoleV2
|
|
|
|
bool isEmergency = false;
|
|
|
|
bool isEmergency = false;
|
|
|
|
bool encrypted = false;
|
|
|
|
bool encrypted = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!system.IsDvm)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
PeerSystem handler = _fneSystemManager.GetFneSystem(system.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if (!channel.IsEnabled)
|
|
|
|
if (!channel.IsEnabled)
|
|
|
|
@ -2088,7 +1448,7 @@ namespace WhackerLinkConsoleV2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception) { }
|
|
|
|
catch (Exception) { }
|
|
|
|
|
|
|
|
|
|
|
|
if (alias.IsNullOrEmpty())
|
|
|
|
if (string.IsNullOrEmpty(alias))
|
|
|
|
channel.LastSrcId = "Last SRC: " + e.SrcId;
|
|
|
|
channel.LastSrcId = "Last SRC: " + e.SrcId;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
channel.LastSrcId = "Last: " + alias;
|
|
|
|
channel.LastSrcId = "Last: " + alias;
|