public async Task <Response> GetResponseAsync()
        {
            try
            {
                Response response = await _taskCompletionSource.Task;
                if (response == null)
                {
                    throw new TradfriException("Failed getting response from gateway.");
                }

                CoapCode coapCode = (CoapCode)response.Code;
                switch (coapCode)
                {
                case CoapCode.Created:
                case CoapCode.Deleted:
                case CoapCode.Valid:
                case CoapCode.Changed:
                case CoapCode.Content:
                    return(response);
                }

                throw new TradfriException("Non-successful response from gateway.", coapCode);
            }
            catch (TradfriException)
            {
                throw;
            }
            catch (Exception exception)
            {
                throw new TradfriException("Internal error communicating with the gateway.", exception);
            }
        }
 /// <summary>
 /// Returns an acknowledgement.
 /// </summary>
 /// <param name="Code">CoAP message code.</param>
 public void ACK(CoapCode Code)
 {
     this.responded = true;
     this.endpoint.Transmit(this.client, this.message.From, this.client.IsEncrypted,
                            this.message.MessageId, CoapMessageType.ACK, Code,
                            Code == CoapCode.EmptyMessage ? (ulong?)null : this.message.Token, false, null, 0, 64, this.resource, null, null, null, null);
 }
示例#3
0
 /// <summary>
 /// Returns a reset message.
 /// </summary>
 /// <param name="Code">CoAP mesasge code.</param>
 public void RST(CoapCode Code)
 {
     this.responded = true;
     this.endpoint.Transmit(this.client, this.remoteEndpoint, this.client.IsEncrypted,
                            this.request.MessageId, CoapMessageType.RST, Code,
                            Code == CoapCode.EmptyMessage ? (ulong?)null : this.request.Token, false, null, 0, 64,
                            this.resource, null, null, null, null);
 }
示例#4
0
 public CoapMessage(Int32 version, CoapType type, CoapCode code, Int32 messageID, byte[] token, List <CoapOption> options, byte[] payload)
 {
     this._version   = version;
     this._type      = type;
     this._code      = code;
     this._messageID = messageID;
     this._token     = token;
     this._options   = options;
     this._payload   = payload;
 }
示例#5
0
        /// <summary>
        /// Returns a response to the caller.
        /// </summary>
        /// <param name="Code">CoAP message code.</param>
        /// <param name="Payload">Optional payload.</param>
        /// <param name="Block2Nr">Block index to transmit.</param>
        /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param>
        /// <param name="Options">Optional options.</param>
        internal void Respond(CoapCode Code, byte[] Payload, int Block2Nr, int BlockSize,
                              params CoapOption[] Options)
        {
            this.endpoint.Transmit(this.client, this.remoteEndpoint, this.client.IsEncrypted,
                                   this.responded ? (ushort?)null : this.request.MessageId,
                                   this.ResponseType, Code, this.request.Token, false, Payload, Block2Nr, BlockSize,
                                   this.resource, null, null, null, null, CoapEndpoint.Merge(Options, this.additionalResponseOptions));

            this.responded = true;
        }
示例#6
0
 internal CoapMessage(CoapMessageType Type, CoapCode Code, ushort MessageId, ulong Token, CoapOption[] Options, byte[] Payload,
                      IPEndPoint From)
 {
     this.type      = Type;
     this.code      = Code;
     this.messageId = MessageId;
     this.token     = Token;
     this.options   = Options;
     this.payload   = Payload;
     this.from      = From;
 }
