370 lines
10 KiB
C++
370 lines
10 KiB
C++
/*
|
|
* Copyright (c) 2016, The OpenThread Authors.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the copyright holder nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* This file includes definitions for generating and processing CoAP headers.
|
|
*/
|
|
|
|
#ifndef COAP_HEADER_HPP_
|
|
#define COAP_HEADER_HPP_
|
|
|
|
#include <string.h>
|
|
|
|
#include <common/encoding.hpp>
|
|
#include <common/message.hpp>
|
|
|
|
using Thread::Encoding::BigEndian::HostSwap16;
|
|
|
|
namespace Thread {
|
|
|
|
/**
|
|
* @namespace Thread::Coap
|
|
* @brief
|
|
* This namespace includes definitions for CoAP.
|
|
*
|
|
*/
|
|
namespace Coap {
|
|
|
|
/**
|
|
* @addtogroup core-coap
|
|
*
|
|
* @brief
|
|
* This module includes definitions for CoAP.
|
|
*
|
|
* @{
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* This class implements CoAP header generation and parsing.
|
|
*
|
|
*/
|
|
class Header
|
|
{
|
|
public:
|
|
/**
|
|
* This method initializes the CoAP header.
|
|
*
|
|
*/
|
|
void Init(void);
|
|
|
|
/**
|
|
* This method parses the CoAP header from a message.
|
|
*
|
|
* @param[in] aMessage A reference to the message.
|
|
*
|
|
* @retval kThreadError_None Successfully parsed the message.
|
|
* @retval kThreadError_Parse Failed to parse the message.
|
|
*
|
|
*/
|
|
ThreadError FromMessage(const Message &aMessage);
|
|
|
|
/**
|
|
* This method returns the Version value.
|
|
*
|
|
* @returns The Version value.
|
|
*
|
|
*/
|
|
uint8_t GetVersion(void) const { return (mHeader[0] & kVersionMask) >> kVersionOffset; }
|
|
|
|
/**
|
|
* This method sets the Version value.
|
|
*
|
|
* @param[in] aVersion The Version value.
|
|
*
|
|
*/
|
|
void SetVersion(uint8_t aVersion) { mHeader[0] &= ~kVersionMask; mHeader[0] |= aVersion << kVersionOffset; }
|
|
|
|
/**
|
|
* CoAP Type values.
|
|
*
|
|
*/
|
|
enum Type
|
|
{
|
|
kTypeConfirmable = 0x00, ///< Confirmable
|
|
kTypeNonConfirmable = 0x10, ///< Non-confirmable
|
|
kTypeAcknowledgment = 0x20, ///< Acknowledgment
|
|
kTypeReset = 0x30, ///< Reset
|
|
};
|
|
|
|
/**
|
|
* This method returns the Type value.
|
|
*
|
|
* @returns The Type value.
|
|
*
|
|
*/
|
|
Type GetType(void) const { return static_cast<Header::Type>(mHeader[0] & kTypeMask); }
|
|
|
|
/**
|
|
* This method sets the Type value.
|
|
*
|
|
* @param[in] aType The Type value.
|
|
*
|
|
*/
|
|
void SetType(Type aType) { mHeader[0] &= ~kTypeMask; mHeader[0] |= aType; }
|
|
|
|
/**
|
|
* CoAP Code values.
|
|
*
|
|
*/
|
|
enum Code
|
|
{
|
|
kCodeGet = 0x01, ///< Get
|
|
kCodePost = 0x02, ///< Post
|
|
kCodePut = 0x03, ///< Put
|
|
kCodeDelete = 0x04, ///< Delete
|
|
kCodeChanged = 0x44, ///< Changed
|
|
kCodeContent = 0x45, ///< Content
|
|
};
|
|
|
|
/**
|
|
* This method returns the Code value.
|
|
*
|
|
* @returns The Code value.
|
|
*
|
|
*/
|
|
Code GetCode(void) const { return static_cast<Code>(mCode); }
|
|
|
|
/**
|
|
* This method sets the Code value.
|
|
*
|
|
* @param[in] aCode The Code value.
|
|
*
|
|
*/
|
|
void SetCode(Code aCode) { mCode = static_cast<uint8_t>(aCode); }
|
|
|
|
/**
|
|
* This method returns the Message ID value.
|
|
*
|
|
* @returns The Message ID value.
|
|
*
|
|
*/
|
|
uint16_t GetMessageId(void) const { return HostSwap16(mMessageId); }
|
|
|
|
/**
|
|
* This method sets the Message ID value.
|
|
*
|
|
* @param[in] aMessageId The Message ID value.
|
|
*
|
|
*/
|
|
void SetMessageId(uint16_t aMessageId) { mMessageId = HostSwap16(aMessageId); }
|
|
|
|
/**
|
|
* This method returns the Token length.
|
|
*
|
|
* @returns The Token length.
|
|
*
|
|
*/
|
|
uint8_t GetTokenLength(void) const { return (mHeader[0] & kTokenLengthMask) >> kTokenLengthOffset; }
|
|
|
|
/**
|
|
* This method returns a pointer to the Token value.
|
|
*
|
|
* @returns A pointer to the Token value.
|
|
*
|
|
*/
|
|
const uint8_t *GetToken(void) const { return mHeader + kTokenOffset; }
|
|
|
|
/**
|
|
* This method sets the Token value and length.
|
|
*
|
|
* @param[in] aToken A pointer to the Token value.
|
|
* @param[in] aTokenLength The Length of @p aToken.
|
|
*
|
|
*/
|
|
void SetToken(const uint8_t *aToken, uint8_t aTokenLength) {
|
|
mHeader[0] = (mHeader[0] & ~kTokenLengthMask) | ((aTokenLength << kTokenLengthOffset) & kTokenLengthMask);
|
|
memcpy(mHeader + kTokenOffset, aToken, aTokenLength);
|
|
mHeaderLength += aTokenLength;
|
|
}
|
|
|
|
/**
|
|
* This structure represents a CoAP option.
|
|
*
|
|
*/
|
|
struct Option
|
|
{
|
|
/**
|
|
* Protocol Constants
|
|
*
|
|
*/
|
|
enum
|
|
{
|
|
kOptionDeltaOffset = 4, ///< Delta Offset
|
|
kOptionDeltaMask = 0xf << kOptionDeltaOffset, ///< Delta Mask
|
|
};
|
|
|
|
/**
|
|
* Option Numbers
|
|
*/
|
|
enum Type
|
|
{
|
|
kOptionUriPath = 11, ///< Uri-Path
|
|
kOptionContentFormat = 12, ///< Content-Format
|
|
};
|
|
|
|
uint16_t mNumber; ///< Option Number
|
|
uint16_t mLength; ///< Option Length
|
|
const uint8_t *mValue; ///< A pointer to the Option Value
|
|
};
|
|
|
|
/**
|
|
* This method appends a CoAP option.
|
|
*
|
|
* @param[in] aOption The CoAP Option.
|
|
*
|
|
* @retval kThreadError_None Successfully appended the option.
|
|
* @retval kThreadError_InvalidArgs The option type is not equal or greater than the last option type.
|
|
*
|
|
*/
|
|
ThreadError AppendOption(const Option &aOption);
|
|
|
|
/**
|
|
* This method appends a Uri-Path option.
|
|
*
|
|
* @param[in] aUriPath A pointer to a NULL-terminated string.
|
|
*
|
|
* @retval kThreadError_None Successfully appended the option.
|
|
* @retval kThreadError_InvalidArgs The option type is not equal or greater than the last option type.
|
|
*
|
|
*/
|
|
ThreadError AppendUriPathOptions(const char *aUriPath);
|
|
|
|
/**
|
|
* Media Types
|
|
*
|
|
*/
|
|
enum MediaType
|
|
{
|
|
kApplicationOctetStream = 42, ///< application/octet-stream
|
|
};
|
|
|
|
/**
|
|
* This method appends a Content-Format option.
|
|
*
|
|
* @param[in] aType The Media Type value.
|
|
*
|
|
* @retval kThreadError_None Successfully appended the option.
|
|
* @retval kThreadError_InvalidArgs The option type is not equal or greater than the last option type.
|
|
*
|
|
*/
|
|
ThreadError AppendContentFormatOption(MediaType aType);
|
|
|
|
/**
|
|
* This method returns a pointer to the current option.
|
|
*
|
|
* @returns A pointer to the current option.
|
|
*
|
|
*/
|
|
const Option *GetCurrentOption(void) const;
|
|
|
|
/**
|
|
* This method returns a pointer to the next option.
|
|
*
|
|
* @returns A pointer to the next option.
|
|
*
|
|
*/
|
|
const Option *GetNextOption(void);
|
|
|
|
/**
|
|
* This method terminates the CoAP header.
|
|
*
|
|
*/
|
|
void Finalize(void) { mHeader[mHeaderLength++] = 0xff; }
|
|
|
|
/**
|
|
* This method returns a pointer to the first byte of the header.
|
|
*
|
|
* @returns A pointer to the first byte of the header.
|
|
*
|
|
*/
|
|
const uint8_t *GetBytes(void) const { return mHeader; }
|
|
|
|
/**
|
|
* This method returns the header length in bytes.
|
|
*
|
|
* @returns The header length in bytes.
|
|
*
|
|
*/
|
|
uint8_t GetLength(void) const { return mHeaderLength; }
|
|
|
|
private:
|
|
/**
|
|
* Protocol Constants (RFC 7252).
|
|
*
|
|
*/
|
|
enum
|
|
{
|
|
kVersionMask = 0xc0, ///< Version mask as specified (RFC 7252).
|
|
kVersionOffset = 6, ///< Version offset as specified (RFC 7252).
|
|
|
|
kTokenLengthMask = 0x0f, ///< Token Length mask as specified (RFC 7252).
|
|
kTokenLengthOffset = 0, ///< Token Length offset as specified (RFC 7252).
|
|
kTokenOffset = 4, ///< Token offset as specified (RFC 7252).
|
|
kMaxTokenLength = 8, ///< Max token length as specified (RFC 7252).
|
|
|
|
kOption1ByteExtension = 13, ///< Indicates a 1 byte extension (RFC 7252).
|
|
kOption2ByteExtension = 14, ///< Indicates a 1 byte extension (RFC 7252).
|
|
|
|
kOption1ByteExtensionOffset = 13, ///< Delta/Length offset as specified (RFC 7252).
|
|
kOption2ByteExtensionOffset = 269, ///< Delta/Length offset as specified (RFC 7252).
|
|
};
|
|
|
|
enum
|
|
{
|
|
kTypeMask = 0x30,
|
|
kMinHeaderLength = 4,
|
|
kMaxHeaderLength = 128,
|
|
};
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint8_t mVersionTypeToken;
|
|
uint8_t mCode;
|
|
uint16_t mMessageId;
|
|
};
|
|
uint8_t mHeader[kMaxHeaderLength];
|
|
};
|
|
uint8_t mHeaderLength;
|
|
uint16_t mOptionLast;
|
|
uint16_t mNextOptionOffset;
|
|
Option mOption;
|
|
};
|
|
|
|
/**
|
|
* @}
|
|
*
|
|
*/
|
|
|
|
} // namespace Coap
|
|
} // namespace Thread
|
|
|
|
#endif // COAP_HEADER_HPP_
|