diff --git a/configs/codeplug.example.yml b/configs/codeplug.example.yml index d7d7a65..14318c5 100644 --- a/configs/codeplug.example.yml +++ b/configs/codeplug.example.yml @@ -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 diff --git a/dvmconsole/Codeplug.cs b/dvmconsole/Codeplug.cs index 4418284..d480f41 100644 --- a/dvmconsole/Codeplug.cs +++ b/dvmconsole/Codeplug.cs @@ -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: diff --git a/dvmconsole/FneSystemBase.DMR.cs b/dvmconsole/FneSystemBase.DMR.cs index 977892c..5c5a59e 100644 --- a/dvmconsole/FneSystemBase.DMR.cs +++ b/dvmconsole/FneSystemBase.DMR.cs @@ -11,12 +11,9 @@ * */ -using System.Diagnostics; using fnecore; using fnecore.DMR; -using NAudio.Wave; - namespace dvmconsole { /// diff --git a/dvmconsole/MainWindow.xaml.cs b/dvmconsole/MainWindow.xaml.cs index bcc3661..3476693 100644 --- a/dvmconsole/MainWindow.xaml.cs +++ b/dvmconsole/MainWindow.xaml.cs @@ -651,122 +651,125 @@ namespace dvmconsole { try { - var channel = selectedChannelsManager.PrimaryChannel; - if (channel == null) + ChannelBox primaryChannel = selectedChannelsManager.PrimaryChannel; + List channelsToProcess = primaryChannel != null + ? new List { 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) diff --git a/fnecore b/fnecore index 13a82b3..0419c2f 160000 --- a/fnecore +++ b/fnecore @@ -1 +1 @@ -Subproject commit 13a82b3a82054e4fe8299368c7258c51176cee87 +Subproject commit 0419c2fac7351e67064437f94751bad21bc92975