public void Run(string[] args) { var settingsReader = new CommandLineClientSettingsReader(); if (!settingsReader.ParseArgs(args)) { return; } var settings = settingsReader.ClientSettings; if (settings.Email == null) { Console.Error.WriteLine("No Email configured"); return; } if (settings.Password == null) { Console.Error.WriteLine("No Password configured"); return; } var credentials = new CredentialsProvider() { Email = settings.Email, Password = settings.Password }; var webClient = new RopuWebClient("asdf", credentials); var keysClient = new KeysClient(webClient, false, encryptionKey => new CachedEncryptionKey(encryptionKey, key => new AesGcmWrapper(key))); var packetEncryption = new PacketEncryption(keysClient); var protocolSwitch = new ProtocolSwitch(_controlPortStarting, new PortFinder(), packetEncryption, keysClient, settings); var servingNodeClient = new ServingNodeClient(protocolSwitch); var callManagementProtocol = new LoadBalancerProtocol(new PortFinder(), 5079, packetEncryption, keysClient); _mediaClient = BuildMediaClient(protocolSwitch, settings); //IPEndPoint loadBalancerEndpoint = new IPEndPoint(settings.LoadBalancerIPAddress, LoadBalancerPort); var beepPlayer = BuildBeepPlayer(settings); _ropuClient = new RopuClient(protocolSwitch, servingNodeClient, _mediaClient, callManagementProtocol, settings, beepPlayer, webClient, keysClient); var ropuClientTask = _ropuClient.Run(); //var consoleTask = TaskCordinator.RunLong(HandleCommands); //TaskCordinator.WaitAll(ropuClientTask, consoleTask).Wait(); ropuClientTask.Wait(); }
IMediaClient BuildMediaClient(ProtocolSwitch protocolSwitch, IClientSettings settings) { if (settings.FakeMedia) { //Console.WriteLine("Using FakeMediaClient"); return(new FakeMediaClient()); } var audioSource = new AlsaAudioSource(); var audioPlayer = new AlsaAudioPlayer(true); var audioCodec = new RawCodec(); var jitterBuffer = new AdaptiveJitterBuffer(2, 50); return(new MediaClient(protocolSwitch, audioSource, audioPlayer, audioCodec, jitterBuffer, settings)); }
public MediaClient( ProtocolSwitch protocolSwitch, IAudioSource audioSource, IAudioPlayer audioPlayer, IAudioCodec audioCodec, IJitterBuffer jitterBuffer, IClientSettings clientSettings) { _protocolSwitch = protocolSwitch; _protocolSwitch.SetMediaPacketParser(this); _audioSource = audioSource; _audioPlayer = audioPlayer; _audioCodec = audioCodec; _jitterBuffer = jitterBuffer; _clientSettings = clientSettings; }
public RopuClient( ProtocolSwitch protocolSwitch, ServingNodeClient servingNodeClient, IMediaClient mediaClient, LoadBalancerProtocol loadBalancerProtocol, IClientSettings clientSettings, IBeepPlayer beepPlayer, RopuWebClient webClient, KeysClient keysClient) { _webClient = webClient; _beepPlayer = beepPlayer; _clientSettings = clientSettings; _loadBalancerProtocol = loadBalancerProtocol; _protocolSwitch = protocolSwitch; _servingNodeClient = servingNodeClient; _mediaClient = mediaClient; _servingNodeClient.SetControllingFunctionHandler(this); _retryTimer = new Ropu.Shared.Timer(); _keysClient = keysClient; var allEvents = (EventId[])Enum.GetValues(typeof(EventId)); //start _start = new RopuState(StateId.Start); _stateManager = new StateManager <StateId, EventId>(_start); _stateManager.AddState(_start); _start.AddTransitions(allEvents, () => _start); //registered _registered = new RopuState(StateId.Registered) { Entry = async token => { if (_clientSettings.UserId == null) { throw new InvalidOperationException("UserId is not set"); } _callGroup = IdleGroup; _registeredUserId = _clientSettings.UserId.Value; if (_heartbeatTask == null) { _heartbeatTask = Heartbeat(_heartbeatCancellationTokenSource.Token); } _heartbeatOnEvent.Set(); //allows the heartbeat to continue await Task.Run(() => {}); }, }; _stateManager.AddState(_registered); _registered.AddTransition(EventId.CallRequest, () => _startingCall !); _registered.AddTransition(EventId.PttDown, () => _startingCall !); _registered.AddTransition(EventId.RegistrationResponseReceived, () => _registered); _registered.AddTransition(EventId.CallStartFailed, () => _registered); _registered.AddTransition(EventId.PttUp, () => _registered); _registered.AddTransition(EventId.GroupSelected, () => _registered); //unregistered _noGroup = new RopuState(StateId.NoGroup); _unregistered = new RopuState(StateId.Unregistered) { Entry = async token => { _heartbeatOnEvent.Reset(); //stops the heartbeat await Register(token); } }; _unregistered.AddTransition(EventId.RegistrationResponseReceived, () => IdleGroup == null ? _noGroup : _registered); _unregistered.AddTransition(EventId.FloorIdle, () => _unregistered); _unregistered.AddTransition(EventId.FloorTaken, () => _unregistered); _unregistered.AddTransition(EventId.CallEnded, () => _unregistered); _unregistered.AddTransition(EventId.CallRequest, () => _unregistered); _unregistered.AddTransition(EventId.CallStartFailed, () => _unregistered); _unregistered.AddTransition(EventId.HeartbeatFailed, () => _unregistered); _unregistered.AddTransition(EventId.PttUp, () => _unregistered); _unregistered.AddTransition(EventId.PttDown, () => _unregistered); _unregistered.AddTransition(EventId.GroupSelected, () => _unregistered); _stateManager.AddState(_unregistered); //no group _noGroup.AddTransition(EventId.PttUp, () => _noGroup); _noGroup.AddTransition(EventId.PttDown, () => _noGroup); _noGroup.AddTransition(EventId.GroupSelected, () => _registered); _noGroup.AddTransition(EventId.RegistrationResponseReceived, () => _noGroup); _noGroup.AddTransition(EventId.CallRequest, () => _noGroup); _noGroup.AddTransition(EventId.CallStartFailed, () => _noGroup); _stateManager.AddState(_noGroup); //deregistering _deregistering = new RopuState(StateId.Deregistering) { Entry = async token => await Deregister(token), }; _deregistering.AddTransition(EventId.DeregistrationResponseReceived, () => _unregistered); _deregistering.AddTransitions(allEvents.Where(e => e != EventId.DeregistrationResponseReceived), () => _deregistering); _deregistering.AddTransition(EventId.GroupSelected, () => _deregistering); _stateManager.AddState(_deregistering); //starting call _startingCall = new RopuState(StateId.StartingCall) { Entry = async token => await StartCall(token), Exit = newState => { if (newState != _inCallTransmitting && newState != _inCallRequestingFloor) { _mediaClient.StopSendingAudio(); } } }; _startingCall.AddTransition(EventId.CallStartFailed, () => _registered); _startingCall.AddTransition(EventId.PttUp, () => _startingCall); _startingCall.AddTransition(EventId.PttDown, () => _startingCall); _startingCall.AddTransition(EventId.RegistrationResponseReceived, () => _startingCall); _startingCall.AddTransition(EventId.CallRequest, () => _startingCall); _startingCall.AddTransition(EventId.GroupSelected, () => _startingCall); _stateManager.AddState(_startingCall); //in call idle _inCallIdle = new RopuState(StateId.InCallIdle); _inCallIdle.AddTransition(EventId.PttDown, () => _inCallRequestingFloor !); _inCallIdle.AddTransition(EventId.PttUp, () => _inCallIdle); _inCallIdle.AddTransition(EventId.RegistrationResponseReceived, () => _inCallIdle); _inCallIdle.AddTransition(EventId.CallRequest, () => _inCallIdle); _inCallIdle.AddTransition(EventId.CallStartFailed, () => _registered); _inCallIdle.AddTransition(EventId.GroupSelected, () => _inCallIdle); _stateManager.AddState(_inCallIdle); //in call receiving _inCallReceiveing = new RopuState(StateId.InCallReceiving); _inCallReceiveing.AddTransition(EventId.PttDown, () => _inCallReceiveing); _inCallReceiveing.AddTransition(EventId.PttUp, () => _inCallReceiveing); _inCallReceiveing.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReceiveing); _inCallReceiveing.AddTransition(EventId.CallRequest, () => _inCallReceiveing); _inCallReceiveing.AddTransition(EventId.CallStartFailed, () => _registered); _inCallReceiveing.AddTransition(EventId.GroupSelected, () => _inCallReceiveing); _stateManager.AddState(_inCallReceiveing); //in call transmitting _inCallTransmitting = new RopuState(StateId.InCallTransmitting) { Entry = async token => { _beepPlayer.PlayGoAhead(); await Task.Run(() => {}); }, Exit = newState => { if (newState != _inCallTransmitting && newState != _inCallRequestingFloor) { _mediaClient.StopSendingAudio(); } } }; _inCallTransmitting.AddTransition(EventId.PttUp, () => _inCallReleasingFloor !); _inCallTransmitting.AddTransition(EventId.RegistrationResponseReceived, () => _inCallTransmitting); _inCallTransmitting.AddTransition(EventId.CallRequest, () => _inCallTransmitting); _inCallTransmitting.AddTransition(EventId.CallStartFailed, () => _inCallTransmitting); _inCallTransmitting.AddTransition(EventId.PttDown, () => _inCallTransmitting); _inCallTransmitting.AddTransition(EventId.GroupSelected, () => _inCallTransmitting); _stateManager.AddState(_inCallTransmitting); //in call requesting floor _inCallRequestingFloor = new RopuState(StateId.InCallRequestingFloor) { Entry = token => { if (_callGroup == null) { return(Task.CompletedTask); } if (_clientSettings.UserId == null) { throw new InvalidOperationException("UserId is not set"); } _servingNodeClient.SendFloorRequest(_callGroup.Value, _clientSettings.UserId.Value); StartSendingAudio(); return(Task.CompletedTask); }, Exit = newState => { if (newState != _inCallTransmitting && newState != _inCallRequestingFloor) { _mediaClient.StopSendingAudio(); _beepPlayer.PlayDenied(); } } }; _inCallRequestingFloor.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReleasingFloor !); _inCallRequestingFloor.AddTransition(EventId.CallRequest, () => _inCallReleasingFloor !); _inCallRequestingFloor.AddTransition(EventId.CallStartFailed, () => _registered); _inCallRequestingFloor.AddTransition(EventId.PttDown, () => _inCallRequestingFloor); _inCallRequestingFloor.AddTransition(EventId.PttUp, () => _inCallIdle); _inCallRequestingFloor.AddTransition(EventId.GroupSelected, () => _inCallRequestingFloor); _stateManager.AddState(_inCallRequestingFloor); //in call releasing floor _inCallReleasingFloor = new RopuState(StateId.InCallReleasingFloor) { Entry = async token => { if (_callGroup == null) { throw new InvalidOperationException("No call group"); } if (_clientSettings.UserId == null) { throw new InvalidOperationException("UserId is not set"); } while (!token.IsCancellationRequested) { _servingNodeClient.SendFloorReleased(_callGroup.Value, _clientSettings.UserId.Value); await Task.Run(() => token.WaitHandle.WaitOne(1000)); } } }; _inCallReleasingFloor.AddTransition(EventId.FloorGranted, () => _inCallReleasingFloor); _inCallReleasingFloor.AddTransition(EventId.RegistrationResponseReceived, () => _inCallReleasingFloor); _inCallReleasingFloor.AddTransition(EventId.CallRequest, () => _inCallReleasingFloor); _inCallReleasingFloor.AddTransition(EventId.CallStartFailed, () => _registered); _inCallReleasingFloor.AddTransition(EventId.PttDown, () => _inCallRequestingFloor); _inCallReleasingFloor.AddTransition(EventId.PttUp, () => _inCallReleasingFloor); _inCallReleasingFloor.AddTransition(EventId.GroupSelected, () => _inCallReleasingFloor); _stateManager.AddState(_inCallReleasingFloor); _inCallReleasingFloor.AddTransition(EventId.FloorGranted, () => _inCallReleasingFloor); _stateManager.StateChanged += (sender, args) => { Console.WriteLine($"State Changed {this._stateManager.CurrentState}"); StateChanged?.Invoke(this, args); }; _stateManager.AddTransitionToAll(EventId.HeartbeatFailed, () => _unregistered, stateId => true); _stateManager.AddTransitionToAll(EventId.NotRegistered, () => _unregistered, stateId => true); _stateManager.AddTransitionToAll(EventId.CallEnded, () => _registered, stateId => stateId != StateId.Unregistered && stateId != StateId.Start && stateId != StateId.Deregistering); _stateManager.AddTransitionToAll(EventId.FloorIdle, () => _inCallIdle, IsRegistered); _stateManager.AddTransitionToAll(EventId.FloorTaken, () => _inCallReceiveing, IsRegistered); _stateManager.AddTransitionToAll(EventId.FloorGranted, () => _inCallTransmitting, stateId => stateId != StateId.InCallReleasingFloor); _stateManager.AddTransitionToAll(EventId.DeregistrationResponseReceived, () => _unregistered, stateId => true); _stateManager.AddTransitionToAll(EventId.GroupDeselected, () => _noGroup, stateId => true); _stateManager.CheckEventsAreHandledByAll((EventId[])Enum.GetValues(typeof(EventId))); }
public ServingNodeClient(ProtocolSwitch protocolSwitch) { _protocolSwitch = protocolSwitch; _protocolSwitch.SetControlPacketParser(this); }