Example #1
0
        public async Task UnbindAsync()
        {
            if (_endPoint == null)
            {
                return;
            }

            var endPoint = _endPoint;

            _endPoint = null;

            endPoint.Dispose();
            await _listenTask.ConfigureAwait(false);

            _listenTask = null;
        }
Example #2
0
        public async Task UnbindAsync()
        {
            if (_endPoint == null)
            {
                return;
            }

            var endPoint = _endPoint;

            _endPoint = null;

            endPoint.Dispose();
            try
            {
                _listenTaskCTS.Cancel();
                await _listenTask.ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            { }

            _listenTask = null;
        }
Example #3
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 #4
0
 public CoapUdpTransport(CoapUdpEndPoint endPoint, ICoapHandler coapHandler, ILogger <CoapUdpTransport> logger = null)
 {
     _endPoint    = endPoint;
     _coapHandler = coapHandler;
     _logger      = logger;
 }
Example #5
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();
        }