kopia lustrzana https://github.com/jgromes/RadioLib
Added option to use only static allocations
rodzic
d7e2dadb9f
commit
adcde6fb6c
|
@ -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
|
||||||
|
|
|
@ -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=\"";
|
||||||
uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4;
|
#ifdef STATIC_ONLY
|
||||||
char* cmd = new char[cmdLen + 1];
|
char cmd[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4;
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
char* cmd = new char[cmdLen + 1];
|
#ifdef STATIC_ONLY
|
||||||
|
char cmd[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
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=";
|
||||||
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
|
#ifdef STATIC_ONLY
|
||||||
|
char cmd[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
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=";
|
||||||
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
|
#ifdef STATIC_ONLY
|
||||||
|
char cmd[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] cmd;
|
||||||
|
#endif
|
||||||
if(!res) {
|
if(!res) {
|
||||||
return(ERR_AT_FAILED);
|
return(ERR_AT_FAILED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
uint8_t* dat = new uint8_t[2 + numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t dat[STATIC_ARRAY_SIZE + 2];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] dat;
|
#ifndef STATIC_ONLY
|
||||||
|
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) {
|
||||||
uint8_t* dat = new uint8_t[1 + numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t dat[STATIC_ARRAY_SIZE + 1];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] dat;
|
#ifndef STATIC_ONLY
|
||||||
|
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)
|
||||||
uint8_t* dat = new uint8_t[1 + numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t dat[STATIC_ARRAY_SIZE + 1];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] dat;
|
#ifndef STATIC_ONLY
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
uint8_t* cmd = new uint8_t[dataLen];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t cmd[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
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;
|
||||||
delete[] _packetData;
|
#ifndef STATIC_ONLY
|
||||||
_packetData = new char[payloadLength];
|
delete[] _packetData;
|
||||||
|
_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);
|
||||||
|
|
||||||
delete[] frame;
|
#ifndef STATIC_ONLY
|
||||||
|
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) ..."));
|
||||||
char* addressHigh = new char[strlen(destinationAddressHigh) + 4];
|
#ifdef STATIC_ONLY
|
||||||
|
char addressHigh[13];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] addressHigh;
|
#ifndef STATIC_ONLY
|
||||||
|
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) ..."));
|
||||||
char* addressLow = new char[strlen(destinationAddressLow) + 4];
|
#ifdef STATIC_ONLY
|
||||||
|
char addressLow[13];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] addressLow;
|
#ifndef STATIC_ONLY
|
||||||
|
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 ..."));
|
||||||
char* cmd = new char[strlen(panId) + 4];
|
#ifdef STATIC_ONLY
|
||||||
|
char cmd[21];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] cmd;
|
#ifndef STATIC_ONLY
|
||||||
|
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;
|
||||||
uint8_t* frame = new uint8_t[frameLength];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t frame[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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
|
||||||
delete[] frame;
|
#ifndef STATIC_ONLY
|
||||||
|
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
|
||||||
uint8_t* resp = new uint8_t[numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t resp[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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];
|
||||||
delete[] resp;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] resp;
|
||||||
|
#endif
|
||||||
return(code);
|
return(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -18,21 +18,25 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
|
||||||
remainingLength += (2 + userNameLen);
|
remainingLength += (2 + userNameLen);
|
||||||
}
|
}
|
||||||
if(passwordLen > 0) {
|
if(passwordLen > 0) {
|
||||||
remainingLength += (2 + passwordLen);
|
remainingLength += (2 + passwordLen);
|
||||||
}
|
}
|
||||||
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
||||||
remainingLength += (2 + willTopicLen) + (2 + willMessageLen);
|
remainingLength += (2 + willTopicLen) + (2 + willMessageLen);
|
||||||
}
|
}
|
||||||
uint8_t encoded[] = {0, 0, 0, 0};
|
uint8_t encoded[] = {0, 0, 0, 0};
|
||||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||||
|
|
||||||
// build the CONNECT packet
|
// build the CONNECT packet
|
||||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t packet[256];
|
||||||
|
#else
|
||||||
|
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;
|
||||||
memcpy(packet + 1, encoded, encodedBytes);
|
memcpy(packet + 1, encoded, encodedBytes);
|
||||||
|
|
||||||
// variable header
|
// variable header
|
||||||
// protocol name
|
// protocol name
|
||||||
size_t pos = encodedBytes + 1;
|
size_t pos = encodedBytes + 1;
|
||||||
|
@ -40,42 +44,42 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
|
||||||
packet[pos++] = 0x04;
|
packet[pos++] = 0x04;
|
||||||
memcpy(packet + pos, "MQTT", 4);
|
memcpy(packet + pos, "MQTT", 4);
|
||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
// protocol level
|
// protocol level
|
||||||
packet[pos++] = 0x04;
|
packet[pos++] = 0x04;
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
packet[pos++] = 0x00;
|
packet[pos++] = 0x00;
|
||||||
if(cleanSession) {
|
if(cleanSession) {
|
||||||
packet[encodedBytes + 8] |= MQTT_CONNECT_CLEAN_SESSION;
|
packet[encodedBytes + 8] |= MQTT_CONNECT_CLEAN_SESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep alive interval in seconds
|
// keep alive interval in seconds
|
||||||
packet[pos++] = (keepAlive & 0xFF00) >> 8;
|
packet[pos++] = (keepAlive & 0xFF00) >> 8;
|
||||||
packet[pos++] = keepAlive & 0x00FF;
|
packet[pos++] = keepAlive & 0x00FF;
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
// clientId
|
// clientId
|
||||||
packet[pos++] = (clientIdLen & 0xFF00) >> 8;
|
packet[pos++] = (clientIdLen & 0xFF00) >> 8;
|
||||||
packet[pos++] = clientIdLen & 0x00FF;
|
packet[pos++] = clientIdLen & 0x00FF;
|
||||||
memcpy(packet + pos, clientId, clientIdLen);
|
memcpy(packet + pos, clientId, clientIdLen);
|
||||||
pos += clientIdLen;
|
pos += clientIdLen;
|
||||||
|
|
||||||
// will topic and message
|
// will topic and message
|
||||||
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
||||||
packet[encodedBytes + 8] |= MQTT_CONNECT_WILL_FLAG;
|
packet[encodedBytes + 8] |= MQTT_CONNECT_WILL_FLAG;
|
||||||
|
|
||||||
packet[pos++] = (willTopicLen & 0xFF00) >> 8;
|
packet[pos++] = (willTopicLen & 0xFF00) >> 8;
|
||||||
packet[pos++] = willTopicLen & 0x00FF;
|
packet[pos++] = willTopicLen & 0x00FF;
|
||||||
memcpy(packet + pos, willTopic, willTopicLen);
|
memcpy(packet + pos, willTopic, willTopicLen);
|
||||||
pos += willTopicLen;
|
pos += willTopicLen;
|
||||||
|
|
||||||
packet[pos++] = (willMessageLen & 0xFF00) >> 8;
|
packet[pos++] = (willMessageLen & 0xFF00) >> 8;
|
||||||
packet[pos++] = willMessageLen & 0x00FF;
|
packet[pos++] = willMessageLen & 0x00FF;
|
||||||
memcpy(packet + pos, willMessage, willMessageLen);
|
memcpy(packet + pos, willMessage, willMessageLen);
|
||||||
pos += willMessageLen;
|
pos += willMessageLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// user name
|
// user name
|
||||||
if(userNameLen > 0) {
|
if(userNameLen > 0) {
|
||||||
packet[encodedBytes + 8] |= MQTT_CONNECT_USER_NAME_FLAG;
|
packet[encodedBytes + 8] |= MQTT_CONNECT_USER_NAME_FLAG;
|
||||||
|
@ -84,7 +88,7 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
|
||||||
memcpy(packet + pos, userName, userNameLen);
|
memcpy(packet + pos, userName, userNameLen);
|
||||||
pos += userNameLen;
|
pos += userNameLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// password
|
// password
|
||||||
if(passwordLen > 0) {
|
if(passwordLen > 0) {
|
||||||
packet[encodedBytes + 8] |= MQTT_CONNECT_PASSWORD_FLAG;
|
packet[encodedBytes + 8] |= MQTT_CONNECT_PASSWORD_FLAG;
|
||||||
|
@ -93,54 +97,66 @@ int16_t MQTTClient::connect(const char* host, const char* clientId, const char*
|
||||||
memcpy(packet + pos, password, passwordLen);
|
memcpy(packet + pos, password, passwordLen);
|
||||||
pos += passwordLen;
|
pos += passwordLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
delete[] packet;
|
#ifndef STATIC_ONLY
|
||||||
|
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);
|
||||||
delete[] packet;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] packet;
|
||||||
|
#endif
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the response length (MQTT CONNACK response has to be 4 bytes long)
|
// get the response length (MQTT CONNACK response has to be 4 bytes long)
|
||||||
size_t numBytes = _tl->getNumBytes();
|
size_t numBytes = _tl->getNumBytes();
|
||||||
if(numBytes != 4) {
|
if(numBytes != 4) {
|
||||||
return(ERR_RESPONSE_MALFORMED_AT);
|
return(ERR_RESPONSE_MALFORMED_AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the response
|
// read the response
|
||||||
uint8_t* response = new uint8_t[numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t response[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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];
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(returnCode);
|
return(returnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(ERR_RESPONSE_MALFORMED);
|
return(ERR_RESPONSE_MALFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t MQTTClient::disconnect() {
|
int16_t MQTTClient::disconnect() {
|
||||||
// build the DISCONNECT packet
|
// build the DISCONNECT packet
|
||||||
uint8_t packet[2];
|
uint8_t packet[2];
|
||||||
|
|
||||||
// fixed header
|
// fixed header
|
||||||
packet[0] = (MQTT_DISCONNECT << 4) | 0b0000;
|
packet[0] = (MQTT_DISCONNECT << 4) | 0b0000;
|
||||||
packet[1] = 0x00;
|
packet[1] = 0x00;
|
||||||
|
|
||||||
// send MQTT packet
|
// send MQTT packet
|
||||||
int16_t state = _tl->send(packet, 2);
|
int16_t state = _tl->send(packet, 2);
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// close tl connection
|
// close tl connection
|
||||||
return(_tl->closeTransportConnection());
|
return(_tl->closeTransportConnection());
|
||||||
}
|
}
|
||||||
|
@ -156,14 +172,18 @@ int16_t MQTTClient::publish(const char* topic, const char* message) {
|
||||||
uint32_t remainingLength = (2 + topicLen) + messageLen;
|
uint32_t remainingLength = (2 + topicLen) + messageLen;
|
||||||
uint8_t encoded[] = {0, 0, 0, 0};
|
uint8_t encoded[] = {0, 0, 0, 0};
|
||||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||||
|
|
||||||
// build the PUBLISH packet
|
// build the PUBLISH packet
|
||||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t packet[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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;
|
||||||
memcpy(packet + 1, encoded, encodedBytes);
|
memcpy(packet + 1, encoded, encodedBytes);
|
||||||
|
|
||||||
// variable header
|
// variable header
|
||||||
// topic name
|
// topic name
|
||||||
size_t pos = encodedBytes + 1;
|
size_t pos = encodedBytes + 1;
|
||||||
|
@ -171,19 +191,21 @@ int16_t MQTTClient::publish(const char* topic, const char* message) {
|
||||||
packet[pos++] = topicLen & 0x00FF;
|
packet[pos++] = topicLen & 0x00FF;
|
||||||
memcpy(packet + pos, topic, topicLen);
|
memcpy(packet + pos, topic, topicLen);
|
||||||
pos += topicLen;
|
pos += topicLen;
|
||||||
|
|
||||||
// packet ID
|
// packet ID
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
// message
|
// message
|
||||||
memcpy(packet + pos, message, messageLen);
|
memcpy(packet + pos, message, messageLen);
|
||||||
pos += messageLen;
|
pos += messageLen;
|
||||||
|
|
||||||
// send MQTT packet
|
// send MQTT packet
|
||||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||||
delete[] packet;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] packet;
|
||||||
|
#endif
|
||||||
return(state);
|
return(state);
|
||||||
|
|
||||||
//TODO: implement QoS > 0 and PUBACK response checking
|
//TODO: implement QoS > 0 and PUBACK response checking
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,21 +215,25 @@ int16_t MQTTClient::subscribe(const char* topicFilter) {
|
||||||
uint32_t remainingLength = 2 + (2 + topicFilterLen + 1);
|
uint32_t remainingLength = 2 + (2 + topicFilterLen + 1);
|
||||||
uint8_t encoded[] = {0, 0, 0, 0};
|
uint8_t encoded[] = {0, 0, 0, 0};
|
||||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||||
|
|
||||||
// build the SUBSCRIBE packet
|
// build the SUBSCRIBE packet
|
||||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t packet[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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;
|
||||||
memcpy(packet + 1, encoded, encodedBytes);
|
memcpy(packet + 1, encoded, encodedBytes);
|
||||||
|
|
||||||
// variable header
|
// variable header
|
||||||
// packet ID
|
// packet ID
|
||||||
size_t pos = encodedBytes + 1;
|
size_t pos = encodedBytes + 1;
|
||||||
uint16_t packetId = _packetId++;
|
uint16_t packetId = _packetId++;
|
||||||
packet[pos++] = (packetId & 0xFF00) >> 8;
|
packet[pos++] = (packetId & 0xFF00) >> 8;
|
||||||
packet[pos++] = packetId & 0x00FF;
|
packet[pos++] = packetId & 0x00FF;
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
// topic filter
|
// topic filter
|
||||||
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
||||||
|
@ -215,35 +241,45 @@ int16_t MQTTClient::subscribe(const char* topicFilter) {
|
||||||
memcpy(packet + pos, topicFilter, topicFilterLen);
|
memcpy(packet + pos, topicFilter, topicFilterLen);
|
||||||
pos += topicFilterLen;
|
pos += topicFilterLen;
|
||||||
packet[pos++] = 0x00; // QoS 0
|
packet[pos++] = 0x00; // QoS 0
|
||||||
|
|
||||||
// send MQTT packet
|
// send MQTT packet
|
||||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||||
delete[] packet;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] packet;
|
||||||
|
#endif
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the response length (MQTT SUBACK response has to be 5 bytes long for single subscription)
|
// get the response length (MQTT SUBACK response has to be 5 bytes long for single subscription)
|
||||||
size_t numBytes = _tl->getNumBytes();
|
size_t numBytes = _tl->getNumBytes();
|
||||||
if(numBytes != 5) {
|
if(numBytes != 5) {
|
||||||
return(ERR_RESPONSE_MALFORMED_AT);
|
return(ERR_RESPONSE_MALFORMED_AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the response
|
// read the response
|
||||||
uint8_t* response = new uint8_t[numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t response[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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];
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(ERR_RESPONSE_MALFORMED);
|
return(ERR_RESPONSE_MALFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,87 +289,109 @@ int16_t MQTTClient::unsubscribe(const char* topicFilter) {
|
||||||
uint32_t remainingLength = 2 + (2 + topicFilterLen);
|
uint32_t remainingLength = 2 + (2 + topicFilterLen);
|
||||||
uint8_t encoded[] = {0, 0, 0, 0};
|
uint8_t encoded[] = {0, 0, 0, 0};
|
||||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||||
|
|
||||||
// build the UNSUBSCRIBE packet
|
// build the UNSUBSCRIBE packet
|
||||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t packet[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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;
|
||||||
memcpy(packet + 1, encoded, encodedBytes);
|
memcpy(packet + 1, encoded, encodedBytes);
|
||||||
|
|
||||||
// variable header
|
// variable header
|
||||||
// packet ID
|
// packet ID
|
||||||
size_t pos = encodedBytes + 1;
|
size_t pos = encodedBytes + 1;
|
||||||
uint16_t packetId = _packetId++;
|
uint16_t packetId = _packetId++;
|
||||||
packet[pos++] = (packetId & 0xFF00) >> 8;
|
packet[pos++] = (packetId & 0xFF00) >> 8;
|
||||||
packet[pos++] = packetId & 0x00FF;
|
packet[pos++] = packetId & 0x00FF;
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
// topic filter
|
// topic filter
|
||||||
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
||||||
packet[pos++] = topicFilterLen & 0x00FF;
|
packet[pos++] = topicFilterLen & 0x00FF;
|
||||||
memcpy(packet + pos, topicFilter, topicFilterLen);
|
memcpy(packet + pos, topicFilter, topicFilterLen);
|
||||||
pos += topicFilterLen;
|
pos += topicFilterLen;
|
||||||
|
|
||||||
// send MQTT packet
|
// send MQTT packet
|
||||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||||
delete[] packet;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] packet;
|
||||||
|
#endif
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the response length (MQTT UNSUBACK response has to be 4 bytes long)
|
// get the response length (MQTT UNSUBACK response has to be 4 bytes long)
|
||||||
size_t numBytes = _tl->getNumBytes();
|
size_t numBytes = _tl->getNumBytes();
|
||||||
if(numBytes != 4) {
|
if(numBytes != 4) {
|
||||||
return(ERR_RESPONSE_MALFORMED_AT);
|
return(ERR_RESPONSE_MALFORMED_AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the response
|
// read the response
|
||||||
uint8_t* response = new uint8_t[numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t response[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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;
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(ERR_RESPONSE_MALFORMED);
|
return(ERR_RESPONSE_MALFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t MQTTClient::ping() {
|
int16_t MQTTClient::ping() {
|
||||||
// build the PINGREQ packet
|
// build the PINGREQ packet
|
||||||
uint8_t packet[2];
|
uint8_t packet[2];
|
||||||
|
|
||||||
// fixed header
|
// fixed header
|
||||||
packet[0] = (MQTT_PINGREQ << 4) | 0b0000;
|
packet[0] = (MQTT_PINGREQ << 4) | 0b0000;
|
||||||
packet[1] = 0x00;
|
packet[1] = 0x00;
|
||||||
|
|
||||||
// send MQTT packet
|
// send MQTT packet
|
||||||
int16_t state = _tl->send(packet, 2);
|
int16_t state = _tl->send(packet, 2);
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the response length (MQTT PINGRESP response has to be 2 bytes long)
|
// get the response length (MQTT PINGRESP response has to be 2 bytes long)
|
||||||
size_t numBytes = _tl->getNumBytes();
|
size_t numBytes = _tl->getNumBytes();
|
||||||
if(numBytes != 2) {
|
if(numBytes != 2) {
|
||||||
return(ERR_RESPONSE_MALFORMED_AT);
|
return(ERR_RESPONSE_MALFORMED_AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the response
|
// read the response
|
||||||
uint8_t* response = new uint8_t[numBytes];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t response[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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)) {
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] response;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] response;
|
||||||
|
#endif
|
||||||
return(ERR_RESPONSE_MALFORMED);
|
return(ERR_RESPONSE_MALFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,42 +401,42 @@ int16_t MQTTClient::check(void (*func)(const char*, const char*)) {
|
||||||
if(state != ERR_NONE) {
|
if(state != ERR_NONE) {
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check new data
|
// check new data
|
||||||
size_t numBytes = _tl->getNumBytes();
|
size_t numBytes = _tl->getNumBytes();
|
||||||
if(numBytes == 0) {
|
if(numBytes == 0) {
|
||||||
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the PUBLISH packet from server
|
// read the PUBLISH packet from server
|
||||||
uint8_t* dataIn = new uint8_t[numBytes];
|
uint8_t* dataIn = new uint8_t[numBytes];
|
||||||
_tl->receive(dataIn, numBytes);
|
_tl->receive(dataIn, numBytes);
|
||||||
if(dataIn[0] == MQTT_PUBLISH << 4) {
|
if(dataIn[0] == MQTT_PUBLISH << 4) {
|
||||||
// TODO: properly decode remaining length
|
// TODO: properly decode remaining length
|
||||||
uint8_t remainingLength = dataIn[1];
|
uint8_t remainingLength = dataIn[1];
|
||||||
|
|
||||||
// get the topic
|
// get the topic
|
||||||
size_t topicLength = dataIn[3] | dataIn[2] << 8;
|
size_t topicLength = dataIn[3] | dataIn[2] << 8;
|
||||||
char* topic = new char[topicLength + 1];
|
char* topic = new char[topicLength + 1];
|
||||||
memcpy(topic, dataIn + 4, topicLength);
|
memcpy(topic, dataIn + 4, topicLength);
|
||||||
topic[topicLength] = 0x00;
|
topic[topicLength] = 0x00;
|
||||||
|
|
||||||
// get the message
|
// get the message
|
||||||
size_t messageLength = remainingLength - topicLength - 2;
|
size_t messageLength = remainingLength - topicLength - 2;
|
||||||
char* message = new char[messageLength + 1];
|
char* message = new char[messageLength + 1];
|
||||||
memcpy(message, dataIn + 4 + topicLength, messageLength);
|
memcpy(message, dataIn + 4 + topicLength, messageLength);
|
||||||
message[messageLength] = 0x00;
|
message[messageLength] = 0x00;
|
||||||
|
|
||||||
// execute the callback function provided by user
|
// execute the callback function provided by user
|
||||||
func(topic, message);
|
func(topic, message);
|
||||||
|
|
||||||
delete[] topic;
|
delete[] topic;
|
||||||
delete[] message;
|
delete[] message;
|
||||||
delete[] dataIn;
|
delete[] dataIn;
|
||||||
return(ERR_NONE);
|
return(ERR_NONE);
|
||||||
}
|
}
|
||||||
delete[] dataIn;
|
delete[] dataIn;
|
||||||
|
|
||||||
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,11 @@ int16_t PhysicalLayer::transmit(__FlashStringHelper* fstr, uint8_t addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamically allocate memory
|
// dynamically allocate memory
|
||||||
char* str = new char[len];
|
#ifdef STATIC_ONLY
|
||||||
|
char str[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] str;
|
#ifndef STATIC_ONLY
|
||||||
|
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
|
||||||
uint8_t* data = new uint8_t[length + 1];
|
#ifdef STATIC_ONLY
|
||||||
if(!data) {
|
uint8_t data[STATIC_ARRAY_SIZE + 1];
|
||||||
return(ERR_MEMORY_ALLOCATION_FAILED);
|
#else
|
||||||
}
|
uint8_t* data = new uint8_t[length + 1];
|
||||||
|
if(!data) {
|
||||||
|
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
|
||||||
delete[] data;
|
#ifndef STATIC_ONLY
|
||||||
|
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
|
||||||
uint8_t* data = new uint8_t[length + 1];
|
#ifdef STATIC_ONLY
|
||||||
if(!data) {
|
uint8_t data[STATIC_ARRAY_SIZE + 1];
|
||||||
return(ERR_MEMORY_ALLOCATION_FAILED);
|
#else
|
||||||
}
|
uint8_t* data = new uint8_t[length + 1];
|
||||||
|
if(!data) {
|
||||||
|
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
|
||||||
delete[] data;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] data;
|
||||||
|
#endif
|
||||||
|
|
||||||
return(state);
|
return(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
delete[] _str;
|
#ifndef STATIC_ONLY
|
||||||
|
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)
|
||||||
uint8_t* temp = new uint8_t[_len*2 + 1];
|
#ifdef STATIC_ONLY
|
||||||
|
uint8_t temp[STATIC_ARRAY_SIZE*2 + 1];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
delete[] temp;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] temp;
|
||||||
|
#endif
|
||||||
|
|
||||||
return(arr);
|
return(arr);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +208,11 @@ size_t RTTYClient::print(__FlashStringHelper* fstr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamically allocate memory
|
// dynamically allocate memory
|
||||||
char* str = new char[len];
|
#ifdef STATIC_ONLY
|
||||||
|
char str[STATIC_ARRAY_SIZE];
|
||||||
|
#else
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
delete[] str;
|
#ifndef STATIC_ONLY
|
||||||
|
delete[] str;
|
||||||
|
#endif
|
||||||
return(n);
|
return(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue