mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 11:16:34 +00:00
Forgot the library swap
This commit is contained in:
parent
0ad250c10b
commit
6cd59d2b3e
7
lib/arduino-mqtt-2.3.3.02/.editorconfig
Normal file
7
lib/arduino-mqtt-2.3.3.02/.editorconfig
Normal file
@ -0,0 +1,7 @@
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[src/*.h,src/*.cpp,examples/**.ino]
|
||||
indent_style = space
|
||||
indent_size = 2
|
2
lib/arduino-mqtt-2.3.3.02/.gitignore
vendored
Normal file
2
lib/arduino-mqtt-2.3.3.02/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.DS_Store
|
||||
cmake-build-debug/
|
46
lib/arduino-mqtt-2.3.3.02/.travis.yml
Normal file
46
lib/arduino-mqtt-2.3.3.02/.travis.yml
Normal file
@ -0,0 +1,46 @@
|
||||
language: generic
|
||||
env:
|
||||
global:
|
||||
- IDE_VERSION=1.8.5
|
||||
matrix:
|
||||
- EXAMPLE="AdafruitHuzzahESP8266" BOARD="esp8266:esp8266:huzzah:FlashSize=4M3M,CpuFrequency=80"
|
||||
- EXAMPLE="AdafruitHuzzahESP8266Secure" BOARD="esp8266:esp8266:huzzah:FlashSize=4M3M,CpuFrequency=80"
|
||||
- EXAMPLE="ArduinoEthernetShield" BOARD="arduino:avr:uno"
|
||||
- EXAMPLE="ArduinoMKRGSM1400" BOARD="arduino:samd:mkrgsm1400"
|
||||
- EXAMPLE="ArduinoMKRGSM1400Secure" BOARD="arduino:samd:mkrgsm1400"
|
||||
- EXAMPLE="ArduinoWiFi101Secure" BOARD="arduino:avr:uno"
|
||||
- EXAMPLE="ArduinoWiFiShield" BOARD="arduino:avr:uno"
|
||||
- EXAMPLE="ArduinoYun" BOARD="arduino:avr:yun"
|
||||
- EXAMPLE="ArduinoYunSecure" BOARD="arduino:avr:yun"
|
||||
- EXAMPLE="ESP32DevelopmentBoard" BOARD="espressif:esp32:esp32:FlashFreq=80"
|
||||
- EXAMPLE="ESP32DevelopmentBoardSecure" BOARD="espressif:esp32:esp32:FlashFreq=80"
|
||||
before_install:
|
||||
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
|
||||
- sleep 3
|
||||
- export DISPLAY=:1.0
|
||||
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
||||
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||
- mv arduino-$IDE_VERSION ~/arduino-ide
|
||||
- export PATH=$PATH:~/arduino-ide
|
||||
- if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then
|
||||
arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json" --install-boards esp8266:esp8266;
|
||||
arduino --pref "boardsmanager.additional.urls=" --save-prefs;
|
||||
fi
|
||||
- if [[ "$BOARD" =~ "espressif:esp32:" ]]; then
|
||||
mkdir -p ~/Arduino/hardware/espressif &&
|
||||
cd ~/Arduino/hardware/espressif &&
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32 &&
|
||||
cd esp32/tools/ &&
|
||||
python get.py &&
|
||||
cd $TRAVIS_BUILD_DIR;
|
||||
fi
|
||||
- if [[ "$BOARD" =~ "arduino:samd:mkrgsm1400" ]]; then
|
||||
arduino --install-boards arduino:samd;
|
||||
arduino --install-library MKRGSM;
|
||||
fi
|
||||
- arduino --install-library WiFi101
|
||||
install:
|
||||
- mkdir -p ~/Arduino/libraries
|
||||
- ln -s $PWD ~/Arduino/libraries/.
|
||||
script:
|
||||
- arduino --verbose-build --verify --board $BOARD $PWD/examples/$EXAMPLE/$EXAMPLE.ino;
|
40
lib/arduino-mqtt-2.3.3.02/CMakeLists.txt
Normal file
40
lib/arduino-mqtt-2.3.3.02/CMakeLists.txt
Normal file
@ -0,0 +1,40 @@
|
||||
# Uncompilable CMake File to enable project editing with CLion IDE
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(arduino-mqtt)
|
||||
|
||||
include_directories(
|
||||
/Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/
|
||||
/Users/256dpi/Development/Arduino/libraries/Ethernet/src
|
||||
/Users/256dpi/Development/Arduino/libraries/WiFi101/src
|
||||
/Users/256dpi/Development/Arduino/libraries/MKRGSM/src
|
||||
/Applications/Arduino.app/Contents/Java/libraries/Bridge/src
|
||||
/Users/256dpi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.3.0/libraries/ESP8266WiFi/src
|
||||
/Users/256dpi/Development/Arduino/hardware/espressif/esp32/libraries/WiFi/src
|
||||
/Users/256dpi/Development/Arduino/hardware/espressif/esp32/libraries/WiFiClientSecure/src
|
||||
src/)
|
||||
|
||||
include_directories(src/)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set(SOURCE_FILES
|
||||
examples/AdafruitHuzzahESP8266/AdafruitHuzzahESP8266.ino
|
||||
examples/AdafruitHuzzahESP8266Secure/AdafruitHuzzahESP8266Secure.ino
|
||||
examples/ArduinoEthernetShield/ArduinoEthernetShield.ino
|
||||
examples/ArduinoMKRGSM1400/ArduinoMKRGSM1400.ino
|
||||
examples/ArduinoMKRGSM1400Secure/ArduinoMKRGSM1400Secure.ino
|
||||
examples/ArduinoWiFi101/ArduinoWiFi101.ino
|
||||
examples/ArduinoWiFi101Secure/ArduinoWiFi101Secure.ino
|
||||
examples/ArduinoWiFiShield/ArduinoWiFiShield.ino
|
||||
examples/ArduinoYun/ArduinoYun.ino
|
||||
examples/ArduinoYunSecure/ArduinoYunSecure.ino
|
||||
examples/ESP32DevelopmentBoard/ESP32DevelopmentBoard.ino
|
||||
examples/ESP32DevelopmentBoardSecure/ESP32DevelopmentBoardSecure.ino
|
||||
src/lwmqtt
|
||||
src/MQTT.h
|
||||
src/MQTTClient.h
|
||||
src/system.cpp
|
||||
src/system.h)
|
||||
|
||||
add_executable(arduino-mqtt ${SOURCE_FILES})
|
21
lib/arduino-mqtt-2.3.3.02/LICENSE.md
Normal file
21
lib/arduino-mqtt-2.3.3.02/LICENSE.md
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Joël Gähwiler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
14
lib/arduino-mqtt-2.3.3.02/Makefile
Normal file
14
lib/arduino-mqtt-2.3.3.02/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
all: fmt
|
||||
|
||||
fmt:
|
||||
clang-format -i src/*.cpp src/*.h -style="{BasedOnStyle: Google, ColumnLimit: 120}"
|
||||
|
||||
update:
|
||||
rm -rf ./lwmqtt
|
||||
git clone --branch v0.6.2 https://github.com/256dpi/lwmqtt.git ./lwmqtt
|
||||
mkdir -p ./src/lwmqtt
|
||||
cp -r ./lwmqtt/src/*.c ./src/lwmqtt/
|
||||
cp -r ./lwmqtt/src/*.h ./src/lwmqtt/
|
||||
cp -r ./lwmqtt/include/*.h ./src/lwmqtt/
|
||||
rm -rf ./lwmqtt
|
||||
sed -i '' "s/<lwmqtt.h>/\"lwmqtt.h\"/g" ./src/lwmqtt/*
|
225
lib/arduino-mqtt-2.3.3.02/README.md
Normal file
225
lib/arduino-mqtt-2.3.3.02/README.md
Normal file
@ -0,0 +1,225 @@
|
||||
# arduino-mqtt
|
||||
|
||||
[](https://travis-ci.org/256dpi/arduino-mqtt)
|
||||
[](https://github.com/256dpi/arduino-mqtt/releases)
|
||||
|
||||
This library bundles the [lwmqtt](https://github.com/256dpi/lwmqtt) MQTT 3.1.1 client and adds a thin wrapper to get an Arduino like API.
|
||||
|
||||
Download the latest version from the [release](https://github.com/256dpi/arduino-mqtt/releases) section. Or even better use the builtin Library Manager in the Arduino IDE and search for "MQTT".
|
||||
|
||||
The library is also available on [PlatformIO](https://platformio.org/lib/show/617/MQTT). You can install it by running: `pio lib install "MQTT"`.
|
||||
|
||||
## Compatibility
|
||||
|
||||
The following examples show how you can use the library with various Arduino compatible hardware:
|
||||
|
||||
- [Arduino Yun & Yun-Shield](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoYun/ArduinoYun.ino) ([Secure](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoYunSecure/ArduinoYunSecure.ino))
|
||||
- [Arduino Ethernet Shield](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoEthernetShield/ArduinoEthernetShield.ino)
|
||||
- [Arduino WiFi Shield](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoWiFiShield/ArduinoWiFiShield.ino)
|
||||
- [Adafruit HUZZAH ESP8266](https://github.com/256dpi/arduino-mqtt/blob/master/examples/AdafruitHuzzahESP8266/AdafruitHuzzahESP8266.ino) ([Secure](https://github.com/256dpi/arduino-mqtt/blob/master/examples/AdafruitHuzzahESP8266Secure/AdafruitHuzzahESP8266Secure.ino))
|
||||
- [Arduino/Genuino WiFi101 Shield](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoWiFi101/ArduinoWiFi101.ino) ([Secure](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoWiFi101Secure/ArduinoWiFi101Secure.ino))
|
||||
- [Arduino MKR GSM 1400](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoMKRGSM1400/ArduinoMKRGSM1400.ino) ([Secure](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ArduinoMKRGSM1400Secure/ArduinoMKRGSM1400Secure.ino))
|
||||
- [ESP32 Development Board](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ESP32DevelopmentBoard/ESP32DevelopmentBoard.ino) ([Secure](https://github.com/256dpi/arduino-mqtt/blob/master/examples/ESP32DevelopmentBoardSecure/ESP32DevelopmentBoardSecure.ino))
|
||||
|
||||
Other shields and boards should also work if they provide a [Client](https://www.arduino.cc/en/Reference/ClientConstructor) based network implementation.
|
||||
|
||||
## Notes
|
||||
|
||||
- The maximum size for packets being published and received is set by default to 128 bytes. To change the buffer sizes, you need to use `MQTTClient client(256)` instead of just `MQTTClient client` on the top of your sketch. The passed value denotes the read and write buffer size.
|
||||
|
||||
- On the ESP8266 it has been reported that an additional `delay(10);` after `client.loop();` fixes many stability issues with WiFi connections.
|
||||
|
||||
- To use the library with shiftr.io, you need to provide the token key (username) and token secret (password) as the second and third argument to `client.connect(name, key, secret)`.
|
||||
|
||||
## Example
|
||||
|
||||
The following example uses an Arduino MKR1000 to connect to shiftr.io. You can check on your device after a successful connection here: https://shiftr.io/try.
|
||||
|
||||
```c++
|
||||
#include <SPI.h>
|
||||
#include <WiFi101.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
Initialize the object using the hostname of the broker, the brokers port (default: `1883`) and the underlying Client class for network transport:
|
||||
|
||||
```c++
|
||||
void begin(const char hostname[], Client &client);
|
||||
void begin(const char hostname[], int port, Client &client);
|
||||
```
|
||||
|
||||
- Specify port `8883` when using secure clients for encrypted connections.
|
||||
- Local domain names (e.g. `Computer.local` on OSX) are not supported by Arduino. You need to set the IP address directly.
|
||||
|
||||
The hostname and port can also be changed after calling `begin()`:
|
||||
|
||||
```c++
|
||||
void setHost(const char hostname[]);
|
||||
void setHost(const char hostname[], int port);
|
||||
```
|
||||
|
||||
Set a will message (last testament) that gets registered on the broker after connecting. `setWill()` has to be called before calling `connect()`:
|
||||
|
||||
```c++
|
||||
void setWill(const char topic[]);
|
||||
void setWill(const char topic[], const char payload[]);
|
||||
void setWill(const char topic[], const char payload[], bool retained, int qos);
|
||||
void clearWill();
|
||||
```
|
||||
|
||||
Register a callback to receive messages:
|
||||
|
||||
```c++
|
||||
void onMessage(MQTTClientCallbackSimple);
|
||||
// Callback signature: void messageReceived(String &topic, String &payload) {}
|
||||
|
||||
void onMessageAdvanced(MQTTClientCallbackAdvanced);
|
||||
// Callback signature: void messageReceived(MQTTClient *client, char topic[], char payload[], int payload_length) {}
|
||||
```
|
||||
|
||||
- The set callback is mostly called during a call to `loop()` but may also be called during a call to `subscribe()`, `unsubscribe()` or `publish() // QoS > 0` if messages have been received before receiving the required acknowledgement. Therefore, it is strongly recommended to not call `subscribe()`, `unsubscribe()` or `publish() // QoS > 0` directly in the callback.
|
||||
|
||||
Set more advanced options:
|
||||
|
||||
```c++
|
||||
void setOptions(int keepAlive, bool cleanSession, int timeout);
|
||||
```
|
||||
|
||||
- The `keepAlive` option controls the keep alive interval in seconds (default: 10).
|
||||
- The `cleanSession` option controls the session retention on the broker side (default: true).
|
||||
- The `timeout` option controls the default timeout for all commands in milliseconds (default: 1000).
|
||||
|
||||
Connect to broker using the supplied client id and an optional username and password:
|
||||
|
||||
```c++
|
||||
bool connect(const char clientId[]);
|
||||
bool connect(const char clientId[], const char username[]);
|
||||
bool connect(const char clientId[], const char username[], const char password[]);
|
||||
```
|
||||
|
||||
- This functions returns a boolean that indicates if the connection has been established successfully.
|
||||
|
||||
Publishes a message to the broker with an optional payload:
|
||||
|
||||
```c++
|
||||
bool publish(const String &topic);
|
||||
bool publish(const char topic[]);
|
||||
bool publish(const String &topic, const String &payload);
|
||||
bool publish(const String &topic, const String &payload, bool retained, int qos);
|
||||
bool publish(const char topic[], const String &payload);
|
||||
bool publish(const char topic[], const String &payload, bool retained, int qos);
|
||||
bool publish(const char topic[], const char payload[]);
|
||||
bool publish(const char topic[], const char payload[], bool retained, int qos);
|
||||
bool publish(const char topic[], const char payload[], int length);
|
||||
bool publish(const char topic[], const char payload[], int length, bool retained, int qos);
|
||||
```
|
||||
|
||||
Subscribe to a topic:
|
||||
|
||||
```c++
|
||||
bool subscribe(const String &topic);
|
||||
bool subscribe(const String &topic, int qos);
|
||||
bool subscribe(const char topic[]);
|
||||
bool subscribe(const char topic[], int qos);
|
||||
```
|
||||
|
||||
Unsubscribe from a topic:
|
||||
|
||||
```c++
|
||||
bool unsubscribe(const String &topic);
|
||||
bool unsubscribe(const char topic[]);
|
||||
```
|
||||
|
||||
Sends and receives packets:
|
||||
|
||||
```c++
|
||||
bool loop();
|
||||
```
|
||||
|
||||
- This function should be called in every `loop`.
|
||||
|
||||
Check if the client is currently connected:
|
||||
|
||||
```c++
|
||||
bool connected();
|
||||
```
|
||||
|
||||
Access low-level information for debugging:
|
||||
|
||||
```c++
|
||||
lwmqtt_err_t lastError();
|
||||
lwmqtt_return_code_t returnCode();
|
||||
```
|
||||
|
||||
- The error codes can be found [here](https://github.com/256dpi/lwmqtt/blob/master/include/lwmqtt.h#L11).
|
||||
- The return codes can be found [here](https://github.com/256dpi/lwmqtt/blob/master/include/lwmqtt.h#L243).
|
||||
|
||||
Disconnect from the broker:
|
||||
|
||||
```c++
|
||||
bool disconnect();
|
||||
```
|
||||
|
||||
## Release Management
|
||||
|
||||
- Update version in `library.properties`.
|
||||
- Create release on GitHub.
|
@ -0,0 +1,69 @@
|
||||
// This example uses an Adafruit Huzzah ESP8266
|
||||
// to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
delay(10); // <- fixes some issues with WiFi stability
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// This example uses an Adafruit Huzzah ESP8266
|
||||
// to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClientSecure net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
//
|
||||
// MQTT brokers usually use port 8883 for secure connections.
|
||||
client.begin("broker.shiftr.io", 8883, net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
delay(10); // <- fixes some issues with WiFi stability
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
// This example uses an Arduino Uno together with
|
||||
// an Ethernet Shield to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <Ethernet.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
byte ip[] = {192, 168, 1, 177}; // <- change to match your network
|
||||
|
||||
EthernetClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("connecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Ethernet.begin(mac, ip);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// This example uses an Arduino MKR GSM 1400 board
|
||||
// to connect to shiftr.io.
|
||||
//
|
||||
// IMPORTANT: This example uses the new MKRGSM library.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Sandeep Mistry
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <MKRGSM.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char pin[] = "";
|
||||
const char apn[] = "apn";
|
||||
const char login[] = "login";
|
||||
const char password[] = "password";
|
||||
|
||||
GSMClient net;
|
||||
GPRS gprs;
|
||||
GSM gsmAccess;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
// connection state
|
||||
bool connected = false;
|
||||
|
||||
Serial.print("connecting to cellular network ...");
|
||||
|
||||
// After starting the modem with gsmAccess.begin()
|
||||
// attach to the GPRS network with the APN, login and password
|
||||
while (!connected) {
|
||||
if ((gsmAccess.begin(pin) == GSM_READY) &&
|
||||
(gprs.attachGPRS(apn, login, password) == GPRS_READY)) {
|
||||
connected = true;
|
||||
} else {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
// This example uses an Arduino MKR GSM 1400 board
|
||||
// to securely connect to shiftr.io.
|
||||
//
|
||||
// IMPORTANT: This example uses the new MKRGSM library.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Sandeep Mistry
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <MKRGSM.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char pin[] = "";
|
||||
const char apn[] = "apn";
|
||||
const char login[] = "login";
|
||||
const char password[] = "password";
|
||||
|
||||
GSMSSLClient net;
|
||||
GPRS gprs;
|
||||
GSM gsmAccess;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
// connection state
|
||||
bool connected = false;
|
||||
|
||||
Serial.print("connecting to cellular network ...");
|
||||
|
||||
// After starting the modem with gsmAccess.begin()
|
||||
// attach to the GPRS network with the APN, login and password
|
||||
while (!connected) {
|
||||
if ((gsmAccess.begin(pin) == GSM_READY) &&
|
||||
(gprs.attachGPRS(apn, login, password) == GPRS_READY)) {
|
||||
connected = true;
|
||||
} else {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
//
|
||||
// MQTT brokers usually use port 8883 for secure connections.
|
||||
client.begin("broker.shiftr.io", 8883, net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// This example uses an Arduino/Genuino Zero together with
|
||||
// a WiFi101 Shield or a MKR1000 to connect to shiftr.io.
|
||||
//
|
||||
// IMPORTANT: This example uses the new WiFi101 library.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Gilberto Conti
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <WiFi101.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
// This example uses an Arduino/Genuino Zero together with
|
||||
// a WiFi101 Shield or a MKR1000 to connect to shiftr.io.
|
||||
//
|
||||
// IMPORTANT: This example uses the new WiFi101 library.
|
||||
//
|
||||
// IMPORTANT: You need to install/update the SSL certificates first:
|
||||
// https://github.com/arduino-libraries/WiFi101-FirmwareUpdater#to-update-ssl-certificates
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Gilberto Conti
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <WiFi101.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiSSLClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
//
|
||||
// MQTT brokers usually use port 8883 for secure connections.
|
||||
client.begin("broker.shiftr.io", 8883, net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// This example uses an Arduino Uno together with
|
||||
// a WiFi Shield to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
60
lib/arduino-mqtt-2.3.3.02/examples/ArduinoYun/ArduinoYun.ino
Normal file
60
lib/arduino-mqtt-2.3.3.02/examples/ArduinoYun/ArduinoYun.ino
Normal file
@ -0,0 +1,60 @@
|
||||
// This example uses an Arduino Yun or a Yun-Shield
|
||||
// and the MQTTClient to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <Bridge.h>
|
||||
#include <BridgeClient.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
BridgeClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("connecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Bridge.begin();
|
||||
Serial.begin(115200);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
// This example uses an Arduino Yun or a Yun-Shield
|
||||
// and the MQTTClient to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <Bridge.h>
|
||||
#include <BridgeSSLClient.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
BridgeSSLClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("connecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Bridge.begin();
|
||||
Serial.begin(115200);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
//
|
||||
// MQTT brokers usually use port 8883 for secure connections.
|
||||
client.begin("broker.shiftr.io", 8883, net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
// This example uses an ESP32 Development Board
|
||||
// to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClient net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
client.begin("broker.shiftr.io", net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
delay(10); // <- fixes some issues with WiFi stability
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// This example uses an ESP32 Development Board
|
||||
// to connect to shiftr.io.
|
||||
//
|
||||
// You can check on your device after a successful
|
||||
// connection here: https://shiftr.io/try.
|
||||
//
|
||||
// by Joël Gähwiler
|
||||
// https://github.com/256dpi/arduino-mqtt
|
||||
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
const char ssid[] = "ssid";
|
||||
const char pass[] = "pass";
|
||||
|
||||
WiFiClientSecure net;
|
||||
MQTTClient client;
|
||||
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
void connect() {
|
||||
Serial.print("checking wifi...");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.print("\nconnecting...");
|
||||
while (!client.connect("arduino", "try", "try")) {
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println("\nconnected!");
|
||||
|
||||
client.subscribe("/hello");
|
||||
// client.unsubscribe("/hello");
|
||||
}
|
||||
|
||||
void messageReceived(String &topic, String &payload) {
|
||||
Serial.println("incoming: " + topic + " - " + payload);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported by Arduino.
|
||||
// You need to set the IP address directly.
|
||||
//
|
||||
// MQTT brokers usually use port 8883 for secure connections.
|
||||
client.begin("broker.shiftr.io", 8883, net);
|
||||
client.onMessage(messageReceived);
|
||||
|
||||
connect();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
delay(10); // <- fixes some issues with WiFi stability
|
||||
|
||||
if (!client.connected()) {
|
||||
connect();
|
||||
}
|
||||
|
||||
// publish a message roughly every second.
|
||||
if (millis() - lastMillis > 1000) {
|
||||
lastMillis = millis();
|
||||
client.publish("/hello", "world");
|
||||
}
|
||||
}
|
9
lib/arduino-mqtt-2.3.3.02/library.properties
Normal file
9
lib/arduino-mqtt-2.3.3.02/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
name=MQTT
|
||||
version=2.3.3
|
||||
author=Joel Gaehwiler <joel.gaehwiler@gmail.com>
|
||||
maintainer=Joel Gaehwiler <joel.gaehwiler@gmail.com>
|
||||
sentence=MQTT library for Arduino
|
||||
paragraph=This library bundles the lwmqtt client and adds a thin wrapper to get an Arduino like API.
|
||||
category=Communication
|
||||
url=https://github.com/256dpi/arduino-mqtt
|
||||
architectures=*
|
386
lib/arduino-mqtt-2.3.3.02/src/MQTTClient.h
Normal file
386
lib/arduino-mqtt-2.3.3.02/src/MQTTClient.h
Normal file
@ -0,0 +1,386 @@
|
||||
#ifndef MQTT_CLIENT_H
|
||||
#define MQTT_CLIENT_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Client.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#include "system.h"
|
||||
|
||||
class MQTTClient;
|
||||
|
||||
typedef void (*MQTTClientCallbackSimple)(String &topic, String &payload);
|
||||
typedef void (*MQTTClientCallbackAdvanced)(MQTTClient *client, char topic[], char bytes[], int length);
|
||||
|
||||
typedef struct {
|
||||
MQTTClient *client = nullptr;
|
||||
MQTTClientCallbackSimple simple = nullptr;
|
||||
MQTTClientCallbackAdvanced advanced = nullptr;
|
||||
} MQTTClientCallback;
|
||||
|
||||
static void MQTTClientHandler(lwmqtt_client_t * /*client*/, void *ref, lwmqtt_string_t topic,
|
||||
lwmqtt_message_t message) {
|
||||
// get callback
|
||||
auto cb = (MQTTClientCallback *)ref;
|
||||
|
||||
// null terminate topic
|
||||
char terminated_topic[topic.len + 1];
|
||||
memcpy(terminated_topic, topic.data, topic.len);
|
||||
terminated_topic[topic.len] = '\0';
|
||||
|
||||
// null terminate payload if available
|
||||
if (message.payload != nullptr) {
|
||||
message.payload[message.payload_len] = '\0';
|
||||
}
|
||||
|
||||
// call the advanced callback and return if available
|
||||
if (cb->advanced != nullptr) {
|
||||
cb->advanced(cb->client, terminated_topic, (char *)message.payload, (int)message.payload_len);
|
||||
return;
|
||||
}
|
||||
|
||||
// return if simple callback is not set
|
||||
if (cb->simple == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create topic string
|
||||
String str_topic = String(terminated_topic);
|
||||
|
||||
// create payload string
|
||||
String str_payload;
|
||||
if (message.payload != nullptr) {
|
||||
str_payload = String((const char *)message.payload);
|
||||
}
|
||||
|
||||
// call simple callback
|
||||
cb->simple(str_topic, str_payload);
|
||||
}
|
||||
|
||||
class MQTTClient {
|
||||
private:
|
||||
size_t bufSize = 0;
|
||||
uint8_t *readBuf = nullptr;
|
||||
uint8_t *writeBuf = nullptr;
|
||||
|
||||
uint16_t keepAlive = 10;
|
||||
bool cleanSession = true;
|
||||
uint32_t timeout = 1000;
|
||||
|
||||
Client *netClient = nullptr;
|
||||
const char *hostname = nullptr;
|
||||
int port = 0;
|
||||
lwmqtt_will_t will = lwmqtt_default_will;
|
||||
bool hasWill = false;
|
||||
MQTTClientCallback callback;
|
||||
|
||||
lwmqtt_arduino_network_t network = {nullptr};
|
||||
lwmqtt_arduino_timer_t timer1 = {0};
|
||||
lwmqtt_arduino_timer_t timer2 = {0};
|
||||
lwmqtt_client_t client;
|
||||
|
||||
bool _connected = false;
|
||||
lwmqtt_return_code_t _returnCode = (lwmqtt_return_code_t)0;
|
||||
lwmqtt_err_t _lastError = (lwmqtt_err_t)0;
|
||||
|
||||
public:
|
||||
explicit MQTTClient(int bufSize = 128) {
|
||||
memset(&client, 0, sizeof(client));
|
||||
this->bufSize = (size_t)bufSize;
|
||||
this->readBuf = (uint8_t *)malloc((size_t)bufSize + 1);
|
||||
this->writeBuf = (uint8_t *)malloc((size_t)bufSize);
|
||||
}
|
||||
|
||||
~MQTTClient() {
|
||||
free(this->readBuf);
|
||||
free(this->writeBuf);
|
||||
}
|
||||
|
||||
void begin(const char hostname[], Client &client) { this->begin(hostname, 1883, client); }
|
||||
|
||||
void begin(const char hostname[], int port, Client &client) {
|
||||
// set hostname and port
|
||||
this->setHost(hostname, port);
|
||||
|
||||
// set client
|
||||
this->netClient = &client;
|
||||
|
||||
// initialize client
|
||||
lwmqtt_init(&this->client, this->writeBuf, this->bufSize, this->readBuf, this->bufSize);
|
||||
|
||||
// set timers
|
||||
lwmqtt_set_timers(&this->client, &this->timer1, &this->timer2, lwmqtt_arduino_timer_set, lwmqtt_arduino_timer_get);
|
||||
|
||||
// set network
|
||||
lwmqtt_set_network(&this->client, &this->network, lwmqtt_arduino_network_read, lwmqtt_arduino_network_write);
|
||||
|
||||
// set callback
|
||||
lwmqtt_set_callback(&this->client, (void *)&this->callback, MQTTClientHandler);
|
||||
}
|
||||
|
||||
void onMessage(MQTTClientCallbackSimple cb) {
|
||||
// set callback
|
||||
this->callback.client = this;
|
||||
this->callback.simple = cb;
|
||||
this->callback.advanced = nullptr;
|
||||
}
|
||||
|
||||
void onMessageAdvanced(MQTTClientCallbackAdvanced cb) {
|
||||
// set callback
|
||||
this->callback.client = this;
|
||||
this->callback.simple = nullptr;
|
||||
this->callback.advanced = cb;
|
||||
}
|
||||
|
||||
void setHost(const char hostname[]) { this->setHost(hostname, 1883); }
|
||||
|
||||
void setHost(const char hostname[], int port) {
|
||||
// free hostname if set
|
||||
if(this->hostname != nullptr) {
|
||||
free((void *)this->hostname);
|
||||
}
|
||||
|
||||
// set hostname and port
|
||||
this->hostname = strdup(hostname);
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
void setWill(const char topic[]) { this->setWill(topic, ""); }
|
||||
|
||||
void setWill(const char topic[], const char payload[]) { this->setWill(topic, payload, false, 0); }
|
||||
|
||||
void setWill(const char topic[], const char payload[], bool retained, int qos) {
|
||||
this->hasWill = true;
|
||||
this->will.topic = lwmqtt_string(topic);
|
||||
this->will.payload = lwmqtt_string(payload);
|
||||
this->will.retained = retained;
|
||||
this->will.qos = (lwmqtt_qos_t)qos;
|
||||
}
|
||||
|
||||
void clearWill() { this->hasWill = false; }
|
||||
|
||||
void setOptions(int keepAlive, bool cleanSession, int timeout) {
|
||||
this->keepAlive = (uint16_t)keepAlive;
|
||||
this->cleanSession = cleanSession;
|
||||
this->timeout = (uint32_t)timeout;
|
||||
}
|
||||
|
||||
bool connect(const char clientId[]) { return this->connect(clientId, nullptr, nullptr); }
|
||||
|
||||
bool connect(const char clientId[], const char username[]) { return this->connect(clientId, username, nullptr); }
|
||||
|
||||
bool connect(const char clientId[], const char username[], const char password[]) {
|
||||
// close left open connection if still connected
|
||||
if (this->connected()) {
|
||||
this->close();
|
||||
}
|
||||
|
||||
// save client
|
||||
this->network.client = this->netClient;
|
||||
|
||||
// connect to host
|
||||
if (this->netClient->connect(this->hostname, (uint16_t)this->port) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare options
|
||||
lwmqtt_options_t options = lwmqtt_default_options;
|
||||
options.keep_alive = this->keepAlive;
|
||||
options.clean_session = this->cleanSession;
|
||||
options.client_id = lwmqtt_string(clientId);
|
||||
|
||||
// set username and password if available
|
||||
if (username != nullptr) {
|
||||
options.username = lwmqtt_string(username);
|
||||
|
||||
if (password != nullptr) {
|
||||
options.password = lwmqtt_string(password);
|
||||
}
|
||||
}
|
||||
|
||||
// prepare will reference
|
||||
lwmqtt_will_t *will = nullptr;
|
||||
if (this->hasWill) {
|
||||
will = &this->will;
|
||||
}
|
||||
|
||||
// connect to broker
|
||||
this->_lastError = lwmqtt_connect(&this->client, options, will, &this->_returnCode, this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// set flag
|
||||
this->_connected = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool publish(const String &topic) { return this->publish(topic.c_str(), ""); }
|
||||
|
||||
bool publish(const char topic[]) { return this->publish(topic, ""); }
|
||||
|
||||
bool publish(const String &topic, const String &payload) { return this->publish(topic.c_str(), payload.c_str()); }
|
||||
|
||||
bool publish(const String &topic, const String &payload, bool retained, int qos) {
|
||||
return this->publish(topic.c_str(), payload.c_str(), retained, qos);
|
||||
}
|
||||
|
||||
bool publish(const char topic[], const String &payload) { return this->publish(topic, payload.c_str()); }
|
||||
|
||||
bool publish(const char topic[], const String &payload, bool retained, int qos) {
|
||||
return this->publish(topic, payload.c_str(), retained, qos);
|
||||
}
|
||||
|
||||
bool publish(const char topic[], const char payload[]) {
|
||||
return this->publish(topic, (char *)payload, (int)strlen(payload));
|
||||
}
|
||||
|
||||
bool publish(const char topic[], const char payload[], bool retained, int qos) {
|
||||
return this->publish(topic, (char *)payload, (int)strlen(payload), retained, qos);
|
||||
}
|
||||
|
||||
bool publish(const char topic[], const char payload[], int length) {
|
||||
return this->publish(topic, payload, length, false, 0);
|
||||
}
|
||||
|
||||
bool publish(const char topic[], const char payload[], int length, bool retained, int qos) {
|
||||
// return immediately if not connected
|
||||
if (!this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare message
|
||||
lwmqtt_message_t message = lwmqtt_default_message;
|
||||
message.payload = (uint8_t *)payload;
|
||||
message.payload_len = (size_t)length;
|
||||
message.retained = retained;
|
||||
message.qos = lwmqtt_qos_t(qos);
|
||||
|
||||
// publish message
|
||||
this->_lastError = lwmqtt_publish(&this->client, lwmqtt_string(topic), message, this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool subscribe(const String &topic) { return this->subscribe(topic.c_str()); }
|
||||
|
||||
bool subscribe(const String &topic, int qos) { return this->subscribe(topic.c_str(), qos); }
|
||||
|
||||
bool subscribe(const char topic[]) { return this->subscribe(topic, 0); }
|
||||
|
||||
bool subscribe(const char topic[], int qos) {
|
||||
// return immediately if not connected
|
||||
if (!this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// subscribe to topic
|
||||
this->_lastError = lwmqtt_subscribe_one(&this->client, lwmqtt_string(topic), (lwmqtt_qos_t)qos, this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool unsubscribe(const String &topic) { return this->unsubscribe(topic.c_str()); }
|
||||
|
||||
bool unsubscribe(const char topic[]) {
|
||||
// return immediately if not connected
|
||||
if (!this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// unsubscribe from topic
|
||||
this->_lastError = lwmqtt_unsubscribe_one(&this->client, lwmqtt_string(topic), this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool loop() {
|
||||
// return immediately if not connected
|
||||
if (!this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get available bytes on the network
|
||||
auto available = (size_t)this->netClient->available();
|
||||
|
||||
// yield if data is available
|
||||
if (available > 0) {
|
||||
this->_lastError = lwmqtt_yield(&this->client, available, this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// keep the connection alive
|
||||
this->_lastError = lwmqtt_keep_alive(&this->client, this->timeout);
|
||||
if (this->_lastError != LWMQTT_SUCCESS) {
|
||||
// close connection
|
||||
this->close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool connected() {
|
||||
// a client is connected if the network is connected, a client is available and
|
||||
// the connection has been properly initiated
|
||||
return this->netClient != nullptr && this->netClient->connected() == 1 && this->_connected;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lastError() { return this->_lastError; }
|
||||
|
||||
lwmqtt_return_code_t returnCode() { return this->_returnCode; }
|
||||
|
||||
bool disconnect() {
|
||||
// return immediately if not connected anymore
|
||||
if (!this->connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// cleanly disconnect
|
||||
this->_lastError = lwmqtt_disconnect(&this->client, this->timeout);
|
||||
|
||||
// close
|
||||
this->close();
|
||||
|
||||
return this->_lastError == LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
void close() {
|
||||
// set flag
|
||||
this->_connected = false;
|
||||
|
||||
// close network
|
||||
this->netClient->stop();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
6
lib/arduino-mqtt-2.3.3.02/src/MQTTlw.h
Normal file
6
lib/arduino-mqtt-2.3.3.02/src/MQTTlw.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef MQTT_H
|
||||
#define MQTT_H
|
||||
|
||||
#include "MQTTClient.h"
|
||||
|
||||
#endif
|
618
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/client.c
Normal file
618
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/client.c
Normal file
@ -0,0 +1,618 @@
|
||||
#include "packet.h"
|
||||
|
||||
void lwmqtt_init(lwmqtt_client_t *client, uint8_t *write_buf, size_t write_buf_size, uint8_t *read_buf,
|
||||
size_t read_buf_size) {
|
||||
client->last_packet_id = 1;
|
||||
client->keep_alive_interval = 0;
|
||||
client->pong_pending = false;
|
||||
|
||||
client->write_buf = write_buf;
|
||||
client->write_buf_size = write_buf_size;
|
||||
client->read_buf = read_buf;
|
||||
client->read_buf_size = read_buf_size;
|
||||
|
||||
client->callback = NULL;
|
||||
client->callback_ref = NULL;
|
||||
|
||||
client->network = NULL;
|
||||
client->network_read = NULL;
|
||||
client->network_write = NULL;
|
||||
|
||||
client->keep_alive_timer = NULL;
|
||||
client->command_timer = NULL;
|
||||
client->timer_set = NULL;
|
||||
client->timer_get = NULL;
|
||||
}
|
||||
|
||||
void lwmqtt_set_network(lwmqtt_client_t *client, void *ref, lwmqtt_network_read_t read, lwmqtt_network_write_t write) {
|
||||
client->network = ref;
|
||||
client->network_read = read;
|
||||
client->network_write = write;
|
||||
}
|
||||
|
||||
void lwmqtt_set_timers(lwmqtt_client_t *client, void *keep_alive_timer, void *command_timer, lwmqtt_timer_set_t set,
|
||||
lwmqtt_timer_get_t get) {
|
||||
client->keep_alive_timer = keep_alive_timer;
|
||||
client->command_timer = command_timer;
|
||||
client->timer_set = set;
|
||||
client->timer_get = get;
|
||||
|
||||
client->timer_set(client->keep_alive_timer, 0);
|
||||
client->timer_set(client->command_timer, 0);
|
||||
}
|
||||
|
||||
void lwmqtt_set_callback(lwmqtt_client_t *client, void *ref, lwmqtt_callback_t cb) {
|
||||
client->callback_ref = ref;
|
||||
client->callback = cb;
|
||||
}
|
||||
|
||||
static uint16_t lwmqtt_get_next_packet_id(lwmqtt_client_t *client) {
|
||||
// check overflow
|
||||
if (client->last_packet_id == 65535) {
|
||||
client->last_packet_id = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// increment packet id
|
||||
client->last_packet_id++;
|
||||
|
||||
return client->last_packet_id;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_read_from_network(lwmqtt_client_t *client, size_t offset, size_t len) {
|
||||
// check read buffer capacity
|
||||
if (client->read_buf_size < offset + len) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// prepare counter
|
||||
size_t read = 0;
|
||||
|
||||
// read while data is missing
|
||||
while (read < len) {
|
||||
// check remaining time
|
||||
int32_t remaining_time = client->timer_get(client->command_timer);
|
||||
if (remaining_time <= 0) {
|
||||
return LWMQTT_NETWORK_TIMEOUT;
|
||||
}
|
||||
|
||||
// read
|
||||
size_t partial_read = 0;
|
||||
lwmqtt_err_t err = client->network_read(client->network, client->read_buf + offset + read, len - read,
|
||||
&partial_read, (uint32_t)remaining_time);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// increment counter
|
||||
read += partial_read;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_write_to_network(lwmqtt_client_t *client, size_t offset, size_t len) {
|
||||
// prepare counter
|
||||
size_t written = 0;
|
||||
|
||||
// write while data is left
|
||||
while (written < len) {
|
||||
// check remaining time
|
||||
int32_t remaining_time = client->timer_get(client->command_timer);
|
||||
if (remaining_time <= 0) {
|
||||
return LWMQTT_NETWORK_TIMEOUT;
|
||||
}
|
||||
|
||||
// write
|
||||
size_t partial_write = 0;
|
||||
lwmqtt_err_t err = client->network_write(client->network, client->write_buf + offset + written, len - written,
|
||||
&partial_write, (uint32_t)remaining_time);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// increment counter
|
||||
written += partial_write;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_read_packet_in_buffer(lwmqtt_client_t *client, size_t *read,
|
||||
lwmqtt_packet_type_t *packet_type) {
|
||||
// preset packet type
|
||||
*packet_type = LWMQTT_NO_PACKET;
|
||||
|
||||
// read or wait for header byte
|
||||
lwmqtt_err_t err = lwmqtt_read_from_network(client, 0, 1);
|
||||
if (err == LWMQTT_NETWORK_TIMEOUT) {
|
||||
// this is ok as no data has been read at all
|
||||
return LWMQTT_SUCCESS;
|
||||
} else if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// detect packet type
|
||||
err = lwmqtt_detect_packet_type(client->read_buf, 1, packet_type);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// prepare variables
|
||||
size_t len = 0;
|
||||
uint32_t rem_len = 0;
|
||||
|
||||
do {
|
||||
// adjust len
|
||||
len++;
|
||||
|
||||
// read next byte
|
||||
err = lwmqtt_read_from_network(client, len, 1);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// attempt to detect remaining length
|
||||
err = lwmqtt_detect_remaining_length(client->read_buf + 1, len, &rem_len);
|
||||
} while (err == LWMQTT_BUFFER_TOO_SHORT);
|
||||
|
||||
// check final error
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// read the rest of the buffer if needed
|
||||
if (rem_len > 0) {
|
||||
err = lwmqtt_read_from_network(client, 1 + len, rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust counter
|
||||
*read += 1 + len + rem_len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_send_packet_in_buffer(lwmqtt_client_t *client, size_t length) {
|
||||
// write to network
|
||||
lwmqtt_err_t err = lwmqtt_write_to_network(client, 0, length);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// reset keep alive timer
|
||||
client->timer_set(client->keep_alive_timer, client->keep_alive_interval);
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_cycle(lwmqtt_client_t *client, size_t *read, lwmqtt_packet_type_t *packet_type) {
|
||||
// read next packet from the network
|
||||
lwmqtt_err_t err = lwmqtt_read_packet_in_buffer(client, read, packet_type);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
} else if (*packet_type == LWMQTT_NO_PACKET) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
switch (*packet_type) {
|
||||
// handle publish packets
|
||||
case LWMQTT_PUBLISH_PACKET: {
|
||||
// decode publish packet
|
||||
bool dup;
|
||||
uint16_t packet_id;
|
||||
lwmqtt_string_t topic;
|
||||
lwmqtt_message_t msg;
|
||||
err = lwmqtt_decode_publish(client->read_buf, client->read_buf_size, &dup, &packet_id, &topic, &msg);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// call callback if set
|
||||
if (client->callback != NULL) {
|
||||
client->callback(client, client->callback_ref, topic, msg);
|
||||
}
|
||||
|
||||
// break early on qos zero
|
||||
if (msg.qos == LWMQTT_QOS0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// define ack packet
|
||||
lwmqtt_packet_type_t ack_type = LWMQTT_NO_PACKET;
|
||||
if (msg.qos == LWMQTT_QOS1) {
|
||||
ack_type = LWMQTT_PUBACK_PACKET;
|
||||
} else if (msg.qos == LWMQTT_QOS2) {
|
||||
ack_type = LWMQTT_PUBREC_PACKET;
|
||||
}
|
||||
|
||||
// encode ack packet
|
||||
size_t len;
|
||||
err = lwmqtt_encode_ack(client->write_buf, client->write_buf_size, &len, ack_type, false, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send ack packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle pubrec packets
|
||||
case LWMQTT_PUBREC_PACKET: {
|
||||
// decode pubrec packet
|
||||
bool dup;
|
||||
uint16_t packet_id;
|
||||
err = lwmqtt_decode_ack(client->read_buf, client->read_buf_size, LWMQTT_PUBREC_PACKET, &dup, &packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// encode pubrel packet
|
||||
size_t len;
|
||||
err = lwmqtt_encode_ack(client->write_buf, client->write_buf_size, &len, LWMQTT_PUBREL_PACKET, 0, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send pubrel packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle pubrel packets
|
||||
case LWMQTT_PUBREL_PACKET: {
|
||||
// decode pubrec packet
|
||||
bool dup;
|
||||
uint16_t packet_id;
|
||||
err = lwmqtt_decode_ack(client->read_buf, client->read_buf_size, LWMQTT_PUBREL_PACKET, &dup, &packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// encode pubcomp packet
|
||||
size_t len;
|
||||
err = lwmqtt_encode_ack(client->write_buf, client->write_buf_size, &len, LWMQTT_PUBCOMP_PACKET, 0, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send pubcomp packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle pingresp packets
|
||||
case LWMQTT_PINGRESP_PACKET: {
|
||||
// set flag
|
||||
client->pong_pending = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// handle all other packets
|
||||
default: { break; }
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
static lwmqtt_err_t lwmqtt_cycle_until(lwmqtt_client_t *client, lwmqtt_packet_type_t *packet_type, size_t available,
|
||||
lwmqtt_packet_type_t needle) {
|
||||
// prepare counter
|
||||
size_t read = 0;
|
||||
|
||||
// loop until timeout has been reached
|
||||
do {
|
||||
// do one cycle
|
||||
lwmqtt_err_t err = lwmqtt_cycle(client, &read, packet_type);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// return when one packet has been successfully read when no availability has been given
|
||||
if (needle == LWMQTT_NO_PACKET && available == 0) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// otherwise check if needle has been found
|
||||
if (*packet_type == needle) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
} while (client->timer_get(client->command_timer) > 0 && (available == 0 || read < available));
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_yield(lwmqtt_client_t *client, size_t available, uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// cycle until timeout has been reached
|
||||
lwmqtt_packet_type_t packet_type = LWMQTT_NO_PACKET;
|
||||
lwmqtt_err_t err = lwmqtt_cycle_until(client, &packet_type, available, LWMQTT_NO_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_connect(lwmqtt_client_t *client, lwmqtt_options_t options, lwmqtt_will_t *will,
|
||||
lwmqtt_return_code_t *return_code, uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// save keep alive interval (take 75% to be a little earlier than actually needed)
|
||||
client->keep_alive_interval = (uint32_t)(options.keep_alive * 750);
|
||||
|
||||
// set keep alive timer
|
||||
client->timer_set(client->keep_alive_timer, client->keep_alive_interval);
|
||||
|
||||
// reset pong pending flag
|
||||
client->pong_pending = false;
|
||||
|
||||
// initialize return code
|
||||
*return_code = LWMQTT_UNKNOWN_RETURN_CODE;
|
||||
|
||||
// encode connect packet
|
||||
size_t len;
|
||||
lwmqtt_err_t err = lwmqtt_encode_connect(client->write_buf, client->write_buf_size, &len, options, will);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// wait for connack packet
|
||||
lwmqtt_packet_type_t packet_type = LWMQTT_NO_PACKET;
|
||||
err = lwmqtt_cycle_until(client, &packet_type, 0, LWMQTT_CONNACK_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
} else if (packet_type != LWMQTT_CONNACK_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// decode connack packet
|
||||
bool session_present;
|
||||
err = lwmqtt_decode_connack(client->read_buf, client->read_buf_size, &session_present, return_code);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// return error if connection was not accepted
|
||||
if (*return_code != LWMQTT_CONNECTION_ACCEPTED) {
|
||||
return LWMQTT_CONNECTION_DENIED;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_subscribe(lwmqtt_client_t *client, int count, lwmqtt_string_t *topic_filter, lwmqtt_qos_t *qos,
|
||||
uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// encode subscribe packet
|
||||
size_t len;
|
||||
lwmqtt_err_t err = lwmqtt_encode_subscribe(client->write_buf, client->write_buf_size, &len,
|
||||
lwmqtt_get_next_packet_id(client), count, topic_filter, qos);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// wait for suback packet
|
||||
lwmqtt_packet_type_t packet_type = LWMQTT_NO_PACKET;
|
||||
err = lwmqtt_cycle_until(client, &packet_type, 0, LWMQTT_SUBACK_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
} else if (packet_type != LWMQTT_SUBACK_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// decode packet
|
||||
int suback_count = 0;
|
||||
lwmqtt_qos_t granted_qos[count];
|
||||
uint16_t packet_id;
|
||||
err = lwmqtt_decode_suback(client->read_buf, client->read_buf_size, &packet_id, count, &suback_count, granted_qos);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check suback codes
|
||||
for (int i = 0; i < suback_count; i++) {
|
||||
if (granted_qos[i] == LWMQTT_QOS_FAILURE) {
|
||||
return LWMQTT_FAILED_SUBSCRIPTION;
|
||||
}
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_subscribe_one(lwmqtt_client_t *client, lwmqtt_string_t topic_filter, lwmqtt_qos_t qos,
|
||||
uint32_t timeout) {
|
||||
return lwmqtt_subscribe(client, 1, &topic_filter, &qos, timeout);
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_unsubscribe(lwmqtt_client_t *client, int count, lwmqtt_string_t *topic_filter, uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// encode unsubscribe packet
|
||||
size_t len;
|
||||
lwmqtt_err_t err = lwmqtt_encode_unsubscribe(client->write_buf, client->write_buf_size, &len,
|
||||
lwmqtt_get_next_packet_id(client), count, topic_filter);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send unsubscribe packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// wait for unsuback packet
|
||||
lwmqtt_packet_type_t packet_type = LWMQTT_NO_PACKET;
|
||||
err = lwmqtt_cycle_until(client, &packet_type, 0, LWMQTT_UNSUBACK_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
} else if (packet_type != LWMQTT_UNSUBACK_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// decode unsuback packet
|
||||
bool dup;
|
||||
uint16_t packet_id;
|
||||
err = lwmqtt_decode_ack(client->read_buf, client->read_buf_size, LWMQTT_UNSUBACK_PACKET, &dup, &packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_unsubscribe_one(lwmqtt_client_t *client, lwmqtt_string_t topic_filter, uint32_t timeout) {
|
||||
return lwmqtt_unsubscribe(client, 1, &topic_filter, timeout);
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_publish(lwmqtt_client_t *client, lwmqtt_string_t topic, lwmqtt_message_t message,
|
||||
uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// add packet id if at least qos 1
|
||||
uint16_t packet_id = 0;
|
||||
if (message.qos == LWMQTT_QOS1 || message.qos == LWMQTT_QOS2) {
|
||||
packet_id = lwmqtt_get_next_packet_id(client);
|
||||
}
|
||||
|
||||
// encode publish packet
|
||||
size_t len = 0;
|
||||
lwmqtt_err_t err =
|
||||
lwmqtt_encode_publish(client->write_buf, client->write_buf_size, &len, 0, packet_id, topic, message);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// immediately return on qos zero
|
||||
if (message.qos == LWMQTT_QOS0) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// define ack packet
|
||||
lwmqtt_packet_type_t ack_type = LWMQTT_NO_PACKET;
|
||||
if (message.qos == LWMQTT_QOS1) {
|
||||
ack_type = LWMQTT_PUBACK_PACKET;
|
||||
} else if (message.qos == LWMQTT_QOS2) {
|
||||
ack_type = LWMQTT_PUBCOMP_PACKET;
|
||||
}
|
||||
|
||||
// wait for ack packet
|
||||
lwmqtt_packet_type_t packet_type = LWMQTT_NO_PACKET;
|
||||
err = lwmqtt_cycle_until(client, &packet_type, 0, ack_type);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
} else if (packet_type != ack_type) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// decode ack packet
|
||||
bool dup;
|
||||
err = lwmqtt_decode_ack(client->read_buf, client->read_buf_size, ack_type, &dup, &packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_disconnect(lwmqtt_client_t *client, uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// encode disconnect packet
|
||||
size_t len;
|
||||
lwmqtt_err_t err = lwmqtt_encode_zero(client->write_buf, client->write_buf_size, &len, LWMQTT_DISCONNECT_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send disconnected packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_keep_alive(lwmqtt_client_t *client, uint32_t timeout) {
|
||||
// set command timer
|
||||
client->timer_set(client->command_timer, timeout);
|
||||
|
||||
// return immediately if keep alive interval is zero
|
||||
if (client->keep_alive_interval == 0) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// return immediately if no ping is due
|
||||
if (client->timer_get(client->keep_alive_timer) > 0) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// a ping is due
|
||||
|
||||
// fail immediately if a pong is already pending
|
||||
if (client->pong_pending) {
|
||||
return LWMQTT_PONG_TIMEOUT;
|
||||
}
|
||||
|
||||
// encode pingreq packet
|
||||
size_t len;
|
||||
lwmqtt_err_t err = lwmqtt_encode_zero(client->write_buf, client->write_buf_size, &len, LWMQTT_PINGREQ_PACKET);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// send packet
|
||||
err = lwmqtt_send_packet_in_buffer(client, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set flag
|
||||
client->pong_pending = true;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
249
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/helpers.c
Normal file
249
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/helpers.c
Normal file
@ -0,0 +1,249 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
uint8_t lwmqtt_read_bits(uint8_t byte, int pos, int num) { return (byte & (uint8_t)((~(0xFF << num)) << pos)) >> pos; }
|
||||
|
||||
void lwmqtt_write_bits(uint8_t *byte, uint8_t value, int pos, int num) {
|
||||
*byte = (*byte & ~(uint8_t)((~(0xFF << num)) << pos)) | (value << pos);
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_read_data(uint8_t **buf, const uint8_t *buf_end, uint8_t **data, size_t len) {
|
||||
// check zero length
|
||||
if (len == 0) {
|
||||
*data = NULL;
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < len) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// read data
|
||||
*data = *buf;
|
||||
|
||||
// advance pointer
|
||||
*buf += len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_write_data(uint8_t **buf, const uint8_t *buf_end, uint8_t *data, size_t len) {
|
||||
// check zero length
|
||||
if (len == 0) {
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < len) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// write data
|
||||
memcpy(*buf, data, len);
|
||||
|
||||
// advance pointer
|
||||
*buf += len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_read_num(uint8_t **buf, const uint8_t *buf_end, uint16_t *num) {
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < 2) {
|
||||
*num = 0;
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// read two byte integer
|
||||
*num = (uint16_t)256 * (*buf)[0] + (*buf)[1];
|
||||
|
||||
// adjust pointer
|
||||
*buf += 2;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_write_num(uint8_t **buf, const uint8_t *buf_end, uint16_t num) {
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < 2) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// write bytes
|
||||
(*buf)[0] = (uint8_t)(num / 256);
|
||||
(*buf)[1] = (uint8_t)(num % 256);
|
||||
|
||||
// adjust pointer
|
||||
*buf += 2;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_read_string(uint8_t **buf, const uint8_t *buf_end, lwmqtt_string_t *str) {
|
||||
// read length
|
||||
uint16_t len;
|
||||
lwmqtt_err_t err = lwmqtt_read_num(buf, buf_end, &len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// read data
|
||||
err = lwmqtt_read_data(buf, buf_end, (uint8_t **)&str->data, len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set length
|
||||
str->len = len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_write_string(uint8_t **buf, const uint8_t *buf_end, lwmqtt_string_t str) {
|
||||
// write string length
|
||||
lwmqtt_err_t err = lwmqtt_write_num(buf, buf_end, str.len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write data
|
||||
err = lwmqtt_write_data(buf, buf_end, (uint8_t *)str.data, str.len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_read_byte(uint8_t **buf, const uint8_t *buf_end, uint8_t *byte) {
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < 1) {
|
||||
*byte = 0;
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// read byte
|
||||
*byte = (*buf)[0];
|
||||
|
||||
// adjust pointer
|
||||
*buf += 1;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_write_byte(uint8_t **buf, const uint8_t *buf_end, uint8_t byte) {
|
||||
// check buffer size
|
||||
if ((size_t)(buf_end - (*buf)) < 1) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// write byte
|
||||
(*buf)[0] = byte;
|
||||
|
||||
// adjust pointer
|
||||
*buf += 1;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_varnum_length(uint32_t varnum, int *len) {
|
||||
if (varnum < 128) {
|
||||
*len = 1;
|
||||
return LWMQTT_SUCCESS;
|
||||
} else if (varnum < 16384) {
|
||||
*len = 2;
|
||||
return LWMQTT_SUCCESS;
|
||||
} else if (varnum < 2097151) {
|
||||
*len = 3;
|
||||
return LWMQTT_SUCCESS;
|
||||
} else if (varnum < 268435455) {
|
||||
*len = 4;
|
||||
return LWMQTT_SUCCESS;
|
||||
} else {
|
||||
*len = 0;
|
||||
return LWMQTT_VARNUM_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_read_varnum(uint8_t **buf, const uint8_t *buf_end, uint32_t *varnum) {
|
||||
// prepare last byte
|
||||
uint8_t byte;
|
||||
|
||||
// prepare multiplier
|
||||
uint32_t multiplier = 1;
|
||||
|
||||
// prepare length
|
||||
size_t len = 0;
|
||||
|
||||
// initialize number
|
||||
*varnum = 0;
|
||||
|
||||
// decode variadic number
|
||||
do {
|
||||
// increment length
|
||||
len++;
|
||||
|
||||
// return error if buffer is to small
|
||||
if ((size_t)(buf_end - (*buf)) < len) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// return error if the length has overflowed
|
||||
if (len > 4) {
|
||||
return LWMQTT_VARNUM_OVERFLOW;
|
||||
}
|
||||
|
||||
// read byte
|
||||
byte = (*buf)[len - 1];
|
||||
|
||||
// add byte to number
|
||||
*varnum += (byte & 127) * multiplier;
|
||||
|
||||
// increase multiplier
|
||||
multiplier *= 128;
|
||||
} while ((byte & 128) != 0);
|
||||
|
||||
// adjust pointer
|
||||
*buf += len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_write_varnum(uint8_t **buf, const uint8_t *buf_end, uint32_t varnum) {
|
||||
// init len counter
|
||||
size_t len = 0;
|
||||
|
||||
// encode variadic number
|
||||
do {
|
||||
// check overflow
|
||||
if (len == 4) {
|
||||
return LWMQTT_VARNUM_OVERFLOW;
|
||||
}
|
||||
|
||||
// return error if buffer is to small
|
||||
if ((size_t)(buf_end - (*buf)) < len + 1) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// calculate current byte
|
||||
uint8_t byte = (uint8_t)(varnum % 128);
|
||||
|
||||
// change remaining length
|
||||
varnum /= 128;
|
||||
|
||||
// set the top bit of this byte if there are more to encode
|
||||
if (varnum > 0) {
|
||||
byte |= 0x80;
|
||||
}
|
||||
|
||||
// write byte
|
||||
(*buf)[len++] = byte;
|
||||
} while (varnum > 0);
|
||||
|
||||
// adjust pointer
|
||||
*buf += len;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
137
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/helpers.h
Normal file
137
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/helpers.h
Normal file
@ -0,0 +1,137 @@
|
||||
#ifndef LWMQTT_HELPERS_H
|
||||
#define LWMQTT_HELPERS_H
|
||||
|
||||
#include "lwmqtt.h"
|
||||
|
||||
/**
|
||||
* Reads bits from a byte.
|
||||
*
|
||||
* @param byte - The byte to read from.
|
||||
* @param pos - The position of the first bit.
|
||||
* @param num - The number of bits to read.
|
||||
* @return The read bits as a byte.
|
||||
*/
|
||||
uint8_t lwmqtt_read_bits(uint8_t byte, int pos, int num);
|
||||
|
||||
/**
|
||||
* Write bits to a byte.
|
||||
*
|
||||
* @param byte - The byte to write bits to.
|
||||
* @param value - The bits to write as a byte.
|
||||
* @param pos - The position of the first bit.
|
||||
* @param num - The number of bits to write.
|
||||
*/
|
||||
void lwmqtt_write_bits(uint8_t *byte, uint8_t value, int pos, int num);
|
||||
|
||||
/**
|
||||
* Reads arbitrary data from the specified buffer. The pointer is incremented by bytes read.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param data - Pointer to beginning of data.
|
||||
* @param len - The amount of data to read.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_read_data(uint8_t **buf, const uint8_t *buf_end, uint8_t **data, size_t len);
|
||||
|
||||
/**
|
||||
* Writes arbitrary data to the specified buffer. The pointer is incremented by the bytes written.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param data - Pointer to the to be written data.
|
||||
* @param len - The amount of data to write.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_write_data(uint8_t **buf, const uint8_t *buf_end, uint8_t *data, size_t len);
|
||||
|
||||
/**
|
||||
* Reads two byte number from the specified buffer. The pointer is incremented by two.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param num - The read number.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_read_num(uint8_t **buf, const uint8_t *buf_end, uint16_t *num);
|
||||
|
||||
/**
|
||||
* Writes a two byte number to the specified buffer. The pointer is incremented by two.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param num - The number to write.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_write_num(uint8_t **buf, const uint8_t *buf_end, uint16_t num);
|
||||
|
||||
/**
|
||||
* Reads a string from the specified buffer into the passed object. The pointer is incremented by the bytes read.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param str - The object into which the data is to be read.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_read_string(uint8_t **buf, const uint8_t *buf_end, lwmqtt_string_t *str);
|
||||
|
||||
/**
|
||||
* Writes a string to the specified buffer. The pointer is incremented by the bytes written.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param str - The string to write.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_write_string(uint8_t **buf, const uint8_t *buf_end, lwmqtt_string_t str);
|
||||
|
||||
/**
|
||||
* Reads one byte from the buffer. The pointer is incremented by one.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param byte - The read byte.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_read_byte(uint8_t **buf, const uint8_t *buf_end, uint8_t *byte);
|
||||
|
||||
/**
|
||||
* Writes one byte to the specified buffer. The pointer is incremented by one.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param byte - The byte to write.
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_BUFFER_TOO_SHORT.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_write_byte(uint8_t **buf, const uint8_t *buf_end, uint8_t byte);
|
||||
|
||||
/**
|
||||
* Returns the amount of bytes required by the variable number.
|
||||
*
|
||||
* @param varnum - The number to check.
|
||||
* @param len - The required length;
|
||||
* @return LWMQTT_SUCCESS or LWMQTT_VARNUM_OVERFLOW.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_varnum_length(uint32_t varnum, int *len);
|
||||
|
||||
/**
|
||||
* Reads a variable number from the specified buffer. The pointer is incremented by the bytes read.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param varnum - The read varnum.
|
||||
* @return LWMQTT_SUCCESS, LWMQTT_BUFFER_TOO_SHORT or LWMQTT_VARNUM_OVERFLOW.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_read_varnum(uint8_t **buf, const uint8_t *buf_end, uint32_t *varnum);
|
||||
|
||||
/**
|
||||
* Writes a variable number to the specified buffer. The pointer is incremented by the bytes written.
|
||||
*
|
||||
* @param buf - Pointer to the buffer.
|
||||
* @param buf_end - Pointer to the end of the buffer.
|
||||
* @param varnum - The number to write.
|
||||
* @return LWMQTT_SUCCESS, LWMQTT_BUFFER_TOO_SHORT or LWMQTT_VARNUM_OVERFLOW.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_write_varnum(uint8_t **buf, const uint8_t *buf_end, uint32_t varnum);
|
||||
|
||||
#endif
|
381
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/lwmqtt.h
Normal file
381
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/lwmqtt.h
Normal file
@ -0,0 +1,381 @@
|
||||
#ifndef LWMQTT_H
|
||||
#define LWMQTT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* The error type used by all exposed APIs.
|
||||
*
|
||||
* If a function returns an error that operates on a connected client (e.g publish, keep_alive, etc.) the caller should
|
||||
* switch into a disconnected state, close and cleanup the current connection and start over by creating a new
|
||||
* connection.
|
||||
*/
|
||||
typedef enum {
|
||||
LWMQTT_SUCCESS = 0,
|
||||
LWMQTT_BUFFER_TOO_SHORT = -1,
|
||||
LWMQTT_VARNUM_OVERFLOW = -2,
|
||||
LWMQTT_NETWORK_FAILED_CONNECT = -3,
|
||||
LWMQTT_NETWORK_TIMEOUT = -4,
|
||||
LWMQTT_NETWORK_FAILED_READ = -5,
|
||||
LWMQTT_NETWORK_FAILED_WRITE = -6,
|
||||
LWMQTT_REMAINING_LENGTH_OVERFLOW = -7,
|
||||
LWMQTT_REMAINING_LENGTH_MISMATCH = -8,
|
||||
LWMQTT_MISSING_OR_WRONG_PACKET = -9,
|
||||
LWMQTT_CONNECTION_DENIED = -10,
|
||||
LWMQTT_FAILED_SUBSCRIPTION = -11,
|
||||
LWMQTT_SUBACK_ARRAY_OVERFLOW = -12,
|
||||
LWMQTT_PONG_TIMEOUT = -13,
|
||||
} lwmqtt_err_t;
|
||||
|
||||
/**
|
||||
* A common string object.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t len;
|
||||
char *data;
|
||||
} lwmqtt_string_t;
|
||||
|
||||
/**
|
||||
* The initializer for string objects.
|
||||
*/
|
||||
#define lwmqtt_default_string \
|
||||
{ 0, NULL }
|
||||
|
||||
/**
|
||||
* Returns a string object for the passed C string.
|
||||
*
|
||||
* @param str - The C string.
|
||||
* @return A string object.
|
||||
*/
|
||||
lwmqtt_string_t lwmqtt_string(const char *str);
|
||||
|
||||
/**
|
||||
* Compares a string object to a C string.
|
||||
*
|
||||
* @param a - The string object to compare.
|
||||
* @param b - The C string to compare.
|
||||
* @return Similarity e.g. strcmp().
|
||||
*/
|
||||
int lwmqtt_strcmp(lwmqtt_string_t a, const char *b);
|
||||
|
||||
/**
|
||||
* The available QOS levels.
|
||||
*/
|
||||
typedef enum { LWMQTT_QOS0 = 0, LWMQTT_QOS1 = 1, LWMQTT_QOS2 = 2, LWMQTT_QOS_FAILURE = 128 } lwmqtt_qos_t;
|
||||
|
||||
/**
|
||||
* The message object used to publish and receive messages.
|
||||
*/
|
||||
typedef struct {
|
||||
lwmqtt_qos_t qos;
|
||||
bool retained;
|
||||
uint8_t *payload;
|
||||
size_t payload_len;
|
||||
} lwmqtt_message_t;
|
||||
|
||||
/**
|
||||
* The initializer for message objects.
|
||||
*/
|
||||
#define lwmqtt_default_message \
|
||||
{ LWMQTT_QOS0, false, NULL, 0 }
|
||||
|
||||
/**
|
||||
* Forward declaration of the client object.
|
||||
*/
|
||||
typedef struct lwmqtt_client_t lwmqtt_client_t;
|
||||
|
||||
/**
|
||||
* The callback used to read from a network object.
|
||||
*
|
||||
* The callbacks is expected to read up to the amount of bytes in to the passed buffer. It should block the specified
|
||||
* timeout and wait for more incoming data.
|
||||
*
|
||||
* @param ref - A custom reference.
|
||||
* @param buf - The buffer.
|
||||
* @param len - The length of the buffer.
|
||||
* @param read - Variable that must be set with the amount of read bytes.
|
||||
* @param timeout - The timeout in milliseconds for the operation.
|
||||
*/
|
||||
typedef lwmqtt_err_t (*lwmqtt_network_read_t)(void *ref, uint8_t *buf, size_t len, size_t *read, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* The callback used to write to a network object.
|
||||
*
|
||||
* The callback is expected to write up to the amount of bytes from the passed buffer. It should wait up to the
|
||||
* specified timeout to write the specified data to the network.
|
||||
*
|
||||
* @param ref - A custom reference.
|
||||
* @param buf - The buffer.
|
||||
* @param len - The length of the buffer.
|
||||
* @param sent - Variable that must be set with the amount of written bytes.
|
||||
* @param timeout - The timeout in milliseconds for the operation.
|
||||
*/
|
||||
typedef lwmqtt_err_t (*lwmqtt_network_write_t)(void *ref, uint8_t *buf, size_t len, size_t *sent, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* The callback used to set a timer.
|
||||
*
|
||||
* @param ref - A custom reference.
|
||||
* @param timeout - The amount of milliseconds until the deadline.
|
||||
*/
|
||||
typedef void (*lwmqtt_timer_set_t)(void *ref, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* The callback used to get a timers value.
|
||||
*
|
||||
* @param - A custom reference.
|
||||
* @return The amount of milliseconds until the deadline. May return negative numbers if the deadline has been reached.
|
||||
*/
|
||||
typedef int32_t (*lwmqtt_timer_get_t)(void *ref);
|
||||
|
||||
/**
|
||||
* The callback used to forward incoming messages.
|
||||
*
|
||||
* Note: The callback is mostly executed because of a call to lwmqtt_yield() that processes incoming messages. However,
|
||||
* it is possible that the callback is also executed during a call to lwmqtt_subscribe(), lwmqtt_publish() or
|
||||
* lwmqtt_unsubscribe() if incoming messages are received between the required acknowledgements. It is therefore not
|
||||
* recommended to call any further lwmqtt methods in the callback as this might result in weird call stacks. The
|
||||
* callback should place the received messages in a queue and dispatch them after the caller has returned.
|
||||
*/
|
||||
typedef void (*lwmqtt_callback_t)(lwmqtt_client_t *client, void *ref, lwmqtt_string_t str, lwmqtt_message_t msg);
|
||||
|
||||
/**
|
||||
* The client object.
|
||||
*/
|
||||
struct lwmqtt_client_t {
|
||||
uint16_t last_packet_id;
|
||||
uint32_t keep_alive_interval;
|
||||
bool pong_pending;
|
||||
|
||||
size_t write_buf_size, read_buf_size;
|
||||
uint8_t *write_buf, *read_buf;
|
||||
|
||||
lwmqtt_callback_t callback;
|
||||
void *callback_ref;
|
||||
|
||||
void *network;
|
||||
lwmqtt_network_read_t network_read;
|
||||
lwmqtt_network_write_t network_write;
|
||||
|
||||
void *keep_alive_timer;
|
||||
void *command_timer;
|
||||
lwmqtt_timer_set_t timer_set;
|
||||
lwmqtt_timer_get_t timer_get;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will initialize the specified client object.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param write_buf - The write buffer.
|
||||
* @param write_buf_size - The write buffer size.
|
||||
* @param read_buf - The read buffer.
|
||||
* @param read_buf_size - The read buffer size.
|
||||
*/
|
||||
void lwmqtt_init(lwmqtt_client_t *client, uint8_t *write_buf, size_t write_buf_size, uint8_t *read_buf,
|
||||
size_t read_buf_size);
|
||||
|
||||
/**
|
||||
* Will set the network reference and callbacks for this client object.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param ref - The reference to the network object.
|
||||
* @param read - The read callback.
|
||||
* @param write - The write callback.
|
||||
*/
|
||||
void lwmqtt_set_network(lwmqtt_client_t *client, void *ref, lwmqtt_network_read_t read, lwmqtt_network_write_t write);
|
||||
|
||||
/**
|
||||
* Will set the timer references and callbacks for this client object.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param keep_alive_timer - The reference to the keep alive timer.
|
||||
* @param command_timer - The reference to the command timer.
|
||||
* @param set - The set callback.
|
||||
* @param get - The get callback.
|
||||
*/
|
||||
void lwmqtt_set_timers(lwmqtt_client_t *client, void *keep_alive_timer, void *command_timer, lwmqtt_timer_set_t set,
|
||||
lwmqtt_timer_get_t get);
|
||||
|
||||
/**
|
||||
* Will set the callback used to receive incoming messages.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param ref - A custom reference that will passed to the callback.
|
||||
* @param cb - The callback to be called.
|
||||
*/
|
||||
void lwmqtt_set_callback(lwmqtt_client_t *client, void *ref, lwmqtt_callback_t cb);
|
||||
|
||||
/**
|
||||
* The object defining the last will of a client.
|
||||
*/
|
||||
typedef struct {
|
||||
lwmqtt_string_t topic;
|
||||
lwmqtt_qos_t qos;
|
||||
bool retained;
|
||||
lwmqtt_string_t payload;
|
||||
} lwmqtt_will_t;
|
||||
|
||||
/**
|
||||
* The default initializer for the will object.
|
||||
*/
|
||||
#define lwmqtt_default_will \
|
||||
{ lwmqtt_default_string, LWMQTT_QOS0, false, lwmqtt_default_string }
|
||||
|
||||
/**
|
||||
* The object containing the connection options for a client.
|
||||
*/
|
||||
typedef struct {
|
||||
lwmqtt_string_t client_id;
|
||||
uint16_t keep_alive;
|
||||
bool clean_session;
|
||||
lwmqtt_string_t username;
|
||||
lwmqtt_string_t password;
|
||||
} lwmqtt_options_t;
|
||||
|
||||
/**
|
||||
* The default initializer for the options object.
|
||||
*/
|
||||
#define lwmqtt_default_options \
|
||||
{ lwmqtt_default_string, 60, true, lwmqtt_default_string, lwmqtt_default_string }
|
||||
|
||||
/**
|
||||
* The available return codes transported by the connack packet.
|
||||
*/
|
||||
typedef enum {
|
||||
LWMQTT_CONNECTION_ACCEPTED = 0,
|
||||
LWMQTT_UNACCEPTABLE_PROTOCOL = 1,
|
||||
LWMQTT_IDENTIFIER_REJECTED = 2,
|
||||
LWMQTT_SERVER_UNAVAILABLE = 3,
|
||||
LWMQTT_BAD_USERNAME_OR_PASSWORD = 4,
|
||||
LWMQTT_NOT_AUTHORIZED = 5,
|
||||
LWMQTT_UNKNOWN_RETURN_CODE = 6
|
||||
} lwmqtt_return_code_t;
|
||||
|
||||
/**
|
||||
* Will send a connect packet and wait for a connack response and set the return code.
|
||||
*
|
||||
* The network object must already be connected to the server. An error is returned if the broker rejects the
|
||||
* connection.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param options - The options object.
|
||||
* @param will - The will object.
|
||||
* @param return_code - The variable that will receive the return code.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_connect(lwmqtt_client_t *client, lwmqtt_options_t options, lwmqtt_will_t *will,
|
||||
lwmqtt_return_code_t *return_code, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send a publish packet and wait for all acks to complete.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param topic - The topic.
|
||||
* @param message - The message.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_publish(lwmqtt_client_t *client, lwmqtt_string_t topic, lwmqtt_message_t msg, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send a subscribe packet with multiple topic filters plus QOS levels and wait for the suback to complete.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param count - The number of topic filters and QOS levels.
|
||||
* @param topic_filter - The list of topic filters.
|
||||
* @param qos - The list of QOS levels.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_subscribe(lwmqtt_client_t *client, int count, lwmqtt_string_t *topic_filter, lwmqtt_qos_t *qos,
|
||||
uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send a subscribe packet with a single topic filter plus QOS level and wait for the suback to complete.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param topic_filter - The topic filter.
|
||||
* @param qos - The QOS level.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_subscribe_one(lwmqtt_client_t *client, lwmqtt_string_t topic_filter, lwmqtt_qos_t qos,
|
||||
uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send an unsubscribe packet with multiple topic filters and wait for the unsuback to complete.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param count - The number of topic filters.
|
||||
* @param topic_filter - The topic filter.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_unsubscribe(lwmqtt_client_t *client, int count, lwmqtt_string_t *topic_filter, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send an unsubscribe packet with a single topic filter and wait for the unsuback to complete.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param topic_filter - The topic filter.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_unsubscribe_one(lwmqtt_client_t *client, lwmqtt_string_t topic_filter, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will send a disconnect packet and finish the client.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_disconnect(lwmqtt_client_t *client, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will yield control to the client and receive incoming packets from the network.
|
||||
*
|
||||
* Single-threaded applications may peek on the network and assess if data is available to read before calling yield and
|
||||
* potentially block until the timeout is reached. Multi-threaded applications may select on the socket and block until
|
||||
* data is available and then yield to the client if data is available. All applications may specify the amount of bytes
|
||||
* available to read in order to constrain the yield to only receive packets that are already in-flight.
|
||||
*
|
||||
* If no availability info is given the yield will return after one packet has been successfully read or the deadline
|
||||
* has been reached but no single bytes has been received.
|
||||
*
|
||||
* Note: The message callback might be called with incoming messages as part of this call.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param available - The available bytes to read.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_yield(lwmqtt_client_t *client, size_t available, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* Will yield control to the client to keep the connection alive.
|
||||
*
|
||||
* This functions must be called at a rate slightly lower than 25% of the configured keep alive. If keep alive is zero,
|
||||
* the function must not be called at all.
|
||||
*
|
||||
* @param client - The client object.
|
||||
* @param timeout - The command timeout.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_keep_alive(lwmqtt_client_t *client, uint32_t timeout);
|
||||
|
||||
#endif // LWMQTT_H
|
742
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/packet.c
Normal file
742
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/packet.c
Normal file
@ -0,0 +1,742 @@
|
||||
#include "packet.h"
|
||||
|
||||
lwmqtt_err_t lwmqtt_detect_packet_type(uint8_t *buf, size_t buf_len, lwmqtt_packet_type_t *packet_type) {
|
||||
// set default packet type
|
||||
*packet_type = LWMQTT_NO_PACKET;
|
||||
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// prepare header
|
||||
uint8_t header;
|
||||
|
||||
// read header
|
||||
lwmqtt_err_t err = lwmqtt_read_byte(&buf_ptr, buf_end, &header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// get packet type
|
||||
*packet_type = (lwmqtt_packet_type_t)lwmqtt_read_bits(header, 4, 4);
|
||||
|
||||
// check if packet type is correct and can be received
|
||||
switch (*packet_type) {
|
||||
case LWMQTT_CONNACK_PACKET:
|
||||
case LWMQTT_PUBLISH_PACKET:
|
||||
case LWMQTT_PUBACK_PACKET:
|
||||
case LWMQTT_PUBREC_PACKET:
|
||||
case LWMQTT_PUBREL_PACKET:
|
||||
case LWMQTT_PUBCOMP_PACKET:
|
||||
case LWMQTT_SUBACK_PACKET:
|
||||
case LWMQTT_UNSUBACK_PACKET:
|
||||
case LWMQTT_PINGRESP_PACKET:
|
||||
return LWMQTT_SUCCESS;
|
||||
default:
|
||||
*packet_type = LWMQTT_NO_PACKET;
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_detect_remaining_length(uint8_t *buf, size_t buf_len, uint32_t *rem_len) {
|
||||
// prepare pointer
|
||||
uint8_t *ptr = buf;
|
||||
|
||||
// attempt to decode remaining length
|
||||
lwmqtt_err_t err = lwmqtt_read_varnum(&ptr, buf + buf_len, rem_len);
|
||||
if (err == LWMQTT_VARNUM_OVERFLOW) {
|
||||
*rem_len = 0;
|
||||
return LWMQTT_REMAINING_LENGTH_OVERFLOW;
|
||||
} else if (err != LWMQTT_SUCCESS) {
|
||||
*rem_len = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_connect(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_options_t options,
|
||||
lwmqtt_will_t *will) {
|
||||
// prepare pointers
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// fixed header is 10
|
||||
uint32_t rem_len = 10;
|
||||
|
||||
// add client id to remaining length
|
||||
rem_len += options.client_id.len + 2;
|
||||
|
||||
// add will if present to remaining length
|
||||
if (will != NULL) {
|
||||
rem_len += will->topic.len + 2 + will->payload.len + 2;
|
||||
}
|
||||
|
||||
// add username if present to remaining length
|
||||
if (options.username.len > 0) {
|
||||
rem_len += options.username.len + 2;
|
||||
|
||||
// add password if present to remaining length
|
||||
if (options.password.len > 0) {
|
||||
rem_len += options.password.len + 2;
|
||||
}
|
||||
}
|
||||
|
||||
// check remaining length length
|
||||
int rem_len_len;
|
||||
lwmqtt_err_t err = lwmqtt_varnum_length(rem_len, &rem_len_len);
|
||||
if (err == LWMQTT_VARNUM_OVERFLOW) {
|
||||
return LWMQTT_REMAINING_LENGTH_OVERFLOW;
|
||||
}
|
||||
|
||||
// prepare header
|
||||
uint8_t header = 0;
|
||||
lwmqtt_write_bits(&header, LWMQTT_CONNECT_PACKET, 4, 4);
|
||||
|
||||
// write header
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write version string
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, lwmqtt_string("MQTT"));
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write version number
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, 4);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// prepare flags
|
||||
uint8_t flags = 0;
|
||||
|
||||
// set clean session
|
||||
lwmqtt_write_bits(&flags, (uint8_t)(options.clean_session), 1, 1);
|
||||
|
||||
// set will flags if present
|
||||
if (will != NULL) {
|
||||
lwmqtt_write_bits(&flags, 1, 2, 1);
|
||||
lwmqtt_write_bits(&flags, will->qos, 3, 2);
|
||||
lwmqtt_write_bits(&flags, (uint8_t)(will->retained), 5, 1);
|
||||
}
|
||||
|
||||
// set username flag if present
|
||||
if (options.username.len > 0) {
|
||||
lwmqtt_write_bits(&flags, 1, 7, 1);
|
||||
|
||||
// set password flag if present
|
||||
if (options.password.len > 0) {
|
||||
lwmqtt_write_bits(&flags, 1, 6, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// write flags
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, flags);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write keep alive
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, options.keep_alive);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write client id
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, options.client_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write will if present
|
||||
if (will != NULL) {
|
||||
// write topic
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, will->topic);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write payload length
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, (uint16_t)will->payload.len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write payload
|
||||
err = lwmqtt_write_data(&buf_ptr, buf_end, (uint8_t *)will->payload.data, will->payload.len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// write username if present
|
||||
if (options.username.len > 0) {
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, options.username);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// write password if present
|
||||
if (options.username.len > 0 && options.password.len > 0) {
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, options.password);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// set written length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_decode_connack(uint8_t *buf, size_t buf_len, bool *session_present,
|
||||
lwmqtt_return_code_t *return_code) {
|
||||
// prepare pointers
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// read header
|
||||
uint8_t header;
|
||||
lwmqtt_err_t err = lwmqtt_read_byte(&buf_ptr, buf_end, &header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check packet type
|
||||
if (lwmqtt_read_bits(header, 4, 4) != LWMQTT_CONNACK_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// read remaining length
|
||||
uint32_t rem_len;
|
||||
err = lwmqtt_read_varnum(&buf_ptr, buf_end, &rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check remaining length
|
||||
if (rem_len != 2) {
|
||||
return LWMQTT_REMAINING_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
// read flags
|
||||
uint8_t flags;
|
||||
err = lwmqtt_read_byte(&buf_ptr, buf_end, &flags);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// read return code
|
||||
uint8_t raw_return_code;
|
||||
err = lwmqtt_read_byte(&buf_ptr, buf_end, &raw_return_code);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// get session present
|
||||
*session_present = lwmqtt_read_bits(flags, 7, 1) == 1;
|
||||
|
||||
// get return code
|
||||
switch (raw_return_code) {
|
||||
case 0:
|
||||
*return_code = LWMQTT_CONNECTION_ACCEPTED;
|
||||
break;
|
||||
case 1:
|
||||
*return_code = LWMQTT_UNACCEPTABLE_PROTOCOL;
|
||||
break;
|
||||
case 2:
|
||||
*return_code = LWMQTT_IDENTIFIER_REJECTED;
|
||||
break;
|
||||
case 3:
|
||||
*return_code = LWMQTT_SERVER_UNAVAILABLE;
|
||||
break;
|
||||
case 4:
|
||||
*return_code = LWMQTT_BAD_USERNAME_OR_PASSWORD;
|
||||
break;
|
||||
case 5:
|
||||
*return_code = LWMQTT_NOT_AUTHORIZED;
|
||||
break;
|
||||
default:
|
||||
*return_code = LWMQTT_UNKNOWN_RETURN_CODE;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_zero(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_packet_type_t packet_type) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// write header
|
||||
uint8_t header = 0;
|
||||
lwmqtt_write_bits(&header, packet_type, 4, 4);
|
||||
lwmqtt_err_t err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, 0);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_decode_ack(uint8_t *buf, size_t buf_len, lwmqtt_packet_type_t packet_type, bool *dup,
|
||||
uint16_t *packet_id) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// read header
|
||||
uint8_t header = 0;
|
||||
lwmqtt_err_t err = lwmqtt_read_byte(&buf_ptr, buf_end, &header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check packet type
|
||||
if (lwmqtt_read_bits(header, 4, 4) != packet_type) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// get dup
|
||||
*dup = lwmqtt_read_bits(header, 3, 1) == 1;
|
||||
|
||||
// read remaining length
|
||||
uint32_t rem_len;
|
||||
err = lwmqtt_read_varnum(&buf_ptr, buf + buf_len, &rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check remaining length
|
||||
if (rem_len != 2) {
|
||||
return LWMQTT_REMAINING_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
// read packet id
|
||||
err = lwmqtt_read_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_ack(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_packet_type_t packet_type, bool dup,
|
||||
uint16_t packet_id) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// prepare header
|
||||
uint8_t header = 0;
|
||||
|
||||
// set packet type
|
||||
lwmqtt_write_bits(&header, packet_type, 4, 4);
|
||||
|
||||
// set dup
|
||||
lwmqtt_write_bits(&header, (uint8_t)(dup), 3, 1);
|
||||
|
||||
// set qos
|
||||
lwmqtt_write_bits(&header, (uint8_t)(packet_type == LWMQTT_PUBREL_PACKET ? LWMQTT_QOS1 : LWMQTT_QOS0), 1, 2);
|
||||
|
||||
// write header
|
||||
lwmqtt_err_t err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, 2);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write packet id
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set written length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_decode_publish(uint8_t *buf, size_t buf_len, bool *dup, uint16_t *packet_id, lwmqtt_string_t *topic,
|
||||
lwmqtt_message_t *msg) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// read header
|
||||
uint8_t header;
|
||||
lwmqtt_err_t err = lwmqtt_read_byte(&buf_ptr, buf_end, &header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check packet type
|
||||
if (lwmqtt_read_bits(header, 4, 4) != LWMQTT_PUBLISH_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// get dup
|
||||
*dup = lwmqtt_read_bits(header, 3, 1) == 1;
|
||||
|
||||
// get retained
|
||||
msg->retained = lwmqtt_read_bits(header, 0, 1) == 1;
|
||||
|
||||
// get qos
|
||||
switch (lwmqtt_read_bits(header, 1, 2)) {
|
||||
case 0:
|
||||
msg->qos = LWMQTT_QOS0;
|
||||
break;
|
||||
case 1:
|
||||
msg->qos = LWMQTT_QOS1;
|
||||
break;
|
||||
case 2:
|
||||
msg->qos = LWMQTT_QOS2;
|
||||
break;
|
||||
default:
|
||||
msg->qos = LWMQTT_QOS0;
|
||||
break;
|
||||
}
|
||||
|
||||
// read remaining length
|
||||
uint32_t rem_len;
|
||||
err = lwmqtt_read_varnum(&buf_ptr, buf_end, &rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check remaining length (topic length)
|
||||
if (rem_len < 2) {
|
||||
return LWMQTT_REMAINING_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
// check buffer capacity
|
||||
if ((uint32_t)(buf_end - buf_ptr) < rem_len) {
|
||||
return LWMQTT_BUFFER_TOO_SHORT;
|
||||
}
|
||||
|
||||
// reset buf end
|
||||
buf_end = buf_ptr + rem_len;
|
||||
|
||||
// read topic
|
||||
err = lwmqtt_read_string(&buf_ptr, buf_end, topic);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// read packet id if qos is at least 1
|
||||
if (msg->qos > 0) {
|
||||
err = lwmqtt_read_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
*packet_id = 0;
|
||||
}
|
||||
|
||||
// set payload length
|
||||
msg->payload_len = buf_end - buf_ptr;
|
||||
|
||||
// read payload
|
||||
err = lwmqtt_read_data(&buf_ptr, buf_end, &msg->payload, buf_end - buf_ptr);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_publish(uint8_t *buf, size_t buf_len, size_t *len, bool dup, uint16_t packet_id,
|
||||
lwmqtt_string_t topic, lwmqtt_message_t msg) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// calculate remaining length
|
||||
uint32_t rem_len = 2 + topic.len + (uint32_t)msg.payload_len;
|
||||
if (msg.qos > 0) {
|
||||
rem_len += 2;
|
||||
}
|
||||
|
||||
// check remaining length length
|
||||
int rem_len_len;
|
||||
lwmqtt_err_t err = lwmqtt_varnum_length(rem_len, &rem_len_len);
|
||||
if (err == LWMQTT_VARNUM_OVERFLOW) {
|
||||
return LWMQTT_REMAINING_LENGTH_OVERFLOW;
|
||||
}
|
||||
|
||||
// prepare header
|
||||
uint8_t header = 0;
|
||||
|
||||
// set packet type
|
||||
lwmqtt_write_bits(&header, LWMQTT_PUBLISH_PACKET, 4, 4);
|
||||
|
||||
// set dup
|
||||
lwmqtt_write_bits(&header, (uint8_t)(dup), 3, 1);
|
||||
|
||||
// set qos
|
||||
lwmqtt_write_bits(&header, msg.qos, 1, 2);
|
||||
|
||||
// set retained
|
||||
lwmqtt_write_bits(&header, (uint8_t)(msg.retained), 0, 1);
|
||||
|
||||
// write header
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write topic
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, topic);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write packet id if qos is at least 1
|
||||
if (msg.qos > 0) {
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// write payload
|
||||
err = lwmqtt_write_data(&buf_ptr, buf_end, msg.payload, msg.payload_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_subscribe(uint8_t *buf, size_t buf_len, size_t *len, uint16_t packet_id, int count,
|
||||
lwmqtt_string_t *topic_filters, lwmqtt_qos_t *qos_levels) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// calculate remaining length
|
||||
uint32_t rem_len = 2;
|
||||
for (int i = 0; i < count; i++) {
|
||||
rem_len += 2 + topic_filters[i].len + 1;
|
||||
}
|
||||
|
||||
// check remaining length length
|
||||
int rem_len_len;
|
||||
lwmqtt_err_t err = lwmqtt_varnum_length(rem_len, &rem_len_len);
|
||||
if (err == LWMQTT_VARNUM_OVERFLOW) {
|
||||
return LWMQTT_REMAINING_LENGTH_OVERFLOW;
|
||||
}
|
||||
|
||||
// prepare header
|
||||
uint8_t header = 0;
|
||||
|
||||
// set packet type
|
||||
lwmqtt_write_bits(&header, LWMQTT_SUBSCRIBE_PACKET, 4, 4);
|
||||
|
||||
// set qos
|
||||
lwmqtt_write_bits(&header, LWMQTT_QOS1, 1, 2);
|
||||
|
||||
// write header
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write packet id
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write all subscriptions
|
||||
for (int i = 0; i < count; i++) {
|
||||
// write topic
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, topic_filters[i]);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write qos level
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, (uint8_t)qos_levels[i]);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// set length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_decode_suback(uint8_t *buf, size_t buf_len, uint16_t *packet_id, int max_count, int *count,
|
||||
lwmqtt_qos_t *granted_qos_levels) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// read header
|
||||
uint8_t header;
|
||||
lwmqtt_err_t err = lwmqtt_read_byte(&buf_ptr, buf_end, &header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check packet type
|
||||
if (lwmqtt_read_bits(header, 4, 4) != LWMQTT_SUBACK_PACKET) {
|
||||
return LWMQTT_MISSING_OR_WRONG_PACKET;
|
||||
}
|
||||
|
||||
// read remaining length
|
||||
uint32_t rem_len;
|
||||
err = lwmqtt_read_varnum(&buf_ptr, buf_end, &rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// check remaining length (packet id + min. one suback code)
|
||||
if (rem_len < 3) {
|
||||
return LWMQTT_REMAINING_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
// read packet id
|
||||
err = lwmqtt_read_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// read all suback codes
|
||||
for (*count = 0; *count < (int)rem_len - 2; (*count)++) {
|
||||
// check max count
|
||||
if (*count > max_count) {
|
||||
return LWMQTT_SUBACK_ARRAY_OVERFLOW;
|
||||
}
|
||||
|
||||
// read qos level
|
||||
uint8_t raw_qos_level;
|
||||
err = lwmqtt_read_byte(&buf_ptr, buf_end, &raw_qos_level);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// set qos level
|
||||
switch (raw_qos_level) {
|
||||
case 0:
|
||||
granted_qos_levels[*count] = LWMQTT_QOS0;
|
||||
break;
|
||||
case 1:
|
||||
granted_qos_levels[*count] = LWMQTT_QOS1;
|
||||
break;
|
||||
case 2:
|
||||
granted_qos_levels[*count] = LWMQTT_QOS2;
|
||||
break;
|
||||
default:
|
||||
granted_qos_levels[*count] = LWMQTT_QOS_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_encode_unsubscribe(uint8_t *buf, size_t buf_len, size_t *len, uint16_t packet_id, int count,
|
||||
lwmqtt_string_t *topic_filters) {
|
||||
// prepare pointer
|
||||
uint8_t *buf_ptr = buf;
|
||||
uint8_t *buf_end = buf + buf_len;
|
||||
|
||||
// calculate remaining length
|
||||
uint32_t rem_len = 2;
|
||||
for (int i = 0; i < count; i++) {
|
||||
rem_len += 2 + topic_filters[i].len;
|
||||
}
|
||||
|
||||
// check remaining length length
|
||||
int rem_len_len;
|
||||
lwmqtt_err_t err = lwmqtt_varnum_length(rem_len, &rem_len_len);
|
||||
if (err == LWMQTT_VARNUM_OVERFLOW) {
|
||||
return LWMQTT_REMAINING_LENGTH_OVERFLOW;
|
||||
}
|
||||
|
||||
// prepare header
|
||||
uint8_t header = 0;
|
||||
|
||||
// set packet type
|
||||
lwmqtt_write_bits(&header, LWMQTT_UNSUBSCRIBE_PACKET, 4, 4);
|
||||
|
||||
// set qos
|
||||
lwmqtt_write_bits(&header, LWMQTT_QOS1, 1, 2);
|
||||
|
||||
// write header
|
||||
err = lwmqtt_write_byte(&buf_ptr, buf_end, header);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write remaining length
|
||||
err = lwmqtt_write_varnum(&buf_ptr, buf_end, rem_len);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write packet id
|
||||
err = lwmqtt_write_num(&buf_ptr, buf_end, packet_id);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// write topics
|
||||
for (int i = 0; i < count; i++) {
|
||||
err = lwmqtt_write_string(&buf_ptr, buf_end, topic_filters[i]);
|
||||
if (err != LWMQTT_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// set length
|
||||
*len = buf_ptr - buf;
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
185
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/packet.h
Normal file
185
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/packet.h
Normal file
@ -0,0 +1,185 @@
|
||||
#ifndef LWMQTT_PACKET_H
|
||||
#define LWMQTT_PACKET_H
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
/**
|
||||
* The available packet types.
|
||||
*/
|
||||
typedef enum {
|
||||
LWMQTT_NO_PACKET = 0,
|
||||
LWMQTT_CONNECT_PACKET = 1,
|
||||
LWMQTT_CONNACK_PACKET,
|
||||
LWMQTT_PUBLISH_PACKET,
|
||||
LWMQTT_PUBACK_PACKET,
|
||||
LWMQTT_PUBREC_PACKET,
|
||||
LWMQTT_PUBREL_PACKET,
|
||||
LWMQTT_PUBCOMP_PACKET,
|
||||
LWMQTT_SUBSCRIBE_PACKET,
|
||||
LWMQTT_SUBACK_PACKET,
|
||||
LWMQTT_UNSUBSCRIBE_PACKET,
|
||||
LWMQTT_UNSUBACK_PACKET,
|
||||
LWMQTT_PINGREQ_PACKET,
|
||||
LWMQTT_PINGRESP_PACKET,
|
||||
LWMQTT_DISCONNECT_PACKET
|
||||
} lwmqtt_packet_type_t;
|
||||
|
||||
/**
|
||||
* Will detect the packet type from the at least one byte long buffer.
|
||||
*
|
||||
* @param buf - The buffer from which the packet type will be detected.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param packet_type - The packet type.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_detect_packet_type(uint8_t *buf, size_t buf_len, lwmqtt_packet_type_t *packet_type);
|
||||
|
||||
/**
|
||||
* Will detect the remaining length form the at least on byte long buffer.
|
||||
*
|
||||
* It will return LWMQTT_BUFFER_TOO_SHORT if the buffer is to short and an additional byte should be read from the
|
||||
* network. In case the remaining length is overflowed it will return LWMQTT_REMAINING_LENGTH_OVERFLOW.
|
||||
*
|
||||
* @param buf - The buffer from which the remaining length will be detected.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param rem_len - The detected remaining length.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_detect_remaining_length(uint8_t *buf, size_t buf_len, uint32_t *rem_len);
|
||||
|
||||
/**
|
||||
* Encodes a connect packet into the supplied buffer.
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param options - The options to be used to build the connect packet.
|
||||
* @param will - The last will and testament.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_connect(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_options_t options,
|
||||
lwmqtt_will_t *will);
|
||||
|
||||
/**
|
||||
* Decodes a connack packet from the supplied buffer.
|
||||
*
|
||||
* @param buf - The raw buffer data.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param session_present - The session present flag.
|
||||
* @param return_code - The return code.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_decode_connack(uint8_t *buf, size_t buf_len, bool *session_present,
|
||||
lwmqtt_return_code_t *return_code);
|
||||
|
||||
/**
|
||||
* Encodes a zero (disconnect, pingreq) packet into the supplied buffer.
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param packet_type - The packets type.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_zero(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_packet_type_t packet_type);
|
||||
|
||||
/**
|
||||
* Decodes an ack (puback, pubrec, pubrel, pubcomp, unsuback) packet from the supplied buffer.
|
||||
*
|
||||
* @param buf - The raw buffer data.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param packet_type - The packet type.
|
||||
* @param dup - The dup flag.
|
||||
* @param packet_id - The packet id.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_decode_ack(uint8_t *buf, size_t buf_len, lwmqtt_packet_type_t packet_type, bool *dup,
|
||||
uint16_t *packet_id);
|
||||
|
||||
/**
|
||||
* Encodes an ack (puback, pubrec, pubrel, pubcomp) packet into the supplied buffer.
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param packet_type - The packets type.
|
||||
* @param dup - The dup flag.
|
||||
* @param packet_id - The packet id.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_ack(uint8_t *buf, size_t buf_len, size_t *len, lwmqtt_packet_type_t packet_type, bool dup,
|
||||
uint16_t packet_id);
|
||||
|
||||
/**
|
||||
* Decodes a publish packet from the supplied buffer.
|
||||
*
|
||||
* @param buf - The raw buffer data.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param dup - The dup flag.
|
||||
* @param packet_id - The packet id.
|
||||
* @param topic - The topic.
|
||||
* @parma msg - The message.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_decode_publish(uint8_t *buf, size_t buf_len, bool *dup, uint16_t *packet_id, lwmqtt_string_t *topic,
|
||||
lwmqtt_message_t *msg);
|
||||
|
||||
/**
|
||||
* Encodes a publish packet into the supplied buffer.
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param dup - The dup flag.
|
||||
* @param packet_id - The packet id.
|
||||
* @param topic - The topic.
|
||||
* @param msg - The message.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_publish(uint8_t *buf, size_t buf_len, size_t *len, bool dup, uint16_t packet_id,
|
||||
lwmqtt_string_t topic, lwmqtt_message_t msg);
|
||||
|
||||
/**
|
||||
* Encodes a subscribe packet into the supplied buffer.
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param packet_id - The packet id.
|
||||
* @param count - The number of members in the topic_filters and qos_levels array.
|
||||
* @param topic_filters - The array of topic filter.
|
||||
* @param qos_levels - The array of requested QoS levels.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_subscribe(uint8_t *buf, size_t buf_len, size_t *len, uint16_t packet_id, int count,
|
||||
lwmqtt_string_t *topic_filters, lwmqtt_qos_t *qos_levels);
|
||||
|
||||
/**
|
||||
* Decodes a suback packet from the supplied buffer.
|
||||
*
|
||||
* @param buf - The raw buffer data.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param packet_id - The packet id.
|
||||
* @param max_count - The maximum number of members allowed in the granted_qos_levels array.
|
||||
* @param count - The number of members in the granted_qos_levels array.
|
||||
* @param granted_qos_levels - The granted QoS levels.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_decode_suback(uint8_t *buf, size_t buf_len, uint16_t *packet_id, int max_count, int *count,
|
||||
lwmqtt_qos_t *granted_qos_levels);
|
||||
|
||||
/**
|
||||
* Encodes the supplied unsubscribe data into the supplied buffer, ready for sending
|
||||
*
|
||||
* @param buf - The buffer into which the packet will be encoded.
|
||||
* @param buf_len - The length of the specified buffer.
|
||||
* @param len - The encoded length of the packet.
|
||||
* @param packet_id - The packet id.
|
||||
* @param count - The number of members in the topic_filters array.
|
||||
* @param topic_filters - The array of topic filters.
|
||||
* @return An error value.
|
||||
*/
|
||||
lwmqtt_err_t lwmqtt_encode_unsubscribe(uint8_t *buf, size_t buf_len, size_t *len, uint16_t packet_id, int count,
|
||||
lwmqtt_string_t *topic_filters);
|
||||
|
||||
#endif // LWMQTT_PACKET_H
|
38
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/string.c
Normal file
38
lib/arduino-mqtt-2.3.3.02/src/lwmqtt/string.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "lwmqtt.h"
|
||||
|
||||
lwmqtt_string_t lwmqtt_string(const char *str) {
|
||||
// check for null
|
||||
if (str == NULL) {
|
||||
return (lwmqtt_string_t){0, NULL};
|
||||
}
|
||||
|
||||
// get length
|
||||
uint16_t len = (uint16_t)strlen(str);
|
||||
|
||||
// check zero length
|
||||
if (len == 0) {
|
||||
return (lwmqtt_string_t){0, NULL};
|
||||
}
|
||||
|
||||
return (lwmqtt_string_t){len, (char *)str};
|
||||
}
|
||||
|
||||
int lwmqtt_strcmp(lwmqtt_string_t a, const char *b) {
|
||||
// get string of b
|
||||
lwmqtt_string_t b_str = lwmqtt_string(b);
|
||||
|
||||
// return if both are zero length
|
||||
if (a.len == 0 && b_str.len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return if lengths are different
|
||||
if (a.len != b_str.len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// compare memory of same length
|
||||
return strncmp(a.data, b_str.data, a.len);
|
||||
}
|
48
lib/arduino-mqtt-2.3.3.02/src/system.cpp
Normal file
48
lib/arduino-mqtt-2.3.3.02/src/system.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "system.h"
|
||||
|
||||
void lwmqtt_arduino_timer_set(void *ref, uint32_t timeout) {
|
||||
// cast timer reference
|
||||
auto t = (lwmqtt_arduino_timer_t *)ref;
|
||||
|
||||
// set future end time
|
||||
t->end = (uint32_t)(millis() + timeout);
|
||||
}
|
||||
|
||||
int32_t lwmqtt_arduino_timer_get(void *ref) {
|
||||
// cast timer reference
|
||||
auto t = (lwmqtt_arduino_timer_t *)ref;
|
||||
|
||||
// get difference to end time
|
||||
return (int32_t)t->end - (int32_t)millis();
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_arduino_network_read(void *ref, uint8_t *buffer, size_t len, size_t *read, uint32_t timeout) {
|
||||
// cast network reference
|
||||
auto n = (lwmqtt_arduino_network_t *)ref;
|
||||
|
||||
// set timeout
|
||||
n->client->setTimeout(timeout);
|
||||
|
||||
// read bytes
|
||||
*read = n->client->readBytes(buffer, len);
|
||||
if (*read <= 0) {
|
||||
return LWMQTT_NETWORK_FAILED_READ;
|
||||
}
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
||||
|
||||
lwmqtt_err_t lwmqtt_arduino_network_write(void *ref, uint8_t *buffer, size_t len, size_t *sent, uint32_t /*timeout*/) {
|
||||
// cast network reference
|
||||
auto n = (lwmqtt_arduino_network_t *)ref;
|
||||
|
||||
// write bytes
|
||||
*sent = n->client->write(buffer, len);
|
||||
if (*sent <= 0) {
|
||||
return LWMQTT_NETWORK_FAILED_WRITE;
|
||||
};
|
||||
|
||||
return LWMQTT_SUCCESS;
|
||||
}
|
26
lib/arduino-mqtt-2.3.3.02/src/system.h
Normal file
26
lib/arduino-mqtt-2.3.3.02/src/system.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef LWMQTT_ARDUINO_H
|
||||
#define LWMQTT_ARDUINO_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Client.h>
|
||||
|
||||
extern "C" {
|
||||
#include "lwmqtt/lwmqtt.h"
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t end;
|
||||
} lwmqtt_arduino_timer_t;
|
||||
|
||||
void lwmqtt_arduino_timer_set(void *ref, uint32_t timeout);
|
||||
|
||||
int32_t lwmqtt_arduino_timer_get(void *ref);
|
||||
|
||||
typedef struct {
|
||||
Client *client;
|
||||
} lwmqtt_arduino_network_t;
|
||||
|
||||
lwmqtt_err_t lwmqtt_arduino_network_read(void *ref, uint8_t *buf, size_t len, size_t *read, uint32_t timeout);
|
||||
lwmqtt_err_t lwmqtt_arduino_network_write(void *ref, uint8_t *buf, size_t len, size_t *sent, uint32_t timeout);
|
||||
|
||||
#endif // LWMQTT_ARDUINO_H
|
28
lib/esp-mqtt-arduino-1.0.1.02.1/.gitignore
vendored
28
lib/esp-mqtt-arduino-1.0.1.02.1/.gitignore
vendored
@ -1,28 +0,0 @@
|
||||
# C++ objects and libs
|
||||
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
#*.a
|
||||
*.la
|
||||
*.lai
|
||||
*.so
|
||||
*.dll
|
||||
*.dylib
|
||||
|
||||
#Makefile
|
||||
*-build-*
|
||||
build-*
|
||||
*.autosave
|
||||
|
||||
# .log files (usually created by QtTest - thanks to VestniK)
|
||||
*.log
|
||||
|
||||
|
||||
# Editors temporary files
|
||||
*~
|
||||
|
||||
|
||||
#OSX
|
||||
.DS_Store
|
||||
._*
|
@ -1,15 +0,0 @@
|
||||
MQTT
|
||||
====
|
||||
|
||||
A Wrapper around mqtt for Arduino to be used with esp8266 modules.
|
||||
|
||||
It wraps a slightly modified version of mqtt for esp8266 ported by Tuan PM.
|
||||
Original code for esp: https://github.com/tuanpmt/esp_mqtt
|
||||
Original code for contiki: https://github.com/esar/contiki-mqtt
|
||||
|
||||
|
||||
====
|
||||
|
||||
**secure libssl:**
|
||||
|
||||
If you want to use secure communication, please use the `secure`-branch!
|
@ -1,102 +0,0 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
void myDataCb(String& topic, String& data);
|
||||
void myPublishedCb();
|
||||
void myDisconnectedCb();
|
||||
void myConnectedCb();
|
||||
|
||||
#define CLIENT_ID "client1"
|
||||
|
||||
// create MQTT object
|
||||
MQTT myMqtt(CLIENT_ID, "192.168.0.1", 1883);
|
||||
|
||||
//
|
||||
const char* ssid = "ssid";
|
||||
const char* password = "ssid_password";
|
||||
|
||||
|
||||
//
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
Serial.println("Connecting to MQTT server");
|
||||
|
||||
// setup callbacks
|
||||
myMqtt.onConnected(myConnectedCb);
|
||||
myMqtt.onDisconnected(myDisconnectedCb);
|
||||
myMqtt.onPublished(myPublishedCb);
|
||||
myMqtt.onData(myDataCb);
|
||||
|
||||
Serial.println("connect mqtt...");
|
||||
myMqtt.connect();
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
//
|
||||
void loop() {
|
||||
|
||||
int value = analogRead(A0);
|
||||
|
||||
String topic("/");
|
||||
topic += CLIENT_ID;
|
||||
topic += "/value";
|
||||
|
||||
String valueStr(value);
|
||||
|
||||
// publish value to topic
|
||||
boolean result = myMqtt.publish(topic, valueStr);
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void myConnectedCb()
|
||||
{
|
||||
Serial.println("connected to MQTT server");
|
||||
}
|
||||
|
||||
void myDisconnectedCb()
|
||||
{
|
||||
Serial.println("disconnected. try to reconnect...");
|
||||
delay(500);
|
||||
myMqtt.connect();
|
||||
}
|
||||
|
||||
void myPublishedCb()
|
||||
{
|
||||
//Serial.println("published.");
|
||||
}
|
||||
|
||||
void myDataCb(String& topic, String& data)
|
||||
{
|
||||
|
||||
Serial.print(topic);
|
||||
Serial.print(": ");
|
||||
Serial.println(data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,95 +0,0 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <MQTT.h>
|
||||
|
||||
void myDataCb(String& topic, String& data);
|
||||
void myPublishedCb();
|
||||
void myDisconnectedCb();
|
||||
void myConnectedCb();
|
||||
|
||||
#define CLIENT_ID "client3"
|
||||
#define TOPIC "/client1/value"
|
||||
|
||||
|
||||
// create MQTT
|
||||
MQTT myMqtt(CLIENT_ID, "192.168.0.1", 1883);
|
||||
|
||||
|
||||
const char* ssid = "ssid";
|
||||
const char* password = "ssid_password";
|
||||
|
||||
|
||||
//
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
|
||||
Serial.println("Connecting to MQTT server");
|
||||
|
||||
// setup callbacks
|
||||
myMqtt.onConnected(myConnectedCb);
|
||||
myMqtt.onDisconnected(myDisconnectedCb);
|
||||
myMqtt.onPublished(myPublishedCb);
|
||||
myMqtt.onData(myDataCb);
|
||||
|
||||
Serial.println("connect mqtt...");
|
||||
myMqtt.connect();
|
||||
|
||||
Serial.println("subscribe to topic...");
|
||||
myMqtt.subscribe(TOPIC);
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
||||
//
|
||||
void loop() {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void myConnectedCb()
|
||||
{
|
||||
Serial.println("connected to MQTT server");
|
||||
}
|
||||
|
||||
void myDisconnectedCb()
|
||||
{
|
||||
Serial.println("disconnected. try to reconnect...");
|
||||
delay(500);
|
||||
myMqtt.connect();
|
||||
}
|
||||
|
||||
void myPublishedCb()
|
||||
{
|
||||
//Serial.println("published.");
|
||||
}
|
||||
|
||||
void myDataCb(String& topic, String& data)
|
||||
{
|
||||
|
||||
Serial.print(topic);
|
||||
Serial.print(": ");
|
||||
Serial.println(data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,43 +0,0 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Test
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
MQTT.h KEYWORD1
|
||||
|
||||
MQTT KEYWORD1
|
||||
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
setClientId KEYWORD2
|
||||
setUserPwd KEYWORD2
|
||||
|
||||
connect KEYWORD2
|
||||
disconnect KEYWORD2
|
||||
isConnected KEYWORD2
|
||||
|
||||
publish KEYWORD2
|
||||
subscribe KEYWORD2
|
||||
|
||||
getState KEYWORD2
|
||||
|
||||
#general
|
||||
onConnected KEYWORD2
|
||||
onDisconnected KEYWORD2
|
||||
onPublished KEYWORD2
|
||||
onData KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
@ -1,9 +0,0 @@
|
||||
name=ESP MQTT
|
||||
version=1.0.1
|
||||
author=Ingo Randolf
|
||||
maintainer=Ingo Randolf
|
||||
sentence=A Wrapper around mqtt for Arduino to be used with esp8266 modules.
|
||||
paragraph=It wraps a slightly modified version of mqtt for esp8266 ported by Tuan PM. Original code for esp: https://github.com/tuanpmt/esp_mqtt (7ec2ef8e1df0422b77348fe1da7885568e0c9d01) Original code for contiki: https://github.com/esar/contiki-mqtt
|
||||
category=Communication
|
||||
url=https://github.com/i-n-g-o/esp-mqtt-arduino
|
||||
architectures=esp8266
|
@ -1,269 +0,0 @@
|
||||
/*//-------------------------------------------------------------------------------
|
||||
* MQTT.cpp
|
||||
*
|
||||
* Implementation file for MQTT Wrapper
|
||||
*
|
||||
* Wrapper for Arduino written by Ingo Randolf during
|
||||
* eTextiles Summercamp 2015.
|
||||
*
|
||||
* This library is intended to be used with esp8266 modules.
|
||||
*
|
||||
*
|
||||
* This class wraps a slightly modified version of mqtt
|
||||
* for esp8266 written by Tuan PM.
|
||||
* Original code: https://github.com/tuanpmt/esp_mqtt
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
//-------------------------------------------------------------------------------*/
|
||||
#include "MQTT.h"
|
||||
|
||||
#include "user_interface.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "mqtt/debug.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// mqtt internal callbacks
|
||||
//------------------------------------------------------------------------------------
|
||||
static void mqttConnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
MQTT* _this = (MQTT*)client->user_data;
|
||||
|
||||
if (_this && _this->onMqttConnectedCb) {
|
||||
_this->onMqttConnectedCb();
|
||||
}
|
||||
}
|
||||
|
||||
static void mqttDisconnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
MQTT* _this = (MQTT*)client->user_data;
|
||||
|
||||
if (_this && _this->onMqttDisconnectedCb) {
|
||||
_this->onMqttDisconnectedCb();
|
||||
}
|
||||
}
|
||||
|
||||
static void mqttPublishedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
MQTT* _this = (MQTT*)client->user_data;
|
||||
|
||||
if (_this && _this->onMqttPublishedCb) {
|
||||
_this->onMqttPublishedCb();
|
||||
}
|
||||
}
|
||||
|
||||
static void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
MQTT* _this = (MQTT*)client->user_data;
|
||||
|
||||
if (_this) {
|
||||
|
||||
_this->_onMqttDataCb(topic, topic_len, data, data_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void mqttTimeoutCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
|
||||
MQTT* _this = (MQTT*)client->user_data;
|
||||
|
||||
// if (_this && _this->onMqttTimeoutCb) {
|
||||
// _this->onMqttTimeoutCb();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// MQTT class implementation
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
//MQTT::MQTT(const char* client_id, const char* host, uint32_t port) :
|
||||
MQTT::MQTT(const char* client_id, const char* host, uint32_t port, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) :
|
||||
onMqttConnectedCb(0)
|
||||
,onMqttDisconnectedCb(0)
|
||||
,onMqttPublishedCb(0)
|
||||
,onMqttDataCb(0)
|
||||
,onMqttDataRawCb(0)
|
||||
{
|
||||
// init connections
|
||||
MQTT_InitConnection(&mqttClient, (uint8_t*)host, port, 0);
|
||||
|
||||
// init client
|
||||
if ( !MQTT_InitClient(&mqttClient, (uint8_t*)client_id, (uint8_t*)"", (uint8_t*)"", 15, 1) ) {
|
||||
MQTT_INFO("Failed to initialize properly. Check MQTT version.\r\n");
|
||||
}
|
||||
|
||||
// init LWT
|
||||
// MQTT_InitLWT(&mqttClient, (uint8_t*)"/lwt", (uint8_t*)"offline", 0, 0);
|
||||
MQTT_InitLWT(&mqttClient, (uint8_t*)willTopic, (uint8_t*)willMessage, willQos, (uint8_t)willRetain);
|
||||
|
||||
// set user data
|
||||
mqttClient.user_data = (void*)this;
|
||||
|
||||
// setup callbacks
|
||||
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
|
||||
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
|
||||
MQTT_OnPublished(&mqttClient, mqttPublishedCb);
|
||||
MQTT_OnData(&mqttClient, mqttDataCb);
|
||||
|
||||
MQTT_OnTimeout(&mqttClient, mqttTimeoutCb);
|
||||
}
|
||||
|
||||
|
||||
MQTT::~MQTT()
|
||||
{
|
||||
MQTT_DeleteClient(&mqttClient);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void MQTT::setClientId(const char* client_id)
|
||||
{
|
||||
MQTT_SetUserId(&mqttClient, client_id);
|
||||
}
|
||||
|
||||
void MQTT::setUserPwd(const char* user, const char* pwd)
|
||||
{
|
||||
MQTT_SetUserPwd(&mqttClient, user, pwd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void MQTT::connect()
|
||||
{
|
||||
MQTT_Connect(&mqttClient);
|
||||
}
|
||||
|
||||
void MQTT::disconnect()
|
||||
{
|
||||
MQTT_Disconnect(&mqttClient);
|
||||
}
|
||||
|
||||
bool MQTT::isConnected()
|
||||
{
|
||||
return (mqttClient.connState >= TCP_CONNECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
bool MQTT::publish(const char* topic, const char* buf, uint32_t buf_len, int qos, int retain)
|
||||
{
|
||||
return MQTT_Publish(&mqttClient, topic, buf, buf_len, qos, retain);
|
||||
}
|
||||
|
||||
bool MQTT::publish(String& topic, String& data, int qos, int retain)
|
||||
{
|
||||
return publish(topic.c_str(), data.c_str(), data.length(), qos, retain);
|
||||
}
|
||||
|
||||
bool MQTT::publish(String& topic, const char* buf, uint32_t buf_len, int qos, int retain)
|
||||
{
|
||||
return publish(topic.c_str(), buf, buf_len, qos, retain);
|
||||
}
|
||||
|
||||
bool MQTT::publish(const char* topic, String& data, int qos, int retain)
|
||||
{
|
||||
return publish(topic, data.c_str(), data.length(), qos, retain);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
bool MQTT::subscribe(const char* topic, uint8_t qos)
|
||||
{
|
||||
return MQTT_Subscribe(&mqttClient, (char*)topic, qos);
|
||||
}
|
||||
|
||||
bool MQTT::subscribe(const String& topic, uint8_t qos)
|
||||
{
|
||||
return MQTT_Subscribe(&mqttClient, (char*)topic.c_str(), qos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// set user callback functions
|
||||
//-------------------------------------------------------------------------------
|
||||
void MQTT::onConnected( void (*function)(void) )
|
||||
{
|
||||
onMqttConnectedCb = function;
|
||||
}
|
||||
|
||||
void MQTT::onDisconnected( void (*function)(void) )
|
||||
{
|
||||
onMqttDisconnectedCb = function;
|
||||
}
|
||||
|
||||
void MQTT::onPublished( void (*function)(void) )
|
||||
{
|
||||
onMqttPublishedCb = function;
|
||||
}
|
||||
|
||||
void MQTT::onData( void (*function)(String&, String&) )
|
||||
{
|
||||
onMqttDataCb = function;
|
||||
}
|
||||
|
||||
void MQTT::onData( void (*function)(const char*, uint32_t, const char*, uint32_t) )
|
||||
{
|
||||
onMqttDataRawCb = function;
|
||||
}
|
||||
|
||||
|
||||
// internal callback, calling user CB
|
||||
void MQTT::_onMqttDataCb(const char* topic, uint32_t topic_len, const char* buf, uint32_t buf_len)
|
||||
{
|
||||
if (onMqttDataRawCb) {
|
||||
onMqttDataRawCb(topic, topic_len, buf, buf_len);
|
||||
}
|
||||
|
||||
if (onMqttDataCb) {
|
||||
|
||||
char* topicCpy = (char*)malloc(topic_len+1);
|
||||
memcpy(topicCpy, topic, topic_len);
|
||||
topicCpy[topic_len] = 0;
|
||||
// string it
|
||||
String topicStr(topicCpy);
|
||||
|
||||
char* bufCpy = (char*)malloc(buf_len+1);
|
||||
memcpy(bufCpy, buf, buf_len);
|
||||
bufCpy[buf_len] = 0;
|
||||
// string it
|
||||
String bufStr(bufCpy);
|
||||
|
||||
onMqttDataCb(topicStr, bufStr);
|
||||
|
||||
free(topicCpy);
|
||||
free(bufCpy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*//-------------------------------------------------------------------------------
|
||||
* MQTT.h
|
||||
*
|
||||
* Header file for MQTT Wrapper
|
||||
*
|
||||
* Wrapper for Arduino written by Ingo Randolf during
|
||||
* eTextiles Summercamp 2015.
|
||||
*
|
||||
* This library is intended to be used with esp8266 modules.
|
||||
*
|
||||
*
|
||||
* This class wraps a slightly modified version of mqtt
|
||||
* for esp8266 written by Tuan PM.
|
||||
* Original code: https://github.com/tuanpmt/esp_mqtt
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
//-------------------------------------------------------------------------------*/
|
||||
#ifndef MQTT_WRAPPER_H
|
||||
#define MQTT_WRAPPER_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include <stddef.h>
|
||||
#include "mqtt/mqtt.h"
|
||||
}
|
||||
|
||||
class MQTT
|
||||
{
|
||||
public:
|
||||
// MQTT(const char* client_id, const char* host, uint32_t port);
|
||||
MQTT(const char* client_id, const char* host, uint32_t port, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
||||
|
||||
~MQTT();
|
||||
|
||||
void setClientId(const char* client_id);
|
||||
void setUserPwd(const char* user, const char* pwd);
|
||||
|
||||
void connect();
|
||||
void disconnect();
|
||||
bool isConnected();
|
||||
|
||||
bool publish(const char* topic, const char* buf, uint32_t buf_len, int qos = 0, int retain = 0);
|
||||
bool publish(String& topic, String& data, int qos = 0, int retain = 0);
|
||||
bool publish(String& topic, const char* buf, uint32_t buf_len, int qos = 0, int retain = 0);
|
||||
bool publish(const char* topic, String& data, int qos = 0, int retain = 0);
|
||||
|
||||
bool subscribe(const char* topic, uint8_t qos = 0);
|
||||
bool subscribe(const String& topic, uint8_t qos = 0);
|
||||
|
||||
int getState() { return mqttClient.connState; };
|
||||
|
||||
// set callbacks
|
||||
void onConnected( void (*)(void) );
|
||||
void onDisconnected( void (*)(void) );
|
||||
void onPublished( void (*)(void) );
|
||||
void onData( void (*)(String&, String&) );
|
||||
void onData( void (*)(const char*, uint32_t, const char*, uint32_t) );
|
||||
|
||||
// user callbacks
|
||||
void (*onMqttConnectedCb)(void);
|
||||
void (*onMqttDisconnectedCb)(void);
|
||||
void (*onMqttPublishedCb)(void);
|
||||
void (*onMqttDataCb) (String&, String&);
|
||||
void (*onMqttDataRawCb) (const char*, uint32_t, const char*, uint32_t);
|
||||
|
||||
// internal callback
|
||||
void _onMqttDataCb(const char*, uint32_t, const char*, uint32_t);
|
||||
|
||||
private:
|
||||
MQTT_Client mqttClient;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* debug.h
|
||||
*
|
||||
* Created on: Dec 4, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
|
||||
#ifndef USER_DEBUG_H_
|
||||
#define USER_DEBUG_H_
|
||||
|
||||
|
||||
#if defined(MQTT_DEBUG_ON)
|
||||
#define MQTT_INFO( format, ... ) os_printf( format, ## __VA_ARGS__ )
|
||||
#else
|
||||
#define MQTT_INFO( format, ... )
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* USER_DEBUG_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,152 +0,0 @@
|
||||
/* mqtt.h
|
||||
*
|
||||
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef USER_AT_MQTT_H_
|
||||
#define USER_AT_MQTT_H_
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_msg.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
#include "queue.h"
|
||||
typedef struct mqtt_event_data_t
|
||||
{
|
||||
uint8_t type;
|
||||
const char* topic;
|
||||
const char* data;
|
||||
uint16_t topic_length;
|
||||
uint16_t data_length;
|
||||
uint16_t data_offset;
|
||||
} mqtt_event_data_t;
|
||||
|
||||
typedef struct mqtt_state_t
|
||||
{
|
||||
uint16_t port;
|
||||
int auto_reconnect;
|
||||
mqtt_connect_info_t* connect_info;
|
||||
uint8_t* in_buffer;
|
||||
uint8_t* out_buffer;
|
||||
int in_buffer_length;
|
||||
int out_buffer_length;
|
||||
uint16_t message_length;
|
||||
uint16_t message_length_read;
|
||||
mqtt_message_t* outbound_message;
|
||||
mqtt_connection_t mqtt_connection;
|
||||
uint16_t pending_msg_id;
|
||||
int pending_msg_type;
|
||||
int pending_publish_qos;
|
||||
} mqtt_state_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_INIT,
|
||||
WIFI_CONNECTING,
|
||||
WIFI_CONNECTING_ERROR,
|
||||
WIFI_CONNECTED,
|
||||
DNS_RESOLVE,
|
||||
TCP_DISCONNECTING,
|
||||
TCP_DISCONNECTED,
|
||||
TCP_RECONNECT_DISCONNECTING,
|
||||
TCP_RECONNECT_REQ,
|
||||
TCP_RECONNECT,
|
||||
TCP_CONNECTING,
|
||||
TCP_CONNECTING_ERROR,
|
||||
TCP_CONNECTED,
|
||||
MQTT_CONNECT_SEND,
|
||||
MQTT_CONNECT_SENDING,
|
||||
MQTT_SUBSCIBE_SEND,
|
||||
MQTT_SUBSCIBE_SENDING,
|
||||
MQTT_DATA,
|
||||
MQTT_KEEPALIVE_SEND,
|
||||
MQTT_PUBLISH_RECV,
|
||||
MQTT_PUBLISHING,
|
||||
MQTT_DELETING,
|
||||
MQTT_DELETED,
|
||||
} tConnState;
|
||||
|
||||
typedef void (*MqttCallback)(uint32_t *args);
|
||||
typedef void (*MqttDataCallback)(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh);
|
||||
|
||||
typedef struct {
|
||||
struct espconn *pCon;
|
||||
uint8_t security;
|
||||
uint8_t* host;
|
||||
uint32_t port;
|
||||
ip_addr_t ip;
|
||||
mqtt_state_t mqtt_state;
|
||||
mqtt_connect_info_t connect_info;
|
||||
MqttCallback connectedCb;
|
||||
MqttCallback disconnectedCb;
|
||||
MqttCallback publishedCb;
|
||||
MqttCallback timeoutCb;
|
||||
MqttDataCallback dataCb;
|
||||
ETSTimer mqttTimer;
|
||||
uint32_t keepAliveTick;
|
||||
uint32_t reconnectTick;
|
||||
uint32_t sendTimeout;
|
||||
tConnState connState;
|
||||
QUEUE msgQueue;
|
||||
void* user_data;
|
||||
} MQTT_Client;
|
||||
|
||||
#define SEC_NONSSL 0
|
||||
#define SEC_SSL 1
|
||||
|
||||
#define MQTT_FLAG_CONNECTED 1
|
||||
#define MQTT_FLAG_READY 2
|
||||
#define MQTT_FLAG_EXIT 4
|
||||
|
||||
#define MQTT_EVENT_TYPE_NONE 0
|
||||
#define MQTT_EVENT_TYPE_CONNECTED 1
|
||||
#define MQTT_EVENT_TYPE_DISCONNECTED 2
|
||||
#define MQTT_EVENT_TYPE_SUBSCRIBED 3
|
||||
#define MQTT_EVENT_TYPE_UNSUBSCRIBED 4
|
||||
#define MQTT_EVENT_TYPE_PUBLISH 5
|
||||
#define MQTT_EVENT_TYPE_PUBLISHED 6
|
||||
#define MQTT_EVENT_TYPE_EXITED 7
|
||||
#define MQTT_EVENT_TYPE_PUBLISH_CONTINUATION 8
|
||||
|
||||
void ICACHE_FLASH_ATTR MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32_t port, uint8_t security);
|
||||
bool ICACHE_FLASH_ATTR MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime, uint8_t cleanSession);
|
||||
void ICACHE_FLASH_ATTR MQTT_DeleteClient(MQTT_Client *mqttClient);
|
||||
void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain);
|
||||
|
||||
void ICACHE_FLASH_ATTR MQTT_SetUserId(MQTT_Client *mqttClient, const char* client_id);
|
||||
void ICACHE_FLASH_ATTR MQTT_SetUserPwd(MQTT_Client *mqttClient, const char* user_id, const char* pwd);
|
||||
|
||||
void ICACHE_FLASH_ATTR MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb);
|
||||
void ICACHE_FLASH_ATTR MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb);
|
||||
void ICACHE_FLASH_ATTR MQTT_OnPublished(MQTT_Client *mqttClient, MqttCallback publishedCb);
|
||||
void ICACHE_FLASH_ATTR MQTT_OnTimeout(MQTT_Client *mqttClient, MqttCallback timeoutCb);
|
||||
void ICACHE_FLASH_ATTR MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb);
|
||||
bool ICACHE_FLASH_ATTR MQTT_Subscribe(MQTT_Client *client, char* topic, uint8_t qos);
|
||||
bool ICACHE_FLASH_ATTR MQTT_UnSubscribe(MQTT_Client *client, char* topic);
|
||||
void ICACHE_FLASH_ATTR MQTT_Connect(MQTT_Client *mqttClient);
|
||||
void ICACHE_FLASH_ATTR MQTT_Disconnect(MQTT_Client *mqttClient);
|
||||
bool ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain);
|
||||
|
||||
#endif /* USER_AT_MQTT_H_ */
|
@ -1,19 +0,0 @@
|
||||
#ifndef __MQTT_CONFIG_H__
|
||||
#define __MQTT_CONFIG_H__
|
||||
|
||||
//#define MQTT_SSL_ENABLE
|
||||
|
||||
/*DEFAULT CONFIGURATIONS*/
|
||||
|
||||
#define MQTT_BUF_SIZE 1024
|
||||
//#define MQTT_KEEPALIVE 120 /*second*/
|
||||
#define MQTT_KEEPALIVE 15 /*second*/
|
||||
|
||||
#define MQTT_RECONNECT_TIMEOUT 5 /*second*/
|
||||
|
||||
#define QUEUE_BUFFER_SIZE 2048
|
||||
|
||||
//#define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*/
|
||||
#define PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/
|
||||
|
||||
#endif // __MQTT_CONFIG_H__
|
@ -1,487 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "mqtt_msg.h"
|
||||
#include "mqtt_config.h"
|
||||
#define MQTT_MAX_FIXED_HEADER_SIZE 3
|
||||
|
||||
enum mqtt_connect_flag
|
||||
{
|
||||
MQTT_CONNECT_FLAG_USERNAME = 1 << 7,
|
||||
MQTT_CONNECT_FLAG_PASSWORD = 1 << 6,
|
||||
MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5,
|
||||
MQTT_CONNECT_FLAG_WILL = 1 << 2,
|
||||
MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1
|
||||
};
|
||||
|
||||
struct __attribute((__packed__)) mqtt_connect_variable_header
|
||||
{
|
||||
uint8_t lengthMsb;
|
||||
uint8_t lengthLsb;
|
||||
#if defined(PROTOCOL_NAMEv31)
|
||||
uint8_t magic[6];
|
||||
#elif defined(PROTOCOL_NAMEv311)
|
||||
uint8_t magic[4];
|
||||
#else
|
||||
#error "Please define protocol name"
|
||||
#endif
|
||||
uint8_t version;
|
||||
uint8_t flags;
|
||||
uint8_t keepaliveMsb;
|
||||
uint8_t keepaliveLsb;
|
||||
};
|
||||
|
||||
static int ICACHE_FLASH_ATTR append_string(mqtt_connection_t* connection, const char* string, int len)
|
||||
{
|
||||
if (connection->message.length + len + 2 > connection->buffer_length)
|
||||
return -1;
|
||||
|
||||
connection->buffer[connection->message.length++] = len >> 8;
|
||||
connection->buffer[connection->message.length++] = len & 0xff;
|
||||
memcpy(connection->buffer + connection->message.length, string, len);
|
||||
connection->message.length += len;
|
||||
|
||||
return len + 2;
|
||||
}
|
||||
|
||||
static uint16_t ICACHE_FLASH_ATTR append_message_id(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
// If message_id is zero then we should assign one, otherwise
|
||||
// we'll use the one supplied by the caller
|
||||
while (message_id == 0)
|
||||
message_id = ++connection->message_id;
|
||||
|
||||
if (connection->message.length + 2 > connection->buffer_length)
|
||||
return 0;
|
||||
|
||||
connection->buffer[connection->message.length++] = message_id >> 8;
|
||||
connection->buffer[connection->message.length++] = message_id & 0xff;
|
||||
|
||||
return message_id;
|
||||
}
|
||||
|
||||
static int ICACHE_FLASH_ATTR init_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
return MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
}
|
||||
|
||||
static mqtt_message_t* ICACHE_FLASH_ATTR fail_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.data = connection->buffer;
|
||||
connection->message.length = 0;
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
static mqtt_message_t* ICACHE_FLASH_ATTR fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain)
|
||||
{
|
||||
int remaining_length = connection->message.length - MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
|
||||
if (remaining_length > 127)
|
||||
{
|
||||
connection->buffer[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[1] = 0x80 | (remaining_length % 128);
|
||||
connection->buffer[2] = remaining_length / 128;
|
||||
connection->message.length = remaining_length + 3;
|
||||
connection->message.data = connection->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[2] = remaining_length;
|
||||
connection->message.length = remaining_length + 2;
|
||||
connection->message.data = connection->buffer + 1;
|
||||
}
|
||||
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length)
|
||||
{
|
||||
memset(connection, 0, sizeof(mqtt_connection_t));
|
||||
connection->buffer = buffer;
|
||||
connection->buffer_length = buffer_length;
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
|
||||
for (i = 1; i < length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if ((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
|
||||
for (i = 1; i < *length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if ((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if (i + 2 >= *length)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if (i + topiclen > *length)
|
||||
return NULL;
|
||||
|
||||
*length = topiclen;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
int blength = *length;
|
||||
*length = 0;
|
||||
|
||||
for (i = 1; i < blength; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if ((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if (i + 2 >= blength)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if (i + topiclen >= blength)
|
||||
return NULL;
|
||||
|
||||
i += topiclen;
|
||||
|
||||
if (mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if (i + 2 >= blength)
|
||||
return NULL;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if (totlen < i)
|
||||
return NULL;
|
||||
|
||||
if (totlen <= blength)
|
||||
*length = totlen - i;
|
||||
else
|
||||
*length = blength - i;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
if (length < 1)
|
||||
return 0;
|
||||
|
||||
switch (mqtt_get_type(buffer))
|
||||
{
|
||||
case MQTT_MSG_TYPE_PUBLISH:
|
||||
{
|
||||
int i;
|
||||
int topiclen;
|
||||
|
||||
for (i = 1; i < length; ++i)
|
||||
{
|
||||
if ((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i + 2 >= length)
|
||||
return 0;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if (i + topiclen >= length)
|
||||
return 0;
|
||||
i += topiclen;
|
||||
|
||||
if (mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if (i + 2 >= length)
|
||||
return 0;
|
||||
//i += 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (buffer[i] << 8) | buffer[i + 1];
|
||||
}
|
||||
case MQTT_MSG_TYPE_PUBACK:
|
||||
case MQTT_MSG_TYPE_PUBREC:
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
case MQTT_MSG_TYPE_PUBCOMP:
|
||||
case MQTT_MSG_TYPE_SUBACK:
|
||||
case MQTT_MSG_TYPE_UNSUBACK:
|
||||
case MQTT_MSG_TYPE_SUBSCRIBE:
|
||||
{
|
||||
// This requires the remaining length to be encoded in 1 byte,
|
||||
// which it should be.
|
||||
if (length >= 4 && (buffer[1] & 0x80) == 0)
|
||||
return (buffer[2] << 8) | buffer[3];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info)
|
||||
{
|
||||
struct mqtt_connect_variable_header* variable_header;
|
||||
|
||||
init_message(connection);
|
||||
|
||||
if (connection->message.length + sizeof(*variable_header) > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
variable_header = (void*)(connection->buffer + connection->message.length);
|
||||
connection->message.length += sizeof(*variable_header);
|
||||
|
||||
variable_header->lengthMsb = 0;
|
||||
#if defined(PROTOCOL_NAMEv31)
|
||||
variable_header->lengthLsb = 6;
|
||||
memcpy(variable_header->magic, "MQIsdp", 6);
|
||||
variable_header->version = 3;
|
||||
#elif defined(PROTOCOL_NAMEv311)
|
||||
variable_header->lengthLsb = 4;
|
||||
memcpy(variable_header->magic, "MQTT", 4);
|
||||
variable_header->version = 4;
|
||||
#else
|
||||
#error "Please define protocol name"
|
||||
#endif
|
||||
|
||||
variable_header->flags = 0;
|
||||
variable_header->keepaliveMsb = info->keepalive >> 8;
|
||||
variable_header->keepaliveLsb = info->keepalive & 0xff;
|
||||
|
||||
if (info->clean_session)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
|
||||
|
||||
if (info->client_id == NULL)
|
||||
{
|
||||
/* Never allowed */
|
||||
return fail_message(connection);
|
||||
}
|
||||
else if (info->client_id[0] == '\0')
|
||||
{
|
||||
#ifdef PROTOCOL_NAMEv311
|
||||
/* Allowed. Format 0 Length ID */
|
||||
append_string(connection, info->client_id, 2) ;
|
||||
#else
|
||||
/* 0 Length not allowed */
|
||||
return fail_message(connection);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No 0 data and at least 1 long. Good to go. */
|
||||
if(append_string(connection, info->client_id, strlen(info->client_id)) < 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
if (info->will_topic != NULL && info->will_topic[0] != '\0')
|
||||
{
|
||||
if (append_string(connection, info->will_topic, strlen(info->will_topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if (append_string(connection, info->will_message, strlen(info->will_message)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL;
|
||||
if (info->will_retain)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
|
||||
variable_header->flags |= (info->will_qos & 3) << 3;
|
||||
}
|
||||
|
||||
if (info->username != NULL && info->username[0] != '\0')
|
||||
{
|
||||
if (append_string(connection, info->username, strlen(info->username)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME;
|
||||
}
|
||||
|
||||
if (info->password != NULL && info->password[0] != '\0')
|
||||
{
|
||||
if (append_string(connection, info->password, strlen(info->password)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_PASSWORD;
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if (topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if (append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if (qos > 0)
|
||||
{
|
||||
if ((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
else
|
||||
*message_id = 0;
|
||||
|
||||
if (connection->message.length + data_length > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
memcpy(connection->buffer + connection->message.length, data, data_length);
|
||||
connection->message.length += data_length;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if (append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if (append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if (append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if (append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if (topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if ((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if (append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if (connection->message.length + 1 > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
connection->buffer[connection->message.length++] = qos;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if (topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if ((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if (append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0);
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* File: mqtt_msg.h
|
||||
* Author: Minh Tuan
|
||||
*
|
||||
* Created on July 12, 2014, 1:05 PM
|
||||
*/
|
||||
|
||||
#ifndef MQTT_MSG_H
|
||||
#define MQTT_MSG_H
|
||||
#include "user_config.h"
|
||||
#include "c_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/* 7 6 5 4 3 2 1 0*/
|
||||
/*| --- Message Type---- | DUP Flag | QoS Level | Retain |
|
||||
/* Remaining Length */
|
||||
|
||||
|
||||
enum mqtt_message_type
|
||||
{
|
||||
MQTT_MSG_TYPE_CONNECT = 1,
|
||||
MQTT_MSG_TYPE_CONNACK = 2,
|
||||
MQTT_MSG_TYPE_PUBLISH = 3,
|
||||
MQTT_MSG_TYPE_PUBACK = 4,
|
||||
MQTT_MSG_TYPE_PUBREC = 5,
|
||||
MQTT_MSG_TYPE_PUBREL = 6,
|
||||
MQTT_MSG_TYPE_PUBCOMP = 7,
|
||||
MQTT_MSG_TYPE_SUBSCRIBE = 8,
|
||||
MQTT_MSG_TYPE_SUBACK = 9,
|
||||
MQTT_MSG_TYPE_UNSUBSCRIBE = 10,
|
||||
MQTT_MSG_TYPE_UNSUBACK = 11,
|
||||
MQTT_MSG_TYPE_PINGREQ = 12,
|
||||
MQTT_MSG_TYPE_PINGRESP = 13,
|
||||
MQTT_MSG_TYPE_DISCONNECT = 14
|
||||
};
|
||||
|
||||
enum mqtt_connect_return_code
|
||||
{
|
||||
CONNECTION_ACCEPTED = 0,
|
||||
CONNECTION_REFUSE_PROTOCOL,
|
||||
CONNECTION_REFUSE_ID_REJECTED,
|
||||
CONNECTION_REFUSE_SERVER_UNAVAILABLE,
|
||||
CONNECTION_REFUSE_BAD_USERNAME,
|
||||
CONNECTION_REFUSE_NOT_AUTHORIZED
|
||||
};
|
||||
|
||||
typedef struct mqtt_message
|
||||
{
|
||||
uint8_t* data;
|
||||
uint16_t length;
|
||||
|
||||
} mqtt_message_t;
|
||||
|
||||
typedef struct mqtt_connection
|
||||
{
|
||||
mqtt_message_t message;
|
||||
|
||||
uint16_t message_id;
|
||||
uint8_t* buffer;
|
||||
uint16_t buffer_length;
|
||||
|
||||
} mqtt_connection_t;
|
||||
|
||||
typedef struct mqtt_connect_info
|
||||
{
|
||||
char* client_id;
|
||||
char* username;
|
||||
char* password;
|
||||
char* will_topic;
|
||||
char* will_message;
|
||||
uint32_t keepalive;
|
||||
int will_qos;
|
||||
int will_retain;
|
||||
int clean_session;
|
||||
|
||||
} mqtt_connect_info_t;
|
||||
|
||||
|
||||
static inline int ICACHE_FLASH_ATTR mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; }
|
||||
static inline int ICACHE_FLASH_ATTR mqtt_get_connect_return_code(uint8_t* buffer) { return buffer[3]; }
|
||||
static inline int ICACHE_FLASH_ATTR mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; }
|
||||
static inline int ICACHE_FLASH_ATTR mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; }
|
||||
static inline int ICACHE_FLASH_ATTR mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); }
|
||||
|
||||
void ICACHE_FLASH_ATTR mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length);
|
||||
int ICACHE_FLASH_ATTR mqtt_get_total_length(uint8_t* buffer, uint16_t length);
|
||||
const char* ICACHE_FLASH_ATTR mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length);
|
||||
const char* ICACHE_FLASH_ATTR mqtt_get_publish_data(uint8_t* buffer, uint16_t* length);
|
||||
uint16_t ICACHE_FLASH_ATTR mqtt_get_id(uint8_t* buffer, uint16_t length);
|
||||
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingreq(mqtt_connection_t* connection);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_pingresp(mqtt_connection_t* connection);
|
||||
mqtt_message_t* ICACHE_FLASH_ATTR mqtt_msg_disconnect(mqtt_connection_t* connection);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MQTT_MSG_H */
|
||||
|
@ -1,129 +0,0 @@
|
||||
#include "proto.h"
|
||||
#include "ringbuf.h"
|
||||
I8 ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, U8 *buf, U16 bufSize)
|
||||
{
|
||||
parser->buf = buf;
|
||||
parser->bufSize = bufSize;
|
||||
parser->dataLen = 0;
|
||||
parser->callback = completeCallback;
|
||||
parser->isEsc = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
I8 ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, U8 value)
|
||||
{
|
||||
switch (value) {
|
||||
case 0x7D:
|
||||
parser->isEsc = 1;
|
||||
break;
|
||||
|
||||
case 0x7E:
|
||||
parser->dataLen = 0;
|
||||
parser->isEsc = 0;
|
||||
parser->isBegin = 1;
|
||||
break;
|
||||
|
||||
case 0x7F:
|
||||
if (parser->callback != NULL)
|
||||
parser->callback();
|
||||
parser->isBegin = 0;
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (parser->isBegin == 0) break;
|
||||
|
||||
if (parser->isEsc) {
|
||||
value ^= 0x20;
|
||||
parser->isEsc = 0;
|
||||
}
|
||||
|
||||
if (parser->dataLen < parser->bufSize)
|
||||
parser->buf[parser->dataLen++] = value;
|
||||
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
I8 ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, U8 *buf, U16 len)
|
||||
{
|
||||
while (len--)
|
||||
PROTO_ParseByte(parser, *buf++);
|
||||
|
||||
return 0;
|
||||
}
|
||||
I16 ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF* rb, U8 *bufOut, U16* len, U16 maxBufLen)
|
||||
{
|
||||
U8 c;
|
||||
|
||||
PROTO_PARSER proto;
|
||||
PROTO_Init(&proto, NULL, bufOut, maxBufLen);
|
||||
while (RINGBUF_Get(rb, &c) == 0) {
|
||||
if (PROTO_ParseByte(&proto, c) == 0) {
|
||||
*len = proto.dataLen;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
I16 ICACHE_FLASH_ATTR PROTO_Add(U8 *buf, const U8 *packet, I16 bufSize)
|
||||
{
|
||||
U16 i = 2;
|
||||
U16 len = *(U16*) packet;
|
||||
|
||||
if (bufSize < 1) return -1;
|
||||
|
||||
*buf++ = 0x7E;
|
||||
bufSize--;
|
||||
|
||||
while (len--) {
|
||||
switch (*packet) {
|
||||
case 0x7D:
|
||||
case 0x7E:
|
||||
case 0x7F:
|
||||
if (bufSize < 2) return -1;
|
||||
*buf++ = 0x7D;
|
||||
*buf++ = *packet++ ^ 0x20;
|
||||
i += 2;
|
||||
bufSize -= 2;
|
||||
break;
|
||||
default:
|
||||
if (bufSize < 1) return -1;
|
||||
*buf++ = *packet++;
|
||||
i++;
|
||||
bufSize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bufSize < 1) return -1;
|
||||
*buf++ = 0x7F;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len)
|
||||
{
|
||||
U16 i = 2;
|
||||
if (RINGBUF_Put(rb, 0x7E) == -1) return -1;
|
||||
while (len--) {
|
||||
switch (*packet) {
|
||||
case 0x7D:
|
||||
case 0x7E:
|
||||
case 0x7F:
|
||||
if (RINGBUF_Put(rb, 0x7D) == -1) return -1;
|
||||
if (RINGBUF_Put(rb, *packet++ ^ 0x20) == -1) return -1;
|
||||
i += 2;
|
||||
break;
|
||||
default:
|
||||
if (RINGBUF_Put(rb, *packet++) == -1) return -1;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (RINGBUF_Put(rb, 0x7F) == -1) return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* File: proto.h
|
||||
* Author: ThuHien
|
||||
*
|
||||
* Created on November 23, 2012, 8:57 AM
|
||||
*/
|
||||
|
||||
#ifndef _PROTO_H_
|
||||
#define _PROTO_H_
|
||||
#include <stdlib.h>
|
||||
#include "typedef.h"
|
||||
#include "ringbuf.h"
|
||||
|
||||
typedef void(PROTO_PARSE_CALLBACK)();
|
||||
|
||||
typedef struct {
|
||||
U8 *buf;
|
||||
U16 bufSize;
|
||||
U16 dataLen;
|
||||
U8 isEsc;
|
||||
U8 isBegin;
|
||||
PROTO_PARSE_CALLBACK* callback;
|
||||
} PROTO_PARSER;
|
||||
|
||||
I8 ICACHE_FLASH_ATTR PROTO_Init(PROTO_PARSER *parser, PROTO_PARSE_CALLBACK *completeCallback, U8 *buf, U16 bufSize);
|
||||
I8 ICACHE_FLASH_ATTR PROTO_Parse(PROTO_PARSER *parser, U8 *buf, U16 len);
|
||||
I16 ICACHE_FLASH_ATTR PROTO_Add(U8 *buf, const U8 *packet, I16 bufSize);
|
||||
I16 ICACHE_FLASH_ATTR PROTO_AddRb(RINGBUF *rb, const U8 *packet, I16 len);
|
||||
I8 ICACHE_FLASH_ATTR PROTO_ParseByte(PROTO_PARSER *parser, U8 value);
|
||||
I16 ICACHE_FLASH_ATTR PROTO_ParseRb(RINGBUF *rb, U8 *bufOut, U16* len, U16 maxBufLen);
|
||||
#endif
|
||||
|
@ -1,75 +0,0 @@
|
||||
/* str_queue.c
|
||||
*
|
||||
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "queue.h"
|
||||
|
||||
#include "user_interface.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
#include "proto.h"
|
||||
|
||||
uint8_t *last_rb_p_r;
|
||||
uint8_t *last_rb_p_w;
|
||||
uint32_t last_fill_cnt;
|
||||
|
||||
void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize)
|
||||
{
|
||||
queue->buf = (uint8_t*)os_zalloc(bufferSize);
|
||||
RINGBUF_Init(&queue->rb, queue->buf, bufferSize);
|
||||
}
|
||||
int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
last_rb_p_r = queue->rb.p_r;
|
||||
last_rb_p_w = queue->rb.p_w;
|
||||
last_fill_cnt = queue->rb.fill_cnt;
|
||||
|
||||
ret = PROTO_AddRb(&queue->rb, buffer, len);
|
||||
if (ret == -1) {
|
||||
// rolling ring buffer back
|
||||
queue->rb.p_r = last_rb_p_r;
|
||||
queue->rb.p_w = last_rb_p_w;
|
||||
queue->rb.fill_cnt = last_fill_cnt;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen)
|
||||
{
|
||||
|
||||
return PROTO_ParseRb(&queue->rb, buffer, len, maxLen);
|
||||
}
|
||||
|
||||
BOOL ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue)
|
||||
{
|
||||
if (queue->rb.fill_cnt <= 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/* str_queue.h --
|
||||
*
|
||||
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef USER_QUEUE_H_
|
||||
#define USER_QUEUE_H_
|
||||
#include "os_type.h"
|
||||
#include "ringbuf.h"
|
||||
typedef struct {
|
||||
uint8_t *buf;
|
||||
RINGBUF rb;
|
||||
} QUEUE;
|
||||
|
||||
void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize);
|
||||
int32_t ICACHE_FLASH_ATTR QUEUE_Puts(QUEUE *queue, uint8_t* buffer, uint16_t len);
|
||||
int32_t ICACHE_FLASH_ATTR QUEUE_Gets(QUEUE *queue, uint8_t* buffer, uint16_t* len, uint16_t maxLen);
|
||||
bool ICACHE_FLASH_ATTR QUEUE_IsEmpty(QUEUE *queue);
|
||||
#endif /* USER_QUEUE_H_ */
|
@ -1,67 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
* Ring Buffer library
|
||||
*/
|
||||
|
||||
#include "ringbuf.h"
|
||||
|
||||
|
||||
/**
|
||||
* \brief init a RINGBUF object
|
||||
* \param r pointer to a RINGBUF object
|
||||
* \param buf pointer to a byte array
|
||||
* \param size size of buf
|
||||
* \return 0 if successfull, otherwise failed
|
||||
*/
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size)
|
||||
{
|
||||
if (r == NULL || buf == NULL || size < 2) return -1;
|
||||
|
||||
r->p_o = r->p_r = r->p_w = buf;
|
||||
r->fill_cnt = 0;
|
||||
r->size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* \brief put a character into ring buffer
|
||||
* \param r pointer to a ringbuf object
|
||||
* \param c character to be put
|
||||
* \return 0 if successfull, otherwise failed
|
||||
*/
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c)
|
||||
{
|
||||
if (r->fill_cnt >= r->size)return -1; // ring buffer is full, this should be atomic operation
|
||||
|
||||
|
||||
r->fill_cnt++; // increase filled slots count, this should be atomic operation
|
||||
|
||||
|
||||
*r->p_w++ = c; // put character into buffer
|
||||
|
||||
if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass
|
||||
r->p_w = r->p_o; // the physical boundary
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* \brief get a character from ring buffer
|
||||
* \param r pointer to a ringbuf object
|
||||
* \param c read character
|
||||
* \return 0 if successfull, otherwise failed
|
||||
*/
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c)
|
||||
{
|
||||
if (r->fill_cnt <= 0)return -1; // ring buffer is empty, this should be atomic operation
|
||||
|
||||
|
||||
r->fill_cnt--; // decrease filled slots count
|
||||
|
||||
|
||||
*c = *r->p_r++; // get the character out
|
||||
|
||||
if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass
|
||||
r->p_r = r->p_o; // the physical boundary
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#ifndef _RING_BUF_H_
|
||||
#define _RING_BUF_H_
|
||||
|
||||
#include <os_type.h>
|
||||
#include <stdlib.h>
|
||||
#include "typedef.h"
|
||||
|
||||
typedef struct {
|
||||
U8* p_o; /**< Original pointer */
|
||||
U8* volatile p_r; /**< Read pointer */
|
||||
U8* volatile p_w; /**< Write pointer */
|
||||
volatile I32 fill_cnt; /**< Number of filled slots */
|
||||
I32 size; /**< Buffer size */
|
||||
} RINGBUF;
|
||||
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Init(RINGBUF *r, U8* buf, I32 size);
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Put(RINGBUF *r, U8 c);
|
||||
I16 ICACHE_FLASH_ATTR RINGBUF_Get(RINGBUF *r, U8* c);
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
/**
|
||||
* \file
|
||||
* Standard Types definition
|
||||
*/
|
||||
|
||||
#ifndef _TYPE_DEF_H_
|
||||
#define _TYPE_DEF_H_
|
||||
|
||||
typedef char I8;
|
||||
typedef unsigned char U8;
|
||||
typedef short I16;
|
||||
typedef unsigned short U16;
|
||||
typedef long I32;
|
||||
typedef unsigned long U32;
|
||||
typedef unsigned long long U64;
|
||||
|
||||
#endif
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Tuan PM
|
||||
* Email: tuanpm@live.com
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str)
|
||||
{
|
||||
uint8_t segs = 0; /* Segment count. */
|
||||
uint8_t chcnt = 0; /* Character count within segment. */
|
||||
uint8_t accum = 0; /* Accumulator for segment. */
|
||||
/* Catch NULL pointer. */
|
||||
if (str == 0)
|
||||
return 0;
|
||||
/* Process every character in string. */
|
||||
|
||||
while (*str != '\0') {
|
||||
/* Segment changeover. */
|
||||
|
||||
if (*str == '.') {
|
||||
/* Must have some digits in segment. */
|
||||
if (chcnt == 0)
|
||||
return 0;
|
||||
/* Limit number of segments. */
|
||||
if (++segs == 4)
|
||||
return 0;
|
||||
/* Reset segment values and restart loop. */
|
||||
chcnt = accum = 0;
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check numeric. */
|
||||
if ((*str < '0') || (*str > '9'))
|
||||
return 0;
|
||||
|
||||
/* Accumulate and check segment. */
|
||||
|
||||
if ((accum = accum * 10 + *str - '0') > 255)
|
||||
return 0;
|
||||
/* Advance other segment specific stuff and continue loop. */
|
||||
|
||||
chcnt++;
|
||||
str++;
|
||||
}
|
||||
|
||||
/* Check enough segments and enough characters in last segment. */
|
||||
|
||||
if (segs != 3)
|
||||
return 0;
|
||||
if (chcnt == 0)
|
||||
return 0;
|
||||
/* Address okay. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip)
|
||||
{
|
||||
|
||||
/* The count of the number of bytes processed. */
|
||||
int i;
|
||||
/* A pointer to the next digit to process. */
|
||||
const char * start;
|
||||
|
||||
start = str;
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* The digit being processed. */
|
||||
char c;
|
||||
/* The value of this byte. */
|
||||
int n = 0;
|
||||
while (1) {
|
||||
c = * start;
|
||||
start++;
|
||||
if (c >= '0' && c <= '9') {
|
||||
n *= 10;
|
||||
n += c - '0';
|
||||
}
|
||||
/* We insist on stopping at "." if we are still parsing
|
||||
the first, second, or third numbers. If we have reached
|
||||
the end of the numbers, we will allow any character. */
|
||||
else if ((i < 3 && c == '.') || i == 3) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (n >= 256) {
|
||||
return 0;
|
||||
}
|
||||
((uint8_t*)ip)[i] = n;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s)
|
||||
{
|
||||
uint32_t value = 0, digit;
|
||||
int8_t c;
|
||||
|
||||
while ((c = *s++)) {
|
||||
if ('0' <= c && c <= '9')
|
||||
digit = c - '0';
|
||||
else if ('A' <= c && c <= 'F')
|
||||
digit = c - 'A' + 10;
|
||||
else if ('a' <= c && c <= 'f')
|
||||
digit = c - 'a' + 10;
|
||||
else break;
|
||||
|
||||
value = (value << 4) | digit;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
uint32_t ICACHE_FLASH_ATTR UTILS_Atoh(const int8_t *s);
|
||||
uint8_t ICACHE_FLASH_ATTR UTILS_StrToIP(const int8_t* str, void *ip);
|
||||
uint8_t ICACHE_FLASH_ATTR UTILS_IsIPV4 (int8_t *str);
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user