private bool HasLineOfSight(UDPVoicePacket udpVoicePacket, out float losLoss)
        {
            losLoss = 0; //0 is NO LOSS
            if (!_serverSettings.GetSettingAsBool(ServerSettingsKeys.LOS_ENABLED))
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clients.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                var myLatLng     = _clientStateSingleton.PlayerCoaltionLocationMetadata.LngLngPosition;
                var clientLatLng = transmittingClient.LatLngPosition;
                if (myLatLng == null || clientLatLng == null || !myLatLng.isValid() || !clientLatLng.isValid())
                {
                    return(true);
                }

                losLoss = transmittingClient.LineOfSightLoss;
                return(transmittingClient.LineOfSightLoss < 1.0f); // 1.0 or greater  is TOTAL loss
            }

            losLoss = 0;
            return(false);
        }
Example #2
0
        private bool HasLineOfSight(UDPVoicePacket udpVoicePacket, out float losLoss)
        {
            losLoss = 0; //0 is NO LOSS
            if (!_serverSettings.GetSettingAsBool(ServerSettingsKeys.LOS_ENABLED))
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clientsList.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                var myPosition = _clientStateSingleton.PlayerCoaltionLocationMetadata.Position;

                var clientPos = transmittingClient.Position;

                if (((myPosition.x == 0) && (myPosition.z == 0)) || ((clientPos.x == 0) && (clientPos.z == 0)))
                {
                    var myLatLng     = _clientStateSingleton.PlayerCoaltionLocationMetadata.LngLngPosition;
                    var clientLatLng = transmittingClient.LatLngPosition;
                    //No DCS Position - do we have LotATC Position?
                    if (((myLatLng.lat == 0) && (myLatLng.lng == 0)) || ((clientLatLng.lat == 0) && (clientLatLng.lng == 0)))
                    {
                        return(true);
                    }
                }

                losLoss = transmittingClient.LineOfSightLoss;
                return(transmittingClient.LineOfSightLoss < 1.0f); // 1.0 or greater  is TOTAL loss
            }

            losLoss = 0;
            return(false);
        }
Example #3
0
        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);
        }
Example #4
0
        public void DecodeMultipleFrequencyVoicePacket()
        {
            var encodedUdpVoicePacket = 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
            };

            var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedUdpVoicePacket);

            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.Guid);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3, 4, 5 }, udpVoicePacket.AudioPart1Bytes);
            Assert.AreEqual(6, udpVoicePacket.AudioPart1Length);
            CollectionAssert.AreEqual(new double[] { 251000000, 30000000, 251000000 }, udpVoicePacket.Frequencies);
            Assert.AreEqual((uint)1, udpVoicePacket.UnitId);
            CollectionAssert.AreEqual(new byte[] { 0, 0, 1 }, udpVoicePacket.Encryptions);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 0 }, udpVoicePacket.Modulations);
            Assert.AreEqual((ulong)1, udpVoicePacket.PacketNumber);
            Assert.AreEqual((ushort)80, udpVoicePacket.PacketLength);
        }
Example #5
0
        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);
        }
        private bool HasLineOfSight(UDPVoicePacket udpVoicePacket, out float losLoss)
        {
            losLoss = 0; //0 is NO LOSS
            if (!ClientSync.ServerSettings[(int)ServerSettingType.LOS_ENABLED])
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clientsList.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                var myPosition = _clientStateSingleton.DcsPlayerRadioInfo.pos;

                var clientPos = transmittingClient.Position;

                if (((myPosition.x == 0) && (myPosition.z == 0)) || ((clientPos.x == 0) && (clientPos.z == 0)))
                {
                    //no real position therefore no line of Sight!
                    return(true);
                }

                losLoss = transmittingClient.LineOfSightLoss;
                return(transmittingClient.LineOfSightLoss < 1.0f); // 1.0 or greater  is TOTAL loss
            }

            losLoss = 0;
            return(false);
        }
Example #7
0
        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");
            }
        }
