示例#1
0
        /*
         * Receive audio data coming on port 1550 and feed it to the speakers to be played.
         */
        private void Receive()
        {
            try
            {
                bStop = false;
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

                while (!bStop)
                {
                    //Receive data.
                    byte[] byteData = udpClient.Receive(ref remoteEP);

                    //G711 compresses the data by 50%, so we allocate a buffer of double
                    //the size to store the decompressed data.
                    byte[] byteDecodedData = new byte[byteData.Length * 2];

                    //Decompress data using the proper vocoder. And decrypt
                    var decryptedData = AES_Crypto.Decrypt(byteData, CallCurrentPass, CallCurrentSalt);
                    ALawDecoder.ALawDecode(decryptedData, out byteDecodedData);

                    //Play the data received to the user.
                    playbackBuffer = new SecondaryBuffer(playbackBufferDescription, device);
                    playbackBuffer.Write(0, byteDecodedData, LockFlag.None);
                    playbackBuffer.Play(0, BufferPlayFlags.Default);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "VoiceChat-Receive ()", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
            }
            finally
            {
                nUdpClientFlag += 1;
            }
        }
示例#2
0
        private void UninitializeCall()
        {
            //Set the flag to end the Send and Receive threads.
            bStop        = true;
            IsCallActive = false;

            window.ButtonSetAsync(true, false, false);
            if (IsCaller)
            {
                CallRepo.createCall(Globals.currentUserId, ReceiverID, CallDate.ToString("yyyy-MM-dd hh:mm:ss"), 1);
            }
            IsCaller = false;
            Thread.Sleep(500);
            //Reinitialize crypto properties after the call
            MyCurrentPass   = AES_Crypto.CreatePass();
            MyCurrentSalt   = AES_Crypto.CreateSalt();
            CallCurrentPass = null;
            CallCurrentSalt = null;
            UserRepo.updateCrypto(MyCurrentPass, MyCurrentSalt);
        }
示例#3
0
        /*
         * Initializes all the data members.
         */
        public CallManager(System.Windows.Window window)
        {
            try
            {
                this.window = (WindowMain)window;
                device      = new Device();
                System.Windows.Interop.WindowInteropHelper helper = new System.Windows.Interop.WindowInteropHelper(window);
                device.SetCooperativeLevel(helper.Handle, CooperativeLevel.Normal);

                CaptureDevicesCollection captureDeviceCollection = new CaptureDevicesCollection();

                DeviceInformation deviceInfo = captureDeviceCollection[0];

                capture = new Capture(deviceInfo.DriverGuid);

                short channels         = 1;     //Stereo.
                short bitsPerSample    = 16;    //16Bit, alternatively use 8Bits.
                int   samplesPerSecond = 22050; //11KHz use 11025 , 22KHz use 22050, 44KHz use 44100 etc.

                //Set up the wave format to be captured.
                waveFormat                       = new WaveFormat();
                waveFormat.Channels              = channels;
                waveFormat.FormatTag             = WaveFormatTag.Pcm;
                waveFormat.SamplesPerSecond      = samplesPerSecond;
                waveFormat.BitsPerSample         = bitsPerSample;
                waveFormat.BlockAlign            = (short)(channels * (bitsPerSample / (short)8));
                waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * samplesPerSecond;

                captureBufferDescription             = new CaptureBufferDescription();
                captureBufferDescription.BufferBytes = waveFormat.AverageBytesPerSecond / 5;//approx 200 milliseconds of PCM data.
                captureBufferDescription.Format      = waveFormat;

                playbackBufferDescription             = new BufferDescription();
                playbackBufferDescription.BufferBytes = waveFormat.AverageBytesPerSecond / 5;
                playbackBufferDescription.Format      = waveFormat;
                playbackBuffer = new SecondaryBuffer(playbackBufferDescription, device);

                bufferSize = captureBufferDescription.BufferBytes;

                IsCallActive   = false;
                nUdpClientFlag = 0;

                //Using UDP sockets
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                EndPoint ourEP = new IPEndPoint(IPAddress.Any, 1450);
                //Listen asynchronously on port 1450 for coming messages (Invite, Bye, etc).
                clientSocket.Bind(ourEP);

                //Receive data from any IP.
                EndPoint remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any, 0));

                byteData = new byte[1024];
                //Receive data asynchornously.
                clientSocket.BeginReceiveFrom(byteData,
                                              0, byteData.Length,
                                              SocketFlags.None,
                                              ref remoteEP,
                                              new AsyncCallback(OnReceive),
                                              null);

                //Create first cryptographic passes
                this.MyCurrentPass = AES_Crypto.CreatePass();
                this.MyCurrentSalt = AES_Crypto.CreateSalt();
                UserRepo.updateCrypto(MyCurrentPass, MyCurrentSalt);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "Initialization Error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
            }
        }
示例#4
0
        /*
         * Send synchronously sends data captured from microphone across the network on port 1550.
         */
        private void Send()
        {
            try
            {
                captureBuffer = new CaptureBuffer(captureBufferDescription, capture);
                //The following lines get audio from microphone and then send them
                //across network

                CreateNotifyPositions();

                int halfBuffer = bufferSize / 2;

                captureBuffer.Start(true);

                bool readFirstBufferPart = true;
                int  offset = 0;

                MemoryStream memStream = new MemoryStream(halfBuffer);
                bStop = false;
                while (!bStop)
                {
                    if (!IsMuted)
                    {
                        autoResetEvent.WaitOne();
                        memStream.Seek(0, SeekOrigin.Begin);
                        captureBuffer.Read(offset, memStream, halfBuffer, LockFlag.None);
                        readFirstBufferPart = !readFirstBufferPart;
                        offset = readFirstBufferPart ? 0 : halfBuffer;

                        //Encode and encrypt data.
                        byte[] dataEncoded = ALawEncoder.ALawEncode(memStream.GetBuffer());

                        byte[] dataToWrite = AES_Crypto.Encrypt(dataEncoded, CallCurrentPass, CallCurrentSalt);

                        udpClient.Send(dataToWrite, dataToWrite.Length, otherPartyIP.Address.ToString(), 1550);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "VoiceChat-Send ()", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
            }
            finally
            {
                captureBuffer.Stop();
                captureBuffer.Dispose();
                //Increment flag by one.
                nUdpClientFlag += 1;

                //When flag is two then it means we have got out of loops in Send and Receive.
                while (nUdpClientFlag != 2)
                {
                }

                //Clear the flag.
                nUdpClientFlag = 0;

                //Close the socket.
                udpClient.Close();
            }
        }
示例#5
0
        /*
         * Commands are received asynchronously. OnReceive is the handler for them.
         */
        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                EndPoint receivedFromEP = new IPEndPoint(IPAddress.Any, 0);

                //Get the IP from where we got a message.
                clientSocket.EndReceiveFrom(ar, ref receivedFromEP);

                //Convert the bytes received into an object of type Data.
                Data msgReceived = new Data(byteData);

                //Act according to the received message.
                switch (msgReceived.cmdCommand)
                {
                //We have an incoming call.
                case Command.Invite:
                {
                    if (IsCallActive == false)
                    {
                        //We have no active call.

                        //Ask the user to accept the call or not.
                        if (MessageBox.Show("Call coming from " + msgReceived.strName + ".\r\n\r\nAccept it?",
                                            "VoiceChat", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes) == MessageBoxResult.Yes)
                        {
                            //Get someones crypto information
                            var cryptoTuple = UserRepo.fetchUsersCrypto(msgReceived.strName);
                            CallCurrentPass = cryptoTuple.Item1;
                            CallCurrentSalt = cryptoTuple.Item2;

                            SendMessage(Command.OK, receivedFromEP);
                            otherPartyEP = receivedFromEP;
                            otherPartyIP = (IPEndPoint)receivedFromEP;
                            InitializeCall();
                        }
                        else
                        {
                            //The call is declined. Send a busy response.
                            SendMessage(Command.Busy, receivedFromEP);
                        }
                    }
                    else
                    {
                        //We already have an existing call. Send a busy response.
                        SendMessage(Command.Busy, receivedFromEP);
                    }
                    break;
                }

                //OK is received in response to an Invite.
                case Command.OK:
                {
                    //Start a call.
                    InitializeCall();
                    MessageBox.Show("Person has answered. Call started.", "Call handler", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                    break;
                }

                //Remote party is busy.
                case Command.Busy:
                {
                    MessageBox.Show("User busy.", "VoiceChat", MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK);
                    CallRepo.createCall(Globals.currentUserId, ReceiverID, CallDate.ToString("yyyy-MM-dd hh:mm:ss"), 5);
                    IsCaller = false;
                    window.ButtonSetAsync(true, false, false);

                    //Reinitialize crypto properties after the call
                    MyCurrentPass   = AES_Crypto.CreatePass();
                    MyCurrentSalt   = AES_Crypto.CreateSalt();
                    CallCurrentPass = null;
                    CallCurrentSalt = null;
                    UserRepo.updateCrypto(MyCurrentPass, MyCurrentSalt);

                    break;
                }

                case Command.Bye:
                {
                    //Check if the Bye command has indeed come from the user/IP with which we have
                    //a call established. This is used to prevent other users from sending a Bye, which
                    //would otherwise end the call.
                    if (receivedFromEP.Equals(otherPartyEP) == true)
                    {
                        //End the call.
                        UninitializeCall();
                    }
                    MessageBox.Show("Person has disconnected", "Call handler", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                    break;
                }
                }

                byteData = new byte[1024];
                //Get ready to receive more commands.
                clientSocket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ref receivedFromEP, new AsyncCallback(OnReceive), null);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "VoiceChat-OnReceive ()", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
            }
        }