coap server basics -- parse input path
receive coap request and parse path actually this is just a stub, but hey, it's a stable one and this is my private branch even if this commit will probably be fast-merged '°_°
This commit is contained in:
parent
dc03eeb307
commit
f34833e955
124
src/coap.cpp
Normal file
124
src/coap.cpp
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#include "coap.h"
|
||||||
|
|
||||||
|
namespace coap {
|
||||||
|
|
||||||
|
uint8_t CoapMessage::getVersion() {
|
||||||
|
return vertkl >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CoapMessage::getType() {
|
||||||
|
return (vertkl & 0x30) >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CoapMessage::getTKL() {
|
||||||
|
return (vertkl & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CoapMessage::getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CoapMessage::getMID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* nonsense: save 8 bits in the network,
|
||||||
|
and waste tens of them for writing such an error-prone code like this! */
|
||||||
|
int CoapMessage::getOptionDelta(const unsigned char* option) {
|
||||||
|
uint8_t delta = option[0] >> 4;
|
||||||
|
if (delta <= 12) {
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta == 13) {
|
||||||
|
delta = option[1] + 13;
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* options delta larger than 269 (256 + 13) bytes are not supported */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int CoapMessage::getOptionLength(const unsigned char* option) {
|
||||||
|
uint8_t len = option[0] & 0xf;
|
||||||
|
|
||||||
|
if (len <= 12) {
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t extended_length_byte;
|
||||||
|
if (getOptionDelta(option) < 13)
|
||||||
|
extended_length_byte = option[1];
|
||||||
|
else
|
||||||
|
extended_length_byte = option[2];
|
||||||
|
|
||||||
|
if (len == 13) {
|
||||||
|
len = extended_length_byte + 13;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* options longer than 269 (256 + 13) are not supported */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* offset of payload wrt beginning of option */
|
||||||
|
int CoapMessage::getOptionValueOffset(const unsigned char* option) {
|
||||||
|
int offset = 1;
|
||||||
|
if (getOptionDelta(option) >= 13) ++offset;
|
||||||
|
if (getOptionLength(option) >= 13) ++offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
const char* CoapMessage::getOptionValue(const unsigned char* option) {
|
||||||
|
return (const char*) &option[getOptionValueOffset(option)];
|
||||||
|
}
|
||||||
|
const unsigned char* CoapMessage::getOptions() {
|
||||||
|
const unsigned char* address = (const unsigned char*)this;
|
||||||
|
address += 4; /* header */
|
||||||
|
address += getTKL();
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoapMessage::getUriPath(char* output_buffer, const char* last) {
|
||||||
|
/* TODO -- possible overflow, malformed input not checked */
|
||||||
|
int number = 0;
|
||||||
|
int len;
|
||||||
|
const unsigned char* options = this->getOptions();
|
||||||
|
|
||||||
|
while (number <= 11) {
|
||||||
|
number += getOptionDelta(options);
|
||||||
|
len = getOptionLength(options);
|
||||||
|
// TODO -- is here a payload? 15 - 15
|
||||||
|
if (number == 11) { /* Uri-Path option number */
|
||||||
|
*output_buffer = '/';
|
||||||
|
output_buffer += 1;
|
||||||
|
memcpy(output_buffer, getOptionValue(options), len);
|
||||||
|
output_buffer += len;
|
||||||
|
}
|
||||||
|
options += (len + getOptionValueOffset(options));
|
||||||
|
if (options == last) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_buffer = '\0';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int coap_server(char* output_buffer, const char* input_buffer, int len) {
|
||||||
|
CoapMessage* input_msg = (CoapMessage*) input_buffer;
|
||||||
|
if (input_msg->getVersion() != 0x1) /* bad CoAP version number */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (input_msg->getType() == RESET || input_msg->getType() == ACKNOWELEDGMENT) /* not implemented on server side */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (input_msg->getTKL() >= 9) /* format error -- TODO, maybe we can answer RST? see RFC */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (input_msg->getCode()) {
|
||||||
|
case GET:
|
||||||
|
input_msg->getUriPath(output_buffer, input_buffer + len);
|
||||||
|
return strlen(output_buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace -- coap::
|
53
src/coap.h
Normal file
53
src/coap.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef COAP_H
|
||||||
|
#define COAP_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
namespace coap {
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
CONFIRMABLE = 0,
|
||||||
|
NON_CONFIRMABLE = 1,
|
||||||
|
ACKNOWELEDGMENT = 2,
|
||||||
|
RESET = 3
|
||||||
|
};
|
||||||
|
enum Code {
|
||||||
|
EMPTY = 0x00, /* 0.00 */
|
||||||
|
GET = 0x01, /* 0.01 */
|
||||||
|
POST = 0x02, /* 0.02 */
|
||||||
|
PUT = 0x03, /* 0.03 */
|
||||||
|
DELETE = 0x04, /* 0.04 */
|
||||||
|
CONTENT = 0x45, /* 2.05 */
|
||||||
|
NOT_FOUND = 0x84,/*4.04 */
|
||||||
|
METHOD_NOT_ALLOWED = 0x85 /* 4.05 */
|
||||||
|
};
|
||||||
|
|
||||||
|
class CoapMessage {
|
||||||
|
private:
|
||||||
|
char vertkl;
|
||||||
|
char code;
|
||||||
|
char id[2];
|
||||||
|
public:
|
||||||
|
uint8_t getVersion();
|
||||||
|
uint8_t getType();
|
||||||
|
uint8_t getTKL();
|
||||||
|
uint8_t getCode();
|
||||||
|
const char* getMID();
|
||||||
|
const char* getPayload();
|
||||||
|
|
||||||
|
int getOptionDelta(const unsigned char* option);
|
||||||
|
int getOptionLength(const unsigned char* option);
|
||||||
|
const char* getOptionValue(const unsigned char* option);
|
||||||
|
int getOptionValueOffset(const unsigned char* option);
|
||||||
|
const unsigned char* getOptions();
|
||||||
|
|
||||||
|
void getUriPath(char* output_buffer, const char* last);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int coap_server(char* output_buffer, const char* input_buffer, int len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user