diff --git a/README.md b/README.md index da40247..16edccf 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # CoAP client, server library for Arduino. -CoAP simple server, client library for Arduino IDE, ESP32. +CoAP simple server, client library for Arduino IDE/PlatformIO, ESP32, ESP8266. ## Source Code -This lightweight library's source code contains only 2 files. coap.cpp, coap.h. +This lightweight library's source code contains only 2 files. coap-simple.cpp, coap-simple.h. ## Example Some sample sketches for Arduino included(/examples/). - coaptest.ino : simple request/response sample. - coapserver.ino : server endpoint url callback sample. + - esp32.ino, esp8266.ino : server endpoint url callback/response. ## How to use Download this source code branch zip file and extract it to the Arduino libraries directory or checkout repository. Here is checkout on MacOS X. diff --git a/coap-simple.cpp b/coap-simple.cpp index 6f56d17..9205abf 100644 --- a/coap-simple.cpp +++ b/coap-simple.cpp @@ -12,10 +12,23 @@ void CoapPacket::addOption(uint8_t number, uint8_t length, uint8_t *opt_payload) ++optionnum; } + Coap::Coap( - UDP& udp + UDP& udp, + int coap_buf_size /* default value is COAP_BUF_MAX_SIZE */ ) { this->_udp = &udp; + this->coap_buf_size = coap_buf_size; + this->tx_buffer = new uint8_t[this->coap_buf_size]; + this->rx_buffer = new uint8_t[this->coap_buf_size]; +} + +Coap::~Coap() { + if (this->tx_buffer != NULL) + delete[] this->tx_buffer; + + if (this->rx_buffer != NULL) + delete[] this->rx_buffer; } bool Coap::start() { @@ -33,8 +46,7 @@ uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip) { } uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip, int port) { - uint8_t buffer[COAP_BUF_MAX_SIZE]; - uint8_t *p = buffer; + uint8_t *p = this->tx_buffer; uint16_t running_delta = 0; uint16_t packetSize = 0; @@ -45,7 +57,7 @@ uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip, int port) { *p++ = packet.code; *p++ = (packet.messageid >> 8); *p++ = (packet.messageid & 0xFF); - p = buffer + COAP_HEADER_SIZE; + p = this->tx_buffer + COAP_HEADER_SIZE; packetSize += 4; // make token @@ -60,7 +72,7 @@ uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip, int port) { uint32_t optdelta; uint8_t len, delta; - if (packetSize + 5 + packet.options[i].length >= COAP_BUF_MAX_SIZE) { + if (packetSize + 5 + packet.options[i].length >= coap_buf_size) { return 0; } optdelta = packet.options[i].number - running_delta; @@ -92,7 +104,7 @@ uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip, int port) { // make payload if (packet.payloadlen > 0) { - if ((packetSize + 1 + packet.payloadlen) >= COAP_BUF_MAX_SIZE) { + if ((packetSize + 1 + packet.payloadlen) >= coap_buf_size) { return 0; } *p++ = 0xFF; @@ -101,7 +113,7 @@ uint16_t Coap::sendPacket(CoapPacket &packet, IPAddress ip, int port) { } _udp->beginPacket(ip, port); - _udp->write(buffer, packetSize); + _udp->write(this->tx_buffer, packetSize); _udp->endPacket(); return packet.messageid; @@ -217,29 +229,27 @@ int Coap::parseOption(CoapOption *option, uint16_t *running_delta, uint8_t **buf } bool Coap::loop() { - - uint8_t buffer[COAP_BUF_MAX_SIZE]; int32_t packetlen = _udp->parsePacket(); while (packetlen > 0) { - packetlen = _udp->read(buffer, packetlen >= COAP_BUF_MAX_SIZE ? COAP_BUF_MAX_SIZE : packetlen); + packetlen = _udp->read(this->rx_buffer, packetlen >= coap_buf_size ? coap_buf_size : packetlen); CoapPacket packet; // parse coap packet header - if (packetlen < COAP_HEADER_SIZE || (((buffer[0] & 0xC0) >> 6) != 1)) { + if (packetlen < COAP_HEADER_SIZE || (((this->rx_buffer[0] & 0xC0) >> 6) != 1)) { packetlen = _udp->parsePacket(); continue; } - packet.type = (buffer[0] & 0x30) >> 4; - packet.tokenlen = buffer[0] & 0x0F; - packet.code = buffer[1]; - packet.messageid = 0xFF00 & (buffer[2] << 8); - packet.messageid |= 0x00FF & buffer[3]; + packet.type = (this->rx_buffer[0] & 0x30) >> 4; + packet.tokenlen = this->rx_buffer[0] & 0x0F; + packet.code = this->rx_buffer[1]; + packet.messageid = 0xFF00 & (this->rx_buffer[2] << 8); + packet.messageid |= 0x00FF & this->rx_buffer[3]; if (packet.tokenlen == 0) packet.token = NULL; - else if (packet.tokenlen <= 8) packet.token = buffer + 4; + else if (packet.tokenlen <= 8) packet.token = this->rx_buffer + 4; else { packetlen = _udp->parsePacket(); continue; @@ -249,8 +259,8 @@ bool Coap::loop() { if (COAP_HEADER_SIZE + packet.tokenlen < packetlen) { int optionIndex = 0; uint16_t delta = 0; - uint8_t *end = buffer + packetlen; - uint8_t *p = buffer + COAP_HEADER_SIZE + packet.tokenlen; + uint8_t *end = this->rx_buffer + packetlen; + uint8_t *p = this->rx_buffer + COAP_HEADER_SIZE + packet.tokenlen; while(optionIndex < COAP_MAX_OPTION_NUM && *p != 0xFF && p < end) { //packet.options[optionIndex]; if (0 != parseOption(&packet.options[optionIndex], &delta, &p, end-p)) diff --git a/coap-simple.h b/coap-simple.h index 0b50239..7942d5d 100644 --- a/coap-simple.h +++ b/coap-simple.h @@ -177,6 +177,9 @@ class Coap { CoapUri uri; CoapCallback resp; int _port; + int coap_buf_size; + uint8_t *tx_buffer = NULL; + uint8_t *rx_buffer = NULL; uint16_t sendPacket(CoapPacket &packet, IPAddress ip); uint16_t sendPacket(CoapPacket &packet, IPAddress ip, int port); @@ -184,8 +187,10 @@ class Coap { public: Coap( - UDP& udp + UDP& udp, + int coap_buf_size = COAP_BUF_MAX_SIZE ); + ~Coap(); bool start(); bool start(int port); void response(CoapCallback c) { resp = c; } diff --git a/examples/esp32/esp32.ino b/examples/esp32/esp32.ino index d53e7f2..89f75ed 100644 --- a/examples/esp32/esp32.ino +++ b/examples/esp32/esp32.ino @@ -12,6 +12,10 @@ void callback_response(CoapPacket &packet, IPAddress ip, int port); void callback_light(CoapPacket &packet, IPAddress ip, int port); // UDP and CoAP class +// other initialize is "Coap coap(Udp, 512);" +// 2nd default parameter is COAP_BUF_MAX_SIZE(defaulit:128) +// For UDP fragmentation, it is good to set the maximum under +// 1280byte when using the internet connection. WiFiUDP udp; Coap coap(udp); diff --git a/examples/esp8266/esp8266.ino b/examples/esp8266/esp8266.ino index 61b27b7..dbdde4a 100644 --- a/examples/esp8266/esp8266.ino +++ b/examples/esp8266/esp8266.ino @@ -12,6 +12,10 @@ void callback_response(CoapPacket &packet, IPAddress ip, int port); void callback_light(CoapPacket &packet, IPAddress ip, int port); // UDP and CoAP class +// other initialize is "Coap coap(Udp, 512);" +// 2nd default parameter is COAP_BUF_MAX_SIZE(defaulit:128) +// For UDP fragmentation, it is good to set the maximum under +// 1280byte when using the internet connection. WiFiUDP udp; Coap coap(udp); diff --git a/library.json b/library.json index b5d8f2d..09086dc 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name" : "CoAP simple library", - "version" : "1.3.24", + "version" : "1.3.25", "description" : "Simple CoAP client/server library for generic Arduino Client hardware.", "keywords" : "communication, coap, wifi", "authors" : { diff --git a/library.properties b/library.properties index ba03cbd..cad4412 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=CoAP simple library -version=1.3.24 +version=1.3.25 author=Hirotaka Niisato maintainer=Hirotaka Niisato sentence=Simple CoAP client/server library for generic Arduino Client hardware. diff --git a/license.txt b/license.txt index 8e8c54b..4f3e8a0 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2018 Hirotaka Niisato +Copyright (c) 2022 Hirotaka Niisato This software is released under the MIT License. Permission is hereby granted, free of charge, to any person obtaining