Added option to use only static allocations

This commit is contained in:
jgromes 2019-09-28 12:49:44 +02:00
parent d7e2dadb9f
commit adcde6fb6c
9 changed files with 319 additions and 139 deletions

View file

@ -10,6 +10,11 @@
// the following platforms do not support SoftwareSerial library // the following platforms do not support SoftwareSerial library
#define SOFTWARE_SERIAL_UNSUPPORTED (defined(ESP32) || defined(SAMD_SERIES) || defined (ARDUINO_ARCH_STM32)) #define SOFTWARE_SERIAL_UNSUPPORTED (defined(ESP32) || defined(SAMD_SERIES) || defined (ARDUINO_ARCH_STM32))
// uncomment to enable static-only memory management: no dynamic allocation will be performed
// Warning: Large static arrays will be created in some methods. It is also not advised to send large packets in this mode.
//#define STATIC_ONLY
#define STATIC_ARRAY_SIZE 256
#define RADIOLIB_DEBUG_PORT Serial #define RADIOLIB_DEBUG_PORT Serial
//#define RADIOLIB_DEBUG //#define RADIOLIB_DEBUG

View file

@ -52,8 +52,12 @@ int16_t ESP8266::join(const char* ssid, const char* password) {
// build AT command // build AT command
const char* atStr = "AT+CWJAP_CUR=\""; const char* atStr = "AT+CWJAP_CUR=\"";
#ifdef STATIC_ONLY
char cmd[STATIC_ARRAY_SIZE];
#else
uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4; uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4;
char* cmd = new char[cmdLen + 1]; char* cmd = new char[cmdLen + 1];
#endif
strcpy(cmd, atStr); strcpy(cmd, atStr);
strcat(cmd, ssid); strcat(cmd, ssid);
strcat(cmd, "\",\""); strcat(cmd, "\",\"");
@ -62,7 +66,9 @@ int16_t ESP8266::join(const char* ssid, const char* password) {
// send command // send command
bool res = _mod->ATsendCommand(cmd); bool res = _mod->ATsendCommand(cmd);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
@ -87,7 +93,11 @@ int16_t ESP8266::openTransportConnection(const char* host, const char* protocol,
if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) { if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) {
cmdLen += strlen(tcpKeepAliveStr) + 1; cmdLen += strlen(tcpKeepAliveStr) + 1;
} }
#ifdef STATIC_ONLY
char cmd[STATIC_ARRAY_SIZE];
#else
char* cmd = new char[cmdLen + 1]; char* cmd = new char[cmdLen + 1];
#endif
strcpy(cmd, atStr); strcpy(cmd, atStr);
strcat(cmd, protocol); strcat(cmd, protocol);
strcat(cmd, "\",\""); strcat(cmd, "\",\"");
@ -101,7 +111,9 @@ int16_t ESP8266::openTransportConnection(const char* host, const char* protocol,
// send command // send command
bool res = _mod->ATsendCommand(cmd); bool res = _mod->ATsendCommand(cmd);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
@ -122,13 +134,19 @@ int16_t ESP8266::send(const char* data) {
char lenStr[8]; char lenStr[8];
itoa(strlen(data), lenStr, 10); itoa(strlen(data), lenStr, 10);
const char* atStr = "AT+CIPSEND="; const char* atStr = "AT+CIPSEND=";
#ifdef STATIC_ONLY
char cmd[STATIC_ARRAY_SIZE];
#else
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1]; char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
#endif
strcpy(cmd, atStr); strcpy(cmd, atStr);
strcat(cmd, lenStr); strcat(cmd, lenStr);
// send command // send command
bool res = _mod->ATsendCommand(cmd); bool res = _mod->ATsendCommand(cmd);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
@ -146,13 +164,19 @@ int16_t ESP8266::send(uint8_t* data, uint32_t len) {
char lenStr[8]; char lenStr[8];
itoa(len, lenStr, 10); itoa(len, lenStr, 10);
const char atStr[] = "AT+CIPSEND="; const char atStr[] = "AT+CIPSEND=";
#ifdef STATIC_ONLY
char cmd[STATIC_ARRAY_SIZE];
#else
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1]; char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
#endif
strcpy(cmd, atStr); strcpy(cmd, atStr);
strcat(cmd, lenStr); strcat(cmd, lenStr);
// send command // send command
bool res = _mod->ATsendCommand(cmd); bool res = _mod->ATsendCommand(cmd);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }

View file

@ -1030,12 +1030,18 @@ int16_t SX126x::setPaConfig(uint8_t paDutyCycle, uint8_t deviceSel, uint8_t hpMa
} }
int16_t SX126x::writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) { int16_t SX126x::writeRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
#ifdef STATIC_ONLY
uint8_t dat[STATIC_ARRAY_SIZE + 2];
#else
uint8_t* dat = new uint8_t[2 + numBytes]; uint8_t* dat = new uint8_t[2 + numBytes];
#endif
dat[0] = (uint8_t)((addr >> 8) & 0xFF); dat[0] = (uint8_t)((addr >> 8) & 0xFF);
dat[1] = (uint8_t)(addr & 0xFF); dat[1] = (uint8_t)(addr & 0xFF);
memcpy(dat + 2, data, numBytes); memcpy(dat + 2, data, numBytes);
int16_t state = SPIwriteCommand(SX126X_CMD_WRITE_REGISTER, dat, 2 + numBytes); int16_t state = SPIwriteCommand(SX126X_CMD_WRITE_REGISTER, dat, 2 + numBytes);
#ifndef STATIC_ONLY
delete[] dat; delete[] dat;
#endif
return(state); return(state);
} }
@ -1045,22 +1051,34 @@ int16_t SX126x::readRegister(uint16_t addr, uint8_t* data, uint8_t numBytes) {
} }
int16_t SX126x::writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) { int16_t SX126x::writeBuffer(uint8_t* data, uint8_t numBytes, uint8_t offset) {
#ifdef STATIC_ONLY
uint8_t dat[STATIC_ARRAY_SIZE + 1];
#else
uint8_t* dat = new uint8_t[1 + numBytes]; uint8_t* dat = new uint8_t[1 + numBytes];
#endif
dat[0] = offset; dat[0] = offset;
memcpy(dat + 1, data, numBytes); memcpy(dat + 1, data, numBytes);
int16_t state = SPIwriteCommand(SX126X_CMD_WRITE_BUFFER, dat, 1 + numBytes); int16_t state = SPIwriteCommand(SX126X_CMD_WRITE_BUFFER, dat, 1 + numBytes);
#ifndef STATIC_ONLY
delete[] dat; delete[] dat;
#endif
return(state); return(state);
} }
int16_t SX126x::readBuffer(uint8_t* data, uint8_t numBytes) { int16_t SX126x::readBuffer(uint8_t* data, uint8_t numBytes) {
// offset will be always set to 0 (one extra NOP is sent) // offset will be always set to 0 (one extra NOP is sent)
#ifdef STATIC_ONLY
uint8_t dat[STATIC_ARRAY_SIZE + 1];
#else
uint8_t* dat = new uint8_t[1 + numBytes]; uint8_t* dat = new uint8_t[1 + numBytes];
#endif
dat[0] = SX126X_CMD_NOP; dat[0] = SX126X_CMD_NOP;
memcpy(dat + 1, data, numBytes); memcpy(dat + 1, data, numBytes);
int16_t state = SPIreadCommand(SX126X_CMD_READ_BUFFER, dat, 1 + numBytes); int16_t state = SPIreadCommand(SX126X_CMD_READ_BUFFER, dat, 1 + numBytes);
memcpy(data, dat + 1, numBytes); memcpy(data, dat + 1, numBytes);
#ifndef STATIC_ONLY
delete[] dat; delete[] dat;
#endif
return(state); return(state);
} }
@ -1180,7 +1198,7 @@ int16_t SX126x::setFrequencyRaw(float freq) {
int16_t SX126x::config(uint8_t modem) { int16_t SX126x::config(uint8_t modem) {
// set regulator mode // set regulator mode
uint8_t* data = new uint8_t[1]; uint8_t data[7];
data[0] = SX126X_REGULATOR_DC_DC; data[0] = SX126X_REGULATOR_DC_DC;
int16_t state = SPIwriteCommand(SX126X_CMD_SET_REGULATOR_MODE, data, 1); int16_t state = SPIwriteCommand(SX126X_CMD_SET_REGULATOR_MODE, data, 1);
if(state != ERR_NONE) { if(state != ERR_NONE) {
@ -1208,8 +1226,6 @@ int16_t SX126x::config(uint8_t modem) {
} }
// set CAD parameters // set CAD parameters
delete[] data;
data = new uint8_t[7];
data[0] = SX126X_CAD_ON_8_SYMB; data[0] = SX126X_CAD_ON_8_SYMB;
data[1] = _sf + 13; data[1] = _sf + 13;
data[2] = 10; data[2] = 10;
@ -1230,8 +1246,6 @@ int16_t SX126x::config(uint8_t modem) {
} }
// calibrate all blocks // calibrate all blocks
delete[] data;
data = new uint8_t[1];
data[0] = SX126X_CALIBRATE_ALL; data[0] = SX126X_CALIBRATE_ALL;
state = SPIwriteCommand(SX126X_CMD_CALIBRATE, data, 1); state = SPIwriteCommand(SX126X_CMD_CALIBRATE, data, 1);
if(state != ERR_NONE) { if(state != ERR_NONE) {
@ -1242,8 +1256,6 @@ int16_t SX126x::config(uint8_t modem) {
delayMicroseconds(1); delayMicroseconds(1);
while(digitalRead(_mod->getRx())); while(digitalRead(_mod->getRx()));
delete[] data;
return(ERR_NONE); return(ERR_NONE);
} }

View file

@ -5,7 +5,6 @@ XBee::XBee(Module* mod) {
_frameID = 0x01; _frameID = 0x01;
_frameLength = 0; _frameLength = 0;
_frameHeaderProcessed = false; _frameHeaderProcessed = false;
_packetData = new char[0];
} }
int16_t XBee::begin(long speed) { int16_t XBee::begin(long speed) {
@ -69,7 +68,11 @@ int16_t XBee::transmit(uint8_t* dest, uint8_t* destNetwork, const char* payload,
// build the frame // build the frame
size_t payloadLen = strlen(payload); size_t payloadLen = strlen(payload);
size_t dataLen = 8 + 2 + 1 + 1 + payloadLen; size_t dataLen = 8 + 2 + 1 + 1 + payloadLen;
#ifdef STATIC_ONLY
uint8_t cmd[STATIC_ARRAY_SIZE];
#else
uint8_t* cmd = new uint8_t[dataLen]; uint8_t* cmd = new uint8_t[dataLen];
#endif
memcpy(cmd, dest, 8); memcpy(cmd, dest, 8);
memcpy(cmd + 8, destNetwork, 2); memcpy(cmd + 8, destNetwork, 2);
cmd[10] = radius; cmd[10] = radius;
@ -79,7 +82,9 @@ int16_t XBee::transmit(uint8_t* dest, uint8_t* destNetwork, const char* payload,
// send frame // send frame
uint8_t frameID = _frameID++; uint8_t frameID = _frameID++;
sendApiFrame(XBEE_API_FRAME_ZIGBEE_TRANSMIT_REQUEST, frameID, cmd, dataLen); sendApiFrame(XBEE_API_FRAME_ZIGBEE_TRANSMIT_REQUEST, frameID, cmd, dataLen);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
// get response code // get response code
return(readApiFrame(frameID, 5)); return(readApiFrame(frameID, 5));
@ -114,20 +119,28 @@ size_t XBee::available() {
return(0); return(0);
} }
uint8_t* frame = new uint8_t[_frameLength]; //24 #ifdef STATIC_ONLY
char frame[STATIC_ARRAY_SIZE];
#else
uint8_t* frame = new uint8_t[_frameLength];
#endif
for(size_t i = 0; i < _frameLength; i++) { for(size_t i = 0; i < _frameLength; i++) {
frame[i] = _mod->ModuleSerial->read(); frame[i] = _mod->ModuleSerial->read();
} }
// save packet source and data // save packet source and data
size_t payloadLength = _frameLength - 12; size_t payloadLength = _frameLength - 12;
#ifndef STATIC_ONLY
delete[] _packetData; delete[] _packetData;
_packetData = new char[payloadLength]; _packetData = new char[payloadLength];
#endif
memcpy(_packetData, frame + 12, payloadLength - 1); memcpy(_packetData, frame + 12, payloadLength - 1);
_packetData[payloadLength - 1] = '\0'; _packetData[payloadLength - 1] = '\0';
memcpy(_packetSource, frame + 1, 8); memcpy(_packetSource, frame + 1, 8);
#ifndef STATIC_ONLY
delete[] frame; delete[] frame;
#endif
_frameLength = 0; _frameLength = 0;
_frameHeaderProcessed = false; _frameHeaderProcessed = false;
@ -219,22 +232,34 @@ int16_t XBeeSerial::setDestinationAddress(const char* destinationAddressHigh, co
// set higher address bytes // set higher address bytes
RADIOLIB_DEBUG_PRINTLN(F("Setting address (high) ...")); RADIOLIB_DEBUG_PRINTLN(F("Setting address (high) ..."));
#ifdef STATIC_ONLY
char addressHigh[13];
#else
char* addressHigh = new char[strlen(destinationAddressHigh) + 4]; char* addressHigh = new char[strlen(destinationAddressHigh) + 4];
#endif
strcpy(addressHigh, "ATDH"); strcpy(addressHigh, "ATDH");
strcat(addressHigh, destinationAddressHigh); strcat(addressHigh, destinationAddressHigh);
bool res = _mod->ATsendCommand(addressHigh); bool res = _mod->ATsendCommand(addressHigh);
#ifndef STATIC_ONLY
delete[] addressHigh; delete[] addressHigh;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
// set lower address bytes // set lower address bytes
RADIOLIB_DEBUG_PRINTLN(F("Setting address (low) ...")); RADIOLIB_DEBUG_PRINTLN(F("Setting address (low) ..."));
#ifdef STATIC_ONLY
char addressLow[13];
#else
char* addressLow = new char[strlen(destinationAddressLow) + 4]; char* addressLow = new char[strlen(destinationAddressLow) + 4];
#endif
strcpy(addressLow, "ATDL"); strcpy(addressLow, "ATDL");
strcat(addressLow, destinationAddressLow); strcat(addressLow, destinationAddressLow);
res = _mod->ATsendCommand(addressLow); res = _mod->ATsendCommand(addressLow);
#ifndef STATIC_ONLY
delete[] addressLow; delete[] addressLow;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
@ -257,11 +282,17 @@ int16_t XBeeSerial::setPanId(const char* panId) {
// set PAN ID // set PAN ID
RADIOLIB_DEBUG_PRINTLN(F("Setting PAN ID ...")); RADIOLIB_DEBUG_PRINTLN(F("Setting PAN ID ..."));
#ifdef STATIC_ONLY
char cmd[21];
#else
char* cmd = new char[strlen(panId) + 4]; char* cmd = new char[strlen(panId) + 4];
#endif
strcpy(cmd, "ATID"); strcpy(cmd, "ATID");
strcat(cmd, panId); strcat(cmd, panId);
bool res = _mod->ATsendCommand(cmd); bool res = _mod->ATsendCommand(cmd);
#ifndef STATIC_ONLY
delete[] cmd; delete[] cmd;
#endif
if(!res) { if(!res) {
return(ERR_AT_FAILED); return(ERR_AT_FAILED);
} }
@ -333,7 +364,11 @@ void XBee::sendApiFrame(uint8_t type, uint8_t id, const char* data) {
void XBee::sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length) { void XBee::sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length) {
// build the API frame // build the API frame
size_t frameLength = 1 + 2 + length + 1 + 2; size_t frameLength = 1 + 2 + length + 1 + 2;
#ifdef STATIC_ONLY
uint8_t frame[STATIC_ARRAY_SIZE];
#else
uint8_t* frame = new uint8_t[frameLength]; uint8_t* frame = new uint8_t[frameLength];
#endif
frame[0] = 0x7E; // start delimiter frame[0] = 0x7E; // start delimiter
frame[1] = ((length + 2) & 0xFF00) >> 8; // length MSB frame[1] = ((length + 2) & 0xFF00) >> 8; // length MSB
@ -355,7 +390,9 @@ void XBee::sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length
} }
// deallocate memory // deallocate memory
#ifndef STATIC_ONLY
delete[] frame; delete[] frame;
#endif
} }
int16_t XBee::readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout) { int16_t XBee::readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout) {
@ -381,7 +418,11 @@ int16_t XBee::readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout) {
RADIOLIB_DEBUG_PRINTLN(numBytes); RADIOLIB_DEBUG_PRINTLN(numBytes);
// read the response // read the response
#ifdef STATIC_ONLY
uint8_t resp[STATIC_ARRAY_SIZE];
#else
uint8_t* resp = new uint8_t[numBytes]; uint8_t* resp = new uint8_t[numBytes];
#endif
for(uint16_t i = 0; i < numBytes; i++) { for(uint16_t i = 0; i < numBytes; i++) {
resp[i] = _mod->ModuleSerial->read(); resp[i] = _mod->ModuleSerial->read();
} }
@ -410,7 +451,9 @@ int16_t XBee::readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout) {
// codePos does not include start delimiter and frame ID // codePos does not include start delimiter and frame ID
uint8_t code = resp[codePos]; uint8_t code = resp[codePos];
#ifndef STATIC_ONLY
delete[] resp; delete[] resp;
#endif
return(code); return(code);
} }

View file

@ -176,7 +176,11 @@ class XBee {
size_t _frameLength; size_t _frameLength;
bool _frameHeaderProcessed; bool _frameHeaderProcessed;
char* _packetData; #ifdef STATIC_ONLY
char _packetData[STATIC_ARRAY_SIZE];
#else
char* _packetData = new char[0];
#endif
uint8_t _packetSource[8]; uint8_t _packetSource[8];
int16_t confirmChanges(); int16_t confirmChanges();

View file

@ -27,7 +27,11 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
size_t encodedBytes = encodeLength(remainingLength, encoded); size_t encodedBytes = encodeLength(remainingLength, encoded);
// build the CONNECT packet // build the CONNECT packet
#ifdef STATIC_ONLY
uint8_t packet[256];
#else
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength]; uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
#endif
// fixed header // fixed header
packet[0] = (MQTT_CONNECT << 4) | 0b0000; packet[0] = (MQTT_CONNECT << 4) | 0b0000;
@ -97,13 +101,17 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
// create TCP connection // create TCP connection
int16_t state = _tl->openTransportConnection(host, "TCP", _port, keepAlive); int16_t state = _tl->openTransportConnection(host, "TCP", _port, keepAlive);
if(state != ERR_NONE) { if(state != ERR_NONE) {
#ifndef STATIC_ONLY
delete[] packet; delete[] packet;
#endif
return(state); return(state);
} }
// send MQTT packet // send MQTT packet
state = _tl->send(packet, 1 + encodedBytes + remainingLength); state = _tl->send(packet, 1 + encodedBytes + remainingLength);
#ifndef STATIC_ONLY
delete[] packet; delete[] packet;
#endif
if(state != ERR_NONE) { if(state != ERR_NONE) {
return(state); return(state);
} }
@ -115,15 +123,23 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
} }
// read the response // read the response
#ifdef STATIC_ONLY
uint8_t response[STATIC_ARRAY_SIZE];
#else
uint8_t* response = new uint8_t[numBytes]; uint8_t* response = new uint8_t[numBytes];
#endif
_tl->receive(response, numBytes); _tl->receive(response, numBytes);
if((response[0] == MQTT_CONNACK << 4) && (response[1] == 2)) { if((response[0] == MQTT_CONNACK << 4) && (response[1] == 2)) {
uint8_t returnCode = response[3]; uint8_t returnCode = response[3];
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(returnCode); return(returnCode);
} }
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(ERR_RESPONSE_MALFORMED); return(ERR_RESPONSE_MALFORMED);
} }
@ -158,7 +174,11 @@ int16_t MQTTClient::publish(const char* topic, const char* message) {
size_t encodedBytes = encodeLength(remainingLength, encoded); size_t encodedBytes = encodeLength(remainingLength, encoded);
// build the PUBLISH packet // build the PUBLISH packet
#ifdef STATIC_ONLY
uint8_t packet[STATIC_ARRAY_SIZE];
#else
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength]; uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
#endif
// fixed header // fixed header
packet[0] = (MQTT_PUBLISH << 4) | 0b0000; packet[0] = (MQTT_PUBLISH << 4) | 0b0000;
@ -181,7 +201,9 @@ int16_t MQTTClient::publish(const char* topic, const char* message) {
// send MQTT packet // send MQTT packet
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength); int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
#ifndef STATIC_ONLY
delete[] packet; delete[] packet;
#endif
return(state); return(state);
//TODO: implement QoS > 0 and PUBACK response checking //TODO: implement QoS > 0 and PUBACK response checking
@ -195,7 +217,11 @@ int16_t MQTTClient::subscribe(const char* topicFilter) {
size_t encodedBytes = encodeLength(remainingLength, encoded); size_t encodedBytes = encodeLength(remainingLength, encoded);
// build the SUBSCRIBE packet // build the SUBSCRIBE packet
#ifdef STATIC_ONLY
uint8_t packet[STATIC_ARRAY_SIZE];
#else
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength]; uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
#endif
// fixed header // fixed header
packet[0] = (MQTT_SUBSCRIBE << 4) | 0b0010; packet[0] = (MQTT_SUBSCRIBE << 4) | 0b0010;
@ -218,7 +244,9 @@ int16_t MQTTClient::subscribe(const char* topicFilter) {
// send MQTT packet // send MQTT packet
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength); int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
#ifndef STATIC_ONLY
delete[] packet; delete[] packet;
#endif
if(state != ERR_NONE) { if(state != ERR_NONE) {
return(state); return(state);
} }
@ -230,20 +258,28 @@ int16_t MQTTClient::subscribe(const char* topicFilter) {
} }
// read the response // read the response
#ifdef STATIC_ONLY
uint8_t response[STATIC_ARRAY_SIZE];
#else
uint8_t* response = new uint8_t[numBytes]; uint8_t* response = new uint8_t[numBytes];
#endif
_tl->receive(response, numBytes); _tl->receive(response, numBytes);
if((response[0] == MQTT_SUBACK << 4) && (response[1] == 3)) { if((response[0] == MQTT_SUBACK << 4) && (response[1] == 3)) {
// check packet ID // check packet ID
uint16_t receivedId = response[3] | response[2] << 8; uint16_t receivedId = response[3] | response[2] << 8;
int16_t returnCode = response[4]; int16_t returnCode = response[4];
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
if(receivedId != packetId) { if(receivedId != packetId) {
return(ERR_MQTT_UNEXPECTED_PACKET_ID); return(ERR_MQTT_UNEXPECTED_PACKET_ID);
} }
return(returnCode); return(returnCode);
} }
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(ERR_RESPONSE_MALFORMED); return(ERR_RESPONSE_MALFORMED);
} }
@ -255,7 +291,11 @@ int16_t MQTTClient::unsubscribe(const char* topicFilter) {
size_t encodedBytes = encodeLength(remainingLength, encoded); size_t encodedBytes = encodeLength(remainingLength, encoded);
// build the UNSUBSCRIBE packet // build the UNSUBSCRIBE packet
#ifdef STATIC_ONLY
uint8_t packet[STATIC_ARRAY_SIZE];
#else
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength]; uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
#endif
// fixed header // fixed header
packet[0] = (MQTT_UNSUBSCRIBE << 4) | 0b0010; packet[0] = (MQTT_UNSUBSCRIBE << 4) | 0b0010;
@ -277,7 +317,9 @@ int16_t MQTTClient::unsubscribe(const char* topicFilter) {
// send MQTT packet // send MQTT packet
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength); int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
#ifndef STATIC_ONLY
delete[] packet; delete[] packet;
#endif
if(state != ERR_NONE) { if(state != ERR_NONE) {
return(state); return(state);
} }
@ -289,19 +331,27 @@ int16_t MQTTClient::unsubscribe(const char* topicFilter) {
} }
// read the response // read the response
#ifdef STATIC_ONLY
uint8_t response[STATIC_ARRAY_SIZE];
#else
uint8_t* response = new uint8_t[numBytes]; uint8_t* response = new uint8_t[numBytes];
#endif
_tl->receive(response, numBytes); _tl->receive(response, numBytes);
if((response[0] == MQTT_UNSUBACK << 4) && (response[1] == 2)) { if((response[0] == MQTT_UNSUBACK << 4) && (response[1] == 2)) {
// check packet ID // check packet ID
uint16_t receivedId = response[3] | response[2] << 8; uint16_t receivedId = response[3] | response[2] << 8;
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
if(receivedId != packetId) { if(receivedId != packetId) {
return(ERR_MQTT_UNEXPECTED_PACKET_ID); return(ERR_MQTT_UNEXPECTED_PACKET_ID);
} }
return(ERR_NONE); return(ERR_NONE);
} }
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(ERR_RESPONSE_MALFORMED); return(ERR_RESPONSE_MALFORMED);
} }
@ -326,14 +376,22 @@ int16_t MQTTClient::ping() {
} }
// read the response // read the response
#ifdef STATIC_ONLY
uint8_t response[STATIC_ARRAY_SIZE];
#else
uint8_t* response = new uint8_t[numBytes]; uint8_t* response = new uint8_t[numBytes];
#endif
_tl->receive(response, numBytes); _tl->receive(response, numBytes);
if((response[0] == MQTT_PINGRESP << 4) && (response[1] == 0)) { if((response[0] == MQTT_PINGRESP << 4) && (response[1] == 0)) {
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(ERR_NONE); return(ERR_NONE);
} }
#ifndef STATIC_ONLY
delete[] response; delete[] response;
#endif
return(ERR_RESPONSE_MALFORMED); return(ERR_RESPONSE_MALFORMED);
} }

