liubin | 281ac46 | 2023-07-19 14:22:54 +0800 | [diff] [blame] | 1 |
|
| 2 | #ifndef __MBTK_COAP_H__
|
| 3 | #define __MBTK_COAP_H__
|
| 4 | #include <stdint.h>
|
| 5 | //#include "ps_in.h"
|
| 6 | #include "ds_ASBuffer.h"
|
| 7 | #include "mbtk_type.h"
|
| 8 |
|
| 9 | #define COAP_HDR_SIZE 4
|
| 10 | #define COAP_OPTION_HDR_BYTE 1
|
| 11 |
|
| 12 | typedef unsigned char uint8_t;
|
| 13 | typedef unsigned short uint16_t;
|
| 14 | //typedef unsigned long uint32_t;
|
| 15 | typedef unsigned long long uint64_t;
|
| 16 |
|
| 17 | /*
|
| 18 | enum ds_appsrv_mem_e_type { APPSRV_MEM };
|
| 19 |
|
| 20 | void* operator new(unsigned int size, void* alloc, ds_appsrv_mem_e_type mem_type) throw();
|
| 21 | void operator delete(void* obj, void* alloc, ds_appsrv_mem_e_type mem_type) throw();
|
| 22 | */
|
| 23 |
|
| 24 | #define ps_ntohs(x) \
|
| 25 | (((((uint16)(x) & 0x00FF) << 8) | (((uint16)(x) & 0xFF00) >> 8)))
|
| 26 |
|
| 27 |
|
| 28 | #define endian_be16(x) ps_ntohs(x)
|
| 29 |
|
| 30 | #define endian_load16(cast, from) ((cast)( \
|
| 31 | (((uint16_t)((uint8_t*)(from))[0]) << 8) | \
|
| 32 | (((uint16_t)((uint8_t*)(from))[1]) ) ))
|
| 33 |
|
| 34 | #define endian_load32(cast, from) ((cast)( \
|
| 35 | (((uint32_t)((uint8_t*)(from))[0]) << 24) | \
|
| 36 | (((uint32_t)((uint8_t*)(from))[1]) << 16) | \
|
| 37 | (((uint32_t)((uint8_t*)(from))[2]) << 8) | \
|
| 38 | (((uint32_t)((uint8_t*)(from))[3]) ) ))
|
| 39 |
|
| 40 | #define endian_load64(cast, from) ((cast)( \
|
| 41 | (((uint64_t)((uint8_t*)(from))[0]) << 56) | \
|
| 42 | (((uint64_t)((uint8_t*)(from))[1]) << 48) | \
|
| 43 | (((uint64_t)((uint8_t*)(from))[2]) << 40) | \
|
| 44 | (((uint64_t)((uint8_t*)(from))[3]) << 32) | \
|
| 45 | (((uint64_t)((uint8_t*)(from))[4]) << 24) | \
|
| 46 | (((uint64_t)((uint8_t*)(from))[5]) << 16) | \
|
| 47 | (((uint64_t)((uint8_t*)(from))[6]) << 8) | \
|
| 48 | (((uint64_t)((uint8_t*)(from))[7]) ) ))
|
| 49 |
|
| 50 | #define endian_store16(to, num) \
|
| 51 | do { uint16_t val = endian_be16(num); memcpy(to, &val, 2); } while(0)
|
| 52 |
|
| 53 | // CoAP PDU format
|
| 54 |
|
| 55 | // 0 1 2 3
|
| 56 | // 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
|
| 57 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| 58 | // |Ver| T | TKL | Code | Message ID |
|
| 59 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| 60 | // | Token (if any, TKL bytes) ...
|
| 61 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| 62 | // | Options (if any) ...
|
| 63 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| 64 | // |1 1 1 1 1 1 1 1| Payload (if any) ...
|
| 65 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| 66 |
|
| 67 | class CoapPDU
|
| 68 | {
|
| 69 |
|
| 70 |
|
| 71 | public:
|
| 72 | /// CoAP message types. Note, values only work as enum.
|
| 73 | enum Type
|
| 74 | {
|
| 75 | COAP_CONFIRMABLE=0x00,
|
| 76 | COAP_NON_CONFIRMABLE=0x10,
|
| 77 | COAP_ACKNOWLEDGEMENT=0x20,
|
| 78 | COAP_RESET=0x30
|
| 79 | };
|
| 80 |
|
| 81 | // CoAP response codes.
|
| 82 | enum Code
|
| 83 | {
|
| 84 | COAP_EMPTY=0x00,
|
| 85 | COAP_GET,
|
| 86 | COAP_POST,
|
| 87 | COAP_PUT,
|
| 88 | COAP_DELETE,
|
| 89 | COAP_LASTMETHOD=0x1F,
|
| 90 | COAP_CREATED=0x41,
|
| 91 | COAP_DELETED,
|
| 92 | COAP_VALID,
|
| 93 | COAP_CHANGED,
|
| 94 | COAP_CONTENT,
|
| 95 | COAP_CONTINUE=0x5F,
|
| 96 | COAP_BAD_REQUEST=0x80,
|
| 97 | COAP_UNAUTHORIZED,
|
| 98 | COAP_BAD_OPTION,
|
| 99 | COAP_FORBIDDEN,
|
| 100 | COAP_NOT_FOUND,
|
| 101 | COAP_METHOD_NOT_ALLOWED,
|
| 102 | COAP_NOT_ACCEPTABLE,
|
| 103 | COAP_PRECONDITION_FAILED=0x8C,
|
| 104 | COAP_REQUEST_ENTITY_TOO_LARGE=0x8D,
|
| 105 | COAP_UNSUPPORTED_CONTENT_FORMAT=0x8F,
|
| 106 | COAP_INTERNAL_SERVER_ERROR=0xA0,
|
| 107 | COAP_NOT_IMPLEMENTED,
|
| 108 | COAP_BAD_GATEWAY,
|
| 109 | COAP_SERVICE_UNAVAILABLE,
|
| 110 | COAP_GATEWAY_TIMEOUT,
|
| 111 | COAP_PROXYING_NOT_SUPPORTED,
|
| 112 | COAP_UNDEFINED_CODE=0xFF
|
| 113 | };
|
| 114 |
|
| 115 | /// CoAP option numbers.
|
| 116 | enum Option
|
| 117 | {
|
| 118 | COAP_OPTION_IF_MATCH=1,
|
| 119 | COAP_OPTION_URI_HOST=3,
|
| 120 | COAP_OPTION_ETAG,
|
| 121 | COAP_OPTION_IF_NONE_MATCH,
|
| 122 | COAP_OPTION_OBSERVE,
|
| 123 | COAP_OPTION_URI_PORT,
|
| 124 | COAP_OPTION_LOCATION_PATH,
|
| 125 | COAP_OPTION_URI_PATH=11,
|
| 126 | COAP_OPTION_CONTENT_FORMAT,
|
| 127 | COAP_OPTION_MAX_AGE=14,
|
| 128 | COAP_OPTION_URI_QUERY,
|
| 129 | COAP_OPTION_ACCEPT=17,
|
| 130 | COAP_OPTION_LOCATION_QUERY=20,
|
| 131 | COAP_OPTION_BLOCK2=23,
|
| 132 | COAP_OPTION_BLOCK1=27,
|
| 133 | COAP_OPTION_SIZE2,
|
| 134 | COAP_OPTION_PROXY_URI=35,
|
| 135 | COAP_OPTION_PROXY_SCHEME=39,
|
| 136 | COAP_OPTION_SIZE1=60
|
| 137 | };
|
| 138 |
|
| 139 | /// CoAP content-formats.
|
| 140 | enum ContentFormat
|
| 141 | {
|
| 142 | COAP_CONTENT_FORMAT_TEXT_PLAIN = 0,
|
| 143 | COAP_CONTENT_FORMAT_APP_LINK = 40,
|
| 144 | COAP_CONTENT_FORMAT_APP_XML,
|
| 145 | COAP_CONTENT_FORMAT_APP_OCTET,
|
| 146 | COAP_CONTENT_FORMAT_APP_EXI = 47,
|
| 147 | COAP_CONTENT_FORMAT_APP_JSON = 50
|
| 148 | };
|
| 149 |
|
| 150 | /// Sequence of these is returned by CoapPDU::getOptions()
|
| 151 | struct CoapOption
|
| 152 | {
|
| 153 | uint16_t optionDelta;
|
| 154 | uint16_t optionNumber;
|
| 155 | uint16_t optionValueLength;
|
| 156 | int totalLength;
|
| 157 | uint8_t *optionPointer;
|
| 158 | uint8_t *optionValuePointer;
|
| 159 | };
|
| 160 |
|
| 161 | // construction and destruction
|
| 162 | CoapPDU();
|
| 163 | CoapPDU(uint8_t *buffer, int bufferLength, int pduLength);
|
| 164 | ~CoapPDU();
|
| 165 | int reset();
|
| 166 | int validate();
|
| 167 |
|
| 168 | // version
|
| 169 | int setVersion(uint8_t version);
|
| 170 | uint8_t getVersion();
|
| 171 |
|
| 172 | // message type
|
| 173 | void setType(int type);
|
| 174 | int getType();
|
| 175 |
|
| 176 | // tokens
|
| 177 | int setTokenLength(uint8_t tokenLength);
|
| 178 | int getTokenLength();
|
| 179 | uint8_t* getTokenPointer();
|
| 180 | int setToken(uint8_t *token, uint8_t tokenLength);
|
| 181 |
|
| 182 | // message code
|
| 183 | void setCode(int code);
|
| 184 | int getCode();
|
| 185 | int httpStatusToCode(int httpStatus);
|
| 186 |
|
| 187 | // message ID
|
| 188 | int setMessageID(uint16_t messageID);
|
| 189 | uint16_t getMessageID();
|
| 190 |
|
| 191 | // options
|
| 192 | int addOption(uint16_t optionNumber, uint16_t optionLength, uint8_t *optionValue);
|
| 193 | // gets a list of all options
|
| 194 | CoapOption* getOptions();
|
| 195 | int getNumOptions();
|
| 196 | // shorthand helpers
|
| 197 | int setURI(char *uri);
|
| 198 | int setURI(char *uri, int urilen);
|
| 199 | int getURI(char *dst, int dstlen, int *outLen);
|
| 200 | int addURIQuery(char *query);
|
| 201 |
|
| 202 | // content format helper
|
| 203 | int setContentFormat(int format);
|
| 204 |
|
| 205 | // payload
|
| 206 | uint8_t* mallocPayload(int bytes);
|
| 207 | int setPayload(uint8_t *value, int len);
|
| 208 | uint8_t* getPayloadPointer();
|
| 209 | int getPayloadLength();
|
| 210 | uint8_t* getPayloadCopy();
|
| 211 |
|
| 212 | // pdu
|
| 213 | int getPDULength();
|
| 214 | uint8_t* getPDUPointer();
|
| 215 | void setPDULength(int len);
|
| 216 | void getOptionValueById(uint16_t optionNumber, uint16_t *optionValueLength,uint8_t *optionValuePointer);
|
| 217 | const char *printHuman();
|
| 218 | const char * printHex();
|
| 219 | int hasOption(uint16_t optionNumber);
|
| 220 | private:
|
| 221 | // variables
|
| 222 | uint8_t *_pdu;
|
| 223 | int _pduLength;
|
| 224 |
|
| 225 | int _constructedFromBuffer;
|
| 226 | int _bufferLength;
|
| 227 |
|
| 228 | uint8_t *_payloadPointer;
|
| 229 | int _payloadLength;
|
| 230 |
|
| 231 | int _numOptions;
|
| 232 | uint16_t _maxAddedOptionNumber;
|
| 233 | ASBuffer content;
|
| 234 |
|
| 235 | // functions
|
| 236 | void shiftPDUUp(int shiftOffset, int shiftAmount);
|
| 237 | void shiftPDUDown(int startLocation, int shiftOffset, int shiftAmount);
|
| 238 | uint8_t codeToValue(int c);
|
| 239 |
|
| 240 | // option stuff
|
| 241 | int findInsertionPosition(uint16_t optionNumber, uint16_t *prevOptionNumber);
|
| 242 | int computeExtraBytes(uint16_t n);
|
| 243 | int insertOption(int insertionPosition, uint16_t optionDelta, uint16_t optionValueLength, uint8_t *optionValue);
|
| 244 | uint16_t getOptionDelta(uint8_t *option);
|
| 245 | void setOptionDelta(int optionPosition, uint16_t optionDelta);
|
| 246 | uint16_t getOptionValueLength(uint8_t *option);
|
| 247 |
|
| 248 | };
|
| 249 |
|
| 250 | /*
|
| 251 | #define COAP_CODE_EMPTY 0x00
|
| 252 |
|
| 253 | // method codes 0.01-0.31
|
| 254 | #define COAP_CODE_GET 0x01
|
| 255 | #define COAP_CODE_POST 0x02
|
| 256 | #define COAP_CODE_PUT 0x03
|
| 257 | #define COAP_CODE_DELETE 0x04
|
| 258 |
|
| 259 | // Response codes 2.00 - 5.31
|
| 260 | // 2.00 - 2.05
|
| 261 | #define COAP_CODE_CREATED 0x41
|
| 262 | #define COAP_CODE_DELETED 0x42
|
| 263 | #define COAP_CODE_VALID 0x43
|
| 264 | #define COAP_CODE_CHANGED 0x44
|
| 265 | #define COAP_CODE_CONTENT 0x45
|
| 266 |
|
| 267 | // 4.00 - 4.15
|
| 268 | #define COAP_CODE_BAD_REQUEST 0x80
|
| 269 | #define COAP_CODE_UNAUTHORIZED 0x81
|
| 270 | #define COAP_CODE_BAD_OPTION 0x82
|
| 271 | #define COAP_CODE_FORBIDDEN 0x83
|
| 272 | #define COAP_CODE_NOT_FOUND 0x84
|
| 273 | #define COAP_CODE_METHOD_NOT_ALLOWED 0x85
|
| 274 | #define COAP_CODE_NOT_ACCEPTABLE 0x86
|
| 275 | #define COAP_CODE_PRECONDITION_FAILED 0x8C
|
| 276 | #define COAP_CODE_REQUEST_ENTITY_TOO_LARGE 0x8D
|
| 277 | #define COAP_CODE_UNSUPPORTED_CONTENT_FORMAT 0x8F
|
| 278 |
|
| 279 | // 5.00 - 5.05
|
| 280 | #define COAP_CODE_INTERNAL_SERVER_ERROR 0xA0
|
| 281 | #define COAP_CODE_NOT_IMPLEMENTED 0xA1
|
| 282 | #define COAP_CODE_BAD_GATEWAY 0xA2
|
| 283 | #define COAP_CODE_SERVICE_UNAVAILABLE 0xA3
|
| 284 | #define COAP_CODE_GATEWAY_TIMEOUT 0xA4
|
| 285 | #define COAP_CODE_PROXYING_NOT_SUPPORTED 0xA5
|
| 286 | */
|
| 287 |
|
| 288 | #endif
|