Example #8
0
        private bool InRange(UDPVoicePacket udpVoicePacket, out double signalStrength)
        {
            signalStrength = 0;
            if (!ClientSync.ServerSettings[(int)ServerSettingType.DISTANCE_ENABLED])
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clientsList.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                var myPosition = RadioDCSSyncServer.DcsPlayerRadioInfo.pos;

                var clientPos = transmittingClient.Position;

                if ((myPosition.x == 0 && myPosition.z == 0) || (clientPos.x == 0 && clientPos.z == 0))
                {
                    //no real position
                    return(true);
                }

                signalStrength =
                    RadioCalculator.FriisTransmissionReceivedPower(
                        RadioCalculator.CalculateDistance(myPosition, clientPos), udpVoicePacket.Frequency);

                return(signalStrength > RadioCalculator.RXSensivity);
            }
            return(false);
        }
        private bool InRange(UDPVoicePacket udpVoicePacket, out double signalStrength)
        {
            signalStrength = 0;
            if (!ClientSync.ServerSettings[(int)ServerSettingType.DISTANCE_ENABLED])
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clientsList.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                var myPosition = _clientStateSingleton.DcsPlayerRadioInfo.pos;

                var clientPos = transmittingClient.Position;

                if (((myPosition.x == 0) && (myPosition.z == 0)) || ((clientPos.x == 0) && (clientPos.z == 0)))
                {
                    //no real position
                    return(true);
                }

                var dist = RadioCalculator.CalculateDistance(myPosition, clientPos);

                var max = RadioCalculator.FriisMaximumTransmissionRange(udpVoicePacket.Frequency);
                // % loss of signal
                // 0 is no loss 1.0 is full loss
                signalStrength = (dist / max);

                return(max > dist);
            }
            return(false);
        }
        private OutgoingUDPPackets GenerateOutgoingPacket(UDPVoicePacket udpVoice, PendingPacket pendingPacket,
                                                          SRClient fromClient)
        {
            var outgoingList = new HashSet <IPEndPoint>();

            var guid = fromClient.ClientGuid;

            foreach (var client in _clientsList)
            {
                if (!client.Key.Equals(guid))
                {
                    var ip = client.Value.VoipPort;
                    if (ip != null)
                    {
                        outgoingList.Add(ip);
                    }
                }
            }

            if (outgoingList.Count > 0)
            {
                return(new OutgoingUDPPackets
                {
                    OutgoingEndPoints = outgoingList.ToList(),
                    ReceivedPacket = pendingPacket.RawBytes
                });
            }
            else
            {
                return(null);
            }
        }
Example #11
0
        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 void DecodeMultipleFrequencyVoicePacket()
        {
            var encodedUdpVoicePacket = new byte[99] {
                // Total packet length
                99, 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,
                254,
                // 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
            };

            var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedUdpVoicePacket);

            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.Guid);
            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.OriginalClientGuid);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3, 4, 5 }, udpVoicePacket.AudioPart1Bytes);
            Assert.AreEqual(6, udpVoicePacket.AudioPart1Length);
            CollectionAssert.AreEqual(new double[] { 251000000, 30000000, 251000000 }, udpVoicePacket.Frequencies);
            Assert.AreEqual((uint)1, udpVoicePacket.UnitId);
            CollectionAssert.AreEqual(new byte[] { 0, 0, 1 }, udpVoicePacket.Encryptions);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 0 }, udpVoicePacket.Modulations);
            Assert.AreEqual((ulong)1, udpVoicePacket.PacketNumber);
            Assert.AreEqual((ushort)99, udpVoicePacket.PacketLength);

            Assert.AreEqual((byte)254, udpVoicePacket.RetransmissionCount);
        }
        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);
        }
        private OutgoingVoice GenerateOutgoingPacket(UDPVoicePacket udpVoice, PendingPacket pendingPacket,
                                                     SRClient fromClient)
        {
            var outgoingList  = new List <IPEndPoint>();
            var outgoingVoice = new OutgoingVoice
            {
                OutgoingEndPoints = outgoingList,
                ReceivedPacket    = pendingPacket.RawBytes
            };

            var coalitionSecurity =
                _serverSettings.ServerSetting[(int)ServerSettingType.COALITION_AUDIO_SECURITY];
            var guid = fromClient.ClientGuid;

            foreach (var client in _clientsList)
            {
                if (!client.Key.Equals(guid))
                {
                    var ip = client.Value.VoipPort;

                    // check that either coalition radio security is disabled OR the coalitions match
                    if ((ip != null) && (!coalitionSecurity || (client.Value.Coalition == fromClient.Coalition)))
                    {
                        var radioInfo = client.Value.RadioInfo;

                        if (radioInfo != null)
                        {
                            RadioReceivingState radioReceivingState = null;
                            var receivingRadio = radioInfo.CanHearTransmission(udpVoice.Frequency,
                                                                               (RadioInformation.Modulation)udpVoice.Modulation,
                                                                               udpVoice.UnitId, out radioReceivingState);

                            //only send if we can hear!
                            if (receivingRadio != null)
                            {
                                outgoingList.Add(ip);
                            }
                        }
                    }
                }
                else
                {
                    var ip = client.Value.VoipPort;

                    if (ip != null)
                    {
                        // outgoingList.Add(ip);
                    }
                }
            }

            return(outgoingList.Count > 0 ? outgoingVoice : null);
        }
