if the server disconnects reset all channel states back to default; add a maintenance loop to check for Rx "stuck" channels and return them to a default state;

pull/2/head
Bryan Biedenkapp 10 months ago
parent 3718f20e0c
commit 7432379ef8

@ -154,6 +154,11 @@ namespace dvmconsole.Controls
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Last Packet Time
/// </summary>
public DateTime LastPktTime = DateTime.Now;
/// <summary>
/// Flag indicating whether or not this channel is receiving.
/// </summary>

@ -261,6 +261,8 @@ namespace dvmconsole
Buffer.BlockCopy(e.Data, 20, data, 0, FneSystemBase.DMR_FRAME_LENGTH_BYTES);
byte bits = e.Data[15];
channel.LastPktTime = pktTime;
// is this a new call stream?
if (e.StreamId != systemStatuses[cpgChannel.Name + e.Slot].RxStreamId)
{
@ -290,18 +292,13 @@ namespace dvmconsole
channel.Background = ChannelBox.GREEN_GRADIENT;
}
string alias = string.Empty;
try
// reset the channel state if we're not Rx
if (!channel.IsReceiving)
{
alias = AliasTools.GetAliasByRid(system.RidAlias, (int)e.SrcId);
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
continue;
}
catch (Exception) { }
if (string.IsNullOrEmpty(alias))
channel.LastSrcId = "Last ID: " + e.SrcId;
else
channel.LastSrcId = "Last: " + alias;
// if we can, use the PI LC from the PI voice header as to keep all options intact
if ((e.FrameType == FrameType.DATA_SYNC) && (e.DataType == DMRDataType.VOICE_PI_HEADER))
@ -322,6 +319,19 @@ namespace dvmconsole
callHistoryWindow.ChannelUnkeyed(cpgChannel.Name, (int)e.SrcId);
}
string alias = string.Empty;
try
{
alias = AliasTools.GetAliasByRid(system.RidAlias, (int)e.SrcId);
}
catch (Exception) { }
if (string.IsNullOrEmpty(alias))
channel.LastSrcId = "Last ID: " + e.SrcId;
else
channel.LastSrcId = "Last: " + alias;
if (e.FrameType == FrameType.VOICE_SYNC || e.FrameType == FrameType.VOICE)
{
byte[] ambe = new byte[FneSystemBase.DMR_AMBE_LENGTH_BYTES];

@ -458,6 +458,7 @@ namespace dvmconsole
channel.Decoder = new MBEDecoder(MBE_MODE.IMBE_88BIT);
SlotStatus slot = systemStatuses[cpgChannel.Name];
channel.LastPktTime = pktTime;
// if this is an LDU1 see if this is the first LDU with HDU encryption data
if (e.DUID == P25DUID.LDU1)
@ -498,6 +499,14 @@ namespace dvmconsole
Log.WriteLine($"({system.Name}) P25D: Traffic *CALL ENC PARMS * PEER {e.PeerId} SRC_ID {e.SrcId} TGID {e.DstId} ALGID {channel.algId} KID {channel.kId} [STREAM ID {e.StreamId}]");
}
// reset the channel state if we're not Rx
if (!channel.IsReceiving)
{
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
continue;
}
// is the call over?
if (((e.DUID == P25DUID.TDU) || (e.DUID == P25DUID.TDULC)) && (slot.RxType != fnecore.FrameType.TERMINATOR))
{
@ -507,7 +516,7 @@ namespace dvmconsole
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
callHistoryWindow.ChannelUnkeyed(cpgChannel.Name, (int)e.SrcId);
return;
continue;
}
// do background updates here -- this catches late entry

@ -40,6 +40,7 @@ using fnecore.DMR;
using fnecore.P25;
using fnecore.P25.KMM;
using fnecore.P25.LC.TSBK;
using System.Net.Sockets;
namespace dvmconsole
{
@ -123,9 +124,12 @@ namespace dvmconsole
private bool selectAll = false;
private CancellationTokenSource maintainenceCancelToken = new CancellationTokenSource();
private Task maintainenceTask = null;
/*
** Properties
*/
** Properties
*/
/// <summary>
/// Codeplug
@ -133,8 +137,8 @@ namespace dvmconsole
public Codeplug Codeplug { get; set; }
/*
** Methods
*/
** Methods
*/
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
@ -418,6 +422,20 @@ namespace dvmconsole
DisableCommandControls();
systemStatusBox.Background = ChannelBox.RED_GRADIENT;
systemStatusBox.ConnectionState = "Disconnected";
foreach (ChannelBox channel in selectedChannelsManager.GetSelectedChannels())
{
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
continue;
if (channel.IsReceiving || channel.IsReceivingEncrypted)
{
channel.IsReceiving = false;
channel.IsReceivingEncrypted = false;
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
}
}
});
};
@ -900,6 +918,22 @@ namespace dvmconsole
{
isShuttingDown = true;
// stop maintainence task
if (maintainenceTask != null)
{
maintainenceCancelToken.Cancel();
try
{
maintainenceTask.GetAwaiter().GetResult();
}
catch (OperationCanceledException) { /* stub */ }
finally
{
maintainenceCancelToken.Dispose();
}
}
waveIn.StopRecording();
fneSystemManager.ClearAll();
@ -920,6 +954,57 @@ namespace dvmconsole
Application.Current.Shutdown();
}
/// <summary>
/// Internal maintainence routine.
/// </summary>
private async void Maintainence()
{
CancellationToken ct = maintainenceCancelToken.Token;
while (!isShuttingDown)
{
foreach (ChannelBox channel in selectedChannelsManager.GetSelectedChannels())
{
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
continue;
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
if (system == null)
continue;
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
if (cpgChannel == null)
continue;
PeerSystem fne = fneSystemManager.GetFneSystem(system.Name);
if (fne == null)
continue;
// check if the channel is stuck reporting Rx
if (channel.IsReceiving)
{
DateTime now = DateTime.Now;
TimeSpan dt = now - channel.LastPktTime;
if (dt.TotalMilliseconds > 2000) // 2 seconds is more then enough time -- the interpacket time for P25 is ~180ms and DMR is ~60ms
{
Log.WriteLine($"({system.Name}) P25D: Traffic *CALL TIMEOUT * TGID {channel.DstId} ALGID {channel.algId} KID {channel.kId}");
Dispatcher.Invoke(() =>
{
channel.IsReceiving = false;
channel.Background = ChannelBox.BLUE_GRADIENT;
channel.VolumeMeterLevel = 0;
});
}
}
}
try
{
await Task.Delay(1000, ct);
}
catch (TaskCanceledException) { /* stub */ }
}
}
/** NAudio Events */
/// <summary>
@ -1097,6 +1182,8 @@ namespace dvmconsole
btnGlobalPttDefaultBg = btnGlobalPtt.Background;
maintainenceTask = Task.Factory.StartNew(Maintainence, maintainenceCancelToken.Token);
// set window configuration
if (settingsManager.Maximized)
{

@ -1 +1 @@
Subproject commit 78e74f9074270c530c86447b01ab06e7527d81bb
Subproject commit 054954fad3e330e665cbbcb1eca67c927e26e425
Loading…
Cancel
Save

Powered by TurnKey Linux.