View file

@ -19,7 +19,11 @@ int16_t PhysicalLayer::transmit(__FlashStringHelper* fstr, uint8_t addr) {
} }
// dynamically allocate memory // dynamically allocate memory
#ifdef STATIC_ONLY
char str[STATIC_ARRAY_SIZE];
#else
char* str = new char[len]; char* str = new char[len];
#endif
// copy string from flash // copy string from flash
p = reinterpret_cast<PGM_P>(fstr); p = reinterpret_cast<PGM_P>(fstr);
@ -29,7 +33,9 @@ int16_t PhysicalLayer::transmit(__FlashStringHelper* fstr, uint8_t addr) {
// transmit string // transmit string
int16_t state = transmit(str, addr); int16_t state = transmit(str, addr);
#ifndef STATIC_ONLY
delete[] str; delete[] str;
#endif
return(state); return(state);
} }
@ -62,10 +68,14 @@ int16_t PhysicalLayer::readData(String& str, size_t len) {
} }
// build a temporary buffer // build a temporary buffer
#ifdef STATIC_ONLY
uint8_t data[STATIC_ARRAY_SIZE + 1];
#else
uint8_t* data = new uint8_t[length + 1]; uint8_t* data = new uint8_t[length + 1];
if(!data) { if(!data) {
return(ERR_MEMORY_ALLOCATION_FAILED); return(ERR_MEMORY_ALLOCATION_FAILED);
} }
#endif
// read the received data // read the received data
state = readData(data, length); state = readData(data, length);
@ -79,7 +89,9 @@ int16_t PhysicalLayer::readData(String& str, size_t len) {
} }
// deallocate temporary buffer // deallocate temporary buffer
#ifndef STATIC_ONLY
delete[] data; delete[] data;
#endif
return(state); return(state);
} }
@ -96,10 +108,14 @@ int16_t PhysicalLayer::receive(String& str, size_t len) {
} }
// build a temporary buffer // build a temporary buffer
#ifdef STATIC_ONLY
uint8_t data[STATIC_ARRAY_SIZE + 1];
#else
uint8_t* data = new uint8_t[length + 1]; uint8_t* data = new uint8_t[length + 1];
if(!data) { if(!data) {
return(ERR_MEMORY_ALLOCATION_FAILED); return(ERR_MEMORY_ALLOCATION_FAILED);
} }
#endif
// attempt packet reception // attempt packet reception
state = receive(data, length); state = receive(data, length);
@ -118,7 +134,9 @@ int16_t PhysicalLayer::receive(String& str, size_t len) {
} }
// deallocate temporary buffer // deallocate temporary buffer
#ifndef STATIC_ONLY
delete[] data; delete[] data;
#endif
return(state); return(state);
} }

