예제 #1
0
        /// <summary>
        /// Parse the CoAP message stream and extract details of the token
        /// </summary>
        /// <param name="coapMsgStream">The CoAP message stream that contains the token length and value</param>
        /// <param name="startIndex">The index to start looking for the value</param>
        /// <param name="extraInfo">Not used</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapMsgStream, int startIndex, UInt16 extraInfo)
        {
            if (coapMsgStream == null || coapMsgStream.Length == 0 || startIndex < 0)
            {
                return(startIndex);                                                                     //do nothing
            }
            if (coapMsgStream.Length < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new CoAPFormatException("Invalid CoAP message stream");
            }
            if (startIndex >= coapMsgStream.Length)
            {
                throw new ArgumentException("Start index beyond message stream length");
            }

            //First get the token length...its there in bits 4-7 starting from left of first byte
            this.Length = (byte)(coapMsgStream[startIndex] & 0x0F);
            if (this.Length > 0)
            {
                //Search for token value
                int tokenValueStartIndex = 4; //Token value follows after first 4 bytes
                if (coapMsgStream.Length < (4 + this.Length))
                {
                    throw new CoAPFormatException("Invalid message stream. Token not present in the stream despite non-zero length");
                }
                byte[] tokenValue = new byte[this.Length];
                Array.Copy(coapMsgStream, tokenValueStartIndex, tokenValue, 0, this.Length);
                tokenValue = AbstractNetworkUtils.FromNetworkByteOrder(tokenValue);
                this.Value = tokenValue;
            }
            //We have parsed the token length...this finishes the byte...the index should move to next byte
            return(startIndex + 1);
        }
예제 #2
0
        /// <summary>
        /// Parse the CoAP message stream and extract message Id (in network byte order)
        /// </summary>
        /// <param name="coapMsgStream">The CoAP message stream that contains the token length and value</param>
        /// <param name="startIndex">The index to start looking for the value</param>
        /// <param name="extraInfo">Not used</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapMsgStream, int startIndex, UInt16 extraInfo)
        {
            if (coapMsgStream == null || coapMsgStream.Length == 0 || startIndex < 0)
            {
                return(startIndex);                                                                     //do nothing
            }
            if (coapMsgStream.Length < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new CoAPFormatException("Invalid CoAP message stream");
            }
            if (startIndex >= coapMsgStream.Length)
            {
                throw new ArgumentException("Start index beyond message stream length");
            }

            //We read two bytes...
            byte[] mid = { coapMsgStream[startIndex], coapMsgStream[startIndex + 1] };
            //We received them in network byte order...fix the order based on the platform
            mid   = AbstractNetworkUtils.FromNetworkByteOrder(mid);
            Value = AbstractByteUtils.ToUInt16(mid);
            return(startIndex + 2);
        }
예제 #3
0
        /// <summary>
        /// Create a header option by parsing the coap data stream
        /// </summary>
        /// <param name="coapStream">The CoAP message stream that contains the option</param>
        /// <param name="startIndex">The index to start looking for the option</param>
        /// <param name="previousOptionNumber">The previous option number in the sequence of options</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapStream, int startIndex, UInt16 previousOptionNumber)
        {
            if (coapStream == null || coapStream.Length < startIndex || startIndex < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new ArgumentNullException("CoAP stream is null or start index is invalid");
            }
            int  nextIndex    = startIndex;
            byte optionDelta  = (byte)((coapStream[nextIndex] & 0xF0) >> 4);
            byte optionLength = (byte)(coapStream[nextIndex] & 0x0F);

            UInt16 optionStreamSizeInBytes = 1;

            //Calculate option number
            if (optionDelta < 13)
            {
                this.Number = (UInt16)(optionDelta + previousOptionNumber);
            }
            else if (optionDelta == 13)
            {
                this.Number              = (UInt16)((UInt16)coapStream[++nextIndex] + 13 + previousOptionNumber);
                optionStreamSizeInBytes += 1;
            }
            else if (optionDelta == 14)
            {
                byte[] optionDeltaEx = new byte[] { coapStream[++nextIndex], coapStream[++nextIndex] };
                optionDeltaEx            = AbstractNetworkUtils.FromNetworkByteOrder(optionDeltaEx);
                this.Number              = (UInt16)(AbstractByteUtils.ToUInt16(optionDeltaEx) + (UInt16)269 + previousOptionNumber);
                optionStreamSizeInBytes += 2;
            }
            else if (optionDelta == 15)
            {
                throw new CoAPFormatException("Option delta cannot contain payload marker value");
            }

            //Calculate option value length
            if (optionLength < 13)
            {
                ValueSizeInBytes = optionLength;
            }
            else if (optionLength == 13)
            {
                ValueSizeInBytes         = (UInt16)(coapStream[++nextIndex] + 13);
                optionStreamSizeInBytes += 1;
            }
            else if (optionLength == 14)
            {
                byte[] optionLengthEx = new byte[] { coapStream[++nextIndex], coapStream[++nextIndex] };
                optionLengthEx           = AbstractNetworkUtils.FromNetworkByteOrder(optionLengthEx);
                ValueSizeInBytes         = (UInt16)(AbstractByteUtils.ToUInt16(optionLengthEx) + (UInt16)269);
                optionStreamSizeInBytes += 2;
            }
            else if (optionLength == 15)
            {
                throw new CoAPFormatException("Option length cannot be 0x0F. This is a reserved value");
            }
            //Check if option is of type uint or is empty
            if ((this.NeedsByteOrdering(this.Number) && optionLength == 0) || this.IsEmpty())
            {
                //this means that the value of the option is zero or this is an empty option
                Value = null;
            }
            else if (ValueSizeInBytes > 0) //normal processing
            {
                //Get option Value
                Value = new byte[ValueSizeInBytes];
                Array.Copy(coapStream, ++nextIndex, Value, 0, ValueSizeInBytes);
                if (this.NeedsByteOrdering(this.Number))
                {
                    Value = AbstractNetworkUtils.FromNetworkByteOrder(Value);
                }
                optionStreamSizeInBytes += ValueSizeInBytes;
            }
            return(startIndex + optionStreamSizeInBytes);
        }