Dropped support for ESP8266, HC05, JDY08, HTTP and MQTT
This commit is contained in:
parent
5c538f31ea
commit
0d9718a603
28 changed files with 5 additions and 2998 deletions
README.md
examples
HC05/HC05_Basic
HTTP
JDY08/JDY08_Basic
MQTT
XBee
extras/bin
src
|
@ -13,9 +13,6 @@ RadioLib was originally created as a driver for [__RadioShield__](https://github
|
|||
|
||||
### Supported modules:
|
||||
* __CC1101__ FSK radio module
|
||||
* __ESP8266__ WiFi module
|
||||
* __HC05__ Bluetooth module
|
||||
* __JDY08__ BLE module
|
||||
* __LLCC68__ LoRa module
|
||||
* __nRF24L01__ 2.4 GHz module
|
||||
* __RF69__ FSK/OOK radio module
|
||||
|
@ -26,13 +23,8 @@ RadioLib was originally created as a driver for [__RadioShield__](https://github
|
|||
* __SX127x__ series LoRa modules (SX1272, SX1273, SX1276, SX1277, SX1278, SX1279)
|
||||
* __SX128x__ series LoRa/GFSK/BLE/FLRC modules (SX1280, SX1281, SX1282)
|
||||
* __SX1231__ FSK/OOK radio module
|
||||
* __XBee__ modules (S2B)
|
||||
|
||||
### Supported protocols and digital modes:
|
||||
* __MQTT__ for modules:
|
||||
ESP8266
|
||||
* __HTTP__ for modules:
|
||||
ESP8266
|
||||
* __AX.25__ using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
|
||||
* [__RTTY__](https://www.sigidwiki.com/wiki/RTTY) using 2-FSK or AFSK for modules:
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
RadioLib HC05 Example
|
||||
|
||||
This example sends data using HC05 Bluetooth module.
|
||||
HC05 works exactly like a Serial line, data are sent to the paired device.
|
||||
The default pairing code for HC05 is 1234 or 1111.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// HC05 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
HC05 bluetooth = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//HC05 bluetooth = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize HC05
|
||||
// baudrate: 9600 baud
|
||||
bluetooth.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// HC05 supports all methods of the Serial class
|
||||
// read data incoming from Serial port and write them to Bluetooth
|
||||
while (Serial.available() > 0) {
|
||||
bluetooth.write(Serial.read());
|
||||
}
|
||||
|
||||
// read data incoming from Bluetooth and write them to Serial port
|
||||
while (bluetooth.available() > 0) {
|
||||
Serial.write(bluetooth.read());
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
RadioLib HTTP GET Example
|
||||
|
||||
This example sends HTTP GET request using ESP8266 WiFi module.
|
||||
|
||||
Please note that the response will be saved including header. HTTP header size
|
||||
can easily exceed Arduino resources and cause the program to behave erratically.
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
|
||||
AT firmware (can be found in the /extras folder of the library)!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// ESP8266 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
ESP8266 wifi = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//ESP8266 wifi = RadioShield.ModuleA;
|
||||
|
||||
// create HTTP client instance using the wifi module
|
||||
// the default port used for HTTP is 80
|
||||
HTTPClient http(&wifi, 80);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize ESP8266
|
||||
Serial.print(F("[ESP8266] Initializing ... "));
|
||||
// baudrate: 9600 baud
|
||||
int state = wifi.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// join access point
|
||||
Serial.print(F("[ESP8266] Joining AP ... "));
|
||||
// name: SSID
|
||||
// password: password
|
||||
state = wifi.join("SSID", "password");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send HTTP GET request to www.httpbin.org/ip
|
||||
// the response will contain origin IP address of the request
|
||||
String response;
|
||||
Serial.print(F("[ESP8266] Sending HTTP GET request ... "));
|
||||
// URL: www.httpbin.org/ip
|
||||
int http_code = http.get("www.httpbin.org/ip", response);
|
||||
if (http_code > 0) {
|
||||
Serial.print(F("HTTP code "));
|
||||
Serial.println(http_code);
|
||||
Serial.print(F("[ESP8266] Response is "));
|
||||
Serial.print(response.length());
|
||||
Serial.println(F(" bytes long."));
|
||||
Serial.println(response);
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(http_code);
|
||||
}
|
||||
|
||||
// wait for a second before sending new request
|
||||
delay(1000);
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
RadioLib HTTP POST Example
|
||||
|
||||
This example sends HTTP POST request using ESP8266 WiFi module.
|
||||
|
||||
Please note that the response will be saved including header. HTTP header size
|
||||
can easily exceed Arduino resources and cause the program to behave erratically.
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
|
||||
AT firmware (can be found in the /extras folder of the library)!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// ESP8266 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
ESP8266 wifi = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//ESP8266 wifi = RadioShield.ModuleA;
|
||||
|
||||
// create HTTP client instance using the wifi module
|
||||
// the default port used for HTTP is 80
|
||||
HTTPClient http(&wifi, 80);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize ESP8266
|
||||
Serial.print(F("[ESP8266] Initializing ... "));
|
||||
// baudrate: 9600 baud
|
||||
int state = wifi.begin(9600);
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
|
||||
// join access point
|
||||
Serial.print(F("[ESP8266] Joining AP ... "));
|
||||
// name: SSID
|
||||
// password: password
|
||||
state = wifi.join("SSID", "password");
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send HTTP POST request to www.httpbin.org/status/404
|
||||
// the server doesn't process the posted data, it just returns
|
||||
// response with the status code 404
|
||||
String response;
|
||||
Serial.print(F("[ESP8266] Sending HTTP POST request ... "));
|
||||
// URL: www.httpbin.org/status/404
|
||||
// content: str
|
||||
// content type: text/plain
|
||||
int http_code = http.post("www.httpbin.org/status/404", "str", response);
|
||||
if(http_code > 0) {
|
||||
Serial.print(F("HTTP code "));
|
||||
Serial.println(http_code);
|
||||
Serial.print(F("[ESP8266] Response is "));
|
||||
Serial.print(response.length());
|
||||
Serial.println(F(" bytes long."));
|
||||
Serial.println(response);
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(http_code);
|
||||
}
|
||||
|
||||
// wait for a second before sending new request
|
||||
delay(1000);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
RadioLib JDY08 Example
|
||||
|
||||
This example sends data using JDY08 Bluetooth module.
|
||||
JDY08 works exactly like a Serial line, data are sent to the paired device.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// JDY08 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
JDY08 ble = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//JDY08 ble = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize JDY08
|
||||
// baudrate: 9600 baud
|
||||
ble.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// JDY08 supports all methods of the Serial class
|
||||
// read data incoming from Serial port and write them to Bluetooth
|
||||
while (Serial.available() > 0) {
|
||||
ble.write(Serial.read());
|
||||
}
|
||||
|
||||
// read data incoming from Bluetooth and write them to Serial port
|
||||
while (ble.available() > 0) {
|
||||
Serial.write(ble.read());
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
RadioLib MQTT Publish Example
|
||||
|
||||
This example publishes MQTT messages using ESP8266 WiFi module.
|
||||
|
||||
The messages are published to https://shiftr.io/try. You can use this namespace
|
||||
for testing purposes, but remember that it is publicly accessible!
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
|
||||
AT firmware (can be found in the /extras folder of the library)!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// ESP8266 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
ESP8266 wifi = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//ESP8266 wifi = RadioShield.ModuleA;
|
||||
|
||||
// create MQTT client instance using the wifi module
|
||||
// the default port used for MQTT is 1883
|
||||
MQTTClient mqtt(&wifi, 1883);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize ESP8266
|
||||
Serial.print(F("[ESP8266] Initializing ... "));
|
||||
// baudrate: 9600 baud
|
||||
int state = wifi.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// join access point
|
||||
Serial.print(F("[ESP8266] Joining AP ... "));
|
||||
// name: SSID
|
||||
// password: password
|
||||
state = wifi.join("SSID", "password");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// connect to MQTT server
|
||||
Serial.print(F("[ESP8266] Connecting to MQTT server ... "));
|
||||
// server URL: broker.shiftr.io
|
||||
// client ID: arduino
|
||||
// username: try
|
||||
// password: try
|
||||
state = mqtt.connect("broker.shiftr.io", "arduino", "try", "try");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// publish MQTT message
|
||||
Serial.print(F("[ESP8266] Publishing MQTT message ... "));
|
||||
// topic name: hello
|
||||
// application message: world
|
||||
int state = mqtt.publish("hello", "world");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait for a second before publishing again
|
||||
delay(1000);
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
RadioLib MQTT Subscribe Example
|
||||
|
||||
This example subscribes to MQTT topic using ESP8266 WiFi module.
|
||||
|
||||
The messages are pulled from https://shiftr.io/try. You can use this namespace
|
||||
for testing purposes, but remember that it is publicly accessible!
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
|
||||
AT firmware (can be found in the /extras folder of the library)!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// ESP8266 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
ESP8266 wifi = new SerialModule(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//ESP8266 wifi = RadioShield.ModuleA;
|
||||
|
||||
// create MQTT client instance using the wifi module
|
||||
// the default port used for MQTT is 1883
|
||||
MQTTClient mqtt(&wifi, 1883);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize ESP8266
|
||||
Serial.print(F("[ESP8266] Initializing ... "));
|
||||
// baudrate: 9600 baud
|
||||
int state = wifi.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// join access point
|
||||
Serial.print(F("[ESP8266] Joining AP ... "));
|
||||
// name: SSID
|
||||
// password: password
|
||||
state = wifi.join("SSID", "password");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// connect to MQTT server
|
||||
Serial.print(F("[ESP8266] Connecting to MQTT server ... "));
|
||||
// server URL: broker.shiftr.io
|
||||
// client ID: arduino
|
||||
// username: try
|
||||
// password: try
|
||||
state = mqtt.connect("broker.shiftr.io", "arduino", "try", "try");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// subscribe to MQTT topic
|
||||
// after calling this method, server will send PUBLISH packets
|
||||
// to this client each time a new message was published at the topic
|
||||
Serial.print(F("[ESP8266] Subscribing to MQTT topic ... "));
|
||||
// topic name: hello
|
||||
state = mqtt.subscribe("hello");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// unsubscribe from MQTT topic
|
||||
// after calling this method, server will stop sending PUBLISH packets
|
||||
Serial.print(F("[ESP8266] Unsubscribing from MQTT topic ... "));
|
||||
// topic filter: hello
|
||||
state = mqtt.unsubscribe("hello");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// create a function that will be called when a new PUBLISH packet
|
||||
// arrives from the server
|
||||
//
|
||||
// IMPORTANT: This function MUST have two C-strings as arguments!
|
||||
void onPublish(const char* topic, const char* message) {
|
||||
Serial.println(F("[ESP8266] Received packet from MQTT server: "));
|
||||
Serial.print(F("[ESP8266] Topic:\t"));
|
||||
Serial.println(topic);
|
||||
Serial.print(F("[ESP8266] Message:\t"));
|
||||
Serial.println(message);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check for new MQTT packets from server each time the loop() runs
|
||||
// this will also send a PING packet, restarting the keep alive timer
|
||||
int state = mqtt.check(onPublish);
|
||||
Serial.print(F("[ESP8266] MQTT check "));
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// the rest of your loop() code goes here
|
||||
// make sure that the maximum time the loop() runs is less than 1.5x keep alive,
|
||||
// otherwise the server will close the network connection
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
RadioLib XBee API Receive Example
|
||||
|
||||
This example receives packets using XBee API mode.
|
||||
In API mode, many XBee modules can form a mesh network.
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the XBee module
|
||||
is running API ROUTER/ENDPOINT firmware!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// XBee has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
// RESET pin: 3
|
||||
XBee bee = new SerialModule(9, 8, 3);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//XBee bee = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize XBee module with baudrate 9600
|
||||
Serial.print(F("[XBee] Initializing ... "));
|
||||
int state = bee.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set PAN ID to 0x0123456789ABCDEF
|
||||
Serial.print(F("[XBee] Setting PAN ID ... "));
|
||||
uint8_t panId[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = bee.setPanId(panId);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if XBee received some data
|
||||
if (bee.available() > 0) {
|
||||
// print source address
|
||||
Serial.print(F("[XBee] Packet source:\t"));
|
||||
Serial.println(bee.getPacketSource());
|
||||
|
||||
// print data
|
||||
Serial.print(F("[XBee] Packet data:\t"));
|
||||
Serial.println(bee.getPacketData());
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
RadioLib XBee API Transmit Example
|
||||
|
||||
This example transmits packets using XBee API mode.
|
||||
In API mode, many XBee modules can form a mesh network.
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the XBee module
|
||||
is running API COORDINATOR firmware!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// XBee has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
// RESET pin: 3
|
||||
XBee bee = new SerialModule(9, 8, 3);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//XBee bee = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize XBee module with baudrate 9600
|
||||
Serial.print(F("[XBee] Initializing ... "));
|
||||
int state = bee.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set PAN ID to 0x0123456789ABCDEF
|
||||
Serial.print(F("[XBee] Setting PAN ID ... "));
|
||||
uint8_t panId[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = bee.setPanId(panId);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// transmit data to the destination module
|
||||
uint8_t dest[] = {0x00, 0x13, 0xA2, 0x00,
|
||||
0x40, 0xA5, 0x8A, 0x6B};
|
||||
Serial.print(F("[XBee] Transmitting message ... "));
|
||||
int state = bee.transmit(dest, "Hello World!");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
RadioLib XBee Transparent Operation Example
|
||||
|
||||
This example transmits packets using XBee Transparent mode.
|
||||
In Transparent mode, two XBee modules act like a Serial line.
|
||||
Both modules must have the same PAN ID, and the destination
|
||||
addresses have to be set properly.
|
||||
|
||||
IMPORTANT: Before uploading this example, make sure that the XBee modules
|
||||
are running AT COORDINATOR and AT ROUTER firmware!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// XBee has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
// RESET pin: 3
|
||||
XBeeSerial bee = new SerialModule(9, 8, 3);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//XBeeSerial bee = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize XBee module with baudrate 9600
|
||||
Serial.print(F("[XBee] Initializing ... "));
|
||||
int state = bee.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set PAN ID to 0123456789ABCDEF
|
||||
Serial.print(F("[XBee] Setting PAN ID ... "));
|
||||
state = bee.setPanId("0123456789ABCDEF");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set destination address to the address of the second module
|
||||
Serial.print(F("[XBee] Setting destination address ... "));
|
||||
state = bee.setDestinationAddress("0013A200", "40A58A5D");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// XBeeSerial supports all methods of the Serial class
|
||||
// read data incoming from Serial port and write them to XBee
|
||||
while (Serial.available() > 0) {
|
||||
bee.write(Serial.read());
|
||||
}
|
||||
|
||||
// read data incoming from XBee and write them to Serial port
|
||||
while (bee.available() > 0) {
|
||||
Serial.write(bee.read());
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
131
src/ISerial.cpp
131
src/ISerial.cpp
|
@ -1,131 +0,0 @@
|
|||
#include "ISerial.h"
|
||||
|
||||
ISerial::ISerial(Module* mod) {
|
||||
_mod = mod;
|
||||
}
|
||||
|
||||
void ISerial::begin(long speed) {
|
||||
_mod->ModuleSerial->begin(speed);
|
||||
}
|
||||
|
||||
#if !defined(__ASR6501__)
|
||||
void ISerial::end() {
|
||||
_mod->ModuleSerial->end();
|
||||
}
|
||||
#endif
|
||||
|
||||
int ISerial::peek() {
|
||||
return(_mod->ModuleSerial->peek());
|
||||
}
|
||||
|
||||
size_t ISerial::write(uint8_t b) {
|
||||
return(_mod->ModuleSerial->write(b));
|
||||
}
|
||||
|
||||
int ISerial::read() {
|
||||
return(_mod->ModuleSerial->read());
|
||||
}
|
||||
|
||||
int ISerial::available() {
|
||||
return(_mod->ModuleSerial->available());
|
||||
}
|
||||
|
||||
void ISerial::flush() {
|
||||
_mod->ModuleSerial->flush();
|
||||
}
|
||||
|
||||
#if !defined(ARDUINO_ARCH_MEGAAVR)
|
||||
size_t ISerial::print(const __FlashStringHelper *ifsh) {
|
||||
return(_mod->ModuleSerial->print(ifsh));
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t ISerial::print(const String &s) {
|
||||
return(_mod->ModuleSerial->print(s));
|
||||
}
|
||||
|
||||
size_t ISerial::print(const char str[]) {
|
||||
return(_mod->ModuleSerial->print(str));
|
||||
}
|
||||
|
||||
size_t ISerial::print(char c) {
|
||||
return(_mod->ModuleSerial->print(c));
|
||||
}
|
||||
|
||||
size_t ISerial::print(unsigned char b, int base) {
|
||||
return(_mod->ModuleSerial->print(b, base));
|
||||
}
|
||||
|
||||
size_t ISerial::print(int n, int base) {
|
||||
return(_mod->ModuleSerial->print(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::print(unsigned int n, int base) {
|
||||
return(_mod->ModuleSerial->print(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::print(long n, int base) {
|
||||
return(_mod->ModuleSerial->print(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::print(unsigned long n, int base) {
|
||||
return(_mod->ModuleSerial->print(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::print(double n, int digits) {
|
||||
return(_mod->ModuleSerial->print(n, digits));
|
||||
}
|
||||
|
||||
size_t ISerial::print(const Printable& x) {
|
||||
return(_mod->ModuleSerial->print(x));
|
||||
}
|
||||
|
||||
#if !defined(ARDUINO_ARCH_MEGAAVR)
|
||||
size_t ISerial::println(const __FlashStringHelper *ifsh) {
|
||||
return(_mod->ModuleSerial->println(ifsh));
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t ISerial::println(const String &s) {
|
||||
return(_mod->ModuleSerial->println(s));
|
||||
}
|
||||
|
||||
size_t ISerial::println(const char str[]) {
|
||||
return(_mod->ModuleSerial->println(str));
|
||||
}
|
||||
|
||||
size_t ISerial::println(char c) {
|
||||
return(_mod->ModuleSerial->println(c));
|
||||
}
|
||||
|
||||
size_t ISerial::println(unsigned char b, int base) {
|
||||
return(_mod->ModuleSerial->println(b, base));
|
||||
}
|
||||
|
||||
size_t ISerial::println(int n, int base) {
|
||||
return(_mod->ModuleSerial->println(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::println(unsigned int n, int base) {
|
||||
return(_mod->ModuleSerial->println(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::println(long n, int base) {
|
||||
return(_mod->ModuleSerial->println(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::println(unsigned long n, int base) {
|
||||
return(_mod->ModuleSerial->println(n, base));
|
||||
}
|
||||
|
||||
size_t ISerial::println(double n, int digits) {
|
||||
return(_mod->ModuleSerial->println(n, digits));
|
||||
}
|
||||
|
||||
size_t ISerial::println(const Printable& x) {
|
||||
return(_mod->ModuleSerial->println(x));
|
||||
}
|
||||
|
||||
size_t ISerial::println(void) {
|
||||
return(_mod->ModuleSerial->println());
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
#if !defined(_RADIOLIB_ISERIAL_H)
|
||||
#define _RADIOLIB_ISERIAL_H
|
||||
|
||||
#include "Module.h"
|
||||
|
||||
/*!
|
||||
\class ISerial
|
||||
|
||||
\brief Interface class for Arduino Serial. Only calls the appropriate methods for the active UART interface.
|
||||
*/
|
||||
class ISerial {
|
||||
public:
|
||||
explicit ISerial(Module* mod);
|
||||
|
||||
void begin(long);
|
||||
#if !defined(__ASR6501__)
|
||||
void end();
|
||||
#endif
|
||||
int peek();
|
||||
size_t write(uint8_t);
|
||||
int read();
|
||||
int available();
|
||||
void flush();
|
||||
|
||||
#if !defined(ARDUINO_ARCH_MEGAAVR)
|
||||
size_t print(const __FlashStringHelper *);
|
||||
#endif
|
||||
size_t print(const String &);
|
||||
size_t print(const char[]);
|
||||
size_t print(char);
|
||||
size_t print(unsigned char, int = DEC);
|
||||
size_t print(int, int = DEC);
|
||||
size_t print(unsigned int, int = DEC);
|
||||
size_t print(long, int = DEC);
|
||||
size_t print(unsigned long, int = DEC);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(const Printable&);
|
||||
|
||||
#if !defined(ARDUINO_ARCH_MEGAAVR)
|
||||
size_t println(const __FlashStringHelper *);
|
||||
#endif
|
||||
size_t println(const String &s);
|
||||
size_t println(const char[]);
|
||||
size_t println(char);
|
||||
size_t println(unsigned char, int = DEC);
|
||||
size_t println(int, int = DEC);
|
||||
size_t println(unsigned int, int = DEC);
|
||||
size_t println(long, int = DEC);
|
||||
size_t println(unsigned long, int = DEC);
|
||||
size_t println(double, int = 2);
|
||||
size_t println(const Printable&);
|
||||
size_t println(void);
|
||||
|
||||
#if !(defined(RADIOLIB_LOW_LEVEL) || defined(RADIOLIB_GODMODE))
|
||||
protected:
|
||||
#endif
|
||||
Module* _mod;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -8,15 +8,12 @@
|
|||
|
||||
\par Currently Supported Wireless Modules and Protocols
|
||||
- CC1101 FSK module
|
||||
- HC05 Bluetooth module
|
||||
- JDY08 BLE module
|
||||
- RF69 FSK module
|
||||
- Si443x FSK module
|
||||
- SX126x LoRa/FSK module
|
||||
- SX127x LoRa/FSK module
|
||||
- SX128x LoRa/GFSK/BLE/FLRC module
|
||||
- SX1231 FSK module
|
||||
- XBee module (S2B)
|
||||
- PhysicalLayer protocols
|
||||
- RTTY (RTTYClient)
|
||||
- Morse Code (MorseClient)
|
||||
|
@ -24,9 +21,6 @@
|
|||
- SSTV (SSTVClient)
|
||||
- Hellschreiber (HellClient)
|
||||
- 4-FSK (FSK4Client)
|
||||
- TransportLayer protocols
|
||||
- HTTP (HTTPClient)
|
||||
- MQTT (MQTTClient)
|
||||
|
||||
\par Quick Links
|
||||
Documentation for most common methods can be found in its reference page (see the list above).\n
|
||||
|
@ -34,7 +28,6 @@
|
|||
\ref status_codes have their own page.\n
|
||||
Some modules implement methods of one or more compatibility layers, loosely based on the ISO/OSI model:
|
||||
- PhysicalLayer - FSK and LoRa radio modules
|
||||
- TransportLayer - Modules with Internet connectivity
|
||||
|
||||
\see https://github.com/jgromes/RadioLib
|
||||
|
||||
|
@ -47,24 +40,21 @@
|
|||
// warnings are printed in this file since BuildOpt.h is compiled in multiple places
|
||||
|
||||
// check God mode
|
||||
#ifdef RADIOLIB_GODMODE
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
#warning "God mode active, I hope it was intentional. Buckle up, lads."
|
||||
#endif
|
||||
|
||||
// print debug info
|
||||
#ifdef RADIOLIB_DEBUG
|
||||
#if defined(RADIOLIB_DEBUG)
|
||||
#pragma message "RADIOLIB_PLATFORM: " RADIOLIB_PLATFORM
|
||||
#endif
|
||||
|
||||
// check unknown/unsupported platform
|
||||
#ifdef RADIOLIB_UNKNOWN_PLATFORM
|
||||
#if defined(RADIOLIB_UNKNOWN_PLATFORM)
|
||||
#warning "RadioLib might not be compatible with this Arduino board - check supported platforms at https://github.com/jgromes/RadioLib!"
|
||||
#endif
|
||||
|
||||
#include "modules/CC1101/CC1101.h"
|
||||
#include "modules/ESP8266/ESP8266.h"
|
||||
#include "modules/HC05/HC05.h"
|
||||
#include "modules/JDY08/JDY08.h"
|
||||
#include "modules/LLCC68/LLCC68.h"
|
||||
#include "modules/nRF24/nRF24.h"
|
||||
#include "modules/RF69/RF69.h"
|
||||
|
@ -89,7 +79,6 @@
|
|||
#include "modules/SX128x/SX1280.h"
|
||||
#include "modules/SX128x/SX1281.h"
|
||||
#include "modules/SX128x/SX1282.h"
|
||||
#include "modules/XBee/XBee.h"
|
||||
|
||||
// physical layer protocols
|
||||
#include "protocols/PhysicalLayer/PhysicalLayer.h"
|
||||
|
@ -101,13 +90,8 @@
|
|||
#include "protocols/SSTV/SSTV.h"
|
||||
#include "protocols/FSK4/FSK4.h"
|
||||
|
||||
// transport layer protocols
|
||||
#include "protocols/TransportLayer/TransportLayer.h"
|
||||
#include "protocols/HTTP/HTTP.h"
|
||||
#include "protocols/MQTT/MQTT.h"
|
||||
|
||||
// only create Radio class when using RadioShield
|
||||
#ifdef RADIOLIB_RADIOSHIELD
|
||||
#if defined(RADIOLIB_RADIOSHIELD)
|
||||
|
||||
// RadioShield pin definitions
|
||||
#define RADIOSHIELD_CS_A 10
|
||||
|
@ -139,7 +123,7 @@ class Radio {
|
|||
ModuleB = new Module(RADIOSHIELD_CS_B, RADIOSHIELD_INT_0, RADIOSHIELD_INT_1, RADIOSHIELD_RX_B, RADIOSHIELD_TX_B, SPI, SPISettings(2000000, MSBFIRST, SPI_MODE0), nullptr);
|
||||
}
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
private:
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
#include "ESP8266.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_ESP8266) && !defined(ESP8266)
|
||||
|
||||
ESP8266::ESP8266(Module* module) {
|
||||
_mod = module;
|
||||
}
|
||||
|
||||
int16_t ESP8266::begin(long speed) {
|
||||
// set module properties
|
||||
char lf[3] = "\r\n";
|
||||
memcpy(_mod->AtLineFeed, lf, strlen(lf));
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
|
||||
// empty UART buffer (garbage data)
|
||||
_mod->ATemptyBuffer();
|
||||
|
||||
// test AT setup
|
||||
if(!_mod->ATsendCommand("AT")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t ESP8266::reset() {
|
||||
// send the reset command
|
||||
if(!_mod->ATsendCommand("AT+RST")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// wait for the module to start
|
||||
Module::delay(2000);
|
||||
|
||||
// test AT setup
|
||||
uint32_t start = Module::millis();
|
||||
while (Module::millis() - start < 3000) {
|
||||
if(!_mod->ATsendCommand("AT")) {
|
||||
Module::delay(100);
|
||||
} else {
|
||||
return(ERR_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
int16_t ESP8266::join(const char* ssid, const char* password) {
|
||||
// set mode to station + soft AP
|
||||
if(!_mod->ATsendCommand("AT+CWMODE_CUR=3")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// build AT command
|
||||
const char* atStr = "AT+CWJAP_CUR=\"";
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char cmd[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t cmdLen = strlen(atStr) + strlen(ssid) + strlen(password) + 4;
|
||||
char* cmd = new char[cmdLen + 1];
|
||||
#endif
|
||||
strcpy(cmd, atStr);
|
||||
strcat(cmd, ssid);
|
||||
strcat(cmd, "\",\"");
|
||||
strcat(cmd, password);
|
||||
strcat(cmd, "\"");
|
||||
|
||||
// send command
|
||||
bool res = _mod->ATsendCommand(cmd);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// disable multiple connection mode
|
||||
if(!_mod->ATsendCommand("AT+CIPMUX=0")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t ESP8266::openTransportConnection(const char* host, const char* protocol, uint16_t port, uint16_t tcpKeepAlive) {
|
||||
char portStr[6];
|
||||
sprintf(portStr, "%u", port);
|
||||
char tcpKeepAliveStr[6];
|
||||
sprintf(tcpKeepAliveStr, "%u", tcpKeepAlive);
|
||||
|
||||
// build AT command
|
||||
const char* atStr = "AT+CIPSTART=\"";
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char cmd[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t cmdLen = strlen(atStr) + strlen(protocol) + strlen(host) + strlen(portStr) + 5;
|
||||
if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) {
|
||||
cmdLen += strlen(tcpKeepAliveStr) + 1;
|
||||
}
|
||||
char* cmd = new char[cmdLen + 1];
|
||||
#endif
|
||||
strcpy(cmd, atStr);
|
||||
strcat(cmd, protocol);
|
||||
strcat(cmd, "\",\"");
|
||||
strcat(cmd, host);
|
||||
strcat(cmd, "\",");
|
||||
strcat(cmd, portStr);
|
||||
if((strcmp(protocol, "TCP") == 0) && (tcpKeepAlive > 0)) {
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd, tcpKeepAliveStr);
|
||||
}
|
||||
|
||||
// send command
|
||||
bool res = _mod->ATsendCommand(cmd);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t ESP8266::closeTransportConnection() {
|
||||
// send AT command
|
||||
if(!_mod->ATsendCommand("AT+CIPCLOSE")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t ESP8266::send(const char* data) {
|
||||
// build AT command
|
||||
char lenStr[12];
|
||||
sprintf(lenStr, "%u", (uint16_t)strlen(data));
|
||||
const char* atStr = "AT+CIPSEND=";
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char cmd[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
|
||||
#endif
|
||||
strcpy(cmd, atStr);
|
||||
strcat(cmd, lenStr);
|
||||
|
||||
// send command
|
||||
bool res = _mod->ATsendCommand(cmd);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// send data
|
||||
if(!_mod->ATsendCommand(data)) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t ESP8266::send(uint8_t* data, size_t len) {
|
||||
// build AT command
|
||||
char lenStr[8];
|
||||
sprintf(lenStr, "%u", (uint16_t)len);
|
||||
const char atStr[] = "AT+CIPSEND=";
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char cmd[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
char* cmd = new char[strlen(atStr) + strlen(lenStr) + 1];
|
||||
#endif
|
||||
strcpy(cmd, atStr);
|
||||
strcat(cmd, lenStr);
|
||||
|
||||
// send command
|
||||
bool res = _mod->ATsendCommand(cmd);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// send data
|
||||
if(!_mod->ATsendData(data, len)) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
size_t ESP8266::receive(uint8_t* data, size_t len, uint32_t timeout) {
|
||||
size_t i = 0;
|
||||
uint32_t start = Module::millis();
|
||||
|
||||
// wait until the required number of bytes is received or until timeout
|
||||
while((Module::millis() - start < timeout) && (i < len)) {
|
||||
Module::yield();
|
||||
while(_mod->ModuleSerial->available() > 0) {
|
||||
uint8_t b = _mod->ModuleSerial->read();
|
||||
RADIOLIB_DEBUG_PRINT(b);
|
||||
data[i] = b;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
size_t ESP8266::getNumBytes(uint32_t timeout, size_t minBytes) {
|
||||
// wait for available data
|
||||
uint32_t start = Module::millis();
|
||||
while(_mod->ModuleSerial->available() < (int16_t)minBytes) {
|
||||
Module::yield();
|
||||
if(Module::millis() - start >= timeout) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
// read response
|
||||
char rawStr[20];
|
||||
uint8_t i = 0;
|
||||
start = Module::millis();
|
||||
while(_mod->ModuleSerial->available() > 0) {
|
||||
Module::yield();
|
||||
char c = _mod->ModuleSerial->read();
|
||||
rawStr[i++] = c;
|
||||
if(c == ':') {
|
||||
rawStr[i++] = 0;
|
||||
break;
|
||||
}
|
||||
if(Module::millis() - start >= timeout) {
|
||||
rawStr[i++] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get the number of bytes in response
|
||||
char* pch = strtok(rawStr, ",:");
|
||||
if(pch == NULL) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
pch = strtok(NULL, ",:");
|
||||
if(pch == NULL) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(atoi(pch));
|
||||
}
|
||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||
#if !defined(_RADIOLIB_ESP8266_H) && !defined(RADIOLIB_EXCLUDE_ESP8266) && !defined(ESP8266)
|
||||
#define _RADIOLIB_ESP8266_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../../Module.h"
|
||||
|
||||
#include "../../protocols/TransportLayer/TransportLayer.h"
|
||||
|
||||
/*!
|
||||
\class ESP8266
|
||||
|
||||
\brief Control class for %ESP8266 module. Implements TransportLayer methods.
|
||||
*/
|
||||
class ESP8266: public TransportLayer {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
ESP8266(Module* module);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param speed Baud rate to use for UART interface.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(long speed);
|
||||
|
||||
/*!
|
||||
\brief Resets module using AT command.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t reset();
|
||||
|
||||
/*!
|
||||
\brief Joins access point.
|
||||
|
||||
\param ssid Access point SSID.
|
||||
|
||||
\param password Access point password.
|
||||
*/
|
||||
int16_t join(const char* ssid, const char* password);
|
||||
|
||||
// transport layer methods (implementations of purely virtual methods in TransportLayer class)
|
||||
int16_t openTransportConnection(const char* host, const char* protocol, uint16_t port, uint16_t tcpKeepAlive = 0) override;
|
||||
int16_t closeTransportConnection() override;
|
||||
int16_t send(const char* data) override;
|
||||
int16_t send(uint8_t* data, size_t len) override;
|
||||
size_t receive(uint8_t* data, size_t len, uint32_t timeout = 10000) override;
|
||||
size_t getNumBytes(uint32_t timeout = 10000, size_t minBytes = 10) override;
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE) && !defined(RADIOLIB_LOW_LEVEL)
|
||||
protected:
|
||||
#endif
|
||||
Module* _mod;
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE)
|
||||
protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
#include "HC05.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_HC05)
|
||||
|
||||
HC05::HC05(Module* mod) : ISerial(mod) {
|
||||
|
||||
}
|
||||
|
||||
void HC05::begin(long speed) {
|
||||
// set module properties
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
#if !defined(_RADIOLIB_HC05_H) && !defined(RADIOLIB_EXCLUDE_HC05)
|
||||
#define _RADIOLIB_HC05_H
|
||||
|
||||
#include "../../ISerial.h"
|
||||
|
||||
/*!
|
||||
\class HC05
|
||||
|
||||
\brief Control class for %HC05 module.
|
||||
Most methods supported by this module are implemented in ISerial interface.
|
||||
*/
|
||||
class HC05: public ISerial {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
HC05(Module* mod);
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param speed Baud rate to use for UART interface.
|
||||
*/
|
||||
void begin(long speed);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
#if !defined(_RADIOLIB_JDY08_H) && !defined(RADIOLIB_EXCLUDE_JDY08)
|
||||
#include "JDY08.h"
|
||||
|
||||
JDY08::JDY08(Module* mod) : ISerial(mod) {
|
||||
|
||||
}
|
||||
|
||||
void JDY08::begin(long speed) {
|
||||
// set module properties
|
||||
char lf[3] = "";
|
||||
memcpy(_mod->AtLineFeed, lf, strlen(lf));
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
#if !defined(_RADIOLIB_JDY08_H) && !defined(RADIOLIB_EXCLUDE_JDY08)
|
||||
#define _RADIOLIB_JDY08_H
|
||||
|
||||
#include "../../ISerial.h"
|
||||
|
||||
/*!
|
||||
\class JDY08
|
||||
|
||||
\brief Control class for %JDY08 module.
|
||||
Most methods supported by this module are implemented in ISerial interface.
|
||||
*/
|
||||
class JDY08: public ISerial {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
JDY08(Module* mod);
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param speed Baud rate to use for UART interface.
|
||||
*/
|
||||
void begin(long speed);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,485 +0,0 @@
|
|||
#include "XBee.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_XBEE)
|
||||
|
||||
XBee::XBee(Module* mod) {
|
||||
_mod = mod;
|
||||
_packetData[0] = '\0';
|
||||
}
|
||||
|
||||
int16_t XBee::begin(long speed) {
|
||||
// set module properties
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
|
||||
// reset module
|
||||
reset();
|
||||
|
||||
// empty UART buffer (garbage data)
|
||||
_mod->ATemptyBuffer();
|
||||
|
||||
// try to find the XBee
|
||||
bool flagFound = false;
|
||||
uint8_t i = 0;
|
||||
while((i < 10) && !flagFound) {
|
||||
// hardware reset should return 2 modem status frames - 1st status 0x00, second status 0x06
|
||||
int16_t state = readApiFrame(0x00, 1, 2000);
|
||||
readApiFrame(0x00, 1, 2000);
|
||||
|
||||
if(state == ERR_NONE) {
|
||||
flagFound = true;
|
||||
} else {
|
||||
RADIOLIB_DEBUG_PRINT(F("XBee not found! ("));
|
||||
RADIOLIB_DEBUG_PRINT(i + 1);
|
||||
RADIOLIB_DEBUG_PRINT(F(" of 10 tries) STATE == "));
|
||||
RADIOLIB_DEBUG_PRINTLN(state);
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Resetting ..."));
|
||||
reset();
|
||||
Module::delay(10);
|
||||
_mod->ATemptyBuffer();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flagFound) {
|
||||
RADIOLIB_DEBUG_PRINTLN(F("No XBee found!"));
|
||||
return(ERR_CMD_MODE_FAILED);
|
||||
} else {
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Found XBee!"));
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void XBee::reset() {
|
||||
Module::pinMode(_mod->getRst(), OUTPUT);
|
||||
Module::digitalWrite(_mod->getRst(), LOW);
|
||||
Module::delay(1);
|
||||
Module::digitalWrite(_mod->getRst(), HIGH);
|
||||
}
|
||||
|
||||
int16_t XBee::transmit(uint8_t* dest, const char* payload, uint8_t radius) {
|
||||
uint8_t destNetwork[] = {0xFF, 0xFE};
|
||||
return(transmit(dest, destNetwork, payload, radius));
|
||||
}
|
||||
|
||||
int16_t XBee::transmit(uint8_t* dest, uint8_t* destNetwork, const char* payload, uint8_t radius) {
|
||||
// build the frame
|
||||
size_t payloadLen = strlen(payload);
|
||||
size_t dataLen = 8 + 2 + 1 + 1 + payloadLen;
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t cmd[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* cmd = new uint8_t[dataLen];
|
||||
#endif
|
||||
memcpy(cmd, dest, 8);
|
||||
memcpy(cmd + 8, destNetwork, 2);
|
||||
cmd[10] = radius;
|
||||
cmd[11] = 0x01; // options: no retries
|
||||
memcpy(cmd + 12, payload, payloadLen);
|
||||
|
||||
// send frame
|
||||
uint8_t frameID = _frameID++;
|
||||
sendApiFrame(XBEE_API_FRAME_ZIGBEE_TRANSMIT_REQUEST, frameID, cmd, dataLen);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
|
||||
// get response code
|
||||
return(readApiFrame(frameID, 5));
|
||||
}
|
||||
|
||||
size_t XBee::available() {
|
||||
// check if there are data available in the buffer
|
||||
size_t serialBytes = _mod->ModuleSerial->available();
|
||||
if(serialBytes < 3) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(!_frameHeaderProcessed) {
|
||||
// read frame header
|
||||
uint8_t header[3];
|
||||
for(uint8_t i = 0; i < 3; i++) {
|
||||
header[i] = _mod->ModuleSerial->read();
|
||||
}
|
||||
|
||||
// check if we received API frame
|
||||
if(header[0] != XBEE_API_START) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
// get expected frame length
|
||||
_frameLength = ((header[1] << 8) | header[2]) + 1;
|
||||
_frameHeaderProcessed = true;
|
||||
}
|
||||
|
||||
// check if the header is complete
|
||||
if(serialBytes < _frameLength) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char frame[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* frame = new uint8_t[_frameLength];
|
||||
#endif
|
||||
for(size_t i = 0; i < _frameLength; i++) {
|
||||
frame[i] = _mod->ModuleSerial->read();
|
||||
}
|
||||
|
||||
// save packet source and data
|
||||
size_t payloadLength = _frameLength - 12;
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] _packetData;
|
||||
_packetData = new char[payloadLength];
|
||||
#endif
|
||||
memcpy(_packetData, frame + 12, payloadLength - 1);
|
||||
_packetData[payloadLength - 1] = '\0';
|
||||
memcpy(_packetSource, frame + 1, 8);
|
||||
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] frame;
|
||||
#endif
|
||||
_frameLength = 0;
|
||||
_frameHeaderProcessed = false;
|
||||
|
||||
// return number of bytes in payload
|
||||
return(payloadLength);
|
||||
}
|
||||
|
||||
String XBee::getPacketSource() {
|
||||
char buff[17];
|
||||
sprintf(buff, "%02X%02X%02X%02X%02X%02X%02X%02X", _packetSource[0], _packetSource[1], _packetSource[2], _packetSource[3],
|
||||
_packetSource[4], _packetSource[5], _packetSource[6], _packetSource[7]);
|
||||
String str(buff);
|
||||
return(str);
|
||||
}
|
||||
|
||||
String XBee::getPacketData() {
|
||||
String str(_packetData);
|
||||
return(str);
|
||||
}
|
||||
|
||||
int16_t XBee::setPanId(uint8_t* panId) {
|
||||
// build AT command
|
||||
uint8_t cmd[10];
|
||||
memcpy(cmd, "ID", 2);
|
||||
memcpy(cmd + 2, panId, 8);
|
||||
|
||||
// send frame
|
||||
uint8_t frameID = _frameID++;
|
||||
sendApiFrame(XBEE_API_FRAME_AT_COMMAND_QUEUE, frameID, cmd, 10);
|
||||
|
||||
// get response code
|
||||
int16_t state = readApiFrame(frameID, 4);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// confirm changes
|
||||
return(confirmChanges());
|
||||
}
|
||||
|
||||
XBeeSerial::XBeeSerial(Module* mod) : ISerial(mod) {
|
||||
|
||||
}
|
||||
|
||||
int16_t XBeeSerial::begin(long speed) {
|
||||
// set module properties
|
||||
char lf[3] = "\r";
|
||||
memcpy(_mod->AtLineFeed, lf, strlen(lf));
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
|
||||
// reset module
|
||||
reset();
|
||||
|
||||
// empty UART buffer (garbage data)
|
||||
_mod->ATemptyBuffer();
|
||||
|
||||
// enter command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Entering command mode ..."));
|
||||
if(!enterCmdMode()) {
|
||||
return(ERR_CMD_MODE_FAILED);
|
||||
}
|
||||
|
||||
// test AT setup
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Sending test command ..."));
|
||||
if(!_mod->ATsendCommand("AT")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// exit command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Exiting command mode ..."));
|
||||
if(!_mod->ATsendCommand("ATCN")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void XBeeSerial::reset() {
|
||||
Module::pinMode(_mod->getRst(), OUTPUT);
|
||||
Module::digitalWrite(_mod->getRst(), LOW);
|
||||
Module::delay(1);
|
||||
Module::digitalWrite(_mod->getRst(), HIGH);
|
||||
Module::pinMode(_mod->getRst(), INPUT);
|
||||
}
|
||||
|
||||
int16_t XBeeSerial::setDestinationAddress(const char* destinationAddressHigh, const char* destinationAddressLow) {
|
||||
// enter command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Entering command mode ..."));
|
||||
if(!enterCmdMode()) {
|
||||
return(ERR_CMD_MODE_FAILED);
|
||||
}
|
||||
|
||||
// set higher address bytes
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Setting address (high) ..."));
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char addressHigh[13];
|
||||
#else
|
||||
char* addressHigh = new char[strlen(destinationAddressHigh) + 4];
|
||||
#endif
|
||||
strcpy(addressHigh, "ATDH");
|
||||
strcat(addressHigh, destinationAddressHigh);
|
||||
bool res = _mod->ATsendCommand(addressHigh);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] addressHigh;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// set lower address bytes
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Setting address (low) ..."));
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char addressLow[13];
|
||||
#else
|
||||
char* addressLow = new char[strlen(destinationAddressLow) + 4];
|
||||
#endif
|
||||
strcpy(addressLow, "ATDL");
|
||||
strcat(addressLow, destinationAddressLow);
|
||||
res = _mod->ATsendCommand(addressLow);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] addressLow;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// exit command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Exiting command mode ..."));
|
||||
if(!_mod->ATsendCommand("ATCN")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t XBeeSerial::setPanId(const char* panId) {
|
||||
// enter command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Entering command mode ..."));
|
||||
if(!enterCmdMode()) {
|
||||
return(ERR_CMD_MODE_FAILED);
|
||||
}
|
||||
|
||||
// set PAN ID
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Setting PAN ID ..."));
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char cmd[21];
|
||||
#else
|
||||
char* cmd = new char[strlen(panId) + 4];
|
||||
#endif
|
||||
strcpy(cmd, "ATID");
|
||||
strcat(cmd, panId);
|
||||
bool res = _mod->ATsendCommand(cmd);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] cmd;
|
||||
#endif
|
||||
if(!res) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// exit command mode
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Exiting command mode ..."));
|
||||
if(!_mod->ATsendCommand("ATCN")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
bool XBeeSerial::enterCmdMode() {
|
||||
for(uint8_t i = 0; i < 10; i++) {
|
||||
Module::delay(1000);
|
||||
|
||||
_mod->ModuleSerial->write('+');
|
||||
_mod->ModuleSerial->write('+');
|
||||
_mod->ModuleSerial->write('+');
|
||||
|
||||
Module::delay(1000);
|
||||
|
||||
if(_mod->ATgetResponse()) {
|
||||
return(true);
|
||||
} else {
|
||||
RADIOLIB_DEBUG_PRINT(F("Unable to enter command mode! ("));
|
||||
RADIOLIB_DEBUG_PRINT(i + 1);
|
||||
RADIOLIB_DEBUG_PRINTLN(F(" of 10 tries)"));
|
||||
|
||||
reset();
|
||||
|
||||
_mod->ATsendCommand("ATCN");
|
||||
}
|
||||
}
|
||||
|
||||
RADIOLIB_DEBUG_PRINTLN(F("Terminated, check your wiring. Is AT FW uploaded?"));
|
||||
return(false);
|
||||
}
|
||||
|
||||
int16_t XBee::confirmChanges() {
|
||||
// save changes to non-volatile memory
|
||||
uint8_t frameID = _frameID++;
|
||||
sendApiFrame(XBEE_API_FRAME_AT_COMMAND_QUEUE, frameID, "WR");
|
||||
|
||||
// get response code
|
||||
int16_t state = readApiFrame(frameID, 4);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// apply changes
|
||||
frameID = _frameID++;
|
||||
sendApiFrame(XBEE_API_FRAME_AT_COMMAND_QUEUE, frameID, "AC");
|
||||
|
||||
// get response code
|
||||
state = readApiFrame(frameID, 4);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
void XBee::sendApiFrame(uint8_t type, uint8_t id, const char* data) {
|
||||
sendApiFrame(type, id, (uint8_t*)data, strlen(data));
|
||||
}
|
||||
|
||||
void XBee::sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length) {
|
||||
// build the API frame
|
||||
size_t frameLength = 1 + 2 + length + 1 + 2;
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t frame[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* frame = new uint8_t[frameLength];
|
||||
#endif
|
||||
|
||||
frame[0] = 0x7E; // start delimiter
|
||||
frame[1] = ((length + 2) & 0xFF00) >> 8; // length MSB
|
||||
frame[2] = (length + 2) & 0x00FF; // length LSB
|
||||
frame[3] = type; // frame type
|
||||
frame[4] = id; // frame ID
|
||||
memcpy(frame + 5, data, length); // data
|
||||
|
||||
// calculate the checksum
|
||||
uint8_t checksum = 0;
|
||||
for(size_t i = 3; i < frameLength - 1; i++) {
|
||||
checksum += frame[i];
|
||||
}
|
||||
frame[5 + length] = 0xFF - checksum;
|
||||
|
||||
// send the frame
|
||||
for(size_t i = 0; i < frameLength; i++) {
|
||||
_mod->ModuleSerial->write(frame[i]);
|
||||
}
|
||||
|
||||
// deallocate memory
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] frame;
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t XBee::readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout) {
|
||||
/// \todo modemStatus frames may be sent at any time, interfering with frame parsing. Add check to make sure this does not happen.
|
||||
|
||||
// get number of bytes in response (must be enough to read the length field
|
||||
uint16_t numBytes = getNumBytes(timeout/2, 3);
|
||||
if(numBytes == 0) {
|
||||
return(ERR_FRAME_NO_RESPONSE);
|
||||
}
|
||||
|
||||
// checksum byte is not included in length field
|
||||
numBytes++;
|
||||
|
||||
// wait until all response bytes are available (5s timeout)
|
||||
uint32_t start = Module::millis();
|
||||
while(_mod->ModuleSerial->available() < (int16_t)numBytes) {
|
||||
Module::yield();
|
||||
if(Module::millis() - start >= timeout/2) {
|
||||
return(ERR_FRAME_MALFORMED);
|
||||
}
|
||||
}
|
||||
RADIOLIB_DEBUG_PRINT(F("frame data field length: "));
|
||||
RADIOLIB_DEBUG_PRINTLN(numBytes);
|
||||
|
||||
// read the response
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t resp[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* resp = new uint8_t[numBytes];
|
||||
#endif
|
||||
for(uint16_t i = 0; i < numBytes; i++) {
|
||||
resp[i] = _mod->ModuleSerial->read();
|
||||
}
|
||||
|
||||
// verify checksum
|
||||
uint8_t checksum = 0;
|
||||
for(uint16_t i = 0; i < numBytes; i++) {
|
||||
RADIOLIB_DEBUG_PRINT(resp[i], HEX);
|
||||
RADIOLIB_DEBUG_PRINT('\t');
|
||||
checksum += resp[i];
|
||||
}
|
||||
RADIOLIB_DEBUG_PRINTLN();
|
||||
if(checksum != 0xFF) {
|
||||
RADIOLIB_DEBUG_PRINTLN(checksum, HEX);
|
||||
return(ERR_FRAME_INCORRECT_CHECKSUM);
|
||||
}
|
||||
|
||||
// check frame ID
|
||||
if(resp[1] != frameID) {
|
||||
RADIOLIB_DEBUG_PRINT(F("received frame ID: "));
|
||||
RADIOLIB_DEBUG_PRINTLN(resp[1]);
|
||||
RADIOLIB_DEBUG_PRINT(F("expected frame ID: "));
|
||||
RADIOLIB_DEBUG_PRINTLN(frameID);
|
||||
return(ERR_FRAME_UNEXPECTED_ID);
|
||||
}
|
||||
|
||||
// codePos does not include start delimiter and frame ID
|
||||
uint8_t code = resp[codePos];
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] resp;
|
||||
#endif
|
||||
return(code);
|
||||
}
|
||||
|
||||
uint16_t XBee::getNumBytes(uint32_t timeout, size_t minBytes) {
|
||||
// wait for available data
|
||||
uint32_t start = Module::millis();
|
||||
while((size_t)_mod->ModuleSerial->available() < minBytes) {
|
||||
Module::yield();
|
||||
if(Module::millis() - start >= timeout) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
// read response
|
||||
uint8_t resp[3];
|
||||
uint8_t i = 0;
|
||||
RADIOLIB_DEBUG_PRINT(F("reading frame length: "));
|
||||
while(_mod->ModuleSerial->available() > 0) {
|
||||
Module::yield();
|
||||
uint8_t b = _mod->ModuleSerial->read();
|
||||
RADIOLIB_DEBUG_PRINT(b, HEX);
|
||||
RADIOLIB_DEBUG_PRINT('\t');
|
||||
resp[i++] = b;
|
||||
if(i == 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
RADIOLIB_DEBUG_PRINTLN();
|
||||
|
||||
return((resp[1] << 8) | resp[2]);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,204 +0,0 @@
|
|||
#if !defined(_RADIOLIB_XBEE_H) && !defined(RADIOLIB_EXCLUDE_XBEE)
|
||||
#define _RADIOLIB_XBEE_H
|
||||
|
||||
#include "../../ISerial.h"
|
||||
#include "../../TypeDef.h"
|
||||
|
||||
// API reserved characters
|
||||
#define XBEE_API_START 0x7E
|
||||
#define XBEE_API_ESCAPE 0x7D
|
||||
#define XBEE_API_XON 0x11
|
||||
#define XBEE_API_XOFF 0x13
|
||||
|
||||
// API frame IDs
|
||||
#define XBEE_API_FRAME_AT_COMMAND 0x08
|
||||
#define XBEE_API_FRAME_AT_COMMAND_QUEUE 0x09
|
||||
#define XBEE_API_FRAME_ZIGBEE_TRANSMIT_REQUEST 0x10
|
||||
#define XBEE_API_FRAME_ZIGBEE_ADDRESS_EXPLICIT 0x11
|
||||
#define XBEE_API_FRAME_REMOTE_COMMAND 0x17
|
||||
#define XBEE_API_FRAME_CREATE_SOURCE_ROUTE 0x21
|
||||
#define XBEE_API_FRAME_AT_COMMAND_RESPONSE 0x88
|
||||
#define XBEE_API_FRAME_MODEM_STATUS 0x8A
|
||||
#define XBEE_API_FRAME_ZIGBEE_TRANSMIT_STATUS 0x8B
|
||||
#define XBEE_API_FRAME_ZIGBEE_RECEIVE_PACKET 0x90
|
||||
#define XBEE_API_FRAME_ZIGBEE_EXPLICIT_RX 0x91
|
||||
#define XBEE_API_FRAME_ZIGBEE_IO_DATA_SAMPLE_RX 0x92
|
||||
#define XBEE_API_FRAME_SENSOR_READ 0x94
|
||||
#define XBEE_API_FRAME_NODE_ID 0x95
|
||||
#define XBEE_API_FRAME_REMOTE_COMMAND_RESPONSE 0x97
|
||||
#define XBEE_API_FRAME_EXTENDED_MODEM_STATUS 0x98
|
||||
#define XBEE_API_FRAME_OTA_FW_UPDATE_STATUS 0xA0
|
||||
#define XBEE_API_FRAME_ROUTE_RECORD 0xA1
|
||||
#define XBEE_API_FRAME_MANY_TO_ONE_ROUTE_REQUEST 0xA3
|
||||
|
||||
/*!
|
||||
\class XBeeSerial
|
||||
|
||||
\brief %XBee Serial interface. This class is used for XBees in transparent mode, i.e. when two XBees act as a "wireless UART".
|
||||
*/
|
||||
class XBeeSerial: public ISerial {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
XBeeSerial(Module* mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param speed Baud rate to use for UART interface.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(long speed);
|
||||
|
||||
/*!
|
||||
\brief Resets module using interrupt/GPIO pin 1.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
// configuration methods
|
||||
|
||||
/*!
|
||||
\brief Sets destination XBee address.
|
||||
|
||||
\param destinationAddressHigh Higher 4 bytes of the destination XBee module, in the form of uppercase hexadecimal string (i.e. 8 characters).
|
||||
|
||||
\param destinationAddressLow Lower 4 bytes of the destination XBee module, in the form of uppercase hexadecimal string (i.e. 8 characters).
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDestinationAddress(const char* destinationAddressHigh, const char* destinationAddressLow);
|
||||
|
||||
/*!
|
||||
\brief Sets PAN (Personal Area Network) ID. Both XBees must be in the same PAN in order to use transparent mode.
|
||||
|
||||
\param panId 8-byte PAN ID to be used, in the form of uppercase hexadecimal string (i.e. 16 characters).
|
||||
*/
|
||||
int16_t setPanId(const char* panId);
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE)
|
||||
private:
|
||||
#endif
|
||||
bool enterCmdMode();
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\class XBee
|
||||
|
||||
\brief Control class for %XBee modules.
|
||||
*/
|
||||
class XBee {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
XBee(Module* mod);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Initialization method.
|
||||
|
||||
\param speed Baud rate to use for UART interface.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(long speed);
|
||||
|
||||
/*!
|
||||
\brief Resets module using interrupt/GPIO pin 1.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/*!
|
||||
\brief Sends data to the destination 64-bit (global) address, when destination 16-bit (local) address is unknown.
|
||||
|
||||
\param dest Destination 64-bit address, in the form of 8-byte array.
|
||||
|
||||
\param payload String of payload bytes.
|
||||
|
||||
\param radius Number of maximum "hops" for a broadcast transmission. Defaults to 1, set to 0 for unlimited number of hops.
|
||||
*/
|
||||
int16_t transmit(uint8_t* dest, const char* payload, uint8_t radius = 1);
|
||||
|
||||
/*!
|
||||
\brief Sends data to the destination 64-bit (global) address, when destination 16-bit (local) address is known.
|
||||
|
||||
\param dest Destination 64-bit address, in the form of 8-byte array.
|
||||
|
||||
\param destNetwork Destination 16-bit address, in the form of 2-byte array.
|
||||
|
||||
\param payload String of payload bytes.
|
||||
|
||||
\param radius Number of maximum "hops" for a broadcast transmission. Defaults to 1, set to 0 for unlimited number of hops.
|
||||
*/
|
||||
int16_t transmit(uint8_t* dest, uint8_t* destNetwork, const char* payload, uint8_t radius = 1);
|
||||
|
||||
/*!
|
||||
\brief Gets the number of payload bytes received.
|
||||
|
||||
\returns Number of available payload bytes, or 0 if nothing was received.
|
||||
*/
|
||||
size_t available();
|
||||
|
||||
/*!
|
||||
\brief Gets packet source 64-bit address.
|
||||
|
||||
\returns Packet source address, in the form of uppercase hexadecimal Arduino String (i.e. 16 characters).
|
||||
*/
|
||||
String getPacketSource();
|
||||
|
||||
/*!
|
||||
\brief Gets packet payload.
|
||||
|
||||
\returns Packet payload, in the form of Arduino String.
|
||||
*/
|
||||
String getPacketData();
|
||||
|
||||
// configuration methods
|
||||
|
||||
/*!
|
||||
\brief Sets PAN (Personal Area Network) ID. All XBees must be in the same PAN in order to communicate.
|
||||
|
||||
\param panId 8-byte PAN ID to be used, in the form of uppercase hexadecimal string (i.e. 16 characters).
|
||||
*/
|
||||
int16_t setPanId(uint8_t* panId);
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE) && !defined(RADIOLIB_LOW_LEVEL)
|
||||
protected:
|
||||
#endif
|
||||
Module* _mod;
|
||||
|
||||
#if !defined(RADIOLIB_GODMODE)
|
||||
protected:
|
||||
#endif
|
||||
|
||||
uint8_t _frameID = 0x01;
|
||||
size_t _frameLength = 0;
|
||||
bool _frameHeaderProcessed = false;
|
||||
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
char _packetData[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
char* _packetData = new char[0];
|
||||
#endif
|
||||
uint8_t _packetSource[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
int16_t confirmChanges();
|
||||
|
||||
void sendApiFrame(uint8_t type, uint8_t id, const char* data);
|
||||
void sendApiFrame(uint8_t type, uint8_t id, uint8_t* data, uint16_t length);
|
||||
int16_t readApiFrame(uint8_t frameID, uint8_t codePos, uint16_t timeout = 5000);
|
||||
|
||||
uint16_t getNumBytes(uint32_t timeout = 10000, size_t minBytes = 10);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,219 +0,0 @@
|
|||
#include "HTTP.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_HTTP)
|
||||
|
||||
HTTPClient::HTTPClient(TransportLayer* tl, uint16_t port) {
|
||||
_tl = tl;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
int16_t HTTPClient::get(String& url, String& response) {
|
||||
return(HTTPClient::get(url.c_str(), response));
|
||||
}
|
||||
|
||||
int16_t HTTPClient::get(const char* url, String& response) {
|
||||
// get the host address and endpoint
|
||||
char* httpPrefix = strstr(url, "http://");
|
||||
char* endpoint;
|
||||
char* host;
|
||||
if(httpPrefix != NULL) {
|
||||
// find the host string
|
||||
char* hostStart = strchr(url, '/');
|
||||
hostStart = strchr(hostStart + 1, '/');
|
||||
char* hostEnd = strchr(hostStart + 1, '/');
|
||||
host = new char[hostEnd - hostStart];
|
||||
strncpy(host, hostStart + 1, hostEnd - hostStart - 1);
|
||||
host[hostEnd - hostStart - 1] = '\0';
|
||||
|
||||
// find the endpoint string
|
||||
endpoint = new char[url + strlen(url) - hostEnd + 1];
|
||||
strcpy(endpoint, hostEnd);
|
||||
} else {
|
||||
// find the host string
|
||||
char* hostEnd = strchr(url, '/');
|
||||
host = new char[hostEnd - url + 1];
|
||||
strncpy(host, url, hostEnd - url);
|
||||
host[hostEnd - url] = '\0';
|
||||
|
||||
// find the endpoint string
|
||||
endpoint = new char[url + strlen(url) - hostEnd + 1];
|
||||
strcpy(endpoint, hostEnd);
|
||||
}
|
||||
|
||||
// build the GET request
|
||||
char* request = new char[strlen(endpoint) + strlen(host) + 25 + 1];
|
||||
strcpy(request, "GET ");
|
||||
strcat(request, endpoint);
|
||||
strcat(request, " HTTP/1.1\r\nHost: ");
|
||||
strcat(request, host);
|
||||
strcat(request, "\r\n\r\n");
|
||||
|
||||
delete[] endpoint;
|
||||
|
||||
// create TCP connection
|
||||
int16_t state = _tl->openTransportConnection(host, "TCP", _port);
|
||||
delete[] host;
|
||||
if(state != ERR_NONE) {
|
||||
delete[] request;
|
||||
return(state);
|
||||
}
|
||||
|
||||
// send the GET request
|
||||
state = _tl->send(request);
|
||||
delete[] request;
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes == 0) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
char* raw = new char[numBytes + 1];
|
||||
size_t rawLength = _tl->receive((uint8_t*)raw, numBytes);
|
||||
if(rawLength == 0) {
|
||||
delete[] raw;
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
// close the tl connection
|
||||
state = _tl->closeTransportConnection();
|
||||
if(state != ERR_NONE) {
|
||||
delete[] raw;
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response body
|
||||
char* responseStart = strstr(raw, "\r\n");
|
||||
if(responseStart == NULL) {
|
||||
delete[] raw;
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
char* responseStr = new char[raw + rawLength - responseStart - 1 + 1];
|
||||
strncpy(responseStr, responseStart + 2, raw + rawLength - responseStart - 1);
|
||||
responseStr[raw + rawLength - responseStart - 2] = '\0';
|
||||
response = String(responseStr);
|
||||
delete[] responseStr;
|
||||
|
||||
// return the HTTP status code
|
||||
char* statusStart = strchr(raw, ' ');
|
||||
delete[] raw;
|
||||
if(statusStart == NULL) {
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
char statusStr[4];
|
||||
strncpy(statusStr, statusStart + 1, 3);
|
||||
statusStr[3] = 0x00;
|
||||
return(atoi(statusStr));
|
||||
}
|
||||
|
||||
int16_t HTTPClient::post(const char* url, const char* content, String& response, const char* contentType) {
|
||||
// get the host address and endpoint
|
||||
char* httpPrefix = strstr(url, "http://");
|
||||
char* endpoint;
|
||||
char* host;
|
||||
if(httpPrefix != NULL) {
|
||||
// find the host string
|
||||
char* hostStart = strchr(url, '/');
|
||||
hostStart = strchr(hostStart + 1, '/');
|
||||
char* hostEnd = strchr(hostStart + 1, '/');
|
||||
host = new char[hostEnd - hostStart];
|
||||
strncpy(host, hostStart + 1, hostEnd - hostStart - 1);
|
||||
host[hostEnd - hostStart - 1] = '\0';
|
||||
|
||||
// find the endpoint string
|
||||
endpoint = new char[url + strlen(url) - hostEnd + 1];
|
||||
strcpy(endpoint, hostEnd);
|
||||
} else {
|
||||
// find the host string
|
||||
char* hostEnd = strchr(url, '/');
|
||||
host = new char[hostEnd - url + 1];
|
||||
strncpy(host, url, hostEnd - url);
|
||||
host[hostEnd - url] = '\0';
|
||||
|
||||
// find the endpoint string
|
||||
endpoint = new char[url + strlen(url) - hostEnd + 1];
|
||||
strcpy(endpoint, hostEnd);
|
||||
}
|
||||
|
||||
// build the POST request
|
||||
char contentLengthStr[12];
|
||||
sprintf(contentLengthStr, "%u", (uint16_t)strlen(content));
|
||||
char* request = new char[strlen(endpoint) + strlen(host) + strlen(contentType) + strlen(contentLengthStr) + strlen(content) + 64 + 1];
|
||||
strcpy(request, "POST ");
|
||||
strcat(request, endpoint);
|
||||
strcat(request, " HTTP/1.1\r\nHost: ");
|
||||
strcat(request, host);
|
||||
strcat(request, "\r\nContent-Type: ");
|
||||
strcat(request, contentType);
|
||||
strcat(request, "\r\nContent-length: ");
|
||||
strcat(request, contentLengthStr);
|
||||
strcat(request, "\r\n\r\n");
|
||||
strcat(request, content);
|
||||
strcat(request, "\r\n\r\n");
|
||||
|
||||
delete[] endpoint;
|
||||
|
||||
// create TCP connection
|
||||
int16_t state = _tl->openTransportConnection(host, "TCP", _port);
|
||||
delete[] host;
|
||||
if(state != ERR_NONE) {
|
||||
delete[] request;
|
||||
return(state);
|
||||
}
|
||||
|
||||
// send the POST request
|
||||
state = _tl->send(request);
|
||||
delete[] request;
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes == 0) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
char* raw = new char[numBytes];
|
||||
size_t rawLength = _tl->receive((uint8_t*)raw, numBytes);
|
||||
if(rawLength == 0) {
|
||||
delete[] raw;
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
// close the tl connection
|
||||
state = _tl->closeTransportConnection();
|
||||
if(state != ERR_NONE) {
|
||||
delete[] raw;
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response body
|
||||
char* responseStart = strstr(raw, "\r\n");
|
||||
if(responseStart == NULL) {
|
||||
delete[] raw;
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
char* responseStr = new char[raw + rawLength - responseStart - 1];
|
||||
strncpy(responseStr, responseStart + 2, raw + rawLength - responseStart - 1);
|
||||
responseStr[raw + rawLength - responseStart - 2] = 0x00;
|
||||
response = String(responseStr);
|
||||
delete[] responseStr;
|
||||
|
||||
// return the HTTP status code
|
||||
char* statusStart = strchr(raw, ' ');
|
||||
delete[] raw;
|
||||
if(statusStart == NULL) {
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
char statusStr[4];
|
||||
strncpy(statusStr, statusStart + 1, 3);
|
||||
statusStr[3] = 0x00;
|
||||
return(atoi(statusStr));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||
#if !defined(_RADIOLIB_HTTP_H)
|
||||
#define _RADIOLIB_HTTP_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
|
||||
#if !defined(RADIOLIB_EXCLUDE_HTTP)
|
||||
|
||||
#include "../TransportLayer/TransportLayer.h"
|
||||
|
||||
/*!
|
||||
\class HTTPClient
|
||||
|
||||
\brief Client for simple HTTP communication.
|
||||
*/
|
||||
class HTTPClient {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param tl Pointer to the wireless module providing TransportLayer communication.
|
||||
|
||||
\param port Port to be used for HTTP. Defaults to 80.
|
||||
*/
|
||||
explicit HTTPClient(TransportLayer* tl, uint16_t port = 80);
|
||||
|
||||
/*!
|
||||
\brief Sends HTTP GET request.
|
||||
|
||||
\param url URL to send the request to.
|
||||
|
||||
\param response Arduino String object that will save the response.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t get(String& url, String& response);
|
||||
|
||||
/*!
|
||||
\brief Sends HTTP GET request.
|
||||
|
||||
\param url URL to send the request to.
|
||||
|
||||
\param response Arduino String object that will save the response.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t get(const char* url, String& response);
|
||||
|
||||
/*!
|
||||
\brief Sends HTTP POST request.
|
||||
|
||||
\param url URL to send the request to.
|
||||
|
||||
\param content Request content.
|
||||
|
||||
\param response Arduino String object that will save the response.
|
||||
|
||||
\param contentType MIME type of request content. Defaults to "text/plain".
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t post(const char* url, const char* content, String& response, const char* contentType = "text/plain");
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
TransportLayer* _tl;
|
||||
|
||||
uint16_t _port;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,472 +0,0 @@
|
|||
#include "MQTT.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_MQTT)
|
||||
|
||||
MQTTClient::MQTTClient(TransportLayer* tl, uint16_t port) {
|
||||
_tl = tl;
|
||||
_port = port;
|
||||
_packetId = 1;
|
||||
}
|
||||
|
||||
int16_t MQTTClient::connect(const char* host, const char* clientId, const char* userName, const char* password, uint16_t keepAlive, bool cleanSession, const char* willTopic, const char* willMessage) {
|
||||
// encode packet length
|
||||
size_t clientIdLen = strlen(clientId);
|
||||
size_t userNameLen = strlen(userName);
|
||||
size_t passwordLen = strlen(password);
|
||||
size_t willTopicLen = strlen(willTopic);
|
||||
size_t willMessageLen = strlen(willMessage);
|
||||
uint32_t remainingLength = 10 + (2 + clientIdLen);
|
||||
if(userNameLen > 0) {
|
||||
remainingLength += (2 + userNameLen);
|
||||
}
|
||||
if(passwordLen > 0) {
|
||||
remainingLength += (2 + passwordLen);
|
||||
}
|
||||
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
||||
remainingLength += (2 + willTopicLen) + (2 + willMessageLen);
|
||||
}
|
||||
uint8_t encoded[] = {0, 0, 0, 0};
|
||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||
|
||||
// build the CONNECT packet
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t packet[256];
|
||||
#else
|
||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
||||
#endif
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_CONNECT << 4) | 0b0000;
|
||||
memcpy(packet + 1, encoded, encodedBytes);
|
||||
|
||||
// variable header
|
||||
// protocol name
|
||||
size_t pos = encodedBytes + 1;
|
||||
packet[pos++] = 0x00;
|
||||
packet[pos++] = 0x04;
|
||||
memcpy(packet + pos, "MQTT", 4);
|
||||
pos += 4;
|
||||
|
||||
// protocol level
|
||||
packet[pos++] = 0x04;
|
||||
|
||||
// flags
|
||||
packet[pos++] = 0x00;
|
||||
if(cleanSession) {
|
||||
packet[encodedBytes + 8] |= MQTT_CONNECT_CLEAN_SESSION;
|
||||
}
|
||||
|
||||
// keep alive interval in seconds
|
||||
packet[pos++] = (keepAlive & 0xFF00) >> 8;
|
||||
packet[pos++] = keepAlive & 0x00FF;
|
||||
|
||||
// payload
|
||||
// clientId
|
||||
packet[pos++] = (clientIdLen & 0xFF00) >> 8;
|
||||
packet[pos++] = clientIdLen & 0x00FF;
|
||||
memcpy(packet + pos, clientId, clientIdLen);
|
||||
pos += clientIdLen;
|
||||
|
||||
// will topic and message
|
||||
if((willTopicLen > 0) && (willMessageLen > 0)) {
|
||||
packet[encodedBytes + 8] |= MQTT_CONNECT_WILL_FLAG;
|
||||
|
||||
packet[pos++] = (willTopicLen & 0xFF00) >> 8;
|
||||
packet[pos++] = willTopicLen & 0x00FF;
|
||||
memcpy(packet + pos, willTopic, willTopicLen);
|
||||
pos += willTopicLen;
|
||||
|
||||
packet[pos++] = (willMessageLen & 0xFF00) >> 8;
|
||||
packet[pos++] = willMessageLen & 0x00FF;
|
||||
memcpy(packet + pos, willMessage, willMessageLen);
|
||||
pos += willMessageLen;
|
||||
}
|
||||
|
||||
// user name
|
||||
if(userNameLen > 0) {
|
||||
packet[encodedBytes + 8] |= MQTT_CONNECT_USER_NAME_FLAG;
|
||||
packet[pos++] = (userNameLen & 0xFF00) >> 8;
|
||||
packet[pos++] = userNameLen & 0x00FF;
|
||||
memcpy(packet + pos, userName, userNameLen);
|
||||
pos += userNameLen;
|
||||
}
|
||||
|
||||
// password
|
||||
if(passwordLen > 0) {
|
||||
packet[encodedBytes + 8] |= MQTT_CONNECT_PASSWORD_FLAG;
|
||||
packet[pos++] = (passwordLen & 0xFF00) >> 8;;
|
||||
packet[pos++] = passwordLen & 0x00FF;
|
||||
memcpy(packet + pos, password, passwordLen);
|
||||
}
|
||||
|
||||
// create TCP connection
|
||||
int16_t state = _tl->openTransportConnection(host, "TCP", _port, keepAlive);
|
||||
if(state != ERR_NONE) {
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] packet;
|
||||
#endif
|
||||
return(state);
|
||||
}
|
||||
|
||||
// send MQTT packet
|
||||
state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] packet;
|
||||
#endif
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length (MQTT CONNACK response has to be 4 bytes long)
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes != 4) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t response[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* response = new uint8_t[numBytes];
|
||||
#endif
|
||||
_tl->receive(response, numBytes);
|
||||
if((response[0] == MQTT_CONNACK << 4) && (response[1] == 2)) {
|
||||
uint8_t returnCode = response[3];
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(returnCode);
|
||||
}
|
||||
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
int16_t MQTTClient::disconnect() {
|
||||
// build the DISCONNECT packet
|
||||
uint8_t packet[2];
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_DISCONNECT << 4) | 0b0000;
|
||||
packet[1] = 0x00;
|
||||
|
||||
// send MQTT packet
|
||||
int16_t state = _tl->send(packet, 2);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// close tl connection
|
||||
return(_tl->closeTransportConnection());
|
||||
}
|
||||
|
||||
int16_t MQTTClient::publish(String& topic, String& message) {
|
||||
return(MQTTClient::publish(topic.c_str(), message.c_str()));
|
||||
}
|
||||
|
||||
int16_t MQTTClient::publish(const char* topic, const char* message) {
|
||||
// encode packet length
|
||||
size_t topicLen = strlen(topic);
|
||||
size_t messageLen = strlen(message);
|
||||
uint32_t remainingLength = (2 + topicLen) + messageLen;
|
||||
uint8_t encoded[] = {0, 0, 0, 0};
|
||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||
|
||||
// build the PUBLISH packet
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t packet[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
||||
#endif
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_PUBLISH << 4) | 0b0000;
|
||||
memcpy(packet + 1, encoded, encodedBytes);
|
||||
|
||||
// variable header
|
||||
// topic name
|
||||
size_t pos = encodedBytes + 1;
|
||||
packet[pos++] = (topicLen & 0xFF00) >> 8;
|
||||
packet[pos++] = topicLen & 0x00FF;
|
||||
memcpy(packet + pos, topic, topicLen);
|
||||
pos += topicLen;
|
||||
|
||||
// packet ID
|
||||
|
||||
// payload
|
||||
// message
|
||||
memcpy(packet + pos, message, messageLen);
|
||||
|
||||
// send MQTT packet
|
||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] packet;
|
||||
#endif
|
||||
return(state);
|
||||
|
||||
/// \todo implement QoS > 0 and PUBACK response checking
|
||||
}
|
||||
|
||||
int16_t MQTTClient::subscribe(const char* topicFilter) {
|
||||
// encode packet length
|
||||
size_t topicFilterLen = strlen(topicFilter);
|
||||
uint32_t remainingLength = 2 + (2 + topicFilterLen + 1);
|
||||
uint8_t encoded[] = {0, 0, 0, 0};
|
||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||
|
||||
// build the SUBSCRIBE packet
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t packet[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
||||
#endif
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_SUBSCRIBE << 4) | 0b0010;
|
||||
memcpy(packet + 1, encoded, encodedBytes);
|
||||
|
||||
// variable header
|
||||
// packet ID
|
||||
size_t pos = encodedBytes + 1;
|
||||
uint16_t packetId = _packetId++;
|
||||
packet[pos++] = (packetId & 0xFF00) >> 8;
|
||||
packet[pos++] = packetId & 0x00FF;
|
||||
|
||||
// payload
|
||||
// topic filter
|
||||
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
||||
packet[pos++] = topicFilterLen & 0x00FF;
|
||||
memcpy(packet + pos, topicFilter, topicFilterLen);
|
||||
pos += topicFilterLen;
|
||||
packet[pos++] = 0x00; // QoS 0
|
||||
|
||||
// send MQTT packet
|
||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] packet;
|
||||
#endif
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length (MQTT SUBACK response has to be 5 bytes long for single subscription)
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes != 5) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t response[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* response = new uint8_t[numBytes];
|
||||
#endif
|
||||
_tl->receive(response, numBytes);
|
||||
if((response[0] == MQTT_SUBACK << 4) && (response[1] == 3)) {
|
||||
// check packet ID
|
||||
uint16_t receivedId = response[3] | response[2] << 8;
|
||||
int16_t returnCode = response[4];
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
if(receivedId != packetId) {
|
||||
return(ERR_MQTT_UNEXPECTED_PACKET_ID);
|
||||
}
|
||||
return(returnCode);
|
||||
}
|
||||
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
int16_t MQTTClient::unsubscribe(const char* topicFilter) {
|
||||
// encode packet length
|
||||
size_t topicFilterLen = strlen(topicFilter);
|
||||
uint32_t remainingLength = 2 + (2 + topicFilterLen);
|
||||
uint8_t encoded[] = {0, 0, 0, 0};
|
||||
size_t encodedBytes = encodeLength(remainingLength, encoded);
|
||||
|
||||
// build the UNSUBSCRIBE packet
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t packet[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* packet = new uint8_t[1 + encodedBytes + remainingLength];
|
||||
#endif
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_UNSUBSCRIBE << 4) | 0b0010;
|
||||
memcpy(packet + 1, encoded, encodedBytes);
|
||||
|
||||
// variable header
|
||||
// packet ID
|
||||
size_t pos = encodedBytes + 1;
|
||||
uint16_t packetId = _packetId++;
|
||||
packet[pos++] = (packetId & 0xFF00) >> 8;
|
||||
packet[pos++] = packetId & 0x00FF;
|
||||
|
||||
// payload
|
||||
// topic filter
|
||||
packet[pos++] = (topicFilterLen & 0xFF00) >> 8;;
|
||||
packet[pos++] = topicFilterLen & 0x00FF;
|
||||
memcpy(packet + pos, topicFilter, topicFilterLen);
|
||||
|
||||
// send MQTT packet
|
||||
int16_t state = _tl->send(packet, 1 + encodedBytes + remainingLength);
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] packet;
|
||||
#endif
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length (MQTT UNSUBACK response has to be 4 bytes long)
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes != 4) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t response[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* response = new uint8_t[numBytes];
|
||||
#endif
|
||||
_tl->receive(response, numBytes);
|
||||
if((response[0] == MQTT_UNSUBACK << 4) && (response[1] == 2)) {
|
||||
// check packet ID
|
||||
uint16_t receivedId = response[3] | response[2] << 8;
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
if(receivedId != packetId) {
|
||||
return(ERR_MQTT_UNEXPECTED_PACKET_ID);
|
||||
}
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
int16_t MQTTClient::ping() {
|
||||
// build the PINGREQ packet
|
||||
uint8_t packet[2];
|
||||
|
||||
// fixed header
|
||||
packet[0] = (MQTT_PINGREQ << 4) | 0b0000;
|
||||
packet[1] = 0x00;
|
||||
|
||||
// send MQTT packet
|
||||
int16_t state = _tl->send(packet, 2);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// get the response length (MQTT PINGRESP response has to be 2 bytes long)
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes != 2) {
|
||||
return(ERR_RESPONSE_MALFORMED_AT);
|
||||
}
|
||||
|
||||
// read the response
|
||||
#ifdef RADIOLIB_STATIC_ONLY
|
||||
uint8_t response[RADIOLIB_STATIC_ARRAY_SIZE];
|
||||
#else
|
||||
uint8_t* response = new uint8_t[numBytes];
|
||||
#endif
|
||||
_tl->receive(response, numBytes);
|
||||
if((response[0] == MQTT_PINGRESP << 4) && (response[1] == 0)) {
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
#ifndef RADIOLIB_STATIC_ONLY
|
||||
delete[] response;
|
||||
#endif
|
||||
return(ERR_RESPONSE_MALFORMED);
|
||||
}
|
||||
|
||||
int16_t MQTTClient::check(void (*func)(const char*, const char*)) {
|
||||
// ping the server
|
||||
int16_t state = ping();
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// check new data
|
||||
size_t numBytes = _tl->getNumBytes();
|
||||
if(numBytes == 0) {
|
||||
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
||||
}
|
||||
|
||||
// read the PUBLISH packet from server
|
||||
uint8_t* dataIn = new uint8_t[numBytes];
|
||||
_tl->receive(dataIn, numBytes);
|
||||
if(dataIn[0] == MQTT_PUBLISH << 4) {
|
||||
uint8_t remLenFieldLen = 0;
|
||||
uint32_t remainingLength = decodeLength(dataIn + 1, remLenFieldLen);
|
||||
|
||||
// get the topic
|
||||
size_t topicLength = dataIn[remLenFieldLen + 2] | dataIn[remLenFieldLen + 1] << 8;
|
||||
char* topic = new char[topicLength + 1];
|
||||
memcpy(topic, dataIn + 4, topicLength);
|
||||
topic[topicLength] = 0x00;
|
||||
|
||||
// get the message
|
||||
size_t messageLength = remainingLength - topicLength - 2;
|
||||
char* message = new char[messageLength + 1];
|
||||
memcpy(message, dataIn + remLenFieldLen + 3 + topicLength, messageLength);
|
||||
message[messageLength] = 0x00;
|
||||
|
||||
// execute the callback function provided by user
|
||||
func(topic, message);
|
||||
|
||||
delete[] topic;
|
||||
delete[] message;
|
||||
delete[] dataIn;
|
||||
return(ERR_NONE);
|
||||
}
|
||||
delete[] dataIn;
|
||||
|
||||
return(ERR_MQTT_NO_NEW_PACKET_AVAILABLE);
|
||||
}
|
||||
|
||||
size_t MQTTClient::encodeLength(uint32_t len, uint8_t* encoded) {
|
||||
// algorithm to encode packet length as per MQTT specification 3.1.1
|
||||
size_t i = 0;
|
||||
do {
|
||||
encoded[i] = len % 128;
|
||||
len /= 128;
|
||||
if(len > 0) {
|
||||
encoded[i] |= 128;
|
||||
}
|
||||
i++;
|
||||
} while(len > 0);
|
||||
return(i);
|
||||
}
|
||||
|
||||
uint32_t MQTTClient::decodeLength(uint8_t* encoded, uint8_t& numBytes) {
|
||||
// algorithm to decode packet length as per MQTT specification 3.1.1
|
||||
uint32_t mult = 1;
|
||||
uint32_t len = 0;
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
len += (encoded[i] & 127) * mult;
|
||||
mult *= 128;
|
||||
if(mult > 2097152) {
|
||||
// malformed remaining length
|
||||
return(0);
|
||||
}
|
||||
} while((encoded[i++] & 128) != 0);
|
||||
numBytes = i;
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
#if !defined(_RADIOLIB_MQTT_H)
|
||||
#define _RADIOLIB_MQTT_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
|
||||
#if !defined(RADIOLIB_EXCLUDE_MQTT)
|
||||
|
||||
#include "../TransportLayer/TransportLayer.h"
|
||||
|
||||
// MQTT packet types
|
||||
#define MQTT_CONNECT 0x01
|
||||
#define MQTT_CONNACK 0x02
|
||||
#define MQTT_PUBLISH 0x03
|
||||
#define MQTT_PUBACK 0x04
|
||||
#define MQTT_PUBREC 0x05
|
||||
#define MQTT_PUBREL 0x06
|
||||
#define MQTT_PUBCOMP 0x07
|
||||
#define MQTT_SUBSCRIBE 0x08
|
||||
#define MQTT_SUBACK 0x09
|
||||
#define MQTT_UNSUBSCRIBE 0x0A
|
||||
#define MQTT_UNSUBACK 0x0B
|
||||
#define MQTT_PINGREQ 0x0C
|
||||
#define MQTT_PINGRESP 0x0D
|
||||
#define MQTT_DISCONNECT 0x0E
|
||||
|
||||
// MQTT CONNECT flags
|
||||
#define MQTT_CONNECT_USER_NAME_FLAG 0b10000000
|
||||
#define MQTT_CONNECT_PASSWORD_FLAG 0b01000000
|
||||
#define MQTT_CONNECT_WILL_RETAIN 0b00100000
|
||||
#define MQTT_CONNECT_WILL_FLAG 0b00000100
|
||||
#define MQTT_CONNECT_CLEAN_SESSION 0b00000010
|
||||
|
||||
/*!
|
||||
\class MQTTClient
|
||||
|
||||
\brief Client for simple MQTT communication.
|
||||
*/
|
||||
class MQTTClient {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param tl Pointer to the wireless module providing TransportLayer communication.
|
||||
*/
|
||||
explicit MQTTClient(TransportLayer* tl, uint16_t port = 1883);
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Connects to MQTT broker (/server).
|
||||
|
||||
\param host URL of the MQTT broker.
|
||||
|
||||
\param clientId ID of the client.
|
||||
|
||||
\param username Username to be used in the connection. Defaults to empty string (no username).
|
||||
|
||||
\param password Password to be used in the connection. Defaults to empty string (no password).
|
||||
|
||||
\param keepAlive Connection keep-alive period in seconds. Defaults to 60.
|
||||
|
||||
\param cleanSession MQTT CleanSession flag. Defaults to true.
|
||||
|
||||
\param willTopic MQTT will topic. Defaults to empty string (no will topic).
|
||||
|
||||
\param willMessage MQTT will message. Defaults to empty string (no will message).
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t connect(const char* host, const char* clientId, const char* userName = "", const char* password = "", uint16_t keepAlive = 60, bool cleanSession = true, const char* willTopic = "", const char* willMessage = "");
|
||||
|
||||
/*!
|
||||
\brief Disconnect from MQTT broker.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t disconnect();
|
||||
|
||||
/*!
|
||||
\brief Publish MQTT message.
|
||||
|
||||
\param topic MQTT topic to which the message will be published.
|
||||
|
||||
\param message Message to be published.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t publish(String& topic, String& message);
|
||||
|
||||
/*!
|
||||
\brief Publish MQTT message.
|
||||
|
||||
\param topic MQTT topic to which the message will be published.
|
||||
|
||||
\param message Message to be published.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t publish(const char* topic, const char* message);
|
||||
|
||||
/*!
|
||||
\brief Subscribe to MQTT topic.
|
||||
|
||||
\param topicFilter Topic to subscribe to.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t subscribe(const char* topicFilter);
|
||||
|
||||
/*!
|
||||
\brief Unsubscribe from MQTT topic.
|
||||
|
||||
\param topicFilter Topic to unsubscribe from.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t unsubscribe(const char* topicFilter);
|
||||
|
||||
/*!
|
||||
\brief Ping MQTT broker. This method can be used to keep connection open.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t ping();
|
||||
|
||||
/*!
|
||||
\brief Set function to be called when checking new messages in subscribed topics.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t check(void (*func)(const char*, const char*));
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
TransportLayer* _tl;
|
||||
|
||||
uint16_t _port;
|
||||
uint16_t _packetId;
|
||||
|
||||
static size_t encodeLength(uint32_t len, uint8_t* encoded);
|
||||
static uint32_t decodeLength(uint8_t* encoded, uint8_t& numBytes);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||
#ifndef _RADIOLIB_TRANSPORT_LAYER_H
|
||||
#define _RADIOLIB_TRANSPORT_LAYER_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
|
||||
/*!
|
||||
\class TransportLayer
|
||||
|
||||
\brief Provides common interface for protocols that run on modules with Internet connectivity, such as HTTP or MQTT.
|
||||
Because this class is used mainly as interface, all of its virtual members must be implemented in the module class.
|
||||
*/
|
||||
class TransportLayer {
|
||||
public:
|
||||
// constructor
|
||||
// this class is purely virtual and does not require explicit constructor
|
||||
|
||||
// basic methods
|
||||
|
||||
/*!
|
||||
\brief Open transport layer connection.
|
||||
|
||||
\param host Host to connect to.
|
||||
|
||||
\param protocol Transport protocol to use. Usually "TCP" or "UDP".
|
||||
|
||||
\param port to be used for the connection.
|
||||
|
||||
\param tcpKeepAlive TCP keep alive interval. Defaults to 0.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual int16_t openTransportConnection(const char* host, const char* protocol, uint16_t port, uint16_t tcpKeepAlive = 0) = 0;
|
||||
|
||||
/*!
|
||||
\brief Close transport layer connection.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual int16_t closeTransportConnection() = 0;
|
||||
|
||||
/*!
|
||||
\brief Send string-based data.
|
||||
|
||||
\param string String data to be sent.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual int16_t send(const char* data) = 0;
|
||||
|
||||
/*!
|
||||
\brief Send arbitrary binary data.
|
||||
|
||||
\param data Data to be sent.
|
||||
|
||||
\param len Number of bytes to send.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual int16_t send(uint8_t* data, size_t len) = 0;
|
||||
|
||||
/*!
|
||||
\brief Receive data.
|
||||
|
||||
\param data Pointer to array to save the received data.
|
||||
|
||||
\param len Number of bytes to read.
|
||||
|
||||
\param timeout Reception timeout in ms. Defaults to 10000.
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
virtual size_t receive(uint8_t* data, size_t len, uint32_t timeout = 10000) = 0;
|
||||
|
||||
/*!
|
||||
\brief Get number of received bytes.
|
||||
|
||||
\param timeout Reception timeout in ms. Defaults to 10000.
|
||||
|
||||
\param minBytes Minimum required number of bytes that must be received.
|
||||
|
||||
\returns Number of received bytes, or 0 on timeout.
|
||||
*/
|
||||
virtual size_t getNumBytes(uint32_t timeout = 10000, size_t minBytes = 10) = 0;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue