default build with coap, reduce coap module mem usage
This commit is contained in:
parent
394cced84b
commit
0b95ae08a2
26
README.md
26
README.md
|
@ -34,6 +34,10 @@ Tencent QQ group: 309957875<br />
|
|||
- cross compiler (done)
|
||||
|
||||
# Change log
|
||||
2015-03-15<br />
|
||||
bugs fixed: #239, #273.<br />
|
||||
reduce coap module memory usage, add coap module to default built.
|
||||
|
||||
2015-03-11<br />
|
||||
fix bugs of spiffs.<br />
|
||||
build both float and integer version [latest releases](https://github.com/nodemcu/nodemcu-firmware/releases/latest).<br />
|
||||
|
@ -414,3 +418,25 @@ They'll be available as `u8g.<font_name>` in Lua.
|
|||
-- first LED green, second LED white
|
||||
ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255))
|
||||
```
|
||||
|
||||
####coap client and server
|
||||
```lua
|
||||
-- use copper addon for firefox
|
||||
cs=coap.Server()
|
||||
cs:listen(5683)
|
||||
|
||||
myvar=1
|
||||
cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1
|
||||
|
||||
-- function should tack one string, return one string.
|
||||
function myfun(payload)
|
||||
print("myfun called")
|
||||
respond = "hello"
|
||||
return respond
|
||||
end
|
||||
cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun
|
||||
|
||||
cc = coap.Client()
|
||||
cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core")
|
||||
cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello")
|
||||
```
|
|
@ -76,7 +76,7 @@ int coap_parseToken(coap_buffer_t *tokbuf, const coap_header_t *hdr, const uint8
|
|||
else
|
||||
if (hdr->tkl <= 8)
|
||||
{
|
||||
if (4 + hdr->tkl > buflen)
|
||||
if (4U + hdr->tkl > buflen)
|
||||
return COAP_ERR_TOKEN_TOO_SHORT; // tok bigger than packet
|
||||
tokbuf->p = buf+4; // past header
|
||||
tokbuf->len = hdr->tkl;
|
||||
|
@ -93,7 +93,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8
|
|||
{
|
||||
// inject token
|
||||
uint8_t *p;
|
||||
if (buflen < 4 + hdr->tkl)
|
||||
if (buflen < (4U + hdr->tkl))
|
||||
return COAP_ERR_BUFFER_TOO_SMALL;
|
||||
p = buf + 4;
|
||||
if ((hdr->tkl > 0) && (hdr->tkl != tokbuf->len))
|
||||
|
@ -102,7 +102,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8
|
|||
if (hdr->tkl > 0)
|
||||
c_memcpy(p, tokbuf->p, hdr->tkl);
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3.1
|
||||
// http://tools.ietf.org/html/rfc7252#section-3.1
|
||||
// inject options
|
||||
return hdr->tkl;
|
||||
}
|
||||
|
@ -111,8 +111,8 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8
|
|||
int coap_parseOption(coap_option_t *option, uint16_t *running_delta, const uint8_t **buf, size_t buflen)
|
||||
{
|
||||
const uint8_t *p = *buf;
|
||||
uint16_t len, delta;
|
||||
uint8_t headlen = 1;
|
||||
uint16_t len, delta;
|
||||
|
||||
if (buflen < headlen) // too small
|
||||
return COAP_ERR_OPTION_TOO_SHORT_FOR_HEADER;
|
||||
|
@ -179,14 +179,14 @@ int coap_parseOption(coap_option_t *option, uint16_t *running_delta, const uint8
|
|||
return 0;
|
||||
}
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3.1
|
||||
// http://tools.ietf.org/html/rfc7252#section-3.1
|
||||
int coap_parseOptionsAndPayload(coap_option_t *options, uint8_t *numOptions, coap_buffer_t *payload, const coap_header_t *hdr, const uint8_t *buf, size_t buflen)
|
||||
{
|
||||
size_t optionIndex = 0;
|
||||
uint16_t delta = 0;
|
||||
const uint8_t *p = buf + 4 + hdr->tkl;
|
||||
const uint8_t *end = buf + buflen;
|
||||
int rc;
|
||||
uint16_t delta = 0;
|
||||
if (p > end)
|
||||
return COAP_ERR_OPTION_OVERRUNS_PACKET; // out of bounds
|
||||
|
||||
|
@ -215,7 +215,7 @@ int coap_parseOptionsAndPayload(coap_option_t *options, uint8_t *numOptions, coa
|
|||
return 0;
|
||||
}
|
||||
|
||||
int coap_buildOptionHeader(unsigned short optDelta, size_t length, uint8_t *buf, size_t buflen)
|
||||
int coap_buildOptionHeader(uint32_t optDelta, size_t length, uint8_t *buf, size_t buflen)
|
||||
{
|
||||
int n = 0;
|
||||
uint8_t *p = buf;
|
||||
|
@ -298,7 +298,7 @@ int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen)
|
|||
}
|
||||
|
||||
// options are always stored consecutively, so can return a block with same option num
|
||||
const coap_option_t * coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count)
|
||||
const coap_option_t *coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count)
|
||||
{
|
||||
// FIXME, options is always sorted, can find faster than this
|
||||
size_t i;
|
||||
|
@ -352,7 +352,7 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt)
|
|||
uint16_t optDelta = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (p-buf > *buflen)
|
||||
if (((size_t)(p-buf)) > *buflen)
|
||||
return COAP_ERR_BUFFER_TOO_SMALL;
|
||||
optDelta = pkt->opts[i].num - running_delta;
|
||||
|
||||
|
@ -381,17 +381,17 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void coap_option_nibble(uint16_t value, uint8_t *nibble)
|
||||
void coap_option_nibble(uint32_t value, uint8_t *nibble)
|
||||
{
|
||||
if (value<13)
|
||||
{
|
||||
*nibble = (0xFF & value);
|
||||
}
|
||||
else
|
||||
if (((uint32_t)value)<=0xFF+13)
|
||||
if (value<=0xFF+13)
|
||||
{
|
||||
*nibble = 13;
|
||||
} else if (((uint32_t)value) -269 <=0xFFFF)
|
||||
} else if (value<=0xFFFF+269)
|
||||
{
|
||||
*nibble = 14;
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ int coap_make_response(coap_rw_buffer_t *scratch, coap_packet_t *pkt, const uint
|
|||
pkt->hdr.code = rspcode;
|
||||
pkt->hdr.id[0] = msgid_hi;
|
||||
pkt->hdr.id[1] = msgid_lo;
|
||||
pkt->numopts = 0;
|
||||
pkt->numopts = 1;
|
||||
|
||||
// need token in response
|
||||
if (tok) {
|
||||
|
@ -442,7 +442,7 @@ unsigned int coap_encode_var_bytes(unsigned char *buf, unsigned int val) {
|
|||
return n;
|
||||
}
|
||||
|
||||
static uint8_t _token_data[4]={'n','o','d','e'};
|
||||
static uint8_t _token_data[4] = {'n','o','d','e'};
|
||||
coap_buffer_t the_token = { _token_data, 4 };
|
||||
static unsigned short message_id;
|
||||
|
||||
|
|
|
@ -18,13 +18,15 @@ extern "C" {
|
|||
|
||||
#define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF)
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3
|
||||
//http://tools.ietf.org/html/rfc7252#section-3
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ver;
|
||||
uint8_t t;
|
||||
uint8_t tkl;
|
||||
uint8_t code;
|
||||
uint8_t ver; /* CoAP version number */
|
||||
uint8_t t; /* CoAP Message Type */
|
||||
uint8_t tkl; /* Token length: indicates length of the Token field */
|
||||
uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx),
|
||||
* client error response (4.xx), or rever error response (5.xx)
|
||||
* For possible values, see http://tools.ietf.org/html/rfc7252#section-12.1 */
|
||||
uint8_t id[2];
|
||||
} coap_header_t;
|
||||
|
||||
|
@ -42,23 +44,24 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t num;
|
||||
coap_buffer_t buf;
|
||||
uint8_t num; /* Option number. See http://tools.ietf.org/html/rfc7252#section-5.10 */
|
||||
coap_buffer_t buf; /* Option value */
|
||||
} coap_option_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
coap_header_t hdr;
|
||||
coap_buffer_t tok;
|
||||
uint8_t numopts;
|
||||
coap_option_t opts[MAXOPT];
|
||||
coap_buffer_t payload;
|
||||
coap_rw_buffer_t scratch; // scratch->p = malloc(...) , and free it when done.
|
||||
coap_header_t hdr; /* Header of the packet */
|
||||
coap_buffer_t tok; /* Token value, size as specified by hdr.tkl */
|
||||
uint8_t numopts; /* Number of options */
|
||||
coap_option_t opts[MAXOPT]; /* Options of the packet. For possible entries see
|
||||
* http://tools.ietf.org/html/rfc7252#section-5.10 */
|
||||
coap_buffer_t payload; /* Payload carried by the packet */
|
||||
coap_rw_buffer_t content; // content->p = malloc(...) , and free it when done.
|
||||
} coap_packet_t;
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.2
|
||||
//http://tools.ietf.org/html/rfc7252#section-12.2
|
||||
typedef enum
|
||||
{
|
||||
COAP_OPTION_IF_MATCH = 1,
|
||||
|
@ -78,7 +81,7 @@ typedef enum
|
|||
COAP_OPTION_PROXY_SCHEME = 39
|
||||
} coap_option_num_t;
|
||||
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.1
|
||||
//http://tools.ietf.org/html/rfc7252#section-12.1.1
|
||||
typedef enum
|
||||
{
|
||||
COAP_METHOD_GET = 1,
|
||||
|
@ -87,7 +90,7 @@ typedef enum
|
|||
COAP_METHOD_DELETE = 4
|
||||
} coap_method_t;
|
||||
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.1
|
||||
//http://tools.ietf.org/html/rfc7252#section-12.1.1
|
||||
typedef enum
|
||||
{
|
||||
COAP_TYPE_CON = 0,
|
||||
|
@ -96,8 +99,8 @@ typedef enum
|
|||
COAP_TYPE_RESET = 3
|
||||
} coap_msgtype_t;
|
||||
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-5.2
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.2
|
||||
//http://tools.ietf.org/html/rfc7252#section-5.2
|
||||
//http://tools.ietf.org/html/rfc7252#section-12.1.2
|
||||
#define MAKE_RSPCODE(clas, det) ((clas << 5) | (det))
|
||||
typedef enum
|
||||
{
|
||||
|
@ -107,7 +110,7 @@ typedef enum
|
|||
COAP_RSPCODE_CHANGED = MAKE_RSPCODE(2, 4)
|
||||
} coap_responsecode_t;
|
||||
|
||||
//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.3
|
||||
//http://tools.ietf.org/html/rfc7252#section-12.3
|
||||
typedef enum
|
||||
{
|
||||
COAP_CONTENTTYPE_NONE = -1, // bodge to allow us not to send option block
|
||||
|
@ -155,15 +158,21 @@ struct coap_luser_entry{
|
|||
coap_luser_entry *next;
|
||||
};
|
||||
|
||||
struct coap_endpoint_t
|
||||
{
|
||||
coap_method_t method;
|
||||
coap_endpoint_func handler;
|
||||
const coap_endpoint_path_t *path;
|
||||
const char *core_attr;
|
||||
coap_luser_entry *user_entry;
|
||||
struct coap_endpoint_t{
|
||||
coap_method_t method; /* (i.e. POST, PUT or GET) */
|
||||
coap_endpoint_func handler; /* callback function which handles this
|
||||
* type of endpoint (and calls
|
||||
* coap_make_response() at some point) */
|
||||
const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */
|
||||
const char *core_attr; /* the 'ct' attribute, as defined in RFC7252, section 7.2.1.:
|
||||
* "The Content-Format code "ct" attribute
|
||||
* provides a hint about the
|
||||
* Content-Formats this resource returns."
|
||||
* (Section 12.3. lists possible ct values.) */
|
||||
coap_luser_entry *user_entry;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////
|
||||
void coap_dumpPacket(coap_packet_t *pkt);
|
||||
int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen);
|
||||
|
@ -173,11 +182,11 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt);
|
|||
void coap_dump(const uint8_t *buf, size_t buflen, bool bare);
|
||||
int coap_make_response(coap_rw_buffer_t *scratch, coap_packet_t *pkt, const uint8_t *content, size_t content_len, uint8_t msgid_hi, uint8_t msgid_lo, const coap_buffer_t* tok, coap_responsecode_t rspcode, coap_content_type_t content_type);
|
||||
int coap_handle_req(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt);
|
||||
void coap_option_nibble(uint16_t value, uint8_t *nibble);
|
||||
void coap_option_nibble(uint32_t value, uint8_t *nibble);
|
||||
void coap_setup(void);
|
||||
void endpoint_setup(void);
|
||||
|
||||
int coap_buildOptionHeader(unsigned short optDelta, size_t length, uint8_t *buf, size_t buflen);
|
||||
int coap_buildOptionHeader(uint32_t optDelta, size_t length, uint8_t *buf, size_t buflen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ void coap_client_response_handler(char *data, unsigned short len, unsigned short
|
|||
{
|
||||
NODE_DBG("coap_client_response_handler is called.\n");
|
||||
coap_packet_t pkt;
|
||||
pkt.content.p = NULL;
|
||||
pkt.content.len = 0;
|
||||
int rc;
|
||||
|
||||
if (0 != (rc = coap_parse(&pkt, data, len))){
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "user_config.h"
|
||||
#include "c_types.h"
|
||||
#include "c_stdlib.h"
|
||||
|
||||
#include "coap.h"
|
||||
|
||||
|
@ -8,6 +9,8 @@ size_t coap_server_respond(char *req, unsigned short reqlen, char *rsp, unsigned
|
|||
NODE_DBG("coap_server_respond is called.\n");
|
||||
size_t rlen = rsplen;
|
||||
coap_packet_t pkt;
|
||||
pkt.content.p = NULL;
|
||||
pkt.content.len = 0;
|
||||
uint8_t scratch_raw[4];
|
||||
coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)};
|
||||
int rc;
|
||||
|
@ -25,13 +28,16 @@ size_t coap_server_respond(char *req, unsigned short reqlen, char *rsp, unsigned
|
|||
else
|
||||
{
|
||||
coap_packet_t rsppkt;
|
||||
rsppkt.content.p = NULL;
|
||||
rsppkt.content.len = 0;
|
||||
#ifdef COAP_DEBUG
|
||||
coap_dumpPacket(&pkt);
|
||||
#endif
|
||||
coap_handle_req(&scratch_buf, &pkt, &rsppkt);
|
||||
if (0 != (rc = coap_build(rsp, &rlen, &rsppkt))){
|
||||
NODE_DBG("coap_build failed rc=%d\n", rc);
|
||||
return 0;
|
||||
// return 0;
|
||||
rlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -44,6 +50,11 @@ size_t coap_server_respond(char *req, unsigned short reqlen, char *rsp, unsigned
|
|||
coap_dumpPacket(&rsppkt);
|
||||
#endif
|
||||
}
|
||||
if(rsppkt.content.p){
|
||||
c_free(rsppkt.content.p);
|
||||
rsppkt.content.p = NULL;
|
||||
rsppkt.content.len = 0;
|
||||
}
|
||||
return rlen;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "c_stdio.h"
|
||||
#include "c_string.h"
|
||||
#include "c_stdlib.h"
|
||||
#include "coap.h"
|
||||
|
||||
#include "lua.h"
|
||||
|
@ -8,20 +9,24 @@
|
|||
|
||||
#include "os_type.h"
|
||||
|
||||
static char rsp[512] = "";
|
||||
const uint16_t rsplen = 512;
|
||||
void build_well_known_rsp(void);
|
||||
void build_well_known_rsp(char *rsp, uint16_t rsplen);
|
||||
|
||||
void endpoint_setup(void)
|
||||
{
|
||||
coap_setup();
|
||||
build_well_known_rsp();
|
||||
}
|
||||
|
||||
static const coap_endpoint_path_t path_well_known_core = {2, {".well-known", "core"}};
|
||||
static int handle_get_well_known_core(const coap_endpoint_t *ep, coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo)
|
||||
{
|
||||
return coap_make_response(scratch, outpkt, (const uint8_t *)rsp, c_strlen(rsp), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_APPLICATION_LINKFORMAT);
|
||||
outpkt->content.p = (uint8_t *)c_zalloc(MAX_PAYLOAD_SIZE); // this should be free-ed when outpkt is built in coap_server_respond()
|
||||
if(outpkt->content.p == NULL){
|
||||
NODE_DBG("not enough memory\n");
|
||||
return COAP_ERR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
outpkt->content.len = MAX_PAYLOAD_SIZE;
|
||||
build_well_known_rsp(outpkt->content.p, outpkt->content.len);
|
||||
return coap_make_response(scratch, outpkt, (const uint8_t *)outpkt->content.p, c_strlen(outpkt->content.p), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_APPLICATION_LINKFORMAT);
|
||||
}
|
||||
|
||||
static const coap_endpoint_path_t path_variable = {2, {"v1", "v"}};
|
||||
|
@ -211,13 +216,13 @@ const coap_endpoint_t endpoints[] =
|
|||
{(coap_method_t)0, NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
void build_well_known_rsp(void)
|
||||
void build_well_known_rsp(char *rsp, uint16_t rsplen)
|
||||
{
|
||||
const coap_endpoint_t *ep = endpoints;
|
||||
int i;
|
||||
uint16_t len = rsplen;
|
||||
|
||||
c_memset(rsp, 0, sizeof(rsp));
|
||||
c_memset(rsp, 0, len);
|
||||
|
||||
len--; // Null-terminated string
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ coap_pdu_t * coap_new_pdu(void) {
|
|||
c_free(pdu);
|
||||
return NULL;
|
||||
}
|
||||
pdu->pkt->content.p = NULL;
|
||||
pdu->pkt->content.len = 0;
|
||||
|
||||
pdu->msg.p = (uint8_t *)c_zalloc(MAX_REQUEST_SIZE+1); // +1 for string '\0'
|
||||
if(!pdu->msg.p){
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define LUA_USE_MODULES_OW
|
||||
#define LUA_USE_MODULES_BIT
|
||||
#define LUA_USE_MODULES_MQTT
|
||||
// #define LUA_USE_MODULES_COAP // need about 1k more ram for now
|
||||
#define LUA_USE_MODULES_COAP
|
||||
#define LUA_USE_MODULES_U8G
|
||||
#define LUA_USE_MODULES_WS2812
|
||||
#endif /* LUA_USE_MODULES */
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
#define NODE_VERSION_INTERNAL 0U
|
||||
|
||||
#define NODE_VERSION "NodeMCU 0.9.5"
|
||||
#define BUILD_DATE "build 20150311"
|
||||
#define BUILD_DATE "build 20150315"
|
||||
|
||||
#endif /* __USER_VERSION_H__ */
|
||||
|
|
|
@ -227,6 +227,8 @@ static void coap_response_handler(void *arg, char *pdata, unsigned short len)
|
|||
struct espconn *pesp_conn = arg;
|
||||
|
||||
coap_packet_t pkt;
|
||||
pkt.content.p = NULL;
|
||||
pkt.content.len = 0;
|
||||
// static uint8_t buf[MAX_MESSAGE_SIZE+1] = {0}; // +1 for string '\0'
|
||||
uint8_t buf[MAX_MESSAGE_SIZE+1] = {0}; // +1 for string '\0'
|
||||
c_memset(buf, 0, sizeof(buf)); // wipe prev data
|
||||
|
@ -421,7 +423,6 @@ static int coap_request( lua_State* L, coap_method_t m )
|
|||
|
||||
extern coap_luser_entry *variable_entry;
|
||||
extern coap_luser_entry *function_entry;
|
||||
extern void build_well_known_rsp(void);
|
||||
// Lua: coap:var/func( string )
|
||||
static int coap_regist( lua_State* L, const char* mt, int isvar )
|
||||
{
|
||||
|
@ -456,8 +457,6 @@ static int coap_regist( lua_State* L, const char* mt, int isvar )
|
|||
h->L = L;
|
||||
h->name = name;
|
||||
|
||||
build_well_known_rsp(); // rebuild .well-known
|
||||
|
||||
NODE_DBG("coap_regist is called.\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue