示例#1
0
        private async Task SynchronizationLoopTaskStart()
        {
            var isGreater = bluetoothAdapter.AdapterId.CompareTo(neighbor.AdapterId) > 0;
            var rateLimit = ChannelFactory.Timer(1000); //5000, 3000);

            try {
                while (true)
                {
                    if (isGreater)
                    {
                        await SynchronizeRemoteToLocalAsync().ConfigureAwait(false);
                        await SynchronizeLocalToRemoteAsync().ConfigureAwait(false);
                    }
                    else
                    {
                        await SynchronizeLocalToRemoteAsync().ConfigureAwait(false);
                        await SynchronizeRemoteToLocalAsync().ConfigureAwait(false);
                    }
                    await ChannelsExtensions.ReadAsync(rateLimit).ConfigureAwait(false);
                }
            } catch (NotConnectedException e) {
                DebugPrint("Got NotConnectedException " + e);
            } catch (Exception e) {
                DebugPrint("Got Exception " + e);
                throw;
            } finally {
                DebugPrint("Sync loop exiting");
                disconnectLatchChannel.SetIsClosed(true);
                neighbor.Disconnect();
            }
        }
示例#2
0
        public async Task CustomProcessTestAsync()
        {
            await TaskEx.YieldToThreadPool();

            ThreadPool.SetMaxThreads(128, 128);

            var cohortCount = 4;
            var cluster     = await TestUtils.CreateCluster <int, SetBox <int> >(cohortCount).ConfigureAwait(false);

            var workerCount = 100;
            var sync        = new AsyncCountdownLatch(workerCount);
            var tasks       = Util.Generate(
                workerCount,
                value => ChannelsExtensions.Go(async() => {
                sync.Signal();
                await sync.WaitAsync().ConfigureAwait(false);

                var node   = cluster[value % cohortCount];
                var result = await node.UserCache.ProcessAsync(0, SetAddEntryOperation <int, int> .Create(value)).ConfigureAwait(false);
                AssertTrue(result);
            }));

            try {
                await Task.WhenAll(tasks).ConfigureAwait(false);

                Console.WriteLine("Validating set contents");
                var result = await cluster[0].UserCache.GetAsync(0).ConfigureAwait(false);
                AssertCollectionDeepEquals(new HashSet <int>(Enumerable.Range(0, 100)), result.Value.Set);
            } catch (Exception e) {
                Console.Error.WriteLine("Test threw " + e);
                throw;
            }
        }
示例#3
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);
            }
示例#4
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);
            }
示例#5
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);
            }
        }
示例#6
0
            public async Task <bool> TryHandshakeAsync(double minTimeoutSeconds)
            {
                try {
                    using (await synchronization.LockAsync().ConfigureAwait(false)) {
                        Console.WriteLine("Attempting to connect to ID " + AdapterId + " AKA " + string.Join(" ", AdapterId.ToByteArray()));

                        bluetoothClient = new BluetoothClient();
                        bluetoothClient.Authenticate = false;
                        bluetoothClient.Encrypt      = false;

                        await bluetoothClient.ConnectAsync(address, CAMPFIRE_NET_SERVICE_CLASS).ConfigureAwait(false);

                        disconnectedChannel.SetIsClosed(false);

                        Console.WriteLine("Connected. Their Adapter ID is " + AdapterId + " AKA " + string.Join(" ", AdapterId.ToByteArray()));

                        ChannelsExtensions.Go(async() => {
                            Console.WriteLine("Entered BT Reader Task");
                            var networkStream = bluetoothClient.GetStream();
                            try {
                                while (!disconnectedChannel.IsClosed)
                                {
                                    Console.WriteLine("Reading BT Frame");
                                    var dataLengthBuffer = await ReadBytesAsync(networkStream, 4).ConfigureAwait(false);
                                    var dataLength       = BitConverter.ToInt32(dataLengthBuffer, 0);
                                    Console.WriteLine("Got BT Frame Length: " + dataLength);
                                    var data = await ReadBytesAsync(networkStream, dataLength).ConfigureAwait(false);
                                    await inboundChannel.WriteAsync(data).ConfigureAwait(false);
                                }
                            } catch (Exception e) {
                                Console.WriteLine(e);
                                Teardown();
                            }
                        }).Forget();
                        return(true);
                    }
                } catch (Exception e) {
                    Console.WriteLine("Failed to connect to ID " + AdapterId + " AKA " + string.Join(" ", AdapterId.ToByteArray()));
                    Console.WriteLine(e.GetType().FullName);
                    return(false);
                }
            }
示例#7
0
        public async Task RunAsync()
        {
            await TaskEx.YieldToThreadPool();

            ThreadPool.SetMaxThreads(128, 128);

            var cohortCount = 4;
            var cluster     = await TestUtils.CreateCluster <int, string>(cohortCount).ConfigureAwait(false);

            var workerCount = 100;
            var sync        = new AsyncCountdownLatch(workerCount);
            var tasks       = Util.Generate(
                workerCount,
                key => ChannelsExtensions.Go(async() => {
                try {
                    Console.WriteLine("Entered thread for worker of key " + key);

                    sync.Signal();
                    await sync.WaitAsync().ConfigureAwait(false);

                    const int kReadCount = 10;
                    for (var i = 0; i < kReadCount; i++)
                    {
                        var node  = cluster[i % cohortCount];
                        var entry = await node.UserCache.GetAsync(key).ConfigureAwait(false);
                        AssertEquals(key, entry.Key);
                        AssertEquals(null, entry.Value);
                        AssertFalse(entry.Exists);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine("Worker on key " + key + " threw " + e);
                    throw;
                }
            }));

            try {
                await Task.WhenAll(tasks).ConfigureAwait(false);
            } catch (Exception e) {
                Console.Error.WriteLine("Test threw " + e);
                throw;
            }
        }
示例#8
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();
                }
            }
示例#9
0
        public async Task DiscoverAsync()
        {
            var rateLimit = ChannelFactory.Timer(1000); // 5000, 5000);
            var connectedNeighborContextsByAdapterId = new ConcurrentDictionary <Guid, NeighborConnectionContext>();

            while (true)
            {
                Debug("Starting discovery round!");
                var discoveryStartTime = DateTime.Now;
                var neighbors          = await bluetoothAdapter.DiscoverAsync().ConfigureAwait(false);

                var discoveryDurationSeconds = Math.Max(10, 3 * (DateTime.Now - discoveryStartTime).TotalSeconds);
                try {
                    var neighborsToConnectTo = new List <IBluetoothNeighbor>();
                    foreach (var neighbor in neighbors)
                    {
                        if (neighbor.IsConnected)
                        {
                            Debug("Connection Candidate: {0} already connected.", neighbor.AdapterId);
                            continue;
                        }

                        if (connectedNeighborContextsByAdapterId.ContainsKey(neighbor.AdapterId))
                        {
                            Debug("Connection Candidate: {0} already has connected context.", neighbor.AdapterId);
                            continue;
                        }

                        Debug("Connection Candidate: {0} looks like a go.", neighbor.AdapterId);
                        neighborsToConnectTo.Add(neighbor);
                    }
                    await Task.WhenAll(
                        neighborsToConnectTo.Select(neighbor => ChannelsExtensions.Go(async() => {
                        Debug("Attempt to connect to: {0}", neighbor.AdapterId);
                        var connected = await neighbor.TryHandshakeAsync(discoveryDurationSeconds).ConfigureAwait(false);
                        if (!connected)
                        {
                            Debug("Failed to connect to: {0}", neighbor.AdapterId);
                            return;
                        }
                        Debug("Successfully connected to: {0}", neighbor.AdapterId);

                        //                           Console.WriteLine("Discovered neighbor: " + neighbor.AdapterId);
                        var remoteMerkleTree  = merkleTreeFactory.CreateForNeighbor(neighbor.AdapterId.ToString("N"));
                        var connectionContext = new NeighborConnectionContext(identity, bluetoothAdapter, neighbor, broadcastMessageSerializer, localMerkleTree, remoteMerkleTree);
                        connectedNeighborContextsByAdapterId.AddOrThrow(neighbor.AdapterId, connectionContext);
                        connectionContext.BroadcastReceived += HandleBroadcastReceived;
                        connectionContext.Start(() => {
                            Debug("Connection Context Torn Down: {0}", neighbor.AdapterId);

                            connectionContext.BroadcastReceived -= HandleBroadcastReceived;
                            connectedNeighborContextsByAdapterId.RemoveOrThrow(neighbor.AdapterId);
                            neighbor.Disconnect();
                        });
                    }))
                        )
                    .ConfigureAwait(false);
                } catch (Exception e) {
                    Debug("Discovery threw!");
                    Debug(e.ToString());
                }
                Debug("Ending discovery round!");
                await ChannelsExtensions.ReadAsync(rateLimit).ConfigureAwait(false);
            }
        }
 private void OnReceive(Context context, Intent intent)
 {
     ChannelsExtensions.Write(intentChannel, intent);
 }
示例#11
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");
            }
        }
示例#12
0
        private async Task SynchronizeLocalToRemoteAsync()
        {
            DebugPrint("Enter Local to Remote");

            var localRootHash = await localMerkleTree.GetRootHashAsync().ConfigureAwait(false) ?? CampfireNetHash.ZERO_HASH_BASE64;

            var havePacket = new HavePacket {
                MerkleRootHash = localRootHash
            };

            DebugPrint("SEND HAVE {0}", havePacket.MerkleRootHash);
            await neighbor.SendAsync(serializer.ToByteArray(havePacket)).ConfigureAwait(false);

            bool done = false;

            while (!done)
            {
                await new Select {
                    ChannelsExtensions.Case(doneChannel, () => {
                        done = true;
                    }),
                    ChannelsExtensions.Case(needChannel, async need => {
//                  Console.WriteLine("RECV NEED " + need.MerkleRootHash);

                        var node = await localMerkleTree.GetNodeAsync(need.MerkleRootHash).ConfigureAwait(false);
                        var give = new GivePacket {
                            NodeHash = need.MerkleRootHash,
                            Node     = node
                        };
                        DebugPrint("SEND GIVE");
                        neighbor.SendAsync(serializer.ToByteArray(give)).Forget();
                        //                  Console.WriteLine("EMIT GIVE " + need.MerkleRootHash);
                    }),
                    ChannelsExtensions.Case(whoisChannel, whois => {
                        // Ideally we send IDs one at a time. However, we are short on time so
                        // we've gone with the simple implementation.
                        var currentIdHash = whois.IdHash;
                        var trustChain    = new List <TrustChainNode>();
                        while (true)
                        {
                            var node = IdentityManager.LookupIdentity(currentIdHash);
                            trustChain.Add(node);

                            if (node.ParentId.SequenceEqual(node.ThisId))
                            {
                                break;
                            }

                            currentIdHash = node.ParentId;
                        }
                        trustChain.Reverse();

                        DebugPrint("SEND IDENT");
                        var ident = new IdentPacket {
                            Id         = trustChain.Last().ThisId,
                            TrustChain = trustChain.ToArray()
                        };
                        neighbor.SendAsync(serializer.ToByteArray(ident)).Forget();
                        Console.WriteLine("EMIT IDENT " + ident.Id.ToHexString());
                    })
                }.ConfigureAwait(false);
            }
        }
示例#13
0
        private async Task SynchronizeRemoteToLocalAsync()
        {
            DebugPrint("Enter Remote to Local");
            var have = await ChannelsExtensions.ReadAsync(haveChannel).ConfigureAwait(false);

            DebugPrint("Have is {0}", have.MerkleRootHash);
            var isRemoteRootSyncedLocally = await IsRemoteObjectHeldLocally(have.MerkleRootHash).ConfigureAwait(false);

            DebugPrint("IRRSL {0}", isRemoteRootSyncedLocally);

            if (!isRemoteRootSyncedLocally)
            {
                var nodesToImport = new List <Tuple <string, MerkleNode> >();
                var neededHashes  = new LinkedList <string>();
                neededHashes.AddLast(have.MerkleRootHash);

                while (neededHashes.Count != 0)
                {
                    var hashesReadLocally = new HashSet <string>();
                    foreach (var hash in neededHashes)
                    {
                        var localNode = await localMerkleTree.GetNodeAsync(hash).ConfigureAwait(false);

                        if (localNode != null)
                        {
                            nodesToImport.Add(Tuple.Create(hash, localNode));
                            hashesReadLocally.Add(hash);
                            continue;
                        }

                        var need = new NeedPacket {
                            MerkleRootHash = hash
                        };
                        DebugPrint("SEND NEED {0}", need.MerkleRootHash);
                        neighbor.SendAsync(serializer.ToByteArray(need)).Forget();
                    }

                    Console.WriteLine($"Found {neededHashes.Count} messages to sync");
                    foreach (var i in Enumerable.Range(0, neededHashes.Count))
                    {
                        var hash = neededHashes.First();
                        neededHashes.RemoveFirst();

                        if (hashesReadLocally.Contains(hash))
                        {
                            continue;
                        }

                        var give = await ChannelsExtensions.ReadAsync(giveChannel).ConfigureAwait(false);

                        Console.WriteLine($"Got hash {give.NodeHash}");
                        nodesToImport.Add(Tuple.Create(give.NodeHash, give.Node));

                        if (!await IsRemoteObjectHeldLocally(give.Node.LeftHash).ConfigureAwait(false))
                        {
                            neededHashes.AddLast(give.Node.LeftHash);
                        }

                        if (!await IsRemoteObjectHeldLocally(give.Node.RightHash).ConfigureAwait(false))
                        {
                            neededHashes.AddLast(give.Node.RightHash);
                        }
                    }
                }

                var broadcastMessagesByNodeHash = nodesToImport.Where(n => n.Item2.TypeTag == MerkleNodeTypeTag.Data)
                                                  .ToDictionary(
                    n => n.Item1,
                    n => broadcastMessageSerializer.Deserialize(n.Item2.Contents)
                    );
                Console.WriteLine($"Need to add {broadcastMessagesByNodeHash.Count} hashes that we don't have");

                var neededSourceIdHashes = broadcastMessagesByNodeHash.Select(kvp => kvp.Value.SourceIdHash)
                                           .GroupBy(sourceIdHash => sourceIdHash.ToHexString())
                                           .Select(g => new { Bytes = g.First(), Hex = g.Key })
                                           .Where(pair => !IdentityManager.IsKnownIdentity(pair.Bytes))
                                           .ToList();

                foreach (var neededSourceId in neededSourceIdHashes)
                {
                    var whois = new WhoisPacket {
                        IdHash = neededSourceId.Bytes
                    };
                    DebugPrint("SEND WHOIS {0}", neededSourceId.Hex);
                    neighbor.SendAsync(serializer.ToByteArray(whois)).Forget();
                }

                foreach (var i in Enumerable.Range(0, neededSourceIdHashes.Count))
                {
                    var ident = await ChannelsExtensions.ReadAsync(identChannel).ConfigureAwait(false);

                    Identity.ValidateAndAdd(ident.TrustChain);
                }

                foreach (var neededSourceId in neededSourceIdHashes)
                {
                    if (!IdentityManager.IsKnownIdentity(neededSourceId.Bytes))
                    {
                        throw new InvalidStateException();
                    }
                }

                foreach (var tuple in nodesToImport)
                {
                    var node = tuple.Item2;
                    if (node.Descendents == 0 && await localMerkleTree.GetNodeAsync(tuple.Item1).ConfigureAwait(false) == null)
                    {
                        var isDataNode = node.TypeTag == MerkleNodeTypeTag.Data;
                        BroadcastMessageDto message = isDataNode ? broadcastMessageSerializer.Deserialize(node.Contents) : null;

                        var sender = IdentityManager.LookupIdentity(message.SourceIdHash);
                        if (message.DestinationIdHash.All(val => val == 0))
                        {
                            if ((sender.HeldPermissions & Permission.Broadcast) == 0)
                            {
                                Console.WriteLine("Sender does not have broadcast permissions. Malicious peer!");
                                throw new InvalidStateException();
                            }
                        }
                        else
                        {
                            if ((sender.HeldPermissions & Permission.Unicast) == 0)
                            {
                                Console.WriteLine("Sender does not have unicast permissions. Malicious peer!");
                                throw new InvalidStateException();
                            }
                        }
                    }
                }

                await remoteMerkleTree.ImportAsync(have.MerkleRootHash, nodesToImport).ConfigureAwait(false);

                Console.WriteLine($"Currently have {nodesToImport.Count} nodes to import still");

                foreach (var tuple in nodesToImport)
                {
                    var node = tuple.Item2;
                    if (node.Descendents == 0 && await localMerkleTree.GetNodeAsync(tuple.Item1).ConfigureAwait(false) == null)
                    {
                        var isDataNode = node.TypeTag == MerkleNodeTypeTag.Data;
                        BroadcastMessageDto message = isDataNode ? broadcastMessageSerializer.Deserialize(node.Contents) : null;

                        Console.WriteLine("Got data node");

                        var insertionResult = await localMerkleTree.TryInsertAsync(tuple.Item2).ConfigureAwait(false);

                        if (insertionResult.Item1 && isDataNode)
                        {
                            byte[] decryptedPayload;
                            Console.WriteLine("Got a message");
                            if (identity.TryDecodePayload(message, out decryptedPayload))
                            {
                                BroadcastReceived?.Invoke(new MessageReceivedEventArgs(neighbor, new BroadcastMessage {
                                    SourceId         = IdentityHash.GetFlyweight(message.SourceIdHash),
                                    DestinationId    = IdentityHash.GetFlyweight(message.DestinationIdHash),
                                    DecryptedPayload = decryptedPayload,
                                    Dto = message
                                }));
                            }
                        }
                    }
                }
            }

            DebugPrint("SEND DONE");
            await neighbor.SendAsync(serializer.ToByteArray(new DonePacket())).ConfigureAwait(false);
        }
示例#14
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;
                    }
                }
            }