View file

@ -2,20 +2,20 @@
ITA2String::ITA2String(char c) { ITA2String::ITA2String(char c) {
_len = 1; _len = 1;
_str = new char[1];
_str[0] = c; _str[0] = c;
_ita2Len = 0; _ita2Len = 0;
} }
ITA2String::ITA2String(const char* str) { ITA2String::ITA2String(const char* str) {
_len = strlen(str); _len = strlen(str);
_str = new char[_len];
strcpy(_str, str); strcpy(_str, str);
_ita2Len = 0; _ita2Len = 0;
} }
ITA2String::~ITA2String() { ITA2String::~ITA2String() {
#ifndef STATIC_ONLY
delete[] _str; delete[] _str;
#endif
} }
size_t ITA2String::length() { size_t ITA2String::length() {
@ -32,7 +32,11 @@ size_t ITA2String::length() {
uint8_t* ITA2String::byteArr() { uint8_t* ITA2String::byteArr() {
// create temporary array 2x the string length (figures may be 3 bytes) // create temporary array 2x the string length (figures may be 3 bytes)
#ifdef STATIC_ONLY
uint8_t temp[STATIC_ARRAY_SIZE*2 + 1];
#else
uint8_t* temp = new uint8_t[_len*2 + 1]; uint8_t* temp = new uint8_t[_len*2 + 1];
#endif
size_t arrayLen = 0; size_t arrayLen = 0;
bool flagFigure = false; bool flagFigure = false;
@ -75,7 +79,9 @@ uint8_t* ITA2String::byteArr() {
uint8_t* arr = new uint8_t[arrayLen]; uint8_t* arr = new uint8_t[arrayLen];
memcpy(arr, temp, arrayLen); memcpy(arr, temp, arrayLen);
#ifndef STATIC_ONLY
delete[] temp; delete[] temp;
#endif
return(arr); return(arr);
} }
@ -202,7 +208,11 @@ size_t RTTYClient::print(__FlashStringHelper* fstr) {
} }
// dynamically allocate memory // dynamically allocate memory
#ifdef STATIC_ONLY
char str[STATIC_ARRAY_SIZE];
#else
char* str = new char[len]; char* str = new char[len];
#endif
// copy string from flash // copy string from flash
p = reinterpret_cast<PGM_P>(fstr); p = reinterpret_cast<PGM_P>(fstr);
@ -217,7 +227,9 @@ size_t RTTYClient::print(__FlashStringHelper* fstr) {
} else if((_encoding == ASCII) || (_encoding == ASCII_EXTENDED)) { } else if((_encoding == ASCII) || (_encoding == ASCII_EXTENDED)) {
n = RTTYClient::write((uint8_t*)str, len); n = RTTYClient::write((uint8_t*)str, len);
} }
#ifndef STATIC_ONLY
delete[] str; delete[] str;
#endif
return(n); return(n);
} }

View file

@ -58,7 +58,11 @@ class ITA2String {
uint8_t* byteArr(); uint8_t* byteArr();
private: private:
char* _str; #ifdef STATIC_ONLY
char _str[STATIC_ARRAY_SIZE];
#else
char* _str = new char[1];
#endif
size_t _len; size_t _len;
size_t _ita2Len; size_t _ita2Len;