This is CoAP library with a focus on simplicity. It offers minimal CoAP PDU construction and decoding to and from byte buffers.

Committer:
ashleymills
Date:
Thu Jan 30 14:07:56 2014 +0000
Revision:
1:5eec2844ad47
Parent:
0:3d62a105fd34
Updated to sync with github version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 1:5eec2844ad47 1 /**
ashleymills 1:5eec2844ad47 2 Copyright (c) 2013, Ashley Mills.
ashleymills 1:5eec2844ad47 3 All rights reserved.
ashleymills 0:3d62a105fd34 4
ashleymills 1:5eec2844ad47 5 Redistribution and use in source and binary forms, with or without
ashleymills 1:5eec2844ad47 6 modification, are permitted provided that the following conditions are met:
ashleymills 1:5eec2844ad47 7
ashleymills 1:5eec2844ad47 8 1. Redistributions of source code must retain the above copyright notice, this
ashleymills 1:5eec2844ad47 9 list of conditions and the following disclaimer.
ashleymills 1:5eec2844ad47 10 2. Redistributions in binary form must reproduce the above copyright notice,
ashleymills 1:5eec2844ad47 11 this list of conditions and the following disclaimer in the documentation
ashleymills 1:5eec2844ad47 12 and/or other materials provided with the distribution.
ashleymills 0:3d62a105fd34 13
ashleymills 1:5eec2844ad47 14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ashleymills 1:5eec2844ad47 15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
ashleymills 1:5eec2844ad47 16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ashleymills 1:5eec2844ad47 17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ashleymills 1:5eec2844ad47 18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
ashleymills 1:5eec2844ad47 19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
ashleymills 1:5eec2844ad47 20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ashleymills 1:5eec2844ad47 21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
ashleymills 1:5eec2844ad47 22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
ashleymills 1:5eec2844ad47 23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ashleymills 1:5eec2844ad47 24 */
ashleymills 1:5eec2844ad47 25
ashleymills 1:5eec2844ad47 26 #pragma once
ashleymills 1:5eec2844ad47 27
ashleymills 1:5eec2844ad47 28 #include <stdint.h>
ashleymills 0:3d62a105fd34 29
ashleymills 0:3d62a105fd34 30 #define COAP_HDR_SIZE 4
ashleymills 0:3d62a105fd34 31 #define COAP_OPTION_HDR_BYTE 1
ashleymills 0:3d62a105fd34 32
ashleymills 0:3d62a105fd34 33 // CoAP PDU format
ashleymills 0:3d62a105fd34 34
ashleymills 0:3d62a105fd34 35 // 0 1 2 3
ashleymills 0:3d62a105fd34 36 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
ashleymills 0:3d62a105fd34 37 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ashleymills 0:3d62a105fd34 38 // |Ver| T | TKL | Code | Message ID |
ashleymills 0:3d62a105fd34 39 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ashleymills 0:3d62a105fd34 40 // | Token (if any, TKL bytes) ...
ashleymills 0:3d62a105fd34 41 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ashleymills 0:3d62a105fd34 42 // | Options (if any) ...
ashleymills 0:3d62a105fd34 43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ashleymills 0:3d62a105fd34 44 // |1 1 1 1 1 1 1 1| Payload (if any) ...
ashleymills 0:3d62a105fd34 45 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ashleymills 0:3d62a105fd34 46
ashleymills 0:3d62a105fd34 47 class CoapPDU {
ashleymills 0:3d62a105fd34 48
ashleymills 0:3d62a105fd34 49
ashleymills 0:3d62a105fd34 50 public:
ashleymills 0:3d62a105fd34 51 /// CoAP message types. Note, values only work as enum.
ashleymills 0:3d62a105fd34 52 enum Type {
ashleymills 0:3d62a105fd34 53 COAP_CONFIRMABLE=0x00,
ashleymills 0:3d62a105fd34 54 COAP_NON_CONFIRMABLE=0x10,
ashleymills 0:3d62a105fd34 55 COAP_ACKNOWLEDGEMENT=0x20,
ashleymills 0:3d62a105fd34 56 COAP_RESET=0x30
ashleymills 0:3d62a105fd34 57 };
ashleymills 0:3d62a105fd34 58
ashleymills 0:3d62a105fd34 59 // CoAP response codes.
ashleymills 0:3d62a105fd34 60 enum Code {
ashleymills 0:3d62a105fd34 61 COAP_EMPTY=0x00,
ashleymills 0:3d62a105fd34 62 COAP_GET,
ashleymills 0:3d62a105fd34 63 COAP_POST,
ashleymills 0:3d62a105fd34 64 COAP_PUT,
ashleymills 0:3d62a105fd34 65 COAP_DELETE,
ashleymills 0:3d62a105fd34 66 COAP_CREATED=0x41,
ashleymills 0:3d62a105fd34 67 COAP_DELETED,
ashleymills 0:3d62a105fd34 68 COAP_VALID,
ashleymills 0:3d62a105fd34 69 COAP_CHANGED,
ashleymills 0:3d62a105fd34 70 COAP_CONTENT,
ashleymills 0:3d62a105fd34 71 COAP_BAD_REQUEST=0x80,
ashleymills 0:3d62a105fd34 72 COAP_UNAUTHORIZED,
ashleymills 0:3d62a105fd34 73 COAP_BAD_OPTION,
ashleymills 0:3d62a105fd34 74 COAP_FORBIDDEN,
ashleymills 0:3d62a105fd34 75 COAP_NOT_FOUND,
ashleymills 0:3d62a105fd34 76 COAP_METHOD_NOT_ALLOWED,
ashleymills 0:3d62a105fd34 77 COAP_NOT_ACCEPTABLE,
ashleymills 0:3d62a105fd34 78 COAP_PRECONDITION_FAILED=0x8C,
ashleymills 0:3d62a105fd34 79 COAP_REQUEST_ENTITY_TOO_LARGE=0x8D,
ashleymills 0:3d62a105fd34 80 COAP_UNSUPPORTED_CONTENT_FORMAT=0x8F,
ashleymills 0:3d62a105fd34 81 COAP_INTERNAL_SERVER_ERROR=0xA0,
ashleymills 0:3d62a105fd34 82 COAP_NOT_IMPLEMENTED,
ashleymills 0:3d62a105fd34 83 COAP_BAD_GATEWAY,
ashleymills 0:3d62a105fd34 84 COAP_SERVICE_UNAVAILABLE,
ashleymills 0:3d62a105fd34 85 COAP_GATEWAY_TIMEOUT,
ashleymills 1:5eec2844ad47 86 COAP_PROXYING_NOT_SUPPORTED,
ashleymills 1:5eec2844ad47 87 COAP_UNDEFINED_CODE=0xFF
ashleymills 0:3d62a105fd34 88 };
ashleymills 0:3d62a105fd34 89
ashleymills 0:3d62a105fd34 90 /// CoAP option numbers.
ashleymills 0:3d62a105fd34 91 enum Option {
ashleymills 0:3d62a105fd34 92 COAP_OPTION_IF_MATCH=1,
ashleymills 0:3d62a105fd34 93 COAP_OPTION_URI_HOST=3,
ashleymills 0:3d62a105fd34 94 COAP_OPTION_ETAG,
ashleymills 0:3d62a105fd34 95 COAP_OPTION_IF_NONE_MATCH,
ashleymills 0:3d62a105fd34 96 COAP_OPTION_OBSERVE,
ashleymills 0:3d62a105fd34 97 COAP_OPTION_URI_PORT,
ashleymills 0:3d62a105fd34 98 COAP_OPTION_LOCATION_PATH,
ashleymills 0:3d62a105fd34 99 COAP_OPTION_URI_PATH=11,
ashleymills 0:3d62a105fd34 100 COAP_OPTION_CONTENT_FORMAT,
ashleymills 0:3d62a105fd34 101 COAP_OPTION_MAX_AGE=14,
ashleymills 0:3d62a105fd34 102 COAP_OPTION_URI_QUERY,
ashleymills 0:3d62a105fd34 103 COAP_OPTION_ACCEPT=17,
ashleymills 0:3d62a105fd34 104 COAP_OPTION_LOCATION_QUERY=20,
ashleymills 0:3d62a105fd34 105 COAP_OPTION_BLOCK2=23,
ashleymills 0:3d62a105fd34 106 COAP_OPTION_BLOCK1=27,
ashleymills 0:3d62a105fd34 107 COAP_OPTION_SIZE2,
ashleymills 0:3d62a105fd34 108 COAP_OPTION_PROXY_URI=35,
ashleymills 0:3d62a105fd34 109 COAP_OPTION_PROXY_SCHEME=39,
ashleymills 0:3d62a105fd34 110 COAP_OPTION_SIZE1=60
ashleymills 0:3d62a105fd34 111 };
ashleymills 0:3d62a105fd34 112
ashleymills 0:3d62a105fd34 113 /// CoAP content-formats.
ashleymills 0:3d62a105fd34 114 enum ContentFormat {
ashleymills 0:3d62a105fd34 115 COAP_CONTENT_FORMAT_TEXT_PLAIN = 0,
ashleymills 0:3d62a105fd34 116 COAP_CONTENT_FORMAT_APP_LINK = 40,
ashleymills 0:3d62a105fd34 117 COAP_CONTENT_FORMAT_APP_XML,
ashleymills 0:3d62a105fd34 118 COAP_CONTENT_FORMAT_APP_OCTET,
ashleymills 0:3d62a105fd34 119 COAP_CONTENT_FORMAT_APP_EXI = 47,
ashleymills 0:3d62a105fd34 120 COAP_CONTENT_FORMAT_APP_JSON = 50
ashleymills 0:3d62a105fd34 121 };
ashleymills 0:3d62a105fd34 122
ashleymills 0:3d62a105fd34 123 /// Sequence of these is returned by CoapPDU::getOptions()
ashleymills 0:3d62a105fd34 124 struct CoapOption {
ashleymills 0:3d62a105fd34 125 uint16_t optionDelta;
ashleymills 0:3d62a105fd34 126 uint16_t optionNumber;
ashleymills 0:3d62a105fd34 127 uint16_t optionValueLength;
ashleymills 0:3d62a105fd34 128 int totalLength;
ashleymills 0:3d62a105fd34 129 uint8_t *optionPointer;
ashleymills 0:3d62a105fd34 130 uint8_t *optionValuePointer;
ashleymills 0:3d62a105fd34 131 };
ashleymills 0:3d62a105fd34 132
ashleymills 0:3d62a105fd34 133 // construction and destruction
ashleymills 0:3d62a105fd34 134 CoapPDU();
ashleymills 0:3d62a105fd34 135 CoapPDU(uint8_t *pdu, int pduLength);
ashleymills 0:3d62a105fd34 136 CoapPDU(uint8_t *buffer, int bufferLength, int pduLength);
ashleymills 0:3d62a105fd34 137 ~CoapPDU();
ashleymills 0:3d62a105fd34 138 int reset();
ashleymills 0:3d62a105fd34 139 int validate();
ashleymills 0:3d62a105fd34 140
ashleymills 0:3d62a105fd34 141 // version
ashleymills 0:3d62a105fd34 142 int setVersion(uint8_t version);
ashleymills 0:3d62a105fd34 143 uint8_t getVersion();
ashleymills 0:3d62a105fd34 144
ashleymills 0:3d62a105fd34 145 // message type
ashleymills 0:3d62a105fd34 146 void setType(CoapPDU::Type type);
ashleymills 0:3d62a105fd34 147 CoapPDU::Type getType();
ashleymills 0:3d62a105fd34 148
ashleymills 0:3d62a105fd34 149 // tokens
ashleymills 0:3d62a105fd34 150 int setTokenLength(uint8_t tokenLength);
ashleymills 0:3d62a105fd34 151 int getTokenLength();
ashleymills 0:3d62a105fd34 152 uint8_t* getTokenPointer();
ashleymills 0:3d62a105fd34 153 int setToken(uint8_t *token, uint8_t tokenLength);
ashleymills 0:3d62a105fd34 154
ashleymills 0:3d62a105fd34 155 // message code
ashleymills 0:3d62a105fd34 156 void setCode(CoapPDU::Code code);
ashleymills 0:3d62a105fd34 157 CoapPDU::Code getCode();
ashleymills 1:5eec2844ad47 158 CoapPDU::Code httpStatusToCode(int httpStatus);
ashleymills 0:3d62a105fd34 159
ashleymills 0:3d62a105fd34 160 // message ID
ashleymills 0:3d62a105fd34 161 int setMessageID(uint16_t messageID);
ashleymills 0:3d62a105fd34 162 uint16_t getMessageID();
ashleymills 0:3d62a105fd34 163
ashleymills 0:3d62a105fd34 164 // options
ashleymills 0:3d62a105fd34 165 int addOption(uint16_t optionNumber, uint16_t optionLength, uint8_t *optionValue);
ashleymills 0:3d62a105fd34 166 // gets a list of all options
ashleymills 0:3d62a105fd34 167 CoapOption* getOptions();
ashleymills 0:3d62a105fd34 168 int getNumOptions();
ashleymills 0:3d62a105fd34 169 // shorthand helpers
ashleymills 1:5eec2844ad47 170 int setURI(char *uri);
ashleymills 0:3d62a105fd34 171 int setURI(char *uri, int urilen);
ashleymills 0:3d62a105fd34 172 int getURI(char *dst, int dstlen, int *outLen);
ashleymills 1:5eec2844ad47 173 int addURIQuery(char *query);
ashleymills 0:3d62a105fd34 174
ashleymills 0:3d62a105fd34 175 // content format helper
ashleymills 0:3d62a105fd34 176 int setContentFormat(CoapPDU::ContentFormat format);
ashleymills 0:3d62a105fd34 177
ashleymills 0:3d62a105fd34 178 // payload
ashleymills 0:3d62a105fd34 179 uint8_t* mallocPayload(int bytes);
ashleymills 0:3d62a105fd34 180 int setPayload(uint8_t *value, int len);
ashleymills 0:3d62a105fd34 181 uint8_t* getPayloadPointer();
ashleymills 0:3d62a105fd34 182 int getPayloadLength();
ashleymills 0:3d62a105fd34 183 uint8_t* getPayloadCopy();
ashleymills 0:3d62a105fd34 184
ashleymills 0:3d62a105fd34 185 // pdu
ashleymills 0:3d62a105fd34 186 int getPDULength();
ashleymills 0:3d62a105fd34 187 uint8_t* getPDUPointer();
ashleymills 0:3d62a105fd34 188 void setPDULength(int len);
ashleymills 0:3d62a105fd34 189
ashleymills 0:3d62a105fd34 190 // debugging
ashleymills 0:3d62a105fd34 191 static void printBinary(uint8_t b);
ashleymills 0:3d62a105fd34 192 void print();
ashleymills 0:3d62a105fd34 193 void printBin();
ashleymills 0:3d62a105fd34 194 void printHex();
ashleymills 0:3d62a105fd34 195 void printOptionHuman(uint8_t *option);
ashleymills 0:3d62a105fd34 196 void printHuman();
ashleymills 0:3d62a105fd34 197 void printPDUAsCArray();
ashleymills 0:3d62a105fd34 198
ashleymills 0:3d62a105fd34 199 private:
ashleymills 0:3d62a105fd34 200 // variables
ashleymills 0:3d62a105fd34 201 uint8_t *_pdu;
ashleymills 0:3d62a105fd34 202 int _pduLength;
ashleymills 0:3d62a105fd34 203
ashleymills 0:3d62a105fd34 204 int _constructedFromBuffer;
ashleymills 0:3d62a105fd34 205 int _bufferLength;
ashleymills 0:3d62a105fd34 206
ashleymills 0:3d62a105fd34 207 uint8_t *_payloadPointer;
ashleymills 0:3d62a105fd34 208 int _payloadLength;
ashleymills 0:3d62a105fd34 209
ashleymills 0:3d62a105fd34 210 int _numOptions;
ashleymills 0:3d62a105fd34 211 uint16_t _maxAddedOptionNumber;
ashleymills 0:3d62a105fd34 212
ashleymills 0:3d62a105fd34 213 // functions
ashleymills 0:3d62a105fd34 214 void shiftPDUUp(int shiftOffset, int shiftAmount);
ashleymills 0:3d62a105fd34 215 void shiftPDUDown(int startLocation, int shiftOffset, int shiftAmount);
ashleymills 0:3d62a105fd34 216 uint8_t codeToValue(CoapPDU::Code c);
ashleymills 0:3d62a105fd34 217
ashleymills 0:3d62a105fd34 218 // option stuff
ashleymills 0:3d62a105fd34 219 int findInsertionPosition(uint16_t optionNumber, uint16_t *prevOptionNumber);
ashleymills 0:3d62a105fd34 220 int computeExtraBytes(uint16_t n);
ashleymills 0:3d62a105fd34 221 int insertOption(int insertionPosition, uint16_t optionDelta, uint16_t optionValueLength, uint8_t *optionValue);
ashleymills 0:3d62a105fd34 222 uint16_t getOptionDelta(uint8_t *option);
ashleymills 0:3d62a105fd34 223 void setOptionDelta(int optionPosition, uint16_t optionDelta);
ashleymills 0:3d62a105fd34 224 uint16_t getOptionValueLength(uint8_t *option);
ashleymills 0:3d62a105fd34 225
ashleymills 0:3d62a105fd34 226 };
ashleymills 0:3d62a105fd34 227
ashleymills 0:3d62a105fd34 228 /*
ashleymills 0:3d62a105fd34 229 #define COAP_CODE_EMPTY 0x00
ashleymills 0:3d62a105fd34 230
ashleymills 0:3d62a105fd34 231 // method codes 0.01-0.31
ashleymills 0:3d62a105fd34 232 #define COAP_CODE_GET 0x01
ashleymills 0:3d62a105fd34 233 #define COAP_CODE_POST 0x02
ashleymills 0:3d62a105fd34 234 #define COAP_CODE_PUT 0x03
ashleymills 0:3d62a105fd34 235 #define COAP_CODE_DELETE 0x04
ashleymills 0:3d62a105fd34 236
ashleymills 0:3d62a105fd34 237 // Response codes 2.00 - 5.31
ashleymills 0:3d62a105fd34 238 // 2.00 - 2.05
ashleymills 0:3d62a105fd34 239 #define COAP_CODE_CREATED 0x41
ashleymills 0:3d62a105fd34 240 #define COAP_CODE_DELETED 0x42
ashleymills 0:3d62a105fd34 241 #define COAP_CODE_VALID 0x43
ashleymills 0:3d62a105fd34 242 #define COAP_CODE_CHANGED 0x44
ashleymills 0:3d62a105fd34 243 #define COAP_CODE_CONTENT 0x45
ashleymills 0:3d62a105fd34 244
ashleymills 0:3d62a105fd34 245 // 4.00 - 4.15
ashleymills 0:3d62a105fd34 246 #define COAP_CODE_BAD_REQUEST 0x80
ashleymills 0:3d62a105fd34 247 #define COAP_CODE_UNAUTHORIZED 0x81
ashleymills 0:3d62a105fd34 248 #define COAP_CODE_BAD_OPTION 0x82
ashleymills 0:3d62a105fd34 249 #define COAP_CODE_FORBIDDEN 0x83
ashleymills 0:3d62a105fd34 250 #define COAP_CODE_NOT_FOUND 0x84
ashleymills 0:3d62a105fd34 251 #define COAP_CODE_METHOD_NOT_ALLOWED 0x85
ashleymills 0:3d62a105fd34 252 #define COAP_CODE_NOT_ACCEPTABLE 0x86
ashleymills 0:3d62a105fd34 253 #define COAP_CODE_PRECONDITION_FAILED 0x8C
ashleymills 0:3d62a105fd34 254 #define COAP_CODE_REQUEST_ENTITY_TOO_LARGE 0x8D
ashleymills 0:3d62a105fd34 255 #define COAP_CODE_UNSUPPORTED_CONTENT_FORMAT 0x8F
ashleymills 0:3d62a105fd34 256
ashleymills 0:3d62a105fd34 257 // 5.00 - 5.05
ashleymills 0:3d62a105fd34 258 #define COAP_CODE_INTERNAL_SERVER_ERROR 0xA0
ashleymills 0:3d62a105fd34 259 #define COAP_CODE_NOT_IMPLEMENTED 0xA1
ashleymills 0:3d62a105fd34 260 #define COAP_CODE_BAD_GATEWAY 0xA2
ashleymills 0:3d62a105fd34 261 #define COAP_CODE_SERVICE_UNAVAILABLE 0xA3
ashleymills 0:3d62a105fd34 262 #define COAP_CODE_GATEWAY_TIMEOUT 0xA4
ashleymills 0:3d62a105fd34 263 #define COAP_CODE_PROXYING_NOT_SUPPORTED 0xA5
ashleymills 1:5eec2844ad47 264 */