Example #16
0
        private void SendToOthers(byte[] bytes, SRClient fromClient, UDPVoicePacket udpVoicePacket)
        {
            var coalitionSecurity =
                _serverSettings.ServerSetting[(int)ServerSettingType.COALITION_AUDIO_SECURITY];
            var guid = fromClient.ClientGuid;

            foreach (var client in _clientsList)
            {
                try
                {
                    if (!client.Key.Equals(guid))
                    {
                        var ip = client.Value.VoipPort;

                        // check that either coalition radio security is disabled OR the coalitions match
                        if (ip != null && (!coalitionSecurity || client.Value.Coalition == fromClient.Coalition))
                        {
                            var radioInfo = client.Value.RadioInfo;

                            if (radioInfo != null)
                            {
                                RadioReceivingState radioReceivingState = null;
                                var receivingRadio = radioInfo.CanHearTransmission(udpVoicePacket.Frequency,
                                                                                   udpVoicePacket.Modulation,
                                                                                   udpVoicePacket.UnitId, out radioReceivingState);

                                //only send if we can hear!
                                if (receivingRadio != null)
                                {
                                    _listener.Send(bytes, bytes.Length, ip);
                                }
                            }
                        }
                    }
                    else
                    {
                        var ip = client.Value.VoipPort;

                        if (ip != null)
                        {
                            //  _listener.Send(bytes, bytes.Length, ip);
                        }
                    }
                }
                catch (Exception e)
                {
                    //      IPEndPoint ip = client.Value;
                    //   logger.Error(e, "Error sending audio UDP for client " + e.Message);
                    SRClient value;
                    _clientsList.TryRemove(guid, out value);
                }
            }
        }
        private void StartPing()
        {
            Logger.Info("Pinging Server - Starting");
            var thread = new Thread(() =>
            {
                byte[] message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                while (!_stop)
                {
                    //wait for cancel or quit
                    var cancelled = _pingStop.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(60));

                    if (cancelled)
                    {
                        return;
                    }

                    try
                    {
                        if (!RadioSendingState.IsSending && _listener != null && _listener.Connected)
                        {
                            var udpVoicePacket = new UDPVoicePacket
                            {
                                GuidBytes        = _guidAsciiBytes,
                                AudioPart1Bytes  = message,
                                AudioPart1Length = (ushort)message.Length,
                                Frequency        = 100,
                                UnitId           = 1,
                                Encryption       = 0,
                                Modulation       = 4,
                                PacketNumber     = 1
                            }.EncodePacket();

                            _listener.Client.Send(udpVoicePacket);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Exception Sending Audio Ping! " + e.Message);
                    }
                }
            });

            thread.Start();
        }
Example #18
0
        private bool HasLineOfSight(UDPVoicePacket udpVoicePacket, out float losLoss)
        {
            losLoss = 0; //0 is NO LOSS
            if (!ClientSync.ServerSettings[(int)ServerSettingType.LOS_ENABLED])
            {
                return(true);
            }

            SRClient transmittingClient;

            if (_clientsList.TryGetValue(udpVoicePacket.Guid, out transmittingClient))
            {
                losLoss = transmittingClient.LineOfSightLoss;
                return(transmittingClient.LineOfSightLoss < 1.0f); // 1.0 or greater  is TOTAL loss
            }

            losLoss = 0;
            return(false);
        }
