add support for DES-OFB; fix alert tone to behave as expected with primary channel; update fnecore submodule

pull/1/head
firealarmss 11 months ago
parent f13a4775e2
commit 5eb294f273

@ -42,7 +42,7 @@ zones:
tgid: "2001"
# Encryption Key Id (If 0 or blank, will be assumed clear)
keyId: 0x50
# Algorithm AES ("aes"), ADP/ARC4 ("arc4"), None ("none")
# Algorithm AES ("aes"), DES-OFB ("des"), ADP/ARC4 ("arc4"), None ("none")
algo: "aes"
# Ignored now, we use dvmfne KMM support (This will be used in the future to ovveride FNE KMM support)
encryptionKey: null

@ -206,6 +206,8 @@ namespace dvmconsole
{
case "aes":
return P25Defines.P25_ALGO_AES;
case "des":
return P25Defines.P25_ALGO_DES;
case "arc4":
return P25Defines.P25_ALGO_ARC4;
default:

@ -11,12 +11,9 @@
*
*/
using System.Diagnostics;
using fnecore;
using fnecore.DMR;
using NAudio.Wave;
namespace dvmconsole
{
/// <summary>

@ -651,122 +651,125 @@ namespace dvmconsole
{
try
{
var channel = selectedChannelsManager.PrimaryChannel;
if (channel == null)
ChannelBox primaryChannel = selectedChannelsManager.PrimaryChannel;
List<ChannelBox> channelsToProcess = primaryChannel != null
? new List<ChannelBox> { primaryChannel }
: selectedChannelsManager.GetSelectedChannels().ToList();
foreach (ChannelBox channel in channelsToProcess)
{
return;
}
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
return;
if (channel.SystemName == PLAYBACKSYS || channel.ChannelName == PLAYBACKCHNAME || channel.DstId == PLAYBACKTG)
return;
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
if (system == null)
{
Log.WriteLine($"{channel.ChannelName} refers to an {INVALID_SYSTEM} {channel.SystemName}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
Codeplug.System system = Codeplug.GetSystemForChannel(channel.ChannelName);
if (system == null)
{
Log.WriteLine($"{channel.ChannelName} refers to an {INVALID_SYSTEM} {channel.SystemName}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
if (cpgChannel == null)
{
Log.WriteLine($"{channel.ChannelName} refers to an {INVALID_CODEPLUG_CHANNEL}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
Codeplug.Channel cpgChannel = Codeplug.GetChannelByName(channel.ChannelName);
if (cpgChannel == null)
{
Log.WriteLine($"{channel.ChannelName} refers to an {INVALID_CODEPLUG_CHANNEL}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
PeerSystem fne = fneSystemManager.GetFneSystem(system.Name);
if (fne == null)
{
Log.WriteLine($"{channel.ChannelName} has a {ERR_INVALID_FNE_REF}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
PeerSystem fne = fneSystemManager.GetFneSystem(system.Name);
if (fne == null)
{
Log.WriteLine($"{channel.ChannelName} has a {ERR_INVALID_FNE_REF}. {ERR_INVALID_CODEPLUG}. {ERR_SKIPPING_AUDIO}.");
channel.IsSelected = false;
selectedChannelsManager.RemoveSelectedChannel(channel);
return;
}
//
if (channel.PageState || (forHold && channel.HoldState))
{
byte[] pcmData;
if (channel.PageState || (forHold && channel.HoldState) || primaryChannel != null)
{
byte[] pcmData;
Task.Run(async () => {
using (var waveReader = new WaveFileReader(filePath))
Task.Run(async () =>
{
if (waveReader.WaveFormat.Encoding != WaveFormatEncoding.Pcm ||
waveReader.WaveFormat.SampleRate != 8000 ||
waveReader.WaveFormat.BitsPerSample != 16 ||
waveReader.WaveFormat.Channels != 1)
using (var waveReader = new WaveFileReader(filePath))
{
MessageBox.Show("The alert tone must be PCM 16-bit, Mono, 8000Hz format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
if (waveReader.WaveFormat.Encoding != WaveFormatEncoding.Pcm ||
waveReader.WaveFormat.SampleRate != 8000 ||
waveReader.WaveFormat.BitsPerSample != 16 ||
waveReader.WaveFormat.Channels != 1)
{
MessageBox.Show("The alert tone must be PCM 16-bit, Mono, 8000Hz format.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
using (MemoryStream ms = new MemoryStream())
{
waveReader.CopyTo(ms);
pcmData = ms.ToArray();
using (MemoryStream ms = new MemoryStream())
{
waveReader.CopyTo(ms);
pcmData = ms.ToArray();
}
}
}
int chunkSize = 1600;
int totalChunks = (pcmData.Length + chunkSize - 1) / chunkSize;
int chunkSize = 1600;
int totalChunks = (pcmData.Length + chunkSize - 1) / chunkSize;
if (pcmData.Length % chunkSize != 0)
{
byte[] paddedData = new byte[totalChunks * chunkSize];
Buffer.BlockCopy(pcmData, 0, paddedData, 0, pcmData.Length);
pcmData = paddedData;
}
if (pcmData.Length % chunkSize != 0)
{
byte[] paddedData = new byte[totalChunks * chunkSize];
Buffer.BlockCopy(pcmData, 0, paddedData, 0, pcmData.Length);
pcmData = paddedData;
}
Task.Run(() =>
{
audioManager.AddTalkgroupStream(cpgChannel.Tgid, pcmData);
});
Task.Run(() =>
{
audioManager.AddTalkgroupStream(cpgChannel.Tgid, pcmData);
});
DateTime startTime = DateTime.UtcNow;
DateTime startTime = DateTime.UtcNow;
for (int i = 0; i < totalChunks; i++)
{
int offset = i * chunkSize;
byte[] chunk = new byte[chunkSize];
Buffer.BlockCopy(pcmData, offset, chunk, 0, chunkSize);
for (int i = 0; i < totalChunks; i++)
{
int offset = i * chunkSize;
byte[] chunk = new byte[chunkSize];
Buffer.BlockCopy(pcmData, offset, chunk, 0, chunkSize);
channel.chunkedPCM = AudioConverter.SplitToChunks(chunk);
channel.chunkedPCM = AudioConverter.SplitToChunks(chunk);
foreach (byte[] audioChunk in channel.chunkedPCM)
{
if (audioChunk.Length == PCM_SAMPLES_LENGTH)
foreach (byte[] audioChunk in channel.chunkedPCM)
{
if (cpgChannel.GetChannelMode() == Codeplug.ChannelMode.P25)
P25EncodeAudioFrame(audioChunk, fne, channel, cpgChannel, system);
else if (cpgChannel.GetChannelMode() == Codeplug.ChannelMode.DMR)
DMREncodeAudioFrame(audioChunk, fne, channel, cpgChannel, system);
if (audioChunk.Length == PCM_SAMPLES_LENGTH)
{
if (cpgChannel.GetChannelMode() == Codeplug.ChannelMode.P25)
P25EncodeAudioFrame(audioChunk, fne, channel, cpgChannel, system);
else if (cpgChannel.GetChannelMode() == Codeplug.ChannelMode.DMR)
DMREncodeAudioFrame(audioChunk, fne, channel, cpgChannel, system);
}
}
}
DateTime nextPacketTime = startTime.AddMilliseconds((i + 1) * 100);
TimeSpan waitTime = nextPacketTime - DateTime.UtcNow;
DateTime nextPacketTime = startTime.AddMilliseconds((i + 1) * 100);
TimeSpan waitTime = nextPacketTime - DateTime.UtcNow;
if (waitTime.TotalMilliseconds > 0)
await Task.Delay(waitTime);
}
if (waitTime.TotalMilliseconds > 0)
await Task.Delay(waitTime);
}
double totalDurationMs = ((double)pcmData.Length / 16000) + 250;
await Task.Delay((int)totalDurationMs + 3000);
double totalDurationMs = ((double)pcmData.Length / 16000) + 250;
await Task.Delay((int)totalDurationMs + 3000);
fne.SendP25TDU(uint.Parse(system.Rid), uint.Parse(cpgChannel.Tgid), false);
fne.SendP25TDU(uint.Parse(system.Rid), uint.Parse(cpgChannel.Tgid), false);
Dispatcher.Invoke(() =>
{
if (forHold)
channel.PttButton.Background = ChannelBox.GRAY_GRADIENT;
else
channel.PageState = false;
Dispatcher.Invoke(() =>
{
if (forHold)
channel.PttButton.Background = ChannelBox.GRAY_GRADIENT;
else
channel.PageState = false;
});
});
});
}
}
}
catch (Exception ex)

@ -1 +1 @@
Subproject commit 13a82b3a82054e4fe8299368c7258c51176cee87
Subproject commit 0419c2fac7351e67064437f94751bad21bc92975
Loading…
Cancel
Save

Powered by TurnKey Linux.