示例#1
0
            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);
            }
示例#2
0
            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);
            }
示例#3
0
        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);
            }
        }
示例#4
0
            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();
                }
            }
示例#5
0
        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");
            }
        }
示例#6
0
            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;
                    }
                }
            }