private async void OnSocketConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            rootPage.NotifyUserFromBackground("Connecting to remote side on L4 layer...", NotifyType.StatusMessage);
            StreamSocket serverSocket = args.Socket;

            try
            {
                SocketReaderWriter socketRW = new SocketReaderWriter(serverSocket, rootPage);
                socketRW.ReadMessage();

                while (true)
                {
                    string sessionId = socketRW.GetCurrentMessage();
                    if (sessionId != null)
                    {
                        rootPage.NotifyUserFromBackground("Connected with remote side on L4 layer", NotifyType.StatusMessage);

                        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            for (int idx = 0; idx < _connectedDevices.Count; idx++)
                            {
                                if (_connectedDevices[idx].DisplayName.Equals("Waiting for client to connect...") == true)
                                {
                                    ConnectedDevice connectedDevice = _connectedDevices[idx];
                                    _connectedDevices.RemoveAt(idx);

                                    connectedDevice.DisplayName = sessionId;
                                    connectedDevice.SocketRW    = socketRW;

                                    _connectedDevices.Add(connectedDevice);
                                    break;
                                }
                            }
                        });


                        break;
                    }

                    await Task.Delay(100);
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUserFromBackground("Connection failed: " + ex.Message, NotifyType.ErrorMessage);
            }
        }
        private async void btnFromId_Click(object sender, RoutedEventArgs e)
        {
            var discoveredDevice = (DiscoveredDevice)lvDiscoveredDevices.SelectedItem;

            if (discoveredDevice == null)
            {
                rootPage.NotifyUser("No device selected, please select one.", NotifyType.ErrorMessage);
                return;
            }

            rootPage.NotifyUser($"Connecting to {discoveredDevice.DeviceInfo.Name}...", NotifyType.StatusMessage);

            if (!discoveredDevice.DeviceInfo.Pairing.IsPaired)
            {
                if (!await connectionSettingsPanel.RequestPairDeviceAsync(discoveredDevice.DeviceInfo.Pairing))
                {
                    return;
                }
            }

            WiFiDirectDevice wfdDevice = null;

            try
            {
                // IMPORTANT: FromIdAsync needs to be called from the UI thread
                wfdDevice = await WiFiDirectDevice.FromIdAsync(discoveredDevice.DeviceInfo.Id);
            }
            catch (TaskCanceledException)
            {
                rootPage.NotifyUser("FromIdAsync was canceled by user", NotifyType.ErrorMessage);
                return;
            }

            // Register for the ConnectionStatusChanged event handler
            wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

            IReadOnlyList <EndpointPair> endpointPairs = wfdDevice.GetConnectionEndpointPairs();
            HostName remoteHostName = endpointPairs[0].RemoteHostName;

            rootPage.NotifyUser($"Devices connected on L2 layer, connecting to IP Address: {remoteHostName} Port: {Globals.strServerPort}",
                                NotifyType.StatusMessage);

            // Wait for server to start listening on a socket
            await Task.Delay(2000);

            // Connect to Advertiser on L4 layer
            StreamSocket clientSocket = new StreamSocket();

            try
            {
                await clientSocket.ConnectAsync(remoteHostName, Globals.strServerPort);

                rootPage.NotifyUser("Connected with remote side on L4 layer", NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser($"Connect operation threw an exception: {ex.Message}", NotifyType.ErrorMessage);
                return;
            }

            SocketReaderWriter socketRW = new SocketReaderWriter(clientSocket, rootPage);

            string          sessionId       = Path.GetRandomFileName();
            ConnectedDevice connectedDevice = new ConnectedDevice(sessionId, wfdDevice, socketRW);

            ConnectedDevices.Add(connectedDevice);

            // The first message sent over the socket is the name of the connection.
            await socketRW.WriteMessageAsync(sessionId);

            while (await socketRW.ReadMessageAsync() != null)
            {
                // Keep reading messages
            }
        }
        private async void OnConnectionRequested(WiFiDirectConnectionListener sender, WiFiDirectConnectionRequestedEventArgs connectionEventArgs)
        {
            try
            {
                var connectionRequest = connectionEventArgs.GetConnectionRequest();

                var tcs = new TaskCompletionSource<bool>();
                var dialogTask = tcs.Task;
                var messageDialog = new MessageDialog("Connection request received from " + connectionRequest.DeviceInformation.Name, "Connection Request");

                // Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers 
                messageDialog.Commands.Add(new UICommand("Accept", null, 0));
                messageDialog.Commands.Add(new UICommand("Decline", null, 1));

                // Set the command that will be invoked by default 
                messageDialog.DefaultCommandIndex = 1;

                // Set the command to be invoked when escape is pressed 
                messageDialog.CancelCommandIndex = 1;

                await Dispatcher.RunAsync(CoreDispatcherPriority.High, async () =>
                {
                    // Show the message dialog 
                    var commandChosen = await messageDialog.ShowAsync();

                    tcs.SetResult((commandChosen.Label == "Accept") ? true : false);
                });

                var fProceed = await dialogTask;

                if (fProceed == true)
                {
                    var tcsWiFiDirectDevice = new TaskCompletionSource<WiFiDirectDevice>();
                    var wfdDeviceTask = tcsWiFiDirectDevice.Task;

                    await Dispatcher.RunAsync(CoreDispatcherPriority.High, async () =>
                    {
                        try
                        {
                            rootPage.NotifyUser("Connecting to " + connectionRequest.DeviceInformation.Name + "...", NotifyType.StatusMessage);

                            WiFiDirectConnectionParameters connectionParams = new WiFiDirectConnectionParameters();
                            connectionParams.GroupOwnerIntent = Convert.ToInt16(txtGOIntent.Text);

                            // IMPORTANT: FromIdAsync needs to be called from the UI thread
                            tcsWiFiDirectDevice.SetResult(await WiFiDirectDevice.FromIdAsync(connectionRequest.DeviceInformation.Id, connectionParams));
                        }
                        catch (Exception ex)
                        {
                            rootPage.NotifyUser("FromIdAsync task threw an exception: " + ex.ToString(), NotifyType.ErrorMessage);
                        }
                    });

                    WiFiDirectDevice wfdDevice = await wfdDeviceTask;

                    // Register for the ConnectionStatusChanged event handler
                    wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

                    await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                    {
                        ConnectedDevice connectedDevice = new ConnectedDevice("Waiting for client to connect...", wfdDevice, null);
                        _connectedDevices.Add(connectedDevice);
                    });

                    var EndpointPairs = wfdDevice.GetConnectionEndpointPairs();

                    _listenerSocket = null;
                    _listenerSocket = new StreamSocketListener();
                    _listenerSocket.ConnectionReceived += OnSocketConnectionReceived;
                    await _listenerSocket.BindEndpointAsync(EndpointPairs[0].LocalHostName, Globals.strServerPort);

                    rootPage.NotifyUserFromBackground("Devices connected on L2, listening on IP Address: " + EndpointPairs[0].LocalHostName.ToString() +
                                            " Port: " + Globals.strServerPort, NotifyType.StatusMessage);
                }
                else
                {
                    // Decline the connection request
                    rootPage.NotifyUserFromBackground("Connection request from " + connectionRequest.DeviceInformation.Name + " was declined", NotifyType.ErrorMessage);
                    connectionRequest.Dispose();
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUserFromBackground("Connect operation threw an exception: " + ex.Message, NotifyType.ErrorMessage);
            }
        }
        private async void btnFromId_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            if (lvDiscoveredDevices.SelectedItems.Count == 0)
            {
                rootPage.NotifyUser("No device selected, please select atleast one.", NotifyType.ErrorMessage);
                return;
            }

            var selectedDevices = lvDiscoveredDevices.SelectedItems;

            foreach (DiscoveredDevice discoveredDevice in selectedDevices)
            {
                rootPage.NotifyUser("Connecting to " + discoveredDevice.DeviceInfo.Name + "...", NotifyType.StatusMessage);

                try
                {
                    WiFiDirectConnectionParameters connectionParams = new WiFiDirectConnectionParameters();
                    connectionParams.GroupOwnerIntent = Convert.ToInt16(txtGOIntent.Text);

                    _cancellationTokenSource = new CancellationTokenSource();

                    // IMPORTANT: FromIdAsync needs to be called from the UI thread
                    var wfdDevice = await WiFiDirectDevice.FromIdAsync(discoveredDevice.DeviceInfo.Id, connectionParams).AsTask(_cancellationTokenSource.Token);

                    // Register for the ConnectionStatusChanged event handler
                    wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

                    var endpointPairs = wfdDevice.GetConnectionEndpointPairs();

                    rootPage.NotifyUser("Devices connected on L2 layer, connecting to IP Address: " + endpointPairs[0].RemoteHostName +
                                        " Port: " + Globals.strServerPort, NotifyType.StatusMessage);

                    // Wait for server to start listening on a socket
                    await Task.Delay(2000);

                    // Connect to Advertiser on L4 layer
                    StreamSocket clientSocket = new StreamSocket();
                    await clientSocket.ConnectAsync(endpointPairs[0].RemoteHostName, Globals.strServerPort);

                    SocketReaderWriter socketRW = new SocketReaderWriter(clientSocket, rootPage);

                    string sessionId = "Session: " + Path.GetRandomFileName();
                    ConnectedDevice connectedDevice = new ConnectedDevice(sessionId, wfdDevice, socketRW);
                    _connectedDevices.Add(connectedDevice);

                    socketRW.ReadMessage();
                    socketRW.WriteMessage(sessionId);

                    rootPage.NotifyUser("Connected with remote side on L4 layer", NotifyType.StatusMessage);
                }
                catch (TaskCanceledException)
                {
                    rootPage.NotifyUser("FromIdAsync was canceled by user", NotifyType.ErrorMessage);
                }
                catch (Exception ex)
                {
                    rootPage.NotifyUser("Connect operation threw an exception: " + ex.Message, NotifyType.ErrorMessage);
                }

                _cancellationTokenSource = null;
            }
        }
        private async void btnFromId_Click(object sender, RoutedEventArgs e)
        {
            var discoveredDevice = (DiscoveredDevice)lvDiscoveredDevices.SelectedItem;

            if (discoveredDevice == null)
            {
                rootPage.NotifyUser("No device selected, please select one.", NotifyType.ErrorMessage);
                return;
            }

            rootPage.NotifyUser($"Connecting to {discoveredDevice.DeviceInfo.Name}...", NotifyType.StatusMessage);

            if (!discoveredDevice.DeviceInfo.Pairing.IsPaired)
            {
                if (!await connectionSettingsPanel.RequestPairDeviceAsync(discoveredDevice.DeviceInfo.Pairing))
                {
                    return;
                }
            }

            try
            {
                // IMPORTANT: FromIdAsync needs to be called from the UI thread
                var wfdDevice = await WiFiDirectDevice.FromIdAsync(discoveredDevice.DeviceInfo.Id);

                // Register for the ConnectionStatusChanged event handler
                wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

                IReadOnlyList<EndpointPair> endpointPairs = wfdDevice.GetConnectionEndpointPairs();
                HostName remoteHostName = endpointPairs[0].RemoteHostName;

                rootPage.NotifyUser($"Devices connected on L2 layer, connecting to IP Address: {remoteHostName} Port: {Globals.strServerPort}",
                    NotifyType.StatusMessage);

                // Wait for server to start listening on a socket
                await Task.Delay(2000);

                // Connect to Advertiser on L4 layer
                StreamSocket clientSocket = new StreamSocket();
                await clientSocket.ConnectAsync(remoteHostName, Globals.strServerPort);
                rootPage.NotifyUser("Connected with remote side on L4 layer", NotifyType.StatusMessage);

                SocketReaderWriter socketRW = new SocketReaderWriter(clientSocket, rootPage);

                string sessionId = Path.GetRandomFileName();
                ConnectedDevice connectedDevice = new ConnectedDevice(sessionId, wfdDevice, socketRW);
                ConnectedDevices.Add(connectedDevice);

                // The first message sent over the socket is the name of the connection.
                await socketRW.WriteMessageAsync(sessionId);

                while (await socketRW.ReadMessageAsync() != null)
                {
                    // Keep reading messages
                }

            }
            catch (TaskCanceledException)
            {
                rootPage.NotifyUser("FromIdAsync was canceled by user", NotifyType.ErrorMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser($"Connect operation threw an exception: {ex.Message}", NotifyType.ErrorMessage);
            }
        }
        private async void OnConnectionRequested(WiFiDirectConnectionListener sender, WiFiDirectConnectionRequestedEventArgs connectionEventArgs)
        {
            try
            {
                var connectionRequest = connectionEventArgs.GetConnectionRequest();

                var tcs           = new TaskCompletionSource <bool>();
                var dialogTask    = tcs.Task;
                var messageDialog = new MessageDialog("Connection request received from " + connectionRequest.DeviceInformation.Name, "Connection Request");

                // Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
                messageDialog.Commands.Add(new UICommand("Accept", null, 0));
                messageDialog.Commands.Add(new UICommand("Decline", null, 1));

                // Set the command that will be invoked by default
                messageDialog.DefaultCommandIndex = 1;

                // Set the command to be invoked when escape is pressed
                messageDialog.CancelCommandIndex = 1;

                await Dispatcher.RunAsync(CoreDispatcherPriority.High, async() =>
                {
                    // Show the message dialog
                    var commandChosen = await messageDialog.ShowAsync();

                    tcs.SetResult((commandChosen.Label == "Accept") ? true : false);
                });

                var fProceed = await dialogTask;

                if (fProceed == true)
                {
                    var tcsWiFiDirectDevice = new TaskCompletionSource <WiFiDirectDevice>();
                    var wfdDeviceTask       = tcsWiFiDirectDevice.Task;

                    await Dispatcher.RunAsync(CoreDispatcherPriority.High, async() =>
                    {
                        try
                        {
                            rootPage.NotifyUser("Connecting to " + connectionRequest.DeviceInformation.Name + "...", NotifyType.StatusMessage);

                            WiFiDirectConnectionParameters connectionParams = new WiFiDirectConnectionParameters();
                            connectionParams.GroupOwnerIntent = Convert.ToInt16(txtGOIntent.Text);

                            // IMPORTANT: FromIdAsync needs to be called from the UI thread
                            tcsWiFiDirectDevice.SetResult(await WiFiDirectDevice.FromIdAsync(connectionRequest.DeviceInformation.Id, connectionParams));
                        }
                        catch (Exception ex)
                        {
                            rootPage.NotifyUser("FromIdAsync task threw an exception: " + ex.ToString(), NotifyType.ErrorMessage);
                        }
                    });

                    WiFiDirectDevice wfdDevice = await wfdDeviceTask;

                    // Register for the ConnectionStatusChanged event handler
                    wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

                    await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                    {
                        ConnectedDevice connectedDevice = new ConnectedDevice("Waiting for client to connect...", wfdDevice, null);
                        _connectedDevices.Add(connectedDevice);
                    });

                    var EndpointPairs = wfdDevice.GetConnectionEndpointPairs();

                    _listenerSocket = null;
                    _listenerSocket = new StreamSocketListener();
                    _listenerSocket.ConnectionReceived += OnSocketConnectionReceived;
                    await _listenerSocket.BindEndpointAsync(EndpointPairs[0].LocalHostName, Globals.strServerPort);

                    rootPage.NotifyUserFromBackground("Devices connected on L2, listening on IP Address: " + EndpointPairs[0].LocalHostName.ToString() +
                                                      " Port: " + Globals.strServerPort, NotifyType.StatusMessage);
                }
                else
                {
                    // Decline the connection request
                    rootPage.NotifyUserFromBackground("Connection request from " + connectionRequest.DeviceInformation.Name + " was declined", NotifyType.ErrorMessage);
                    connectionRequest.Dispose();
                }
            }
            catch (Exception ex)
            {
                rootPage.NotifyUserFromBackground("Connect operation threw an exception: " + ex.Message, NotifyType.ErrorMessage);
            }
        }
        private async void btnFromId_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            if (lvDiscoveredDevices.SelectedItems.Count == 0)
            {
                rootPage.NotifyUser("No device selected, please select atleast one.", NotifyType.ErrorMessage);
                return;
            }

            var selectedDevices = lvDiscoveredDevices.SelectedItems;

            foreach (DiscoveredDevice discoveredDevice in selectedDevices)
            {
                rootPage.NotifyUser("Connecting to " + discoveredDevice.DeviceInfo.Name + "...", NotifyType.StatusMessage);

                try
                {
                    WiFiDirectConnectionParameters connectionParams = new WiFiDirectConnectionParameters();
                    connectionParams.GroupOwnerIntent = Convert.ToInt16(txtGOIntent.Text);

                    _cancellationTokenSource = new CancellationTokenSource();

                    // IMPORTANT: FromIdAsync needs to be called from the UI thread
                    var wfdDevice = await WiFiDirectDevice.FromIdAsync(discoveredDevice.DeviceInfo.Id, connectionParams).AsTask(_cancellationTokenSource.Token);

                    // Register for the ConnectionStatusChanged event handler
                    wfdDevice.ConnectionStatusChanged += OnConnectionStatusChanged;

                    var endpointPairs = wfdDevice.GetConnectionEndpointPairs();

                    rootPage.NotifyUser("Devices connected on L2 layer, connecting to IP Address: " + endpointPairs[0].RemoteHostName +
                                        " Port: " + Globals.strServerPort, NotifyType.StatusMessage);

                    // Wait for server to start listening on a socket
                    await Task.Delay(2000);

                    // Connect to Advertiser on L4 layer
                    StreamSocket clientSocket = new StreamSocket();
                    await clientSocket.ConnectAsync(endpointPairs[0].RemoteHostName, Globals.strServerPort);

                    SocketReaderWriter socketRW = new SocketReaderWriter(clientSocket, rootPage);

                    string          sessionId       = "Session: " + Path.GetRandomFileName();
                    ConnectedDevice connectedDevice = new ConnectedDevice(sessionId, wfdDevice, socketRW);
                    _connectedDevices.Add(connectedDevice);

                    socketRW.ReadMessage();
                    socketRW.WriteMessage(sessionId);

                    rootPage.NotifyUser("Connected with remote side on L4 layer", NotifyType.StatusMessage);
                }
                catch (TaskCanceledException)
                {
                    rootPage.NotifyUser("FromIdAsync was canceled by user", NotifyType.ErrorMessage);
                }
                catch (Exception ex)
                {
                    rootPage.NotifyUser("Connect operation threw an exception: " + ex.Message, NotifyType.ErrorMessage);
                }

                _cancellationTokenSource = null;
            }
        }