private bool IsBareRequest(CoapPacket packet, byte[] payload)
        {
            var message = CoapMessage.CreateFromBytes(packet.Payload);

            if (!message.Code.IsRequest())
            {
                return(false);
            }

            if (message.Options.Get <Options.Block1>() != null)
            {
                return(false);
            }

            if (message.Options.Get <Options.Block2>() != null)
            {
                return(false);
            }

            if (payload != null && !payload.SequenceEqual(message.Payload))
            {
                return(false);
            }

            return(true);
        }
        private bool IsBlockSequence(CoapPacket packet, int blockNumber, int blockSize, bool hasMore, byte[] payload)
        {
            var message = CoapMessage.CreateFromBytes(packet.Payload);
            var block   = message.Options.Get <Options.Block1>() as Options.BlockBase
                          ?? message.Options.Get <Options.Block2>();

            if (block is Options.Block1)
            {
                if (!block.Equals(new Options.Block1(blockNumber, blockSize, hasMore)))
                {
                    return(false);
                }
                if (payload != null && !payload.SequenceEqual(message.Payload))
                {
                    return(false);
                }
            }
            else if (block is Options.Block2)
            {
                if (!block.Equals(new Options.Block2(blockNumber, blockSize, hasMore)))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #3
0
 public virtual Task SendAsync(CoapPacket packet, CancellationToken token)
 {
     Debug.WriteLine($"Writing packet {{{string.Join(", ", packet.Payload)}}} {CoapMessage.CreateFromBytes(packet.Payload)}");
     return(IsDisposed
         ? throw new CoapEndpointException("Encdpoint Disposed")
         : MockSendAsync(packet, token));
 }
Example #4
0
 public void EnqueueReceivePacket(CoapPacket packet)
 {
     lock (_receiveQueue)
     {
         _receiveQueue.Enqueue(packet);
     }
     _receiveEnqueuedEvent.Set();
 }
Example #5
0
 public Task SendAsync(CoapPacket packet, CancellationToken token)
 {
     if (!_udpTransport.IsClosed && _dtlsTransport != null)
     {
         _dtlsTransport.Send(packet.Payload, 0, packet.Payload.Length);
     }
     return(Task.CompletedTask);
 }
        public Task SendAsync(CoapPacket packet, CancellationToken token)
        {
            EnsureConnected();

            var bytes = packet.Payload;

            _datagramTransport.Send(bytes, 0, bytes.Length);
            return(Task.CompletedTask);
        }
Example #7
0
 public void EnqueueReceivePacket(CoapPacket packet)
 {
     lock (_receiveQueue)
     {
         Debug.WriteLine($"MockEndpoint: Enqueing packet {{{string.Join(", ", packet.Payload)}}} {CoapMessage.CreateFromBytes(packet.Payload)}");
         _receiveQueue.Enqueue(packet);
     }
     _receiveEnqueuedEvent.Set();
 }
        public override Task MockSendAsync(CoapPacket packet, CancellationToken token)
        {
            var request = CoapMessage.CreateFromBytes(packet.Payload);
            var block   = request.Options.Get <Block1>() as BlockBase
                          ?? request.Options.Get <Block2>();

            var blockNumber = block != null
                ? block.BlockNumber
                : 0;
            var from = block != null
                ? (block.BlockNumber * block.BlockSize)
                : 0;
            var to = block != null
                ? Math.Min(from + block.BlockSize, TotalBytes)
                : BlockSize;

            CoapMessage response;

            if (block is Block1)
            {
                if (block.BlockSize > BlockSize)
                {
                    response = BaseResponse.Clone();
                    switch (Mode)
                    {
                    case MockBlockwiseEndpointMode.ReduceBlockSize:
                        response.Options.Add(new Options.Block1(0, BlockSize, true));
                        break;

                    case MockBlockwiseEndpointMode.RequestTooLarge:
                        response.Code = CoapMessageCode.RequestEntityTooLarge;
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    response = block.IsMoreFollowing
                        ? BaseResponse.Clone()
                        : FinalResponse.Clone();

                    if (!block.IsMoreFollowing)
                    {
                        response.Options.Add(new Options.Block2(0, BlockSize, TotalBytes > BlockSize));
                        response.Payload = ByteRange(0, BlockSize);
                    }

                    response.Options.Add(new Options.Block1(block.BlockNumber, block.BlockSize, block.IsMoreFollowing));
                    response.Code = CoapMessageCode.Continue;
                }
            }
            else //if (block is Block2)
            {
                if (block != null && block.BlockSize < BlockSize)
                {
                    BlockSize = block.BlockSize;
                    to        = from + BlockSize;
                }

                response = FinalResponse.Clone();

                response.Options.Add(new Block2(blockNumber, BlockSize, to < TotalBytes));
                response.Payload = ByteRange(from, to);
            }

            response.Id    = request.Id;
            response.Token = request.Token;
            response.Type  = CoapMessageType.Acknowledgement;

            EnqueueReceivePacket(new CoapPacket {
                Payload = response.ToBytes()
            });

            return(Task.CompletedTask);
        }
Example #9
0
        public async Task SendAsync(CoapPacket packet)
        {
            if (Client == null)
            {
                await BindAsync();
            }


            CoapUdpEndPoint udpDestEndpoint;

            switch (packet.Endpoint)
            {
            case CoapUdpEndPoint udpEndPoint:
                udpDestEndpoint = udpEndPoint;
                break;

            case CoapEndpoint coapEndpoint:
                int port = coapEndpoint.BaseUri.Port;
                if (port == -1)
                {
                    port = coapEndpoint.IsSecure ? Coap.PortDTLS : Coap.Port;
                }

                IPAddress address = null;
                if (coapEndpoint.IsMulticast)
                {
                    address = _multicastAddressIPv4;
                }
                else if (coapEndpoint.BaseUri.HostNameType == UriHostNameType.IPv4 || coapEndpoint.BaseUri.HostNameType == UriHostNameType.IPv6)
                {
                    address = IPAddress.Parse(coapEndpoint.BaseUri.Host);
                }
                else if (coapEndpoint.BaseUri.HostNameType == UriHostNameType.Dns)
                {
                    // TODO: how do we select the best ip address after looking it up?
                    address = (await Dns.GetHostAddressesAsync(coapEndpoint.BaseUri.Host)).FirstOrDefault();
                }
                else
                {
                    throw new CoapUdpEndpointException($"Unsupported Uri HostNameType ({coapEndpoint.BaseUri.HostNameType:G}");
                }

                // Check is we still don't have an address
                if (address == null)
                {
                    throw new CoapUdpEndpointException($"Can not resolve host name for {coapEndpoint.BaseUri.Host}");
                }

                udpDestEndpoint = new CoapUdpEndPoint(address, port);     // TODO: Support sending to IPv6 multicast endpoints as well.


                break;

            default:
                throw new CoapUdpEndpointException($"Unsupported {nameof(CoapPacket)}.{nameof(CoapPacket.Endpoint)} type ({packet.Endpoint.GetType().FullName})");
            }

            try
            {
                await Client.SendAsync(packet.Payload, packet.Payload.Length, udpDestEndpoint.Endpoint);
            }
            catch (SocketException se)
            {
                _logger?.LogInformation($"Failed to send data. {se.GetType().FullName} (0x{se.HResult:x}): {se.Message}", se);
            }
        }
Example #10
0
 public Task SendAsync(CoapPacket packet)
 => _coapEndpoint.SendAsync(packet);
 public async Task SendAsync(CoapPacket packet, CancellationToken token)
 {
     //packet has the CoapDtlsServerClientEndPoint which we have to respond to.
     await packet.Endpoint.SendAsync(packet, token);
 }
Example #12
0
        public async Task SendAsync(CoapPacket packet, CancellationToken token)
        {
            if (Client == null)
            {
                await BindAsync();
            }


            CoapUdpEndPoint udpDestEndpoint;

            switch (packet.Endpoint)
            {
            case CoapUdpEndPoint udpEndPoint:
                udpDestEndpoint = udpEndPoint;
                break;

            case CoapEndpoint coapEndpoint:
                int port = coapEndpoint.BaseUri.Port;
                if (port == -1)
                {
                    port = coapEndpoint.IsSecure ? Coap.PortDTLS : Coap.Port;
                }

                IPAddress address = null;
                if (coapEndpoint.IsMulticast)
                {
                    address = _multicastAddressIPv4;
                }
                else if (coapEndpoint.BaseUri.HostNameType == UriHostNameType.IPv4 || coapEndpoint.BaseUri.HostNameType == UriHostNameType.IPv6)
                {
                    address = IPAddress.Parse(coapEndpoint.BaseUri.Host);
                }
                else if (coapEndpoint.BaseUri.HostNameType == UriHostNameType.Dns)
                {
                    // TODO: how do we select the best ip address after looking it up?
                    address = (await Dns.GetHostAddressesAsync(coapEndpoint.BaseUri.Host)).FirstOrDefault();
                }
                else
                {
                    throw new CoapUdpEndpointException($"Unsupported Uri HostNameType ({coapEndpoint.BaseUri.HostNameType:G}");
                }

                // Check is we still don't have an address
                if (address == null)
                {
                    throw new CoapUdpEndpointException($"Can not resolve host name for {coapEndpoint.BaseUri.Host}");
                }

                udpDestEndpoint = new CoapUdpEndPoint(address, port);     // TODO: Support sending to IPv6 multicast endpoints as well.


                break;

            default:
                throw new CoapUdpEndpointException($"Unsupported {nameof(CoapPacket)}.{nameof(CoapPacket.Endpoint)} type ({packet.Endpoint.GetType().FullName})");
            }

            token.ThrowIfCancellationRequested();

            var tcs = new TaskCompletionSource <bool>();

            using (token.Register(() => tcs.SetResult(false)))
            {
                try
                {
                    await Task.WhenAny(Client.SendAsync(packet.Payload, packet.Payload.Length, udpDestEndpoint.Endpoint), tcs.Task);

                    if (token.IsCancellationRequested)
                    {
                        Client.Dispose(); // Since UdpClient doesn't provide a mechanism for cancelling an async task. the safest way is to dispose the whole object
                    }
                }
                catch (SocketException se)
                {
                    _logger?.LogInformation($"Failed to send data. {se.GetType().FullName} (0x{se.HResult:x}): {se.Message}", se);
                }
            }

            token.ThrowIfCancellationRequested();
        }
Example #13
0
 public virtual Task MockSendAsync(CoapPacket packet)
 {
     return(Task.CompletedTask);
 }
Example #14
0
 public virtual Task SendAsync(CoapPacket packet)
 {
     return(IsDisposed
         ? throw new CoapEndpointException("Encdpoint Disposed")
         : MockSendAsync(packet));
 }
Example #15
0
 public virtual Task SendAsync(CoapPacket packet, CancellationToken token)
 {
     return(Task.CompletedTask);
 }