A connection type that uses Bluetooth RFCOMM to communicate
Inheritance: Connection
        /// <summary>
        /// Internal <see cref="BluetoothConnection"/> creation which hides the necessary internal calls
        /// </summary>
        /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param>
        /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param>
        /// <param name="btClient">If this is an incoming connection we will already have access to the btClient, otherwise use null</param>
        /// <param name="establishIfRequired">Establish during create if true</param>
        /// <returns>An existing connection or a new one</returns>
        internal static BluetoothConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, BluetoothClient btClient, bool establishIfRequired = true)
        {
            connectionInfo.ConnectionType = ConnectionType.Bluetooth;

            //If we have a tcpClient at this stage we must be server side
            if (btClient != null)
            {
                connectionInfo.ServerSide = true;
            }

            bool newConnection = false;
            BluetoothConnection connection;

            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                List <Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteEndPoint, connectionInfo.LocalEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol);

                //Check to see if a connection already exists, if it does return that connection, if not return a new one
                if (existingConnections.Count > 0)
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Attempted to create new BluetoothConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead.");
                    }

                    establishIfRequired = false;
                    connection          = (BluetoothConnection)existingConnections[0];
                }
                else
                {
                    if (NetworkComms.LoggingEnabled)
                    {
                        NetworkComms.Logger.Trace("Creating new BluetoothConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established."));
                    }

                    if (connectionInfo.ConnectionState == ConnectionState.Establishing)
                    {
                        throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug.");
                    }

                    //If an existing connection does not exist but the info we are using suggests it should we need to reset the info
                    //so that it can be reused correctly. This case generally happens when using NetworkComms.Net in the format
                    //TCPConnection.GetConnection(info).SendObject(packetType, objToSend);
                    if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown)
                    {
                        connectionInfo.ResetConnectionInfo();
                    }

                    //We add a reference to networkComms for this connection within the constructor
                    connection = new BluetoothConnection(connectionInfo, defaultSendReceiveOptions, btClient);

                    newConnection = true;
                }
            }

            if (newConnection && establishIfRequired)
            {
                connection.EstablishConnection();
            }
            else if (!newConnection)
            {
                connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS);
            }

            if (!NetworkComms.commsShutdown)
            {
                TriggerConnectionKeepAliveThread();
            }

            return(connection);
        }
Exemple #2
0
        /// <summary>
        /// Handle a new incoming bluetooth connection
        /// </summary>
        /// <param name="ar"></param>
        private void BluetoothConnectionReceivedAsync(IAsyncResult ar)
        {
            if (!IsListening)
            {
                return;
            }

            try
            {
                var            newBTClient       = listenerInstance.EndAcceptBluetoothClient(ar);
                ConnectionInfo newConnectionInfo = new ConnectionInfo(ConnectionType.Bluetooth, newBTClient.Client.RemoteEndPoint, newBTClient.Client.LocalEndPoint, ApplicationLayerProtocol, this);

                if (NetworkComms.LoggingEnabled)
                {
                    NetworkComms.Logger.Info("New bluetooth connection from " + newConnectionInfo);
                }

                NetworkComms.IncomingConnectionEstablishThreadPool.EnqueueItem(QueueItemPriority.Normal, new WaitCallback((obj) =>
                {
                    #region Pickup The New Connection
                    try
                    {
                        BluetoothConnection.GetConnection(newConnectionInfo, ListenerDefaultSendReceiveOptions, newBTClient, true);
                    }
                    catch (ConfirmationTimeoutException)
                    {
                        //If this exception gets thrown its generally just a client closing a connection almost immediately after creation
                    }
                    catch (CommunicationException)
                    {
                        //If this exception gets thrown its generally just a client closing a connection almost immediately after creation
                    }
                    catch (ConnectionSetupException)
                    {
                        //If we are the server end and we did not pick the incoming connection up then tooo bad!
                    }
                    catch (SocketException)
                    {
                        //If this exception gets thrown its generally just a client closing a connection almost immediately after creation
                    }
                    catch (Exception ex)
                    {
                        //For some odd reason SocketExceptions don't always get caught above, so another check
                        if (ex.GetBaseException().GetType() != typeof(SocketException))
                        {
                            //Can we catch the socketException by looking at the string error text?
                            if (ex.ToString().StartsWith("System.Net.Sockets.SocketException"))
                            {
                                LogTools.LogException(ex, "ConnectionSetupError_SE");
                            }
                            else
                            {
                                LogTools.LogException(ex, "ConnectionSetupError");
                            }
                        }
                    }
                    #endregion
                }), null);
            }
            catch (SocketException)
            {
                //If this exception gets thrown its generally just a client closing a connection almost immediately after creation
            }
            catch (Exception ex)
            {
                //For some odd reason SocketExceptions don't always get caught above, so another check
                if (ex.GetBaseException().GetType() != typeof(SocketException))
                {
                    //Can we catch the socketException by looking at the string error text?
                    if (ex.ToString().StartsWith("System.Net.Sockets.SocketException"))
                    {
                        LogTools.LogException(ex, "ConnectionSetupError_SE");
                    }
                    else
                    {
                        LogTools.LogException(ex, "ConnectionSetupError");
                    }
                }
            }
            finally
            {
                listenerInstance.BeginAcceptBluetoothClient(BluetoothConnectionReceivedAsync, null);
            }
        }
        /// <summary>
        /// Internal <see cref="BluetoothConnection"/> creation which hides the necessary internal calls
        /// </summary>
        /// <param name="connectionInfo">ConnectionInfo to be used to create connection</param>
        /// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param>
        /// <param name="btClient">If this is an incoming connection we will already have access to the btClient, otherwise use null</param>
        /// <param name="establishIfRequired">Establish during create if true</param>
        /// <returns>An existing connection or a new one</returns>
        internal static BluetoothConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, BluetoothClient btClient, bool establishIfRequired = true)
        {
            connectionInfo.ConnectionType = ConnectionType.Bluetooth;

            //If we have a tcpClient at this stage we must be server side
            if (btClient != null) connectionInfo.ServerSide = true;

            bool newConnection = false;
            BluetoothConnection connection;

            lock (NetworkComms.globalDictAndDelegateLocker)
            {
                List<Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteEndPoint, connectionInfo.LocalEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol);

                //Check to see if a connection already exists, if it does return that connection, if not return a new one
                if (existingConnections.Count > 0)
                {
                    if (NetworkComms.LoggingEnabled)
                        NetworkComms.Logger.Trace("Attempted to create new BluetoothConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead.");

                    establishIfRequired = false;
                    connection = (BluetoothConnection)existingConnections[0];
                }
                else
                {
                    if (NetworkComms.LoggingEnabled)
                        NetworkComms.Logger.Trace("Creating new BluetoothConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established."));

                    if (connectionInfo.ConnectionState == ConnectionState.Establishing)
                        throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug.");

                    //If an existing connection does not exist but the info we are using suggests it should we need to reset the info
                    //so that it can be reused correctly. This case generally happens when using NetworkComms.Net in the format 
                    //TCPConnection.GetConnection(info).SendObject(packetType, objToSend);
                    if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown)
                        connectionInfo.ResetConnectionInfo();

                    //We add a reference to networkComms for this connection within the constructor
                    connection = new BluetoothConnection(connectionInfo, defaultSendReceiveOptions, btClient);
     
                    newConnection = true;
                }
            }

            if (newConnection && establishIfRequired) connection.EstablishConnection();
            else if (!newConnection) connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS);

            if (!NetworkComms.commsShutdown) TriggerConnectionKeepAliveThread();

            return connection;
        }