public void EncodeMultipleFrequencyVoicePacket() { var udpVoicePacket = new UDPVoicePacket { GuidBytes = Encoding.ASCII.GetBytes("ufYS_WlLVkmFPjqCgxz6GA"), AudioPart1Bytes = new byte[] { 0, 1, 2, 3, 4, 5 }, AudioPart1Length = (ushort)6, Frequencies = new double[] { 251000000, 30000000, 251000000 }, UnitId = 1, Encryptions = new byte[] { 0, 0, 1 }, Modulations = new byte[] { 0, 1, 0 }, PacketNumber = 1 }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); Assert.AreEqual(80, encodedUdpVoicePacket.Length); var expectedEncodedUdpVoicePacket = new byte[80] { 80, 0, 6, 0, 30, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 128, 233, 235, 173, 65, 0, 0, 0, 0, 0, 0, 56, 156, 124, 65, 1, 0, 0, 0, 0, 128, 233, 235, 173, 65, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 117, 102, 89, 83, 95, 87, 108, 76, 86, 107, 109, 70, 80, 106, 113, 67, 103, 120, 122, 54, 71, 65 }; CollectionAssert.AreEqual(expectedEncodedUdpVoicePacket, encodedUdpVoicePacket); }
public void EncodeInitialVoicePacket() { var udpVoicePacket = new UDPVoicePacket { GuidBytes = Encoding.ASCII.GetBytes("ufYS_WlLVkmFPjqCgxz6GA"), AudioPart1Bytes = new byte[] { 0, 1, 2, 3, 4, 5 }, AudioPart1Length = (ushort)6, Frequencies = new double[] { 100 }, UnitId = 1, Encryptions = new byte[] { 0 }, Modulations = new byte[] { 4 }, PacketNumber = 1 }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); Assert.AreEqual(60, udpVoicePacket.PacketLength); Assert.AreEqual(60, encodedUdpVoicePacket.Length); var expectedEncodedUdpVoicePacket = new byte[60] { 60, 0, 6, 0, 10, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 4, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 117, 102, 89, 83, 95, 87, 108, 76, 86, 107, 109, 70, 80, 106, 113, 67, 103, 120, 122, 54, 71, 65 }; CollectionAssert.AreEqual(expectedEncodedUdpVoicePacket, encodedUdpVoicePacket); }
public void SendMusicPacket(byte[] musicBytes) { try { if (!stop && (musicBytes != null)) { musicClient.IsBroadcasting = true; musicClient.PacketNumber += 1; // Generate packet var udpVoicePacketBlufor = new UDPVoicePacket { GuidBytes = musicClient.GuidAsciiBytes, AudioPart1Bytes = musicBytes, AudioPart1Length = (ushort)musicBytes.Length, Frequencies = musicClient.Frequencies.ToArray(), UnitId = musicClient.UnitId, Encryptions = musicClient.Encryptions.ToArray(), Modulations = musicClient.Modulations.ToArray(), PacketNumber = musicClient.PacketNumber }; var encodedUdpVoicePacketBlufor = udpVoicePacketBlufor.EncodePacket(); // Send audio audioUdpClient.Send(encodedUdpVoicePacketBlufor, encodedUdpVoicePacketBlufor.Length, serverEndPoint); } } catch (Exception ex) { Logger.Error(ex, "Error when building and sending music packet to server"); } }
public void EncodeMultipleFrequencyVoicePacket() { var udpVoicePacket = new UDPVoicePacket { GuidBytes = Encoding.ASCII.GetBytes("ufYS_WlLVkmFPjqCgxz6GA"), AudioPart1Bytes = new byte[] { 0, 1, 2, 3, 4, 5 }, AudioPart1Length = (ushort)6, Frequencies = new double[] { 251000000, 30000000, 251000000 }, UnitId = 1, Encryptions = new byte[] { 0, 0, 1 }, Modulations = new byte[] { 0, 1, 0 }, PacketNumber = 1 }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); Assert.AreEqual(76, udpVoicePacket.PacketLength); Assert.AreEqual(76, encodedUdpVoicePacket.Length); var expectedEncodedUdpVoicePacket = new byte[76] { // Total packet length 76, 0, // Length of audio part 6, 0, // Length of frequencies part 30, 0, // Audio part 0, 1, 2, 3, 4, 5, // Radio frequency #1 0, 0, 0, 128, 233, 235, 173, 65, // Radio modulation #1 0, // Radio encryption #1 0, // Radio frequency #2 0, 0, 0, 0, 56, 156, 124, 65, // Radio modulation #2 1, // Radio encryption #2 0, // Radio frequency #3 0, 0, 0, 128, 233, 235, 173, 65, // Radio modulation #3 0, // Radio encryption #3 1, // Unit ID 1, 0, 0, 0, // Packet ID 1, 0, 0, 0, 0, 0, 0, 0, // Client GUID 117, 102, 89, 83, 95, 87, 108, 76, 86, 107, 109, 70, 80, 106, 113, 67, 103, 120, 122, 54, 71, 65 }; CollectionAssert.AreEqual(expectedEncodedUdpVoicePacket, encodedUdpVoicePacket); }
public bool Send(byte[] bytes, int radioId) { if (bytes != null) { try { var currentlySelectedRadio = _mainClient.DcsPlayerRadioInfo.radios[radioId]; var frequencies = new List <double>(1); var encryptions = new List <byte>(1); var modulations = new List <byte>(1); frequencies.Add(currentlySelectedRadio.freq); encryptions.Add(currentlySelectedRadio.enc ? currentlySelectedRadio.encKey : (byte)0); modulations.Add((byte)currentlySelectedRadio.modulation); //generate packet var udpVoicePacket = new UDPVoicePacket { GuidBytes = _guidAsciiBytes, OriginalClientGuidBytes = _guidAsciiBytes, AudioPart1Bytes = bytes, AudioPart1Length = (ushort)bytes.Length, Frequencies = frequencies.ToArray(), UnitId = _mainClient.DcsPlayerRadioInfo.unitId, Encryptions = encryptions.ToArray(), Modulations = modulations.ToArray(), PacketNumber = _packetNumber++ }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); _listener.Send(encodedUdpVoicePacket, encodedUdpVoicePacket.Length, _serverEndpoint); RadioSendingState = new RadioSendingState { IsSending = true, LastSentAt = DateTime.Now.Ticks, SendingOn = radioId }; return(true); } catch (Exception e) { Logger.Error(e, $"{_mainClient.LogClientId}| Exception Sending Audio Message " + e.Message); return(false); } } if (RadioSendingState.IsSending) { RadioSendingState.IsSending = false; } return(false); }
public void EncodeInitialVoicePacket() { var udpVoicePacket = new UDPVoicePacket { GuidBytes = Encoding.ASCII.GetBytes("ufYS_WlLVkmFPjqCgxz6GA"), AudioPart1Bytes = new byte[] { 0, 1, 2, 3, 4, 5 }, AudioPart1Length = (ushort)6, Frequencies = new double[] { 100 }, UnitId = 1, Encryptions = new byte[] { 0 }, Modulations = new byte[] { 4 }, OriginalClientGuidBytes = Encoding.ASCII.GetBytes("ufYS_WlLVkmFPjqCgxz6GA"), PacketNumber = 1, RetransmissionCount = (byte)4u }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); Assert.AreEqual(79, udpVoicePacket.PacketLength); Assert.AreEqual(79, encodedUdpVoicePacket.Length); var expectedEncodedUdpVoicePacket = new byte[79] { // Total packet length 79, 0, // Length of audio part 6, 0, // Length of frequencies part 10, 0, // Audio part 0, 1, 2, 3, 4, 5, // Radio frequency #1 0, 0, 0, 0, 0, 0, 89, 64, // Radio modulation #1 4, // Radio encryption #1 0, // Unit ID 1, 0, 0, 0, // Packet ID 1, 0, 0, 0, 0, 0, 0, 0, //Retransmission Count, 4, // Transmission GUID 117, 102, 89, 83, 95, 87, 108, 76, 86, 107, 109, 70, 80, 106, 113, 67, 103, 120, 122, 54, 71, 65, // Client GUID 117, 102, 89, 83, 95, 87, 108, 76, 86, 107, 109, 70, 80, 106, 113, 67, 103, 120, 122, 54, 71, 65 }; for (int i = 0; i < expectedEncodedUdpVoicePacket.Length; i++) { Assert.AreEqual(expectedEncodedUdpVoicePacket[i], encodedUdpVoicePacket[i]); } CollectionAssert.AreEqual(expectedEncodedUdpVoicePacket, encodedUdpVoicePacket); }
public bool Send(byte[] bytes, int len, double[] freq, byte[] modulation) { if (!_stop && _listener != null && (bytes != null)) //can only send if IL2 is connected { try { //generate packet var udpVoicePacket = new UDPVoicePacket { GuidBytes = _guidAsciiBytes, AudioPart1Bytes = bytes, AudioPart1Length = (ushort)bytes.Length, Frequencies = freq, UnitId = gameState.unitId, Modulations = modulation, PacketNumber = _packetNumber++, OriginalClientGuidBytes = _guidAsciiBytes, RetransmissionCount = 0, Encryptions = new byte[] { 0 }, }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); _listener?.Send(encodedUdpVoicePacket, encodedUdpVoicePacket.Length, new IPEndPoint(_address, _port)); } catch (Exception e) { Logger.Error(e, "Exception Sending Audio Message " + e.Message); } } else { //couldnt send } return(false); }
public bool Send(byte[] bytes, int len) { // List of radios the transmission is sent to (can me multiple if simultaneous transmission is enabled) List <RadioInformation> transmittingRadios; //if either PTT is true, a microphone is available && socket connected etc var sendingOn = -1; if (_ready && _listener != null && _audioInputSingleton.MicrophoneAvailable && (bytes != null) && (transmittingRadios = PTTPressed(out sendingOn)).Count > 0) //can only send if IL2 is connected { try { if (transmittingRadios.Count > 0) { List <double> frequencies = new List <double>(transmittingRadios.Count); List <byte> encryptions = new List <byte>(transmittingRadios.Count); List <byte> modulations = new List <byte>(transmittingRadios.Count); for (int i = 0; i < transmittingRadios.Count; i++) { var radio = transmittingRadios[i]; // Further deduplicate transmitted frequencies if they have the same freq./modulation/encryption (caused by differently named radios) bool alreadyIncluded = false; for (int j = 0; j < frequencies.Count; j++) { if (frequencies[j] == radio.freq && modulations[j] == (byte)radio.modulation) { alreadyIncluded = true; break; } } if (alreadyIncluded) { continue; } frequencies.Add(radio.freq); encryptions.Add((byte)0); modulations.Add((byte)radio.modulation); } //generate packet var udpVoicePacket = new UDPVoicePacket { GuidBytes = _guidAsciiBytes, AudioPart1Bytes = bytes, AudioPart1Length = (ushort)bytes.Length, Frequencies = frequencies.ToArray(), UnitId = _clientStateSingleton.PlayerGameState.unitId, Modulations = modulations.ToArray(), PacketNumber = _packetNumber++, OriginalClientGuidBytes = _guidAsciiBytes }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); _listener.Send(encodedUdpVoicePacket, encodedUdpVoicePacket.Length, new IPEndPoint(_address, _port)); var currentlySelectedRadio = _clientStateSingleton.PlayerGameState.radios[sendingOn]; //not sending or really quickly switched sending if (currentlySelectedRadio != null && (!_clientStateSingleton.RadioSendingState.IsSending || _clientStateSingleton.RadioSendingState.SendingOn != sendingOn)) { _audioManager.PlaySoundEffectStartTransmit(sendingOn, currentlySelectedRadio.volume, currentlySelectedRadio.modulation); } //set radio overlay state _clientStateSingleton.RadioSendingState = new RadioSendingState { IsSending = true, LastSentAt = DateTime.Now.Ticks, SendingOn = sendingOn }; return(true); } } catch (Exception e) { Logger.Error(e, "Exception Sending Audio Message " + e.Message); } } else { if (_clientStateSingleton.RadioSendingState.IsSending) { _clientStateSingleton.RadioSendingState.IsSending = false; if (_clientStateSingleton.RadioSendingState.SendingOn >= 0) { var radio = _clientStateSingleton.PlayerGameState.radios[_clientStateSingleton.RadioSendingState.SendingOn]; _audioManager.PlaySoundEffectEndTransmit(_clientStateSingleton.RadioSendingState.SendingOn, radio.volume, radio.modulation); } } } return(false); }
private void RetransmitAudio(UDPVoicePacket udpVoicePacket, List <RadioReceivingPriority> radioReceivingPriorities) { if (udpVoicePacket.Guid == _guid) //|| udpVoicePacket.OriginalClientGuid == _guid { return; //my own transmission - throw away - stops test frequencies } //Hop count can limit the retransmission too var nodeLimit = _serverSettings.RetransmitNodeLimit; if (nodeLimit < udpVoicePacket.RetransmissionCount) { //Reached hop limit - no retransmit return; } //Check if Global List <double> globalFrequencies = _serverSettings.GlobalFrequencies; // filter radios by ability to hear it AND decryption works List <RadioReceivingPriority> retransmitOn = new List <RadioReceivingPriority>(); //artificially limit some retransmissions - if encryption fails dont retransmit //from the subset of receiving radios - find any other radios that have retransmit - and dont retransmit on any with the same frequency //to stop loops //and ignore global frequencies //and only if we can decrypt it (or no encryption) //and not received on Guard var receivingWithRetransmit = radioReceivingPriorities.Where(receivingRadio => (receivingRadio.Decryptable || (receivingRadio.Encryption == 0)) && receivingRadio.ReceivingRadio.retransmit //check global && !globalFrequencies.Any(freq => DCSPlayerRadioInfo.FreqCloseEnough(receivingRadio.ReceivingRadio.freq, freq)) && !receivingRadio.ReceivingState.IsSecondary).ToList(); //didnt receive on any radios that we could decrypt //stop if (receivingWithRetransmit.Count == 0) { return; } //radios able to retransmit var radiosWithRetransmit = _clientStateSingleton.DcsPlayerRadioInfo.radios.Where(radio => radio.retransmit); //Check we're not retransmitting through a radio we just received on? foreach (var receivingRadio in receivingWithRetransmit) { radiosWithRetransmit = radiosWithRetransmit.Where(radio => !DCSPlayerRadioInfo.FreqCloseEnough(radio.freq, receivingRadio.Frequency)); } var finalList = radiosWithRetransmit.ToList(); if (finalList.Count == 0) { //quit return; } //From the remaining list - build up a new outgoing packet var frequencies = new double[finalList.Count]; var encryptions = new byte[finalList.Count]; var modulations = new byte[finalList.Count]; for (int i = 0; i < finalList.Count; i++) { frequencies[i] = finalList[i].freq; encryptions[i] = finalList[i].enc ? (byte)finalList[i].encKey:(byte)0; modulations[i] = (byte)finalList[i].modulation; } //generate packet var relayedPacket = new UDPVoicePacket { GuidBytes = _guidAsciiBytes, AudioPart1Bytes = udpVoicePacket.AudioPart1Bytes, AudioPart1Length = udpVoicePacket.AudioPart1Length, Frequencies = frequencies, UnitId = _clientStateSingleton.DcsPlayerRadioInfo.unitId, Encryptions = encryptions, Modulations = modulations, PacketNumber = udpVoicePacket.PacketNumber, OriginalClientGuidBytes = udpVoicePacket.OriginalClientGuidBytes, RetransmissionCount = (byte)(udpVoicePacket.RetransmissionCount + 1u), }; var packet = relayedPacket.EncodePacket(); try { _listener.Send(packet, packet.Length, new IPEndPoint(_address, _port)); } catch (Exception) { } }
public bool Send(byte[] bytes, int len) { //if either PTT is true, a microphone is available && socket connected etc if (_ready && _listener != null && (_ptt || _clientStateSingleton.DcsPlayerRadioInfo.ptt) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent() && _clientStateSingleton.MicrophoneAvailable && (bytes != null)) //can only send if DCS is connected { try { // List of radios the transmission is sent to (can me multiple if simultaneous transmission is enabled) List <RadioInformation> transmittingRadios = new List <RadioInformation>(); // Always add currently selected radio (if valid) var currentSelected = _clientStateSingleton.DcsPlayerRadioInfo.selected; RadioInformation currentlySelectedRadio = null; if (currentSelected >= 0 && currentSelected < _clientStateSingleton.DcsPlayerRadioInfo.radios.Length) { currentlySelectedRadio = _clientStateSingleton.DcsPlayerRadioInfo.radios[currentSelected]; if (currentlySelectedRadio != null && currentlySelectedRadio.modulation != RadioInformation.Modulation.DISABLED && (currentlySelectedRadio.freq > 100 || currentlySelectedRadio.modulation == RadioInformation.Modulation.INTERCOM)) { transmittingRadios.Add(currentlySelectedRadio); } } // Add all radios toggled for simultaneous transmission if the global flag has been set if (_clientStateSingleton.DcsPlayerRadioInfo.simultaneousTransmission) { foreach (var radio in _clientStateSingleton.DcsPlayerRadioInfo.radios) { if (radio != null && radio.simul && radio.modulation != RadioInformation.Modulation.DISABLED && (radio.freq > 100 || radio.modulation == RadioInformation.Modulation.INTERCOM) && !transmittingRadios.Contains(radio) ) // Make sure we don't add the selected radio twice { transmittingRadios.Add(radio); } } } if (transmittingRadios.Count > 0) { List <double> frequencies = new List <double>(transmittingRadios.Count); List <byte> encryptions = new List <byte>(transmittingRadios.Count); List <byte> modulations = new List <byte>(transmittingRadios.Count); for (int i = 0; i < transmittingRadios.Count; i++) { var radio = transmittingRadios[i]; // Further deduplicate transmitted frequencies if they have the same freq./modulation/encryption (caused by differently named radios) bool alreadyIncluded = false; for (int j = 0; j < frequencies.Count; j++) { if (frequencies[j] == radio.freq && modulations[j] == (byte)radio.modulation && encryptions[j] == (radio.enc ? radio.encKey : (byte)0)) { alreadyIncluded = true; break; } } if (alreadyIncluded) { continue; } frequencies.Add(radio.freq); encryptions.Add(radio.enc ? radio.encKey : (byte)0); modulations.Add((byte)radio.modulation); } //generate packet var udpVoicePacket = new UDPVoicePacket { GuidBytes = _guidAsciiBytes, AudioPart1Bytes = bytes, AudioPart1Length = (ushort)bytes.Length, Frequencies = frequencies.ToArray(), UnitId = _clientStateSingleton.DcsPlayerRadioInfo.unitId, Encryptions = encryptions.ToArray(), Modulations = modulations.ToArray(), PacketNumber = _packetNumber++ }; var encodedUdpVoicePacket = udpVoicePacket.EncodePacket(); _listener.Send(encodedUdpVoicePacket, encodedUdpVoicePacket.Length, new IPEndPoint(_address, _port)); //not sending or really quickly switched sending if (currentlySelectedRadio != null && (!RadioSendingState.IsSending || RadioSendingState.SendingOn != currentSelected)) { _audioManager.PlaySoundEffectStartTransmit(currentSelected, currentlySelectedRadio.enc && (currentlySelectedRadio.encKey > 0), currentlySelectedRadio.volume); } //set radio overlay state RadioSendingState = new RadioSendingState { IsSending = true, LastSentAt = DateTime.Now.Ticks, SendingOn = currentSelected }; return(true); } } catch (Exception e) { Logger.Error(e, "Exception Sending Audio Message " + e.Message); } } else { if (RadioSendingState.IsSending) { RadioSendingState.IsSending = false; if (RadioSendingState.SendingOn >= 0) { var radio = _clientStateSingleton.DcsPlayerRadioInfo.radios[RadioSendingState.SendingOn]; _audioManager.PlaySoundEffectEndTransmit(RadioSendingState.SendingOn, radio.volume); } } } return(false); }