MQTT support in lvgl simulator
This commit is contained in:
parent
73caf51198
commit
665b6908e1
29 changed files with 4673 additions and 52 deletions
|
@ -52,6 +52,6 @@ jobs:
|
|||
working-directory: ./Platformio
|
||||
run: pio run -e esp32
|
||||
|
||||
- name: Build PlatformIO env:windows_linux_64bit
|
||||
- name: Build PlatformIO env:linux_64bit
|
||||
working-directory: ./Platformio
|
||||
run: pio run -e windows_linux_64bit
|
||||
run: pio run -e linux_64bit
|
||||
|
|
|
@ -52,12 +52,12 @@ jobs:
|
|||
working-directory: ./Platformio
|
||||
run: pio run -e esp32
|
||||
|
||||
- name: Build PlatformIO env:windows_linux_64bit
|
||||
- name: Build PlatformIO env:windows_64bit
|
||||
if: ${{matrix.sys == 'mingw64'}}
|
||||
working-directory: ./Platformio
|
||||
run: pio run -e windows_linux_64bit
|
||||
run: pio run -e windows_64bit
|
||||
|
||||
- name: Build PlatformIO env:windows_linux_32bit
|
||||
- name: Build PlatformIO env:windows_32bit
|
||||
if: ${{matrix.sys == 'mingw32'}}
|
||||
working-directory: ./Platformio
|
||||
run: pio run -e windows_linux_32bit
|
||||
run: pio run -e windows_32bit
|
||||
|
|
|
@ -46,9 +46,9 @@ uint8_t IR_VCC_GPIO = 25; // IR receiver power
|
|||
|
||||
bool irReceiverEnabled = false;
|
||||
|
||||
tShowNewIRmessage_cb thisShowNewIRmessage_cb = NULL;
|
||||
void set_showNewIRmessage_cb_HAL(tShowNewIRmessage_cb pShowNewIRmessage_cb) {
|
||||
thisShowNewIRmessage_cb = pShowNewIRmessage_cb;
|
||||
tAnnounceNewIRmessage_cb thisAnnounceNewIRmessage_cb = NULL;
|
||||
void set_announceNewIRmessage_cb_HAL(tAnnounceNewIRmessage_cb pAnnounceNewIRmessage_cb) {
|
||||
thisAnnounceNewIRmessage_cb = pAnnounceNewIRmessage_cb;
|
||||
}
|
||||
|
||||
// The Serial connection baud rate.
|
||||
|
@ -190,8 +190,8 @@ void infraredReceiver_loop_HAL() {
|
|||
message += typeToString((&results)->decode_type, (&results)->repeat);
|
||||
message += " ";
|
||||
message += resultToHexidecimal(&results);
|
||||
if (thisShowNewIRmessage_cb != NULL) {
|
||||
thisShowNewIRmessage_cb(std::string(message.c_str()));
|
||||
if (thisAnnounceNewIRmessage_cb != NULL) {
|
||||
thisAnnounceNewIRmessage_cb(std::string(message.c_str()));
|
||||
}
|
||||
|
||||
yield(); // Feed the WDT (again)
|
||||
|
|
|
@ -12,5 +12,5 @@ void infraredReceiver_loop_HAL(void);
|
|||
bool get_irReceiverEnabled_HAL();
|
||||
void set_irReceiverEnabled_HAL(bool aIrReceiverEnabled);
|
||||
|
||||
typedef void (*tShowNewIRmessage_cb)(std::string message);
|
||||
void set_showNewIRmessage_cb_HAL(tShowNewIRmessage_cb pShowNewIRmessage_cb);
|
||||
typedef void (*tAnnounceNewIRmessage_cb)(std::string message);
|
||||
void set_announceNewIRmessage_cb_HAL(tAnnounceNewIRmessage_cb pAnnounceNewIRmessage_cb);
|
||||
|
|
|
@ -8,9 +8,14 @@ WiFiClient espClient;
|
|||
PubSubClient mqttClient(espClient);
|
||||
bool isWifiConnected = false;
|
||||
|
||||
showWiFiconnected_cb thisShowWiFiconnected_cb = NULL;
|
||||
void set_showWiFiconnected_cb_HAL(showWiFiconnected_cb pShowWiFiconnected_cb) {
|
||||
thisShowWiFiconnected_cb = pShowWiFiconnected_cb;
|
||||
tAnnounceWiFiconnected_cb thisAnnounceWiFiconnected_cb = NULL;
|
||||
void set_announceWiFiconnected_cb_HAL(tAnnounceWiFiconnected_cb pAnnounceWiFiconnected_cb) {
|
||||
thisAnnounceWiFiconnected_cb = pAnnounceWiFiconnected_cb;
|
||||
}
|
||||
|
||||
tAnnounceSubscribedTopics_cb thisAnnounceSubscribedTopics_cb = NULL;
|
||||
void set_announceSubscribedTopics_cb_HAL(tAnnounceSubscribedTopics_cb pAnnounceSubscribedTopics_cb) {
|
||||
thisAnnounceSubscribedTopics_cb = pAnnounceSubscribedTopics_cb;
|
||||
}
|
||||
|
||||
bool getIsWifiConnected_HAL() {
|
||||
|
@ -30,12 +35,12 @@ void WiFiEvent(WiFiEvent_t event){
|
|||
// Set status bar icon based on WiFi status
|
||||
if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP || event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) {
|
||||
isWifiConnected = true;
|
||||
thisShowWiFiconnected_cb(true);
|
||||
thisAnnounceWiFiconnected_cb(true);
|
||||
Serial.printf("WiFi connected, IP address: %s\r\n", WiFi.localIP().toString().c_str());
|
||||
|
||||
} else if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
|
||||
isWifiConnected = false;
|
||||
thisShowWiFiconnected_cb(false);
|
||||
thisAnnounceWiFiconnected_cb(false);
|
||||
// automatically try to reconnect
|
||||
Serial.printf("WiFi got disconnected. Will try to reconnect.\r\n");
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
|
@ -44,7 +49,7 @@ void WiFiEvent(WiFiEvent_t event){
|
|||
// e.g. ARDUINO_EVENT_WIFI_STA_CONNECTED or many others
|
||||
// connected is not enough, will wait for IP
|
||||
isWifiConnected = false;
|
||||
thisShowWiFiconnected_cb(false);
|
||||
thisAnnounceWiFiconnected_cb(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +62,29 @@ void init_mqtt_HAL(void) {
|
|||
WiFi.setSleep(true);
|
||||
}
|
||||
|
||||
std::string subscribeTopicOMOTEtest = "OMOTE/test";
|
||||
|
||||
void callback(char* topic, byte* payload, unsigned int length) {
|
||||
// handle message arrived
|
||||
std::string topicReceived(topic);
|
||||
std::string strPayload(reinterpret_cast<const char *>(payload), length);
|
||||
|
||||
if (topicReceived == subscribeTopicOMOTEtest) {
|
||||
Serial.printf("MQTT: received topic %s with payload %s\r\n", subscribeTopicOMOTEtest.c_str(), strPayload.c_str());
|
||||
|
||||
}
|
||||
|
||||
thisAnnounceSubscribedTopics_cb(topicReceived, strPayload);
|
||||
}
|
||||
|
||||
void mqtt_subscribeTopics() {
|
||||
mqttClient.setCallback(&callback);
|
||||
|
||||
mqttClient.subscribe(subscribeTopicOMOTEtest.c_str());
|
||||
Serial.printf(" Successfully subscribed to MQTT topic %s\r\n", subscribeTopicOMOTEtest.c_str());
|
||||
|
||||
}
|
||||
|
||||
bool checkMQTTconnection() {
|
||||
|
||||
if (WiFi.isConnected()) {
|
||||
|
@ -64,10 +92,17 @@ bool checkMQTTconnection() {
|
|||
return true;
|
||||
} else {
|
||||
// try to connect to mqtt server
|
||||
mqttClient.setBufferSize(512); // default is 256
|
||||
//mqttClient.setKeepAlive(15); // default is 15 Client will send MQTTPINGREQ to keep connection alive
|
||||
//mqttClient.setSocketTimeout(15); // default is 15 This determines how long the client will wait for incoming data when it expects data to arrive - for example, whilst it is in the middle of reading an MQTT packet.
|
||||
mqttClient.setServer(MQTT_SERVER, MQTT_SERVER_PORT); // MQTT initialization
|
||||
if (mqttClient.connect(MQTT_CLIENTNAME, MQTT_USER, MQTT_PASS)) {
|
||||
|
||||
std::string mqttClientName = std::string(MQTT_CLIENTNAME) + "_esp32_" + std::string(WiFi.macAddress().c_str());
|
||||
if (mqttClient.connect(mqttClientName.c_str(), MQTT_USER, MQTT_PASS)) {
|
||||
Serial.printf(" Successfully connected to MQTT broker\r\n");
|
||||
|
||||
mqtt_subscribeTopics();
|
||||
|
||||
} else {
|
||||
Serial.printf(" MQTT connection failed (but WiFi is available). Will try later ...\r\n");
|
||||
|
||||
|
@ -75,11 +110,29 @@ bool checkMQTTconnection() {
|
|||
return mqttClient.connected();
|
||||
}
|
||||
} else {
|
||||
Serial.printf(" No connection to MQTT server, because WiFi ist not connected.\r\n");
|
||||
// Serial.printf(" No connection to MQTT server, because WiFi ist not connected.\r\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long reconnectInterval = 100;
|
||||
// in order to do reconnect immediately ...
|
||||
unsigned long lastReconnectAttempt = millis() - reconnectInterval - 1;
|
||||
void mqtt_loop_HAL() {
|
||||
if (!mqttClient.connected()) {
|
||||
unsigned long currentMillis = millis();
|
||||
if ((currentMillis - lastReconnectAttempt) > reconnectInterval) {
|
||||
lastReconnectAttempt = currentMillis;
|
||||
// Attempt to reconnect
|
||||
checkMQTTconnection();
|
||||
}
|
||||
}
|
||||
|
||||
if (mqttClient.connected()) {
|
||||
mqttClient.loop();
|
||||
}
|
||||
}
|
||||
|
||||
bool publishMQTTMessage_HAL(const char *topic, const char *payload){
|
||||
|
||||
if (checkMQTTconnection()) {
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
void init_mqtt_HAL(void);
|
||||
bool getIsWifiConnected_HAL();
|
||||
void mqtt_loop_HAL();
|
||||
bool publishMQTTMessage_HAL(const char *topic, const char *payload);
|
||||
void wifiStop_HAL();
|
||||
|
||||
typedef void (*showWiFiconnected_cb)(bool connected);
|
||||
void set_showWiFiconnected_cb_HAL(showWiFiconnected_cb pShowWiFiconnected_cb);
|
||||
typedef void (*tAnnounceWiFiconnected_cb)(bool connected);
|
||||
void set_announceWiFiconnected_cb_HAL(tAnnounceWiFiconnected_cb pAnnounceWiFiconnected_cb);
|
||||
typedef void (*tAnnounceSubscribedTopics_cb)(std::string topic, std::string payload);
|
||||
void set_announceSubscribedTopics_cb_HAL(tAnnounceSubscribedTopics_cb pAnnounceSubscribedTopics_cb);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,4 +19,4 @@ void set_irReceiverEnabled_HAL(bool aIrReceiverEnabled) {
|
|||
irReceiverEnabled = aIrReceiverEnabled;
|
||||
}
|
||||
|
||||
void set_showNewIRmessage_cb_HAL(tShowNewIRmessage_cb pShowNewIRmessage_cb) {}
|
||||
void set_announceNewIRmessage_cb_HAL(tAnnounceNewIRmessage_cb pAnnounceNewIRmessage_cb) {}
|
||||
|
|
|
@ -9,5 +9,5 @@ void infraredReceiver_loop_HAL(void);
|
|||
bool get_irReceiverEnabled_HAL();
|
||||
void set_irReceiverEnabled_HAL(bool aIrReceiverEnabled);
|
||||
|
||||
typedef void (*tShowNewIRmessage_cb)(std::string message);
|
||||
void set_showNewIRmessage_cb_HAL(tShowNewIRmessage_cb pShowNewIRmessage_cb);
|
||||
typedef void (*tAnnounceNewIRmessage_cb)(std::string message);
|
||||
void set_announceNewIRmessage_cb_HAL(tAnnounceNewIRmessage_cb pAnnounceNewIRmessage_cb);
|
||||
|
|
21
Platformio/hardware/windows_linux/lib/MQTT-C/LICENSE
Normal file
21
Platformio/hardware/windows_linux/lib/MQTT-C/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Liam Bindle
|
||||
|
||||
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.
|
106
Platformio/hardware/windows_linux/lib/MQTT-C/README.md
Normal file
106
Platformio/hardware/windows_linux/lib/MQTT-C/README.md
Normal file
|
@ -0,0 +1,106 @@
|
|||
<p align="right">
|
||||
<a href="https://github.com/LiamBindle/MQTT-C/stargazers"><img src="https://img.shields.io/github/stars/LiamBindle/MQTT-C.svg?style=social&label=Star" style="margin-left:5em"></a>
|
||||
<a href="https://github.com/LiamBindle/MQTT-C/network/members"><img src="https://img.shields.io/github/forks/LiamBindle/MQTT-C.svg?style=social&label=Fork"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img width="70%" src="docs/mqtt-c-logo.png"><br>
|
||||
<a href="https://liambindle.ca/MQTT-C"><img src="https://img.shields.io/badge/docs-passing-brightgreen.svg"></a>
|
||||
<a href="https://github.com/LiamBindle/MQTT-C/issues"><img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg"></a>
|
||||
<a href="https://GitHub.com/LiamBindle/MQTT-C/issues/"><img src="https://img.shields.io/github/issues/LiamBindle/MQTT-C.svg"></a>
|
||||
<a href="https://github.com/LiamBindle/MQTT-C/issues"><img src="https://img.shields.io/github/issues-closed/LiamBindle/MQTT-C.svg"></a>
|
||||
<a href="https://github.com/LiamBindle/MQTT-C/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
</p>
|
||||
|
||||
MQTT-C is an [MQTT v3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html)
|
||||
client written in C. MQTT is a lightweight publisher-subscriber-based messaging protocol that is
|
||||
commonly used in IoT and networking applications where high-latency and low data-rate links
|
||||
are expected. The purpose of MQTT-C is to provide a **portable** MQTT client, **written in C**,
|
||||
for embedded systems and PC's alike. MQTT-C does this by providing a transparent Platform
|
||||
Abstraction Layer (PAL) which makes porting to new platforms easy. MQTT-C is completely
|
||||
thread-safe but can also run perfectly fine on single-threaded systems making MQTT-C
|
||||
well-suited for embedded systems and microcontrollers. Finally, MQTT-C is small; there are only
|
||||
two source files totalling less than 2000 lines.
|
||||
|
||||
#### A note from the author
|
||||
It's been great to hear about all the places MQTT-C is being used! Please don't hesitate
|
||||
to get in touch with me or submit issues on GitHub!
|
||||
|
||||
## Getting Started
|
||||
To use MQTT-C you first instantiate a `struct mqtt_client` and initialize it by calling
|
||||
@ref mqtt_init.
|
||||
```c
|
||||
struct mqtt_client client; /* instantiate the client */
|
||||
mqtt_init(&client, ...); /* initialize the client */
|
||||
```
|
||||
Once your client is initialized you need to connect to an MQTT broker.
|
||||
```c
|
||||
mqtt_connect(&client, ...); /* send a connection request to the broker. */
|
||||
```
|
||||
At this point the client is ready to use! For example, we can subscribe to a topic like so:
|
||||
```c
|
||||
/* subscribe to "toaster/temperature" with a max QoS level of 0 */
|
||||
mqtt_subscribe(&client, "toaster/temperature", 0);
|
||||
```
|
||||
And we can publish to a topic like so:
|
||||
```c
|
||||
/* publish coffee temperature with a QoS level of 1 */
|
||||
int temperature = 67;
|
||||
mqtt_publish(&client, "coffee/temperature", &temperature, sizeof(int), MQTT_PUBLISH_QOS_1);
|
||||
```
|
||||
Those are the basics! From here the [examples](https://github.com/LiamBindle/MQTT-C/tree/master/examples) and [API documentation](https://liambindle.ca/MQTT-C/group__api.html) are good places to get started.
|
||||
|
||||
## Building
|
||||
There are **only two source files** that need to be built, `mqtt.c` and `mqtt_pal.c`.
|
||||
These files are ANSI C (C89) compatible, and should compile with any C compiler.
|
||||
|
||||
Then, simply <code>\#include <mqtt.h></code>.
|
||||
|
||||
Alternatively, you can build MQTT-C with CMake or the provided Makefile. These are provided for convenience.
|
||||
|
||||
## Documentation
|
||||
Pre-built documentation can be found here: [https://liambindle.ca/MQTT-C](https://liambindle.ca/MQTT-C). Be sure to check out the [examples](https://github.com/LiamBindle/MQTT-C/tree/master/examples) too.
|
||||
|
||||
The @ref api documentation contains all the documentation application programmers should need.
|
||||
The @ref pal documentation contains everything you should need to port MQTT-C to a new platform,
|
||||
and the other modules contain documentation for MQTT-C developers.
|
||||
|
||||
## Testing and Building the Tests
|
||||
The MQTT-C unit tests use the [cmocka unit testing framework](https://cmocka.org/).
|
||||
Therefore, [cmocka](https://cmocka.org/) *must* be installed on your machine to build and run
|
||||
the unit tests. For convenience, a simple `"makefile"` is included to build the unit tests and
|
||||
examples on UNIX-like machines. The unit tests and examples can be built as follows:
|
||||
```bash
|
||||
$ make all
|
||||
```
|
||||
The unit tests and examples will be built in the `"bin/"` directory. The unit tests can be run
|
||||
like so:
|
||||
```bash
|
||||
$ ./bin/tests [address [port]]
|
||||
```
|
||||
Note that the \c address and \c port arguments are both optional to specify the location of the
|
||||
MQTT broker that is to be used for the tests. If no \c address is given then the
|
||||
[Mosquitto MQTT Test Server](https://test.mosquitto.org/) will be used. If no \c port is given,
|
||||
port 1883 will be used.
|
||||
|
||||
## Portability
|
||||
MQTT-C provides a transparent platform abstraction layer (PAL) in `mqtt_pal.h` and `mqtt_pal.c`.
|
||||
These files declare and implement the types and calls that MQTT-C requires. Refer to
|
||||
@ref pal for the complete documentation of the PAL.
|
||||
|
||||
## Contributing
|
||||
Please feel free to submit issues and pull-requests [here](https://github.com/LiamBindle/MQTT-C).
|
||||
When submitting a pull-request please ensure you have *fully documented* your changes and
|
||||
added the appropriate unit tests.
|
||||
|
||||
|
||||
## License
|
||||
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). See the
|
||||
`"LICENSE"` file for more details.
|
||||
|
||||
## Authors
|
||||
MQTT-C was initially developed as a CMPT 434 (Winter Term, 2018) final project at the University of
|
||||
Saskatchewan by:
|
||||
- **Liam Bindle**
|
||||
- **Demilade Adeoye**
|
||||
|
1623
Platformio/hardware/windows_linux/lib/MQTT-C/include/mqtt.h
Normal file
1623
Platformio/hardware/windows_linux/lib/MQTT-C/include/mqtt.h
Normal file
File diff suppressed because it is too large
Load diff
203
Platformio/hardware/windows_linux/lib/MQTT-C/include/mqtt_pal.h
Normal file
203
Platformio/hardware/windows_linux/lib/MQTT-C/include/mqtt_pal.h
Normal file
|
@ -0,0 +1,203 @@
|
|||
#if !defined(__MQTT_PAL_H__)
|
||||
#define __MQTT_PAL_H__
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Includes/supports the types/calls required by the MQTT-C client.
|
||||
*
|
||||
* @note This is the \em only file included in mqtt.h, and mqtt.c. It is therefore
|
||||
* responsible for including/supporting all the required types and calls.
|
||||
*
|
||||
* @defgroup pal Platform abstraction layer
|
||||
* @brief Documentation of the types and calls required to port MQTT-C to a new platform.
|
||||
*
|
||||
* mqtt_pal.h is the \em only header file included in mqtt.c. Therefore, to port MQTT-C to a
|
||||
* new platform the following types, functions, constants, and macros must be defined in
|
||||
* mqtt_pal.h:
|
||||
* - Types:
|
||||
* - \c size_t, \c ssize_t
|
||||
* - \c uint8_t, \c uint16_t, \c uint32_t
|
||||
* - \c va_list
|
||||
* - \c mqtt_pal_time_t : return type of \c MQTT_PAL_TIME()
|
||||
* - \c mqtt_pal_mutex_t : type of the argument that is passed to \c MQTT_PAL_MUTEX_LOCK and
|
||||
* \c MQTT_PAL_MUTEX_RELEASE
|
||||
* - Functions:
|
||||
* - \c memcpy, \c strlen
|
||||
* - \c va_start, \c va_arg, \c va_end
|
||||
* - Constants:
|
||||
* - \c INT_MIN
|
||||
*
|
||||
* Additionally, three macro's are required:
|
||||
* - \c MQTT_PAL_HTONS(s) : host-to-network endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_NTOHS(s) : network-to-host endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_TIME() : returns [type: \c mqtt_pal_time_t] current time in seconds.
|
||||
* - \c MQTT_PAL_MUTEX_LOCK(mtx_pointer) : macro that locks the mutex pointed to by \c mtx_pointer.
|
||||
* - \c MQTT_PAL_MUTEX_RELEASE(mtx_pointer) : macro that unlocks the mutex pointed to by
|
||||
* \c mtx_pointer.
|
||||
*
|
||||
* Lastly, \ref mqtt_pal_sendall and \ref mqtt_pal_recvall, must be implemented in mqtt_pal.c
|
||||
* for sending and receiving data using the platforms socket calls.
|
||||
*/
|
||||
|
||||
|
||||
/* UNIX-like platform support */
|
||||
#if defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef pthread_mutex_t mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) pthread_mutex_init(mtx_ptr, NULL)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) pthread_mutex_lock(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) pthread_mutex_unlock(mtx_ptr)
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
struct mbedtls_ssl_context;
|
||||
typedef struct mbedtls_ssl_context *mqtt_pal_socket_handle;
|
||||
#elif defined(MQTT_USE_WOLFSSL)
|
||||
#include <wolfssl/ssl.h>
|
||||
typedef WOLFSSL* mqtt_pal_socket_handle;
|
||||
#elif defined(MQTT_USE_BIO)
|
||||
#include <openssl/bio.h>
|
||||
typedef BIO* mqtt_pal_socket_handle;
|
||||
#elif defined(MQTT_USE_BEARSSL)
|
||||
#include <bearssl.h>
|
||||
|
||||
typedef struct _bearssl_context {
|
||||
br_ssl_client_context sc;
|
||||
br_x509_minimal_context xc;
|
||||
br_sslio_context ioc;
|
||||
size_t ta_count;
|
||||
br_x509_trust_anchor *anchOut;
|
||||
int fd;
|
||||
int (*low_read)(void *read_context, unsigned char *buf, size_t len);
|
||||
int (*low_write)(void *write_context, const unsigned char *buf, size_t len);
|
||||
} bearssl_context;
|
||||
|
||||
typedef bearssl_context* mqtt_pal_socket_handle;
|
||||
#else
|
||||
typedef int mqtt_pal_socket_handle;
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
#include <limits.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// original from MQTT-C
|
||||
// typedef SSIZE_T ssize_t;
|
||||
// changed for usage in OMOTE
|
||||
#if defined(WIN64)
|
||||
typedef SSIZE_T ssize_t;
|
||||
#endif
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef CRITICAL_SECTION mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) InitializeCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) EnterCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) LeaveCriticalSection(mtx_ptr)
|
||||
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
#if defined(MQTT_USE_BIO)
|
||||
#include <openssl/bio.h>
|
||||
typedef BIO* mqtt_pal_socket_handle;
|
||||
#else
|
||||
typedef SOCKET mqtt_pal_socket_handle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sends all the bytes in a buffer.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the first byte in the buffer to send.
|
||||
* @param[in] len The number of bytes to send (starting at \p buf).
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes sent if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* @brief Non-blocking receive all the byte available.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the receive buffer.
|
||||
* @param[in] bufsz The max number of bytes that can be put into \p buf.
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes received if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,103 @@
|
|||
#if !defined(__POSIX_SOCKET_TEMPLATE_H__)
|
||||
#define __POSIX_SOCKET_TEMPLATE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if !defined(WIN32)
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#if defined(__VMS)
|
||||
#include <ioctl.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
A template for opening a non-blocking POSIX socket.
|
||||
*/
|
||||
int open_nb_socket(const char* addr, const char* port);
|
||||
|
||||
int open_nb_socket(const char* addr, const char* port, char *MACaddress) {
|
||||
struct addrinfo hints = {0};
|
||||
|
||||
hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
|
||||
hints.ai_socktype = SOCK_STREAM; /* Must be TCP */
|
||||
int sockfd = -1;
|
||||
int rv;
|
||||
struct addrinfo *p, *servinfo;
|
||||
|
||||
/* get address information */
|
||||
rv = getaddrinfo(addr, port, &hints, &servinfo);
|
||||
if(rv != 0) {
|
||||
fprintf(stderr, "Failed to open socket (getaddrinfo): %s\r\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the first possible socket */
|
||||
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
if (sockfd == -1) continue;
|
||||
|
||||
/* connect to server */
|
||||
rv = connect(sockfd, p->ai_addr, p->ai_addrlen);
|
||||
if(rv == -1) {
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
#if !defined(WIN32)
|
||||
// get MAC address
|
||||
struct ifreq s;
|
||||
ioctl(sockfd, SIOCGIFHWADDR, &s);
|
||||
char buffer[6*3];
|
||||
int i;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
sprintf(&buffer[i*3], "%02x:", (unsigned char) s.ifr_addr.sa_data[i]);
|
||||
//printf(" %02x", (unsigned char) s.ifr_addr.sa_data[i]);
|
||||
}
|
||||
//printf("\r\n");
|
||||
buffer[17] = '\0';
|
||||
|
||||
std::string strMACaddress = std::string(buffer, 18);
|
||||
strMACaddress.copy(MACaddress, 18);
|
||||
// printf(" MAC address from posix_sockets %s\r\n", strMACaddress.c_str());
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* free servinfo */
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
/* make non-blocking */
|
||||
#if !defined(WIN32)
|
||||
if (sockfd != -1) fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
|
||||
#else
|
||||
if (sockfd != INVALID_SOCKET) {
|
||||
// original from MQTT-C
|
||||
// int iMode = 1;
|
||||
// changed for usage in OMOTE
|
||||
u_long iMode = 1;
|
||||
ioctlsocket(sockfd, FIONBIO, &iMode);
|
||||
}
|
||||
#endif
|
||||
#if defined(__VMS)
|
||||
/*
|
||||
OpenVMS only partially implements fcntl. It works on file descriptors
|
||||
but silently fails on socket descriptors. So we need to fall back on
|
||||
to the older ioctl system to set non-blocking IO
|
||||
*/
|
||||
int on = 1;
|
||||
if (sockfd != -1) ioctl(sockfd, FIONBIO, &on);
|
||||
#endif
|
||||
|
||||
/* return the new socket fd */
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
#endif
|
1791
Platformio/hardware/windows_linux/lib/MQTT-C/src/mqtt.c
Normal file
1791
Platformio/hardware/windows_linux/lib/MQTT-C/src/mqtt.c
Normal file
File diff suppressed because it is too large
Load diff
440
Platformio/hardware/windows_linux/lib/MQTT-C/src/mqtt_pal.c
Normal file
440
Platformio/hardware/windows_linux/lib/MQTT-C/src/mqtt_pal.c
Normal file
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <mqtt.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Implements @ref mqtt_pal_sendall and @ref mqtt_pal_recvall and
|
||||
* any platform-specific helpers you'd like.
|
||||
* @cond Doxygen_Suppress
|
||||
*/
|
||||
|
||||
#if defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
|
||||
/*
|
||||
* In case of MQTT_USE_CUSTOM_SOCKET_HANDLE, a pal implemantation is
|
||||
* provided by the user.
|
||||
*/
|
||||
|
||||
/* Note: Some toolchains complain on an object without symbols */
|
||||
|
||||
int _mqtt_pal_dummy;
|
||||
|
||||
#else /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while(sent < len) {
|
||||
int rv = mbedtls_ssl_write(fd, (const unsigned char*)buf + sent, len - sent);
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_write later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Note: rv can be 0 here eg. when mbedtls just flushed
|
||||
* the previous incomplete record.
|
||||
*
|
||||
* Note: we never send an empty TLS record.
|
||||
*/
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
int rv;
|
||||
do {
|
||||
rv = mbedtls_ssl_read(fd, (unsigned char*)buf, bufsz);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* Note: mbedtls_ssl_read returns 0 when the underlying
|
||||
* transport was closed without CloseNotify.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_read later again */
|
||||
break;
|
||||
}
|
||||
/* Note: MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is handled here. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char*)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (const char *)buf - (const char*)start;
|
||||
}
|
||||
|
||||
#elif defined(MQTT_USE_WOLFSSL)
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
int tmp = wolfSSL_write(fd, buf + sent, (int)(len - sent));
|
||||
if (tmp <= 0) {
|
||||
tmp = wolfSSL_get_error(fd, tmp);
|
||||
if (tmp == WOLFSSL_ERROR_WANT_READ || tmp == WOLFSSL_ERROR_WANT_WRITE) {
|
||||
break;
|
||||
}
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
sent += (size_t)tmp;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
const void* const start = buf;
|
||||
int tmp;
|
||||
do {
|
||||
tmp = wolfSSL_read(fd, buf, (int)bufsz);
|
||||
if (tmp <= 0) {
|
||||
tmp = wolfSSL_get_error(fd, tmp);
|
||||
if (tmp == WOLFSSL_ERROR_WANT_READ || tmp == WOLFSSL_ERROR_WANT_WRITE) {
|
||||
break;
|
||||
}
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
buf = (char*)buf + tmp;
|
||||
bufsz -= tmp;
|
||||
} while (tmp > 0 && bufsz > 0);
|
||||
|
||||
return (ssize_t)(buf - start);
|
||||
}
|
||||
|
||||
#elif defined(MQTT_USE_BEARSSL)
|
||||
#include <bearssl.h>
|
||||
#include <memory.h>
|
||||
|
||||
static int do_rec_data(mqtt_pal_socket_handle fd, unsigned int status) {
|
||||
ssize_t rc;
|
||||
uint8_t *buffer;
|
||||
size_t length;
|
||||
int err;
|
||||
|
||||
err = br_ssl_engine_last_error(&fd->sc.eng);
|
||||
|
||||
if (err != BR_ERR_OK) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if ((status & BR_SSL_SENDREC) == BR_SSL_SENDREC) {
|
||||
buffer = br_ssl_engine_sendrec_buf(&fd->sc.eng, &length);
|
||||
|
||||
if (length > 0) {
|
||||
if ((rc = fd->low_write(&fd->fd, buffer, length)) < 0) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
br_ssl_engine_sendrec_ack(&fd->sc.eng, rc);
|
||||
}
|
||||
}
|
||||
else if ((status & BR_SSL_RECVREC) == BR_SSL_RECVREC) {
|
||||
buffer = br_ssl_engine_recvrec_buf(&fd->sc.eng, &length);
|
||||
|
||||
if (length > 0) {
|
||||
if ((rc = fd->low_read(&fd->fd, buffer, length)) < 0) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
br_ssl_engine_recvrec_ack(&fd->sc.eng, rc);
|
||||
}
|
||||
}
|
||||
else if ((status && BR_SSL_CLOSED) == BR_SSL_CLOSED) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
return MQTT_OK;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
int rc = MQTT_OK;
|
||||
uint8_t *buffer;
|
||||
size_t length;
|
||||
size_t remaining_bytes = len;
|
||||
const uint8_t *walker = buf;
|
||||
unsigned int status;
|
||||
|
||||
while (remaining_bytes > 0) {
|
||||
|
||||
if (rc == MQTT_ERROR_SOCKET_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
status = br_ssl_engine_current_state(&fd->sc.eng);
|
||||
|
||||
if ((status & BR_SSL_CLOSED) != 0) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if ((status & (BR_SSL_RECVREC | BR_SSL_SENDREC)) != 0) {
|
||||
rc = do_rec_data(fd, status);
|
||||
|
||||
if (rc != MQTT_OK) {
|
||||
return rc;
|
||||
}
|
||||
status = br_ssl_engine_current_state(&fd->sc.eng);
|
||||
}
|
||||
|
||||
if ((status & BR_SSL_SENDAPP) == BR_SSL_SENDAPP) {
|
||||
buffer = br_ssl_engine_sendapp_buf(&fd->sc.eng, &length);
|
||||
|
||||
if (length > 0) {
|
||||
size_t write = length >= remaining_bytes? remaining_bytes : length;
|
||||
memcpy(buffer, walker, write);
|
||||
remaining_bytes -= write;
|
||||
walker += write;
|
||||
br_ssl_engine_sendapp_ack(&fd->sc.eng, write);
|
||||
br_ssl_engine_flush(&fd->sc.eng, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
int rc = MQTT_OK;
|
||||
uint8_t *buffer;
|
||||
size_t length;
|
||||
size_t remaining_bytes = bufsz;
|
||||
uint8_t *walker = buf;
|
||||
unsigned int status;
|
||||
|
||||
if (rc == MQTT_ERROR_SOCKET_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
status = br_ssl_engine_current_state(&fd->sc.eng);
|
||||
|
||||
if ((status & (BR_SSL_RECVREC | BR_SSL_SENDREC)) != 0) {
|
||||
rc = do_rec_data(fd, status);
|
||||
|
||||
if (rc != MQTT_OK) {
|
||||
return rc;
|
||||
}
|
||||
status = br_ssl_engine_current_state(&fd->sc.eng);
|
||||
}
|
||||
|
||||
if ((status & BR_SSL_RECVAPP) == BR_SSL_RECVAPP) {
|
||||
buffer = br_ssl_engine_recvapp_buf(&fd->sc.eng, &length);
|
||||
|
||||
if (length > 0) {
|
||||
size_t write = length >= remaining_bytes? remaining_bytes : length;
|
||||
memcpy(walker, buffer, write);
|
||||
remaining_bytes -= write;
|
||||
walker += write;
|
||||
br_ssl_engine_recvapp_ack(&fd->sc.eng, write);
|
||||
}
|
||||
}
|
||||
|
||||
return bufsz - remaining_bytes;
|
||||
}
|
||||
|
||||
#elif defined(MQTT_USE_BIO)
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
size_t sent = 0;
|
||||
while(sent < len) {
|
||||
int tmp = BIO_write(fd, (const char*)buf + sent, (int)(len - sent));
|
||||
if (tmp > 0) {
|
||||
sent += (size_t) tmp;
|
||||
} else if (tmp <= 0 && !BIO_should_retry(fd)) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
const char* const start = (const char*)buf;
|
||||
char* bufptr = (char*)buf;
|
||||
int rv;
|
||||
do {
|
||||
rv = BIO_read(fd, bufptr, (int)bufsz);
|
||||
if (rv > 0) {
|
||||
/* successfully read bytes from the socket */
|
||||
bufptr += rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} else if (!BIO_should_retry(fd)) {
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
} while (!BIO_should_read(fd) && bufsz > 0);
|
||||
|
||||
return (ssize_t)(bufptr - start);
|
||||
}
|
||||
|
||||
#elif defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while(sent < len) {
|
||||
ssize_t rv = send(fd, (const char*)buf + sent, len - sent, flags);
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* should call send later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv == 0) {
|
||||
/* is this possible? maybe OS bug. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* recv returns 0 when the socket is (half) closed by the peer.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* should call recv later again */
|
||||
break;
|
||||
}
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char*)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (char*)buf - (const char*)start;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int flags) {
|
||||
size_t sent = 0;
|
||||
while(sent < len) {
|
||||
ssize_t tmp = send(fd, (char*)buf + sent, len - sent, flags);
|
||||
if (tmp < 1) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
sent += (size_t) tmp;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
|
||||
const char *const start = buf;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv > 0) {
|
||||
/* successfully read bytes from the socket */
|
||||
buf = (char*)buf + rv;
|
||||
bufsz -= rv;
|
||||
} else if (rv < 0) {
|
||||
int err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
} while (rv > 0 && bufsz > 0);
|
||||
|
||||
return (ssize_t)((char*)buf - start);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error No PAL!
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
/** @endcond */
|
|
@ -1,18 +1,198 @@
|
|||
#include <string>
|
||||
#include "mqtt_hal_windows_linux.h"
|
||||
#include "secrets.h"
|
||||
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
// example is mainly taken from .pio/libdeps/windows_linux_64bit/MQTT-C/tests.c, TEST__api__publish_subscribe__single
|
||||
#if !defined(WIN32)
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/wait.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
/* Some shortcuts to call winapi in a posix-like way */
|
||||
#define close(sock) closesocket(sock)
|
||||
#define usleep(usec) Sleep((usec) / 1000)
|
||||
#endif
|
||||
|
||||
#include "lib/MQTT-C/include/mqtt.h"
|
||||
#include "lib/MQTT-C/include/posix_sockets.h"
|
||||
|
||||
int sockfd = -1;
|
||||
uint8_t sendmem1[1024], sendmem2[1024];
|
||||
uint8_t recvmem1[1024], recvmem2[1024];
|
||||
struct mqtt_client mqttClient;
|
||||
std::string uniqueClientSuffix = "";
|
||||
int state = 0;
|
||||
|
||||
tAnnounceWiFiconnected_cb thisAnnounceWiFiconnected_cb = NULL;
|
||||
void set_announceWiFiconnected_cb_HAL(tAnnounceWiFiconnected_cb pAnnounceWiFiconnected_cb) {
|
||||
thisAnnounceWiFiconnected_cb = pAnnounceWiFiconnected_cb;
|
||||
}
|
||||
|
||||
tAnnounceSubscribedTopics_cb thisAnnounceSubscribedTopics_cb = NULL;
|
||||
void set_announceSubscribedTopics_cb_HAL(tAnnounceSubscribedTopics_cb pAnnounceSubscribedTopics_cb) {
|
||||
thisAnnounceSubscribedTopics_cb = pAnnounceSubscribedTopics_cb;
|
||||
}
|
||||
|
||||
bool getIsWifiConnected_HAL() {
|
||||
return (sockfd != -1);
|
||||
}
|
||||
|
||||
void publish_callback(void** state, struct mqtt_response_publish *publish) {
|
||||
**(int**)state += 1;
|
||||
printf("message nr %d received\r\n", **(int**)state);
|
||||
|
||||
std::string topic((const char*) (publish->topic_name), publish->topic_name_size);
|
||||
std::string payload((const char*) (publish->application_message), publish->application_message_size);
|
||||
|
||||
printf("Received a PUBLISH(topic=%s, DUP=%d, QOS=%d, RETAIN=%d, pid=%d) from the broker. Data='%s'\r\n",
|
||||
topic.c_str(), publish->dup_flag, publish->qos_level, publish->retain_flag, publish->packet_id,
|
||||
payload.c_str()
|
||||
);
|
||||
|
||||
thisAnnounceSubscribedTopics_cb(topic, payload);
|
||||
}
|
||||
|
||||
void mqtt_subscribeTopics() {
|
||||
mqtt_subscribe(&mqttClient, "OMOTE/test", 2);
|
||||
|
||||
}
|
||||
|
||||
void reconnect_mqtt(struct mqtt_client *mqttClient, void**) {
|
||||
printf("MQTT: will reconnect ...\r\n");
|
||||
|
||||
mqtt_reinit(mqttClient, sockfd, sendmem1, sizeof(sendmem1), recvmem1, sizeof(recvmem1));
|
||||
|
||||
std::string mqttClientName = std::string(MQTT_CLIENTNAME) + uniqueClientSuffix;
|
||||
// client_id, will_topic, will_message, will_message_size, user_name, password, connect_flags, keep_alive
|
||||
mqtt_connect(mqttClient, mqttClientName.c_str(), NULL, NULL, 0, MQTT_USER, MQTT_PASS, 0, 30);
|
||||
if (mqttClient->error != MQTT_OK) {
|
||||
printf("MQTT: connect error: %s\r\n", mqtt_error_str(mqttClient->error));
|
||||
// sockfd = -1;
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(WIN32)
|
||||
std::string getMACaddress() {
|
||||
struct ifreq s;
|
||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
|
||||
strcpy(s.ifr_name, "eth0");
|
||||
if (0 == ioctl(fd, SIOCGIFHWADDR, &s)) {
|
||||
char buffer[6*3];
|
||||
int i;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
sprintf(&buffer[i*3], "%02x:", (unsigned char) s.ifr_addr.sa_data[i]);
|
||||
// printf(" %02x", (unsigned char) s.ifr_addr.sa_data[i]);
|
||||
}
|
||||
//printf("\r\n");
|
||||
|
||||
std::string MACaddress = std::string(buffer, 17);
|
||||
printf(" result in MACaddress(): %s\r\n", MACaddress.c_str());
|
||||
return MACaddress;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_mqtt_HAL(void) {
|
||||
#if defined(WIN32)
|
||||
WSADATA wsaData;
|
||||
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (iResult != NO_ERROR) {
|
||||
printf("Failed to init sockets: %i\r\n", iResult);
|
||||
return; // return iResult;
|
||||
}
|
||||
#endif
|
||||
|
||||
char MACaddress[6*3];
|
||||
sockfd = open_nb_socket(MQTT_SERVER, std::to_string(MQTT_SERVER_PORT).c_str(), MACaddress);
|
||||
if (sockfd == -1) {
|
||||
printf("MQTT: Failed to open socket\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(WIN32)
|
||||
// MAC address is not the best. You cannot start more than one instance like that, otherwise the MQTT broker will only keep the last connection.
|
||||
// printf("MQTT: received MAC address from posix_sockets.h is %s\r\n", MACaddress);
|
||||
// uniqueClientSuffix = std::string(MACaddress, 18);
|
||||
// simply use a random number
|
||||
srand(time(NULL)); // Initialization, should only be called once.
|
||||
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
|
||||
uniqueClientSuffix = "_linux_" + std::to_string(r);
|
||||
#else
|
||||
srand(time(NULL)); // Initialization, should only be called once.
|
||||
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
|
||||
uniqueClientSuffix = "_windows_" + std::to_string(r);
|
||||
#endif
|
||||
|
||||
// printf("MQTT: MAC address from getMACaddress() in mqtt_hal_windows_linux.cpp is %s\r\n", getMACaddress().c_str());
|
||||
|
||||
// printf("MQTT: will init ...\r\n");
|
||||
// mqtt_init(&mqttClient, sockfd, sendmem1, sizeof(sendmem1), recvmem1, sizeof(recvmem1), publish_callback);
|
||||
printf("MQTT: will init with reconnect ...\r\n");
|
||||
mqtt_init_reconnect(&mqttClient, reconnect_mqtt, NULL, publish_callback);
|
||||
reconnect_mqtt(&mqttClient, NULL);
|
||||
mqttClient.publish_response_callback_state = &state;
|
||||
|
||||
mqtt_subscribeTopics();
|
||||
|
||||
thisAnnounceWiFiconnected_cb(true);
|
||||
|
||||
}
|
||||
|
||||
void mqtt_loop_HAL() {
|
||||
if (sockfd != -1) {
|
||||
mqtt_sync(&mqttClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool publishMQTTMessage_HAL(const char *topic, const char *payload) {
|
||||
|
||||
if (sockfd == -1) {
|
||||
init_mqtt_HAL();
|
||||
}
|
||||
|
||||
mqtt_publish(&mqttClient, topic, payload, strlen(payload), MQTT_PUBLISH_QOS_0);
|
||||
if (mqttClient.error != MQTT_OK) {
|
||||
printf("MQTT: publish error %s\r\n", mqtt_error_str(mqttClient.error));
|
||||
sockfd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void init_mqtt_HAL(void) {}
|
||||
void wifiStop_HAL() {
|
||||
/* disconnect */
|
||||
if (sockfd != -1) {
|
||||
mqtt_disconnect(&mqttClient);
|
||||
mqtt_sync(&mqttClient);
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
bool publishMQTTMessage_HAL(const char *topic, const char *payload){
|
||||
return false;
|
||||
}
|
||||
|
||||
void wifiStop_HAL() {}
|
||||
|
||||
void set_showWiFiconnected_cb_HAL(showWiFiconnected_cb pShowWiFiconnected_cb) {}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
void init_mqtt_HAL(void);
|
||||
bool getIsWifiConnected_HAL();
|
||||
void mqtt_loop_HAL();
|
||||
bool publishMQTTMessage_HAL(const char *topic, const char *payload);
|
||||
void wifiStop_HAL();
|
||||
|
||||
typedef void (*showWiFiconnected_cb)(bool connected);
|
||||
void set_showWiFiconnected_cb_HAL(showWiFiconnected_cb pShowWiFiconnected_cb);
|
||||
typedef void (*tAnnounceWiFiconnected_cb)(bool connected);
|
||||
void set_announceWiFiconnected_cb_HAL(tAnnounceWiFiconnected_cb pAnnounceWiFiconnected_cb);
|
||||
typedef void (*tAnnounceSubscribedTopics_cb)(std::string topic, std::string payload);
|
||||
void set_announceSubscribedTopics_cb_HAL(tAnnounceSubscribedTopics_cb pAnnounceSubscribedTopics_cb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -143,8 +143,8 @@ build_src_filter =
|
|||
+<../hardware/ESP32/*>
|
||||
;+<../hardware/ESP32/lib/ESP32-BLE-Keyboard/*>
|
||||
|
||||
; use this if you have a 64 bit compiler (Ubuntu, WSL2, Windows with MSYS2 MINGW64)
|
||||
[env:windows_linux_64bit]
|
||||
; use this if you are using Ubuntu or WSL2 (64 bit compiler)
|
||||
[env:linux_64bit]
|
||||
platform = native@^1.2.1
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
|
@ -169,20 +169,29 @@ build_flags =
|
|||
-D SDL_ZOOM=2
|
||||
;-- hardware abstraction, needed to find hardwareLayer.h ------------------
|
||||
-I hardware
|
||||
-I hardware/windows_linux/lib/MQTT-C/include
|
||||
build_src_filter =
|
||||
+<*>
|
||||
+<../hardware/windows_linux/*>
|
||||
|
||||
; use this if you have a 32 bit compiler (Windows MSYS2 MINGW32)
|
||||
[env:windows_linux_32bit]
|
||||
extends = env:windows_linux_64bit
|
||||
; use this if you are using Windows MSYS2 MINGW64 (64 bit compiler)
|
||||
[env:windows_64bit]
|
||||
extends = env:linux_64bit
|
||||
build_flags =
|
||||
${env:linux_64bit.build_flags}
|
||||
; winsock
|
||||
-l ws2_32
|
||||
|
||||
; use this if you are using Windows MSYS2 MINGW32 (32 bit compiler)
|
||||
[env:windows_32bit]
|
||||
extends = env:windows_64bit
|
||||
build_unflags =
|
||||
${env:windows_linux_64bit.build_unflags}
|
||||
${env:windows_64bit.build_unflags}
|
||||
;-- lvgl ------------------------------------------------------------------
|
||||
-D LV_MEM_CUSTOM=0
|
||||
-D LV_MEM_SIZE="(64U * 1024U)"
|
||||
build_flags =
|
||||
${env:windows_linux_64bit.build_flags}
|
||||
${env:windows_64bit.build_flags}
|
||||
;-- lvgl ------------------------------------------------------------------
|
||||
; 32 bit needs exact the same lvgl memory as on ESP32
|
||||
-D LV_MEM_CUSTOM=0
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#include "applicationInternal/scenes/sceneHandler.h"
|
||||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
#include "devices/misc/device_specialCommands.h"
|
||||
// show WiFi status
|
||||
#include "applicationInternal/gui/guiBase.h"
|
||||
// show received IR and MQTT messages
|
||||
#include "guis/gui_irReceiver.h"
|
||||
|
||||
uint16_t KEYBOARD_DUMMY_UP ; //"Keyboard_dummy_up"
|
||||
uint16_t KEYBOARD_DUMMY_DOWN ; //"Keyboard_dummy_down"
|
||||
|
@ -250,3 +254,29 @@ void executeCommand(uint16_t command, std::string additionalPayload) {
|
|||
Serial.printf("executeCommand: internal error, command not registered\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void receiveNewIRmessage_cb(std::string message) {
|
||||
showNewIRmessage(message);
|
||||
}
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
void receiveWiFiConnected_cb(bool connected) {
|
||||
// show status in header
|
||||
showWiFiConnected(connected);
|
||||
|
||||
if (connected) {
|
||||
// Here you could add sending a MQTT message. This message could be recognized by your home automation software.
|
||||
// When receiving this message, your home automation software could send the states of the smart home devices known to OMOTE.
|
||||
// With that, OMOTE could show on startup the correct status of the smart home devices.
|
||||
//
|
||||
// Remark: in your home automation software, maybe add a short delay (e.g. 100-200 ms) between receiving this message and sending out the status of the smart home devices.
|
||||
// WiFi connection could be already available, but MQTT connection could be not completely ready. Just try what works for you.
|
||||
|
||||
// executeCommand(TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES);
|
||||
|
||||
}
|
||||
}
|
||||
void receiveMQTTmessage_cb(std::string topic, std::string payload) {
|
||||
showMQTTmessage(topic, payload);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -116,3 +116,10 @@ void get_uniqueCommandID(uint16_t *command);
|
|||
void register_keyboardCommands();
|
||||
commandData makeCommandData(commandHandlers a, std::list<std::string> b);
|
||||
void executeCommand(uint16_t command, std::string additionalPayload = "");
|
||||
|
||||
void receiveNewIRmessage_cb(std::string message);
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
// used as callbacks from hardware
|
||||
void receiveWiFiConnected_cb(bool connected);
|
||||
void receiveMQTTmessage_cb(std::string topic, std::string payload);
|
||||
#endif
|
||||
|
|
|
@ -291,7 +291,7 @@ void setActiveTab(uint32_t index, lv_anim_enable_t anim_en) {
|
|||
}
|
||||
}
|
||||
|
||||
void showWiFiConnected_cb(bool connected) {
|
||||
void showWiFiConnected(bool connected) {
|
||||
if (connected) {
|
||||
if (WifiLabel != NULL) {lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI);}
|
||||
} else {
|
||||
|
|
|
@ -33,5 +33,5 @@ void tabview_tab_changed_event_cb(lv_event_t* e);
|
|||
void setActiveTab(uint32_t index, lv_anim_enable_t anim_en);
|
||||
// used by memoryUsage.cpp
|
||||
void showMemoryUsageBar(bool showBar);
|
||||
// used as callback from hardware
|
||||
void showWiFiConnected_cb(bool connected);
|
||||
// used by commandHandler to show WiFi status
|
||||
void showWiFiConnected(bool connected);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "applicationInternal/hardware/hardwarePresenter.h"
|
||||
// for registering the callback to show received IR messages
|
||||
#include "guis/gui_irReceiver.h"
|
||||
// for registering the callback to receive MQTT messages
|
||||
#include "../commandHandler.h"
|
||||
// for registering the callback to show WiFi status
|
||||
#include "applicationInternal/gui/guiBase.h"
|
||||
|
||||
|
@ -111,9 +113,9 @@ bool get_irReceiverEnabled() {
|
|||
}
|
||||
void set_irReceiverEnabled(bool aIrReceiverEnabled) {
|
||||
if (aIrReceiverEnabled) {
|
||||
set_showNewIRmessage_cb_HAL(&showNewIRmessage_cb);
|
||||
set_announceNewIRmessage_cb_HAL(&receiveNewIRmessage_cb);
|
||||
} else {
|
||||
set_showNewIRmessage_cb_HAL(NULL);
|
||||
set_announceNewIRmessage_cb_HAL(NULL);
|
||||
}
|
||||
set_irReceiverEnabled_HAL(aIrReceiverEnabled);
|
||||
}
|
||||
|
@ -169,13 +171,17 @@ void init_lvgl_hardware() {
|
|||
// --- WiFi / MQTT ------------------------------------------------------------
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
void init_mqtt(void) {
|
||||
set_showWiFiconnected_cb_HAL(&showWiFiConnected_cb);
|
||||
set_announceWiFiconnected_cb_HAL(&receiveWiFiConnected_cb);
|
||||
set_announceSubscribedTopics_cb_HAL(receiveMQTTmessage_cb);
|
||||
init_mqtt_HAL();
|
||||
}
|
||||
// used by "commandHandler.cpp", "sleep.cpp"
|
||||
bool getIsWifiConnected() {
|
||||
return getIsWifiConnected_HAL();
|
||||
}
|
||||
void mqtt_loop() {
|
||||
mqtt_loop_HAL();
|
||||
}
|
||||
bool publishMQTTMessage(const char *topic, const char *payload) {
|
||||
return publishMQTTMessage_HAL(topic, payload);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ void init_lvgl_hardware();
|
|||
void init_mqtt(void);
|
||||
// used by "commandHandler.cpp", "sleep.cpp"
|
||||
bool getIsWifiConnected();
|
||||
void mqtt_loop();
|
||||
bool publishMQTTMessage(const char *topic, const char *payload);
|
||||
void wifiStop();
|
||||
#endif
|
||||
|
|
|
@ -3,11 +3,15 @@
|
|||
|
||||
uint16_t COMMAND_UNKNOWN ;
|
||||
uint16_t MY_SPECIAL_COMMAND; //"My_special_command";
|
||||
// uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
|
||||
|
||||
void register_specialCommands() {
|
||||
get_uniqueCommandID(&COMMAND_UNKNOWN);
|
||||
|
||||
// command to trigger your home automation software to send the states of the smart home devices known to OMOTE
|
||||
// register_command(&TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES, makeCommandData(MQTT, {"put_here_your_topic_to_trigger_update_of_omote_smart_home_devices", "PRESS"}));
|
||||
|
||||
// put SPECIAL commands here if you want
|
||||
register_command(&MY_SPECIAL_COMMAND , makeCommandData(SPECIAL, {""}));
|
||||
register_command(&MY_SPECIAL_COMMAND, makeCommandData(SPECIAL, {""}));
|
||||
|
||||
}
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
|
||||
extern uint16_t COMMAND_UNKNOWN;
|
||||
extern uint16_t MY_SPECIAL_COMMAND;
|
||||
// extern uint16_t TRIGGER_UPDATE_OF_OMOTE_SMART_HOME_DEVICES;
|
||||
|
||||
void register_specialCommands();
|
||||
|
|
|
@ -16,6 +16,20 @@ int messagePos = 0;
|
|||
int messageCount = 0;
|
||||
bool tabIsInMemory = false;
|
||||
|
||||
lv_obj_t* objMQTTmessageReceivedTopic;
|
||||
lv_obj_t* objMQTTmessageReceivedPayload;
|
||||
|
||||
void showMQTTmessage(std::string topic, std::string payload) {
|
||||
if (!tabIsInMemory) {return;}
|
||||
|
||||
if (objMQTTmessageReceivedTopic != NULL) {
|
||||
lv_label_set_text(objMQTTmessageReceivedTopic, topic.c_str());
|
||||
}
|
||||
if (objMQTTmessageReceivedPayload != NULL) {
|
||||
lv_label_set_text(objMQTTmessageReceivedPayload, payload.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void printReceivedMessages(bool clearMessages = false) {
|
||||
if (!tabIsInMemory) {return;}
|
||||
|
||||
|
@ -44,7 +58,7 @@ void printReceivedMessages(bool clearMessages = false) {
|
|||
}
|
||||
}
|
||||
|
||||
void showNewIRmessage_cb(std::string message) {
|
||||
void showNewIRmessage(std::string message) {
|
||||
setLastActivityTimestamp(); // Reset the sleep timer when a IR message is received
|
||||
|
||||
// Serial.printf(" new IR message received: %s\r\n", message.c_str());
|
||||
|
@ -130,6 +144,23 @@ void create_tab_content_irReceiver(lv_obj_t* tab) {
|
|||
printReceivedMessages(true);
|
||||
}
|
||||
|
||||
// Show MQTT messages we subscribed to ------------------------------------------------------
|
||||
menuLabel = lv_label_create(tab);
|
||||
lv_label_set_text(menuLabel, "MQTT messages arrived");
|
||||
lv_obj_t* menuBox = lv_obj_create(tab);
|
||||
lv_obj_set_size(menuBox, lv_pct(100), 46);
|
||||
lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN);
|
||||
|
||||
objMQTTmessageReceivedTopic = lv_label_create(menuBox);
|
||||
lv_label_set_text(objMQTTmessageReceivedTopic, "");
|
||||
lv_obj_set_style_text_font(objMQTTmessageReceivedTopic, &lv_font_montserrat_10, LV_PART_MAIN);
|
||||
lv_obj_align(objMQTTmessageReceivedTopic, LV_ALIGN_TOP_LEFT, 0, -4);
|
||||
objMQTTmessageReceivedPayload = lv_label_create(menuBox);
|
||||
lv_label_set_text(objMQTTmessageReceivedPayload, "");
|
||||
lv_obj_set_style_text_font(objMQTTmessageReceivedPayload, &lv_font_montserrat_10, LV_PART_MAIN);
|
||||
lv_obj_align(objMQTTmessageReceivedPayload, LV_ALIGN_TOP_LEFT, 0, 8);
|
||||
|
||||
}
|
||||
|
||||
void notify_tab_before_delete_irReceiver(void) {
|
||||
|
|
|
@ -6,4 +6,6 @@
|
|||
const char * const tabName_irReceiver = "IR Receiver";
|
||||
void register_gui_irReceiver(void);
|
||||
|
||||
void showNewIRmessage_cb(std::string);
|
||||
// used by commandHandler to show WiFi status
|
||||
void showNewIRmessage(std::string);
|
||||
void showMQTTmessage(std::string topic, std::string payload);
|
|
@ -138,6 +138,10 @@ void loop(unsigned long *pIMUTaskTimer, unsigned long *pUpdateStatusTimer) {
|
|||
}
|
||||
// update LVGL UI
|
||||
gui_loop();
|
||||
// call mqtt loop to receive mqtt messages, if you are subscribed to some topics
|
||||
#if (ENABLE_WIFI_AND_MQTT == 1)
|
||||
mqtt_loop();
|
||||
#endif
|
||||
|
||||
// --- every 100 ms -------------------------------------------------------------------
|
||||
// Refresh IMU data (motion detection) every 100 ms
|
||||
|
@ -146,6 +150,7 @@ void loop(unsigned long *pIMUTaskTimer, unsigned long *pUpdateStatusTimer) {
|
|||
*pIMUTaskTimer = millis();
|
||||
|
||||
check_activity();
|
||||
|
||||
}
|
||||
|
||||
// --- every 1000 ms ------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue