/// <summary>
        /// Initializes a new instance of the <see cref="FtpSessionState"/> class
        /// with the provided server address, control channel, server options and logger.
        /// </summary>
        /// <param name="serverAddress">Address of the server</param>
        /// <param name="publicServerAddress">
        /// External IP address of the server. This address will be used in passive mode
        /// </param>
        /// <param name="controlChannel">Control channel for the session</param>
        /// <param name="serverOptions">FTP server options</param>
        /// <param name="logger">Current logger instance</param>
        public FtpSessionState(
            IPAddress serverAddress,
            IPAddress publicServerAddress,
            IControlChannel controlChannel,
            FtpServerOptions serverOptions,
            ILogger logger)
        {
            if (serverAddress == null)
            {
                throw new ArgumentNullException(nameof(serverAddress));
            }

            if (publicServerAddress == null)
            {
                throw new ArgumentNullException(nameof(publicServerAddress));
            }

            if (controlChannel == null)
            {
                throw new ArgumentNullException(nameof(controlChannel));
            }

            if (serverOptions == null)
            {
                throw new ArgumentNullException(nameof(serverOptions));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            ServerAddress       = serverAddress;
            PublicServerAddress = publicServerAddress;
            ControlChannel      = controlChannel;
            LineFeed            = serverOptions.CommandEncoding.GetBytes(serverOptions.LineFeed);
            Logger = logger;

            ControlEncoding = serverOptions.CommandEncoding;
            PathEncoding    = Encoding.ASCII;

            TransferType = FileTransferType.ASCII;
        }
        private void CreatePhoneControllerClient(IDataSource dataSource)
        {
            if (dataSource == null)
            {
                throw new ArgumentNullException("dataSource");
            }

            // capture the current synchronization context
            _synchronizationContext = SynchronizationContext.Current;
            if (_synchronizationContext == null)
            {
                // create a default implementation
                _synchronizationContext = new SynchronizationContext();
            }

            // store and set up data source
            DataSource = dataSource;
            DataSource.DataAcquired += DataSource_DataAcquired;

            // create all required networking objects
            _broadCaster = new MulticastClient();
            _broadCaster.ServerDiscovered += BroadCaster_ServerDiscovered;
            _broadCaster.TimeoutElapsed += BroadCaster_TimeoutElapsed;

            _controlChannel = _communicationFactory.CreateControlChannel();
            _controlChannel.Error += ControlChannel_Error;
            _controlChannel.ControlCommandReceived += ControlChannel_ControlCommandReceived;
            _controlChannel.Connected += ControlChannel_Connected;
            _controlChannel.ConnectionClosed += ControlChannel_ConnectionClosed;

            _dataChannel = _communicationFactory.CreateDataChannel();
            _dataChannel.Error += DataChannel_Error;
            _dataChannel.Connected += DataChannel_Connected;
            _dataChannel.ConnectionClosed += DataChannel_ConnectionClosed;

            // configure some default values for the configuration here
            // these typically are overridden by a configuration sent down from the server side
            var configuration = new ControllerConfiguration();
            configuration.AutoReconnectOnActivation = false;
            configuration.TouchInputMargin = new Thickness(90, 20, 20, 20);
            configuration.MinAccelerometerDataRate = 0;
            configuration.MinCompassDataRate = 0;
            configuration.MinGyroscopeDataRate = 0;
            configuration.MinMotionDataRate = 0;
            configuration.MinMillisecondsBetweenMessages = 0; // as fast as possible
            configuration.EnableTracing = false;
            configuration.TracingEndpointAddress = null;
            Configure(configuration);

            State = PhoneControllerState.Created;
        }
        private void CreatePhoneControllerServer()
        {
            // capture the current synchronization context
            _synchronizationContext = SynchronizationContext.Current;
            if (_synchronizationContext == null)
            {
                // create a default implementation
                _synchronizationContext = new SynchronizationContext();
            }

            // create all required networking objects
            _broadCastListener = new MulticastListener();

            _controlChannel = _communicationFactory.CreateControlChannel();
            _controlChannel.ClientAccepted += ControlChannel_ClientAccepted;
            _controlChannel.ConnectionClosed += ControlChannel_ConnectionClosed;
            _controlChannel.ControlCommandSent += ControlChannel_ControlCommandSent;
            _controlChannel.Error += ControlChannel_Error;

            _dataChannel = _communicationFactory.CreateDataChannel();
            _dataChannel.ClientAccepted += DataChannel_ClientAccepted;
            _dataChannel.ConnectionClosed += DataChannel_ConnectionClosed;
            _dataChannel.Error += DataChannel_Error;
            _dataChannel.DataMessageReceived += DataChannel_DataMessageReceived;

            // set initial state
            State = PhoneControllerState.Created;
        }