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