示例#7
0
        /// <summary>
        /// Returns a response to the caller.
        /// </summary>
        /// <param name="Code">CoAP message code.</param>
        /// <param name="Payload">Optional payload to be encoded.</param>
        /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param>
        /// <param name="Options">Optional options.</param>
        public void Respond(CoapCode Code, object Payload, int BlockSize, params CoapOption[] Options)
        {
            byte[] Data = CoapEndpoint.Encode(Payload, out int ContentFormat);

            if (!CoapEndpoint.HasOption(Options, 12))
            {
                Options = CoapEndpoint.Merge(Options, new CoapOptionContentFormat((ulong)ContentFormat));
            }

            this.Respond(Code, Data, BlockSize, Options);
        }
        /// <summary>
        /// Returns a reset message.
        /// </summary>
        /// <param name="Code">CoAP message code.</param>
        public void RST(CoapCode Code)
        {
            if (this.message.Type == CoapMessageType.ACK || this.message.Type == CoapMessageType.RST)
            {
                throw new IOException("You cannot respond to ACK or RST messages.");
            }

            this.responded = true;
            this.endpoint.Transmit(this.client, this.message.From, this.client.IsEncrypted,
                                   this.message.MessageId, CoapMessageType.RST, Code,
                                   Code == CoapCode.EmptyMessage ? (ulong?)null : this.message.Token, false, null, 0, 64, this.resource, null, null, null, null);
        }
示例#9
0
        public static string GetDisplayName(this CoapCode coapCode)
        {
            switch (coapCode)
            {
            case CoapCode.Created: return("2.01 Created");

            case CoapCode.Deleted: return("2.02 Deleted");

            case CoapCode.Valid: return("2.03 Valid");

            case CoapCode.Changed: return("2.04 Changed");

            case CoapCode.Content: return("2.05 Content");

            case CoapCode.BadRequest: return("4.00 Bad Request");

            case CoapCode.Unauthorized: return("4.01 Unauthorized");

            case CoapCode.BadOption: return("4.02 Bad Option");

            case CoapCode.Forbidden: return("4.03 Forbidden");

            case CoapCode.NotFound: return("4.04 Not Found");

            case CoapCode.MethodNotAllowed: return("4.05 Method Not Allowed");

            case CoapCode.NotAcceptable: return("4.06 Not Acceptable");

            case CoapCode.PreconditionFailed: return("4.12 Precondition Failed");

            case CoapCode.RequestEntityTooLarge: return("4.13 Request Entity Too Large");

            case CoapCode.UnsupportedContentFormat: return("4.15 Unsupported Content-Format");

            case CoapCode.InternalServerError: return("5.00 Internal Server Error");

            case CoapCode.NotImplemented: return("5.01 Not Implemented");

            case CoapCode.BadGateway: return("5.02 Bad Gateway");

            case CoapCode.ServiceUnavailable: return("5.03 Service Unavailable");

            case CoapCode.GatewayTimeout: return("5.04 Gateway Timeout");

            case CoapCode.ProxyingNotSupported: return("Proxying Not Supported");

            default:
                throw new ArgumentOutOfRangeException(nameof(coapCode), coapCode, null);
            }
        }
示例#10
0
        /// <summary>
        /// Returns a response to the caller.
        /// </summary>
        /// <param name="Code">CoAP message code.</param>
        /// <param name="Payload">Optional payload.</param>
        /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param>
        /// <param name="Options">Optional options.</param>
        public void Respond(CoapCode Code, byte[] Payload, int BlockSize, params CoapOption[] Options)
        {
            if (this.message.Type == CoapMessageType.ACK || this.message.Type == CoapMessageType.RST)
            {
                throw new IOException("You cannot respond to ACK or RST messages.");
            }

            int BlockNr = this.message.Block2 != null ? this.message.Block2.Number : 0;

            this.endpoint.Transmit(this.client, this.message.From, this.client.IsEncrypted,
                                   this.responded ? (ushort?)null : this.message.MessageId,
                                   this.responded ? this.message.Type : CoapMessageType.ACK, Code,
                                   this.message.Token, false, Payload, BlockNr, BlockSize, this.resource, null, null, null, null, Options);

            this.responded = true;
        }
示例#11
0
 public TradfriException(string message, CoapCode coapCode, Exception innerException)
     : base(message, innerException)
 {
     CoapCode = coapCode;
 }
示例#12
0
 public TradfriException(string message, CoapCode coapCode)
     : base(message)
 {
     CoapCode = coapCode;
 }
示例#13
0
        /// <summary>
        /// Returns a response to the caller.
        /// </summary>
        /// <param name="Code">CoAP message code.</param>
        /// <param name="Payload">Optional payload.</param>
        /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param>
        /// <param name="Options">Optional options.</param>
        public void Respond(CoapCode Code, byte[] Payload, int BlockSize, params CoapOption[] Options)
        {
            int BlockNr = this.request.Block2 != null ? this.request.Block2.Number : 0;

            this.Respond(Code, Payload, BlockNr, BlockSize, Options);
        }
示例#14
0
 /// <summary>
 /// Returns a response to the caller.
 /// </summary>
 /// <param name="Code">CoAP message code.</param>
 /// <param name="Options">Optional options.</param>
 public void Respond(CoapCode Code, params CoapOption[] Options)
 {
     this.Respond(Code, null, 64, Options);
 }
示例#15
0
 /// <summary>
 /// CoAP Exception
 /// </summary>
 /// <param name="ErrorCode">Error code.</param>
 public CoapException(CoapCode ErrorCode)
     : base("CoAP Exception: " + ErrorCode.ToString())
 {
     this.errorCode = ErrorCode;
 }
        public static CoapMessage decode(IByteBuffer buf)
        {
            byte firstByte = buf.ReadByte();

            int version = firstByte >> 6;

            if (version != 1)
            {
                throw new ArgumentException("Invalid version:" + version);
            }

            int      typeValue = (firstByte >> 4) & 2;
            CoapType type      = (CoapType)typeValue;

            int tokenLength = firstByte & 0xf;

            if (tokenLength < 0 || tokenLength > 8)
            {
                throw new ArgumentException("Invalid token length:" + tokenLength);
            }

            int codeByte  = buf.ReadByte();
            int codeValue = (codeByte >> 5) * 100;

            codeValue += codeByte & 0x1F;
            CoapCode code = (CoapCode)codeValue;

            int messageID = buf.ReadShort();

            if (messageID < 0 || messageID > 65535)
            {
                throw new ArgumentException("Invalid messageID value:" + messageID);
            }

            byte[] token = new byte[tokenLength];
            if (tokenLength > 0)
            {
                buf.ReadBytes(token, 0, tokenLength);
            }
            int number = 0;

            List <CoapOption> options = new List <CoapOption>();

            while (buf.IsReadable())
            {
                byte nextByte = buf.ReadByte();
                if (nextByte == 0xFF)
                {
                    break;
                }

                int delta = ((nextByte >> 4) & 15);
                if (delta == 13)
                {
                    delta = (delta << 8 | buf.ReadByte()) - 13;
                }
                else if (delta == 14)
                {
                    delta = (delta << 16 | buf.ReadByte() << 8 | buf.ReadByte()) - 269;
                }
                else if (delta < 0 || delta > 14)
                {
                    throw new ArgumentException("invalid option delta value:" + delta);
                }

                number += delta;
                if (number < 0)
                {
                    throw new ArgumentException("invalid negative option number:" + number + ", delta:" + delta);
                }

                int optionLength = nextByte & 15;
                if (optionLength == 13)
                {
                    optionLength = buf.ReadByte() + 13;
                }
                else if (optionLength == 14)
                {
                    optionLength = buf.ReadByte() + 269;
                }
                else if (optionLength < 0 || optionLength > 14)
                {
                    throw new ArgumentException("invalid option length");
                }

                byte[] optionValue = new byte[optionLength];
                if (optionLength > 0)
                {
                    buf.ReadBytes(optionValue, 0, optionLength);
                }

                options.Add(new CoapOption(number, optionLength, optionValue));
            }

            byte[] payload = null;
            if (buf.IsReadable())
            {
                payload = new byte[buf.ReadableBytes];
                buf.ReadBytes(payload);
            }

            return(new CoapMessage(version, type, code, messageID, token, options, payload));
        }