public async Task SendAsync(DeviceAgent sender, byte[] contents) { var interval = TimeSpan.FromMilliseconds(SimulationBluetoothConstants.SEND_TICK_INTERVAL); var completionBox = new AsyncBox <bool>(); var sendEvent = new SendEvent(DateTime.Now + interval, interval, sender, completionBox, contents, 0); await ChannelsExtensions.WriteAsync(adapterEventQueueChannel, sendEvent).ConfigureAwait(false); await completionBox.GetResultAsync().ConfigureAwait(false); }
public async Task ConnectAsync(DeviceAgent sender) { var now = DateTime.Now; var connectEvent = new BeginConnectEvent(now + TimeSpan.FromMilliseconds(SimulationBluetoothConstants.BASE_HANDSHAKE_DELAY_MILLIS), sender); await ChannelsExtensions.WriteAsync(adapterEventQueueChannel, connectEvent).ConfigureAwait(false); var timeoutEvent = new TimeoutConnectEvent(now + TimeSpan.FromMilliseconds(SimulationBluetoothConstants.HANDSHAKE_TIMEOUT_MILLIS), connectEvent); await ChannelsExtensions.WriteAsync(adapterEventQueueChannel, timeoutEvent).ConfigureAwait(false); await connectEvent.ResultBox.GetResultAsync().ConfigureAwait(false); }
public async Task GiveAsync(BluetoothSocket socket) { Channel <BluetoothSocket> channel; using (await synchronization.LockAsync().ConfigureAwait(false)) { var deviceId = MacUtilities.ConvertMacToGuid(socket.RemoteDevice.Address); Console.WriteLine("INBOUND CONNECTION FROM " + deviceId + " aka " + (socket.RemoteDevice.Name ?? "[unknown]")); channel = pendingRequests.GetOrAdd(deviceId, add => ChannelFactory.Nonblocking <BluetoothSocket>()); await ChannelsExtensions.WriteAsync(channel, socket).ConfigureAwait(false); } }
private async Task HandshakeAsync(double minTimeoutSeconds) { using (await synchronization.LockAsync().ConfigureAwait(false)) { var isServer = androidBluetoothAdapter.AdapterId.CompareTo(AdapterId) > 0; // Michael's laptop is always the client as windows client doesn't understand being a server. if (Name?.Contains("DESKTOP") ?? false) { isServer = true; } if (isServer) { socket = await inboundBluetoothSocketTable.TakeAsyncOrTimeout(device).ConfigureAwait(false); } else { var socketBox = new AsyncBox <BluetoothSocket>(); new Thread(() => { try { socketBox.SetResult(device.CreateInsecureRfcommSocketToServiceRecord(CampfireNetBluetoothConstants.APP_UUID)); } catch (Exception e) { socketBox.SetException(e); } }).Start(); socket = await socketBox.GetResultAsync().ConfigureAwait(false); var connectedChannel = ChannelFactory.Nonblocking <bool>(); Go(async() => { await socket.ConnectAsync().ConfigureAwait(false); await ChannelsExtensions.WriteAsync(connectedChannel, true); }).Forget(); bool isTimeout = false; await new Select { Case(ChannelFactory.Timer(TimeSpan.FromSeconds(minTimeoutSeconds)), () => { socket.Dispose(); isTimeout = true; }), Case(connectedChannel, () => { // whee! }) }.ConfigureAwait(false); if (isTimeout) { throw new TimeoutException(); } } disconnectedChannel.SetIsClosed(false); ChannelsExtensions.Go(async() => { Console.WriteLine("Entered BT Reader Task"); var networkStream = socket.InputStream; try { while (!disconnectedChannel.IsClosed) { Console.WriteLine("Reading BT Frame"); var dataLengthBuffer = await ReadBytesAsync(networkStream, 4).ConfigureAwait(false); var dataLength = BitConverter.ToInt32(dataLengthBuffer, 0); var data = await ReadBytesAsync(networkStream, dataLength).ConfigureAwait(false); await ChannelsExtensions.WriteAsync(inboundChannel, data).ConfigureAwait(false); } } catch (Exception e) { Console.WriteLine(e); Teardown(); } }).Forget(); } }
private async Task RouterTaskStart() { var inboundChannel = neighbor.InboundChannel; try { while (true) { byte[] packetData = null; bool quit = false; await new Select { Case(ChannelFactory.Timeout(TimeSpan.FromSeconds(30)), () => quit = true), Case(inboundChannel, x => packetData = x) }.ConfigureAwait(false); if (quit) { break; } var packet = serializer.ToObject(packetData); switch (packet.GetType().Name) { case nameof(HavePacket): DebugPrint("Got HAVE {0}", ((HavePacket)packet).MerkleRootHash); await ChannelsExtensions.WriteAsync(haveChannel, (HavePacket)packet).ConfigureAwait(false); break; case nameof(NeedPacket): DebugPrint("Got NEED {0}", ((NeedPacket)packet).MerkleRootHash); await ChannelsExtensions.WriteAsync(needChannel, (NeedPacket)packet).ConfigureAwait(false); break; case nameof(GivePacket): DebugPrint("Got GIVE {0}", ((GivePacket)packet).NodeHash); var p = (GivePacket)packet; Console.WriteLine($"Recieved data hash {p.NodeHash} ({p.Node.Contents.Length} '{BitConverter.ToString(p.Node.Contents)}')"); await ChannelsExtensions.WriteAsync(giveChannel, (GivePacket)packet).ConfigureAwait(false); break; case nameof(WhoisPacket): DebugPrint("Got WHOIS {0}", ((WhoisPacket)packet).IdHash.ToHexString()); await ChannelsExtensions.WriteAsync(whoisChannel, (WhoisPacket)packet).ConfigureAwait(false); break; case nameof(IdentPacket): DebugPrint("Got IDENT {0}", ((IdentPacket)packet).Id.ToHexString()); await ChannelsExtensions.WriteAsync(identChannel, (IdentPacket)packet).ConfigureAwait(false); break; case nameof(DonePacket): DebugPrint("Got DONE"); await ChannelsExtensions.WriteAsync(doneChannel, (DonePacket)packet).ConfigureAwait(false); break; default: throw new InvalidStateException(); } } } catch (NotConnectedException e) { DebugPrint("Got NotConnectedException " + e); disconnectLatchChannel.SetIsClosed(true); try { await neighbor.SendAsync(new byte[0]).ConfigureAwait(false); throw new InvalidStateException(); } catch (NotConnectedException) { } } catch (Exception e) { DebugPrint("Got Exception " + e); throw; } finally { disconnectLatchChannel.SetIsClosed(true); neighbor.Disconnect(); DebugPrint("Router loop exiting"); } }
private async Task RunAsync() { var pendingBeginConnect = (BeginConnectEvent)null; while (true) { var adapterEvent = await adapterEventQueueChannel.ReadAsync(CancellationToken.None, x => true).ConfigureAwait(false); switch (adapterEvent.GetType().Name) { case nameof(BeginConnectEvent): var beginConnect = (BeginConnectEvent)adapterEvent; if (pendingBeginConnect == null) { pendingBeginConnect = beginConnect; } else { firstDisconnectChannel.SetIsClosed(false); secondDisconnectChannel.SetIsClosed(false); var pendingBeginConnectCapture = pendingBeginConnect; pendingBeginConnect = null; pendingBeginConnectCapture.ResultBox.SetResult(true); beginConnect.ResultBox.SetResult(true); } break; case nameof(TimeoutConnectEvent): var timeout = (TimeoutConnectEvent)adapterEvent; if (timeout.BeginEvent == pendingBeginConnect) { pendingBeginConnect.ResultBox.SetException(new TimeoutException()); pendingBeginConnect = null; } break; case nameof(SendEvent): var send = (SendEvent)adapterEvent; if (!GetIsConnected(send.Initiator)) { send.CompletionBox.SetException(new NotConnectedException()); break; } var connectivity = SimulationBluetoothCalculator.ComputeConnectivity(firstAgent, secondAgent); if (!connectivity.InRange) { firstDisconnectChannel.SetIsClosed(true); secondDisconnectChannel.SetIsClosed(true); send.CompletionBox.SetException(new NotConnectedException()); break; } var deltaBytesSent = (int)Math.Ceiling(connectivity.SignalQuality * send.Interval.TotalSeconds * SimulationBluetoothConstants.MAX_OUTBOUND_BYTES_PER_SECOND); var bytesSent = send.BytesSent + deltaBytesSent; if (bytesSent >= send.Payload.Length) { await ChannelsExtensions.WriteAsync(GetOtherInboundChannelInternal(send.Initiator), send.Payload).ConfigureAwait(false); send.CompletionBox.SetResult(true); break; } var nextEvent = new SendEvent(DateTime.Now + send.Interval, send.Interval, send.Initiator, send.CompletionBox, send.Payload, bytesSent); await adapterEventQueueChannel.WriteAsync(nextEvent, CancellationToken.None).ConfigureAwait(false); break; } } }