Example #19
0
        public void DecodeInitialVoicePacket()
        {
            var encodedUdpVoicePacket = new byte[78] {
                // Total packet length
                78, 0,
                // Length of audio part
                6, 0,
                // Length of frequencies part
                9, 0,
                // Audio part
                0, 1, 2, 3, 4, 5,
                // Radio frequency #1
                0, 0, 0, 0, 0, 0, 89, 64,
                // Radio modulation #1
                4,
                // Unit ID
                1, 0, 0, 0,
                // Packet ID
                1, 0, 0, 0, 0, 0, 0, 0,
                //Retransmission Count,
                231,
                // 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
            };

            var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedUdpVoicePacket);

            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.Guid);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3, 4, 5 }, udpVoicePacket.AudioPart1Bytes);
            Assert.AreEqual(6, udpVoicePacket.AudioPart1Length);
            CollectionAssert.AreEqual(new double[] { 100 }, udpVoicePacket.Frequencies);
            Assert.AreEqual((int)1, udpVoicePacket.UnitId);
            CollectionAssert.AreEqual(new byte[] { 4 }, udpVoicePacket.Modulations);
            Assert.AreEqual((ulong)1, udpVoicePacket.PacketNumber);
            Assert.AreEqual((ushort)78, udpVoicePacket.PacketLength);
            Assert.AreEqual((byte)231, udpVoicePacket.RetransmissionCount);
            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.OriginalClientGuid);
        }
