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); }
/* * 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); } }
/* * 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); } }