示例#1
0
        private void AddOption(CoapOptionNumber number, CoapOption option)
        {
            if (Options == null)
            {
                Options = new SortedDictionary <CoapOptionNumber, List <CoapOption> >();
            }

            if (Options.ContainsKey(number) == false)
            {
                Options[number] = new List <CoapOption>();
            }

            Options[number].Add(option);
        }
示例#2
0
        public void AddOption(CoapOptionNumber type, int value)
        {
            CoapOption option = new CoapOption((int)type, value);

            AddOption(type, option);
        }
示例#3
0
        public static CoapMessage FromByteArray(byte[] bytes, IPEndPoint remoteEndpoint)
        {
            int pos = 0;

            if (bytes.Length < 4)
            {
                throw new CoapMessageFormatException("Not enough data to form a valid header");
            }

            // header processing
            CoapMessage message = new CoapMessage();

            // need to do this now because we might need the endpoint and port for the url
            message.Source = remoteEndpoint;

            byte b = bytes[pos++];

            message.Version     = (byte)((b & 0xc0) >> 6);
            message.Type        = (CoapMessageType)((b & 0x30000000) >> 4);
            message.TokenLength = (byte)((b & 0x0f000000));

            if (message.TokenLength > 8)
            {
                throw new CoapMessageFormatException("Token length must be 0-8 bytes in length.");
            }

            b            = bytes[pos++];
            message.Code = (CoapMessageCode)b;

            b = bytes[pos++];
            message.MessageID = (UInt16)(b << 8);
            b = bytes[pos++];
            message.MessageID |= b;

            if (message.TokenLength > 0)
            {
                message.TokenValue = new byte[message.TokenLength];
                Array.Copy(bytes, pos, message.TokenValue, 0, message.TokenLength);
                pos += message.TokenLength;
            }

            bool processingOptions = true;
            int  optionNumber      = 0;
            int  optionLength      = 0;

            while (pos < bytes.Length && processingOptions)
            {
                if (bytes[pos] == 0xff)
                {
                    pos++;
                    processingOptions = false;

                    // process payload
                    int payloadLength = bytes.Length - pos;
                    if (payloadLength == 0)
                    {
                        throw new CoapMessageFormatException("Payload marker cannot be followed by no payload");
                    }

                    if (payloadLength > 0)
                    {
                        message.Payload = new byte[payloadLength];
                        Array.Copy(bytes, pos, message.Payload, 0, payloadLength);
                    }
                }

                if (processingOptions)
                {
                    int delta = (char)((bytes[pos] & 0xf0) >> 4);
                    optionLength = (char)(bytes[pos] & 0x0f);
                    pos++;

                    switch (delta)
                    {
                    case 13:
                    {
                        byte extendedDelta = bytes[pos++];
                        optionNumber += (extendedDelta + 13);
                    }
                    break;

                    case 14:
                    {
                        UInt16 extendedDelta = (UInt16)bytes[pos++];
                        extendedDelta <<= 8;
                        extendedDelta  |= bytes[pos++];
                        optionNumber   += (extendedDelta + 269);
                    }
                    break;

                    case 15:
                        if (bytes[pos] == 0xff)
                        {
                            processingOptions = false;
                        }
                        else
                        {
                            throw new CoapMessageFormatException("Malformed payload marker or invalid option");
                        }
                        break;

                    default:
                        optionNumber += delta;
                        break;
                    }

                    switch (optionLength)
                    {
                    case 13:
                    {
                        byte extendedLength = bytes[pos++];
                        optionLength = (extendedLength + 13);
                    }
                    break;

                    case 14:
                    {
                        UInt16 extendedLength = (UInt16)bytes[pos++];
                        extendedLength <<= 8;
                        extendedLength  |= bytes[pos++];
                        optionLength     = (extendedLength + 269);
                    }
                    break;

                    case 15:
                    {
                    }
                    break;
                    }

                    // TODO: based on table in 5.10 process options according to format and store in subclasses according to type
                    // switch (optionNumber)
                    // {
                    //     case 1:
                    //         { // If-Match - opaque - 0-8
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 3:
                    //         { // Uri-Host - string - 1-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 4:
                    //         { // ETag - opaque - 1-8
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 5:
                    //         { // If-None-Match - empty - 0
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 7:
                    //         { // Uri-Port - uint - 0-2
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 8:
                    //         { // Location-Path - string - 0-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 11:
                    //         { // Uri-Path - string - 0-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 12:
                    //         { // Content-Format - uint - 0-2
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 14:
                    //         { // Max-Age - uint - 0-4
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 15:
                    //         { // Uri-Query - string - 0-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 17:
                    //         { // Accept - uint - 0-2
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 20:
                    //         { // Location-Query - string - 0-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 35:
                    //         { // Proxy-Uri - string - 1-1034
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 39:
                    //         { // Proxy-Scheme - string - 1-255
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    //     case 60:
                    //         { // Size1 - uint - 0-4
                    //             byte[] value = new byte[optionLength];
                    //             Array.Copy(bytes, pos, value, 0, optionLength);
                    //         }
                    //         break;
                    // }

                    byte[] value = new byte[optionLength];
                    Array.Copy(bytes, pos, value, 0, optionLength);
                    pos += optionLength;

                    // add value as option
                    if (message.Options == null)
                    {
                        message.Options = new SortedDictionary <CoapOptionNumber, List <CoapOption> >();
                    }

                    if (!message.Options.ContainsKey((CoapOptionNumber)optionNumber))
                    {
                        message.Options[(CoapOptionNumber)optionNumber] = new List <CoapOption>();
                    }

                    CoapOption option = new CoapOption();
                    option.Number = optionNumber;
                    option.Length = optionLength;
                    option.Value  = value;

                    message.Options[(CoapOptionNumber)optionNumber].Add(option);
                }
            }

            // construct URL for easier processing by consumers
            message.Uri = message.ComposeUri();

            return(message);
        }