Example #20
0
        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);
        }
        private void StartPing()
        {
            Logger.Info("Pinging Server - Starting");
            var thread = new Thread(() =>
            {
                byte[] message = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

                while (!_stop)
                {
                    Thread.Sleep(60 * 1000);

                    try
                    {
                        if (!RadioSendingState.IsSending && _listener != null && _listener.Connected)
                        {
                            var udpVoicePacket = new UDPVoicePacket
                            {
                                GuidBytes        = _guidAsciiBytes,
                                AudioPart1Bytes  = message,
                                AudioPart1Length = (ushort)message.Length,
                                Frequency        = 100,
                                UnitId           = 1,
                                Encryption       = 0,
                                Modulation       = 4,
                                PacketNumber     = 1
                            }.EncodePacket();

                            _listener.Client.Send(udpVoicePacket);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Exception Sending Audio Ping! " + e.Message);
                    }
                }
            });

            thread.Start();
        }
Example #22
0
        public void DecodeInitialVoicePacket()
        {
            var encodedUdpVoicePacket = 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
            };

            var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedUdpVoicePacket);

            Assert.AreEqual("ufYS_WlLVkmFPjqCgxz6GA", udpVoicePacket.Guid);
            CollectionAssert.AreEqual(new byte[] { 0, 1, 2, 3, 4, 5 }, udpVoicePacket.AudioPart1Bytes);
            Assert.AreEqual(6, udpVoicePacket.AudioPart1Length);
            CollectionAssert.AreEqual(new double[] { 100 }, udpVoicePacket.Frequencies);
            Assert.AreEqual((uint)1, udpVoicePacket.UnitId);
            CollectionAssert.AreEqual(new byte[] { 0 }, udpVoicePacket.Encryptions);
            CollectionAssert.AreEqual(new byte[] { 4 }, udpVoicePacket.Modulations);
            Assert.AreEqual((ulong)1, udpVoicePacket.PacketNumber);
            Assert.AreEqual((ushort)60, udpVoicePacket.PacketLength);
        }
        public bool Send(byte[] bytes, int len)
        {
            //if either PTT is true, a microphone is available && socket connected etc
            if (_ready &&
                _listener != null &&
                _listener.Connected &&
                (_ptt || _clientStateSingleton.DcsPlayerRadioInfo.ptt) &&
                _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent() &&
                _clientStateSingleton.MicrophoneAvailable &&
                (bytes != null))
            //can only send if DCS is connected
            {
                try
                {
                    var currentSelected = _clientStateSingleton.DcsPlayerRadioInfo.selected;
                    //removes race condition by assigning here with the current selected changing
                    if ((currentSelected >= 0) &&
                        (currentSelected < _clientStateSingleton.DcsPlayerRadioInfo.radios.Length))
                    {
                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.radios[currentSelected];

                        if (((radio != null) && (radio.freq > 100) &&
                             (radio.modulation != RadioInformation.Modulation.DISABLED)) ||
                            (radio.modulation == RadioInformation.Modulation.INTERCOM))
                        {
                            //generate packet
                            var udpVoicePacket = new UDPVoicePacket
                            {
                                GuidBytes        = _guidAsciiBytes,
                                AudioPart1Bytes  = bytes,
                                AudioPart1Length = (ushort)bytes.Length,
                                Frequency        = radio.freq,
                                UnitId           = _clientStateSingleton.DcsPlayerRadioInfo.unitId,
                                Encryption       = radio.enc ? radio.encKey : (byte)0,
                                Modulation       = (byte)radio.modulation,
                                PacketNumber     = _packetNumber++
                            }.EncodePacket();

                            //send audio
                            _listener.Client.Send(udpVoicePacket);

                            //not sending or really quickly switched sending
                            if (!RadioSendingState.IsSending || (RadioSendingState.SendingOn != currentSelected))
                            {
                                _audioManager.PlaySoundEffectStartTransmit(currentSelected,
                                                                           radio.enc && (radio.encKey > 0), radio.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);
        }
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = GetTickCount64(); //should add at the receive instead?

                        if ((encodedOpusAudio != null) && (encodedOpusAudio.Length > 36))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                // check the radio
                                RadioReceivingState receivingState = null;
                                var receivingRadio =
                                    _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                        udpVoicePacket.Frequency,
                                        (RadioInformation.Modulation)udpVoicePacket.Modulation,
                                        udpVoicePacket.UnitId, out receivingState);

                                //Check that we're not transmitting on this radio

                                double receivingPowerLossPercent = 0;
                                float  lineOfSightLoss           = 0;

                                if ((receivingRadio != null) && (receivingState != null)
                                    &&
                                    ((receivingRadio.modulation == RadioInformation.Modulation.INTERCOM)
                                     // INTERCOM Modulation is 2 so if its two dont bother checking LOS and Range
                                     ||
                                     (
                                         HasLineOfSight(udpVoicePacket, out lineOfSightLoss)
                                         &&
                                         InRange(udpVoicePacket, out receivingPowerLossPercent)
                                         &&
                                         !ShouldBlockRxAsTransmitting(receivingState.ReceivedOn)
                                     )
                                    )
                                    )
                                {
                                    //  RadioReceivingState[receivingState.ReceivedOn] = receivingState;

                                    //DECODE audio
                                    int len1;
                                    var decoded = _decoder.Decode(udpVoicePacket.AudioPart1Bytes,
                                                                  udpVoicePacket.AudioPart1Bytes.Length, out len1);


                                    if (len1 > 0)
                                    {
                                        // for some reason if this is removed then it lags?!
                                        //guess it makes a giant buffer and only uses a little?
                                        var tmp = new byte[len1];
                                        Buffer.BlockCopy(decoded, 0, tmp, 0, len1);

                                        //ALL GOOD!
                                        //create marker for bytes
                                        var audio = new ClientAudio
                                        {
                                            ClientGuid    = udpVoicePacket.Guid,
                                            PcmAudioShort = ConversionHelpers.ByteArrayToShortArray(tmp),
                                            //Convert to Shorts!
                                            ReceiveTime   = GetTickCount64(),
                                            Frequency     = udpVoicePacket.Frequency,
                                            Modulation    = udpVoicePacket.Modulation,
                                            Volume        = receivingRadio.volume,
                                            ReceivedRadio = receivingState.ReceivedOn,
                                            UnitId        = udpVoicePacket.UnitId,
                                            Encryption    = udpVoicePacket.Encryption,
                                            Decryptable   =
                                                (udpVoicePacket.Encryption == receivingRadio.encKey) &&
                                                receivingRadio.enc,
                                            // mark if we can decrypt it
                                            RadioReceivingState = receivingState,
                                            RecevingPower       =
                                                receivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                            LineOfSightLoss = lineOfSightLoss, // Loss of 1.0 or greater is total loss
                                            PacketNumber    = udpVoicePacket.PacketNumber
                                        };


                                        //handle effects
                                        var radioState = RadioReceivingState[audio.ReceivedRadio];

                                        if ((radioState == null) || radioState.PlayedEndOfTransmission ||
                                            !radioState.IsReceiving)
                                        {
                                            var decrytable = audio.Decryptable || (audio.Encryption == 0);

                                            //mark that we have decrpyted encrypted audio for sound effects
                                            if (decrytable && (audio.Encryption > 0))
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          true,
                                                                                          audio.Volume);
                                            }
                                            else
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          false,
                                                                                          audio.Volume);
                                            }
                                        }

                                        RadioReceivingState[audio.ReceivedRadio] = new RadioReceivingState
                                        {
                                            IsSecondary             = receivingState.IsSecondary,
                                            LastReceviedAt          = DateTime.Now.Ticks,
                                            PlayedEndOfTransmission = false,
                                            ReceivedOn = receivingState.ReceivedOn
                                        };

                                        _audioManager.AddClientAudio(audio);
                                    }
                                    else
                                    {
                                        Logger.Info("Failed to decode audio from Packet");
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Info("Failed to decode audio from Packet");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        public void Listen()
        {
            _ready = false;

            //start audio processing threads
            var decoderThread = new Thread(UdpAudioDecode);

            decoderThread.Start();

            var settings = SettingsStore.Instance;

            _inputManager.StartDetectPtt(pressed =>
            {
                var radios = _clientStateSingleton.DcsPlayerRadioInfo;

                var radioSwitchPtt = _settings.GetClientSetting(SettingsKeys.RadioSwitchIsPTT).BoolValue;

                var ptt = false;
                foreach (var inputBindState in pressed)
                {
                    if (inputBindState.IsActive)
                    {
                        //radio switch?
                        if ((int)inputBindState.MainDevice.InputBind >= (int)InputBinding.Intercom &&
                            (int)inputBindState.MainDevice.InputBind <= (int)InputBinding.Switch10)
                        {
                            //gives you radio id if you minus 100
                            var radioId = (int)inputBindState.MainDevice.InputBind - 100;

                            if (radioId < _clientStateSingleton.DcsPlayerRadioInfo.radios.Length)
                            {
                                var clientRadio = _clientStateSingleton.DcsPlayerRadioInfo.radios[radioId];

                                if (clientRadio.modulation != RadioInformation.Modulation.DISABLED &&
                                    radios.control == DCSPlayerRadioInfo.RadioSwitchControls.HOTAS)
                                {
                                    radios.selected = (short)radioId;
                                }

                                //turn on PTT
                                if (radioSwitchPtt)
                                {
                                    ptt = true;
                                }
                            }
                        }
                        else if (inputBindState.MainDevice.InputBind == InputBinding.Ptt)
                        {
                            ptt = true;
                        }
                    }
                }

                //if length is zero - no keybinds or no PTT pressed set to false
                _ptt = ptt;
            });

            StartTimer();

            StartPing();

            //keep reconnecting until stop
            while (!_stop)
            {
                try
                {
                    //set to false so we sent one packet to open up the radio
                    //automatically rather than the user having to press Send
                    hasSentVoicePacket = false;

                    _packetNumber = 1; //reset packet number

                    _listener         = new TcpClient();
                    _listener.NoDelay = true;

                    _listener.Connect(_address, _port);

                    //initial packet to get audio setup
                    var udpVoicePacket = new UDPVoicePacket
                    {
                        GuidBytes        = _guidAsciiBytes,
                        AudioPart1Bytes  = new byte[] { 0, 1, 2, 3, 4, 5 },
                        AudioPart1Length = (ushort)6,
                        Frequency        = 100,
                        UnitId           = 1,
                        Encryption       = 0,
                        Modulation       = 4,
                        PacketNumber     = 1
                    }.EncodePacket();

                    _listener.Client.Send(udpVoicePacket);

                    //contains short for audio packet length
                    byte[] lengthBuffer = new byte[2];

                    _ready = true;

                    Logger.Info("Connected to VOIP TCP " + _port);

                    while (_listener.Connected && !_stop)
                    {
                        int received = _listener.Client.Receive(lengthBuffer, 2, SocketFlags.None);

                        if (received == 0)
                        {
                            // didnt receive enough, quit.
                            Logger.Warn(
                                "Didnt Receive full packet for VOIP - Disconnecting & Reconnecting if next Recieve fails");
                            //break;
                        }
                        else
                        {
                            ushort packetLength =
                                BitConverter.ToUInt16(new byte[2] {
                                lengthBuffer[0], lengthBuffer[1]
                            }, 0);

                            byte[] audioPacketBuffer = new byte[packetLength];

                            //add pack in length to full buffer for packet decode
                            audioPacketBuffer[0] = lengthBuffer[0];
                            audioPacketBuffer[1] = lengthBuffer[1];

                            received = _listener.Client.Receive(audioPacketBuffer, 2, packetLength - 2,
                                                                SocketFlags.None);

                            int offset    = received + 2;
                            int remaining = packetLength - 2 - received;
                            while (remaining > 0 && received > 0)
                            {
                                received = _listener.Client.Receive(audioPacketBuffer, offset, remaining,
                                                                    SocketFlags.None);

                                remaining = remaining - received;
                                offset    = offset + received;
                            }

                            if (remaining == 0)
                            {
                                _encodedAudio.Add(audioPacketBuffer);
                            }
                            else
                            {
                                //didnt receive enough - log and reconnect
                                Logger.Warn("Didnt Receive any packet for VOIP - Disconnecting & Reconnecting");
                                break;
                            }
                        }
                    }

                    _ready = false;
                }
                catch (Exception e)
                {
                    Logger.Error("Error with VOIP TCP Connection on port " + _port + " Reconnecting");
                }

                try
                {
                    _listener.Close();
                }
                catch (Exception e)
                {
                }
            }
        }
        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 UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null))
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null)
                                {
                                    var vehicleId = -1;
                                    if (_clients.TryGetValue(udpVoicePacket.Guid, out var transmittingClient))
                                    {
                                        vehicleId = transmittingClient.GameState.vehicleId;
                                    }

                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);


                                        var radio = _clientStateSingleton.PlayerGameState.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.UnitId,
                                            vehicleId,
                                            blockedRadios,
                                            out state);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                globalFrequency ||
                                                (!blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Frequency      = udpVoicePacket.Frequencies[i],
                                                    Modulation     = udpVoicePacket.Modulations[i],
                                                    ReceivingRadio = radio,
                                                    ReceivingState = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,

                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                PacketNumber        = udpVoicePacket.PacketNumber,
                                                OriginalClientGuid  = udpVoicePacket.OriginalClientGuid
                                            };


                                            //handle effects
                                            var radioState = _radioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          false,
                                                                                          audio.Volume, (RadioInformation.Modulation)audio.Modulation);
                                            }

                                            var transmitterName = "";
                                            if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.SHOW_TRANSMITTER_NAME) &&
                                                _globalSettings.GetClientSettingBool(GlobalSettingsKeys.ShowTransmitterName) &&
                                                transmittingClient != null)

                                            {
                                                transmitterName = transmittingClient.Name;
                                            }

                                            var newRadioReceivingState = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                LastReceivedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn,
                                                SentBy     = transmitterName
                                            };

                                            _radioReceivingState[audio.ReceivedRadio] = newRadioReceivingState;

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        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)
            {
            }
        }
Example #29
0
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null && udpVoicePacket.Modulations[0] != 4)
                                {
                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);

                                        if (globalFrequency)
                                        {
                                            //remove encryption for global
                                            udpVoicePacket.Encryptions[i] = 0;
                                        }

                                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.Encryptions[i],
                                            udpVoicePacket.UnitId,
                                            blockedRadios,
                                            out state,
                                            out decryptable);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                globalFrequency ||
                                                (
                                                    HasLineOfSight(udpVoicePacket, out losLoss) &&
                                                    InRange(udpVoicePacket.Guid, udpVoicePacket.Frequencies[i],
                                                            out receivPowerLossPercent) &&
                                                    !blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                decryptable =
                                                    (udpVoicePacket.Encryptions[i] == 0) ||
                                                    (udpVoicePacket.Encryptions[i] == radio.encKey && radio.enc);

                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Decryptable               = decryptable,
                                                    Encryption                = udpVoicePacket.Encryptions[i],
                                                    Frequency                 = udpVoicePacket.Frequencies[i],
                                                    LineOfSightLoss           = losLoss,
                                                    Modulation                = udpVoicePacket.Modulations[i],
                                                    ReceivingPowerLossPercent = receivPowerLossPercent,
                                                    ReceivingRadio            = radio,
                                                    ReceivingState            = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,
                                                Encryption    = destinationRadio.Encryption,
                                                Decryptable   = destinationRadio.Decryptable,
                                                // mark if we can decrypt it
                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                RecevingPower       =
                                                    destinationRadio
                                                    .ReceivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                                LineOfSightLoss =
                                                    destinationRadio
                                                    .LineOfSightLoss,     // Loss of 1.0 or greater is total loss
                                                PacketNumber = udpVoicePacket.PacketNumber
                                            };


                                            //handle effects
                                            var radioState = RadioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                var audioDecryptable = audio.Decryptable || (audio.Encryption == 0);

                                                //mark that we have decrpyted encrypted audio for sound effects
                                                if (audioDecryptable && (audio.Encryption > 0))
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              true,
                                                                                              audio.Volume);
                                                }
                                                else
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              false,
                                                                                              audio.Volume);
                                                }
                                            }

                                            RadioReceivingState[audio.ReceivedRadio] = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                IsSimultaneous          = isSimultaneousTransmission,
                                                LastReceviedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn
                                            };

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        public override void ChannelRead(IChannelHandlerContext context, object message)
        {
            var byteBuffer = message as IByteBuffer;

            if (byteBuffer != null)
            {
                byte[] udpData = new byte[byteBuffer.ReadableBytes];
                byteBuffer.GetBytes(0, udpData);

                var decodedPacket = UDPVoicePacket.DecodeVoicePacket(udpData, false);

                SRClient srClient;
                if (_clientsList.TryGetValue(decodedPacket.Guid, out srClient))
                {
                    srClient.ClientChannelId = context.Channel.Id.AsShortText();

                    var spectatorAudioDisabled =
                        _serverSettings.GetGeneralSetting(ServerSettingsKeys.SPECTATORS_AUDIO_DISABLED).BoolValue;

                    if ((srClient.Coalition == 0) && spectatorAudioDisabled)
                    {
                        byteBuffer.Release();
                        return;
                    }
                    else
                    {
                        HashSet <string> matchingClients = new HashSet <string>();

                        for (int i = 0; i < decodedPacket.Frequencies.Length; i++)
                        {
                            // Magical ignore message 4 - just used for ping
                            if (decodedPacket.Modulations[0] == 4)
                            {
                                continue;
                            }

                            var coalitionSecurity =
                                _serverSettings.GetGeneralSetting(ServerSettingsKeys.COALITION_AUDIO_SECURITY).BoolValue;

                            foreach (KeyValuePair <string, SRClient> _client in _clientsList)
                            {
                                //dont send to receiver
                                if (_client.Value.ClientGuid != decodedPacket.Guid)
                                {
                                    //check frequencies
                                    if ((!coalitionSecurity || (_client.Value.Coalition == srClient.Coalition)))
                                    {
                                        var radioInfo = _client.Value.RadioInfo;

                                        if (radioInfo != null)
                                        {
                                            RadioReceivingState radioReceivingState = null;
                                            bool decryptable;
                                            var  receivingRadio = radioInfo.CanHearTransmission(decodedPacket.Frequencies[i],
                                                                                                (RadioInformation.Modulation)decodedPacket.Modulations[i],
                                                                                                decodedPacket.Encryptions[i],
                                                                                                decodedPacket.UnitId,
                                                                                                emptyBlockedRadios,
                                                                                                out radioReceivingState,
                                                                                                out decryptable);

                                            //only send if we can hear!
                                            if (receivingRadio != null && !matchingClients.Contains(_client.Value.ClientChannelId))
                                            {
                                                matchingClients.Add(_client.Value.ClientChannelId);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //send to other connected clients
                        if (matchingClients.Count > 0)
                        {
                            group.WriteAndFlushAsync(message, new AllMatchingChannels(matchingClients));
                        }
                        else
                        {
                            byteBuffer.Release();
                        }
                    }
                }
                else
                {
                    byteBuffer.Release();
                }
            }
        }