-
Notifications
You must be signed in to change notification settings - Fork 161
[mosq]: Add serverless broker example #710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
david-cermak
merged 5 commits into
espressif:master
from
david-cermak:feat/mosq_p2p_example
Dec 19, 2024
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d57b8c5
feat(mosq): Add example with two brokers synced on P2P
david-cermak 6cce87e
fix(mosq): Fix dependency issues moving esp-tls to public deps
david-cermak cdeab8f
feat(mosq): Add support for on-message callback
david-cermak 3b2c614
feat(mosq): Upgrade to mosquitto v2.0.20
david-cermak e6fb8aa
bump(mosq): 2.0.18~0 -> 2.0.20~0
david-cermak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
components/mosquitto/examples/serverless_mqtt/components/libjuice/port/juice_random.c |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
components/mosquitto/examples/serverless_mqtt: | ||
disable: | ||
- if: IDF_TARGET not in ["esp32", "esp32s3", "esp32c3"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# The following five lines of boilerplate have to be in your project's | ||
# CMakeLists in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(serverless_mqtt) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Brokerless MQTT Example | ||
|
||
MQTT served by (two) mosquitto's running on two ESP chips. | ||
|
||
* Leverages MQTT connectivity between two private networks without cloud premisses. | ||
* Creates two local MQTT servers (on ESP32x's) which are being synchronized over peer to peer connection (established via ICE protocol, by [libjuice](https://github.com/paullouisageneau/libjuice)). | ||
|
||
## How it works | ||
|
||
This example needs two ESP32 chipsets, that will create two separate Wi-Fi networks (IoT networks) used for IoT devices. | ||
Each IoT network is served by an MQTT server (using mosquitto component). | ||
This example will also synchronize these two MQTT brokers, as if there was only one IoT network with one broker. | ||
This example creates a peer to peer connection between two chipsets to keep them synchronize. This connection utilizes libjuice (which implements a simplified ICE-UDP) to traverse NATs, which enabling direct connection between two private networks behind NATs. | ||
|
||
* Diagram | ||
|
||
 | ||
|
||
Here's a step-by-step procedure of establishing this remote connection: | ||
1) Initialize and start Wi-Fi AP (for IoT networks) and Wi-Fi station (for internet connection) | ||
2) Start mosquitto broker on IoT network | ||
3) Start libjuice to gather connection candidates | ||
4) Synchronize using a public MQTT broker and exchange ICE descriptors | ||
5) Establish ICE UDP connection between the two ESP32 chipsets | ||
6) Start forwarding mqtt messages | ||
- Each remote datagram (received from ICE-UDP channel) is re-published to the local MQTT server | ||
- Each local MQTT message (received from mosquitto on_message callback) is sent in ICE-UDP datagram | ||
|
||
## How to use this example | ||
|
||
You need two ESP32 devices that support Wi-Fi station and Wi-Fi software access point. | ||
|
||
* Configure Wi-Fi credentials for both devices on both interfaces | ||
* These devices would be deployed in distinct Wi-Fi environments, so the Wi-Fi station credentials would likely be different. | ||
* They also create their own IoT network (on the soft-AP interface) Wi-Fi, so the AP credentials would likely be the same, suggesting the IoT networks will be keep synchronized (even though these are two distict Wi-Fi networks). | ||
* Choose `CONFIG_EXAMPLE_SERVERLESS_ROLE_PEER1` for one device and `CONFIG_EXAMPLE_SERVERLESS_ROLE_PEER2` for another. It's not important which device is PEER1, since the code is symmetric, but these two devices need to have different role. | ||
* Optionally: You can use `idf.py` `-D` and `-B` flag to keep separate build directories and sdkconfigs for these two roles | ||
``` | ||
idf.py -B build1 -DSDKCONFIG=build1/sdkconfig menuconfig build flash monitor | ||
``` | ||
* Flash and run the two devices and wait for them to connect and synchronize. | ||
* Now you can test MQTT connectivity, for example: | ||
* Join PEER1 device's AP and connect to the MQTT broker with one or more clients, subscribing to one or more topics. | ||
* Join PEER2 device's AP and connect to the MQTT broker with one or more clients, subscribing to one or more topics. | ||
* Whenever you publish to a topic, all subscribed clients should receive the message, no matter which Wi-Fi network they're connected to. | ||
|
||
## Warning | ||
|
||
This example uses libjuice as a dependency: | ||
|
||
* libjuice (UDP Interactive Connectivity Establishment): https://github.com/paullouisageneau/libjuice | ||
|
||
which is distributed under Mozilla Public License v2.0. |
44 changes: 44 additions & 0 deletions
44
components/mosquitto/examples/serverless_mqtt/components/libjuice/CMakeLists.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
set(LIBJUICE_VERSION "73785387eafe15c02b6a210edb10f722474e8e14") | ||
set(LIBJUICE_URL "https://github.com/paullouisageneau/libjuice/archive/${LIBJUICE_VERSION}.zip") | ||
|
||
set(libjuice_dir ${CMAKE_BINARY_DIR}/libjuice/libjuice-${LIBJUICE_VERSION}) | ||
|
||
# Fetch the library | ||
if(NOT EXISTS ${libjuice_dir}) | ||
message(STATUS "Downloading libjuice ${LIBJUICE_VERSION}...") | ||
file(DOWNLOAD ${LIBJUICE_URL} ${CMAKE_BINARY_DIR}/libjuice.zip SHOW_PROGRESS) | ||
execute_process(COMMAND unzip -o ${CMAKE_BINARY_DIR}/libjuice.zip -d ${CMAKE_BINARY_DIR}/libjuice | ||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) | ||
endif() | ||
|
||
set(JUICE_SOURCES ${libjuice_dir}/src/addr.c | ||
${libjuice_dir}/src/agent.c | ||
${libjuice_dir}/src/base64.c | ||
${libjuice_dir}/src/conn.c | ||
${libjuice_dir}/src/conn_mux.c | ||
${libjuice_dir}/src/conn_poll.c | ||
${libjuice_dir}/src/conn_thread.c | ||
${libjuice_dir}/src/const_time.c | ||
${libjuice_dir}/src/crc32.c | ||
${libjuice_dir}/src/hash.c | ||
${libjuice_dir}/src/ice.c | ||
${libjuice_dir}/src/juice.c | ||
${libjuice_dir}/src/log.c | ||
${libjuice_dir}/src/server.c | ||
${libjuice_dir}/src/stun.c | ||
${libjuice_dir}/src/timestamp.c | ||
${libjuice_dir}/src/turn.c | ||
${libjuice_dir}/src/udp.c | ||
# Use hmac from mbedtls and random numbers from esp_random: | ||
# ${libjuice_dir}/src/hmac.c | ||
# ${libjuice_dir}/src/random.c | ||
) | ||
|
||
idf_component_register(SRCS port/juice_random.c | ||
${JUICE_SOURCES} | ||
INCLUDE_DIRS "include" "${libjuice_dir}/include" "${libjuice_dir}/include/juice" | ||
REQUIRES esp_netif | ||
PRIV_REQUIRES sock_utils) | ||
|
||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") | ||
david-cermak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
set_source_files_properties(${libjuice_dir}/src/udp.c PROPERTIES COMPILE_FLAGS -Wno-unused-variable) |
13 changes: 13 additions & 0 deletions
13
components/mosquitto/examples/serverless_mqtt/components/libjuice/include/ifaddrs.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Unlicense OR CC0-1.0 | ||
*/ | ||
#pragma once | ||
|
||
// Purpose of this header is to replace udp_sendto() to avoid name conflict with lwip | ||
// added here since ifaddrs.h is included from juice_udp sources | ||
#define udp_sendto juice_udp_sendto | ||
|
||
// other than that, let's just include the ifaddrs (from sock_utils) | ||
#include_next "ifaddrs.h" |
40 changes: 40 additions & 0 deletions
40
components/mosquitto/examples/serverless_mqtt/components/libjuice/port/juice_random.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) 2020 Paul-Louis Ageneau | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
#include "esp_random.h" | ||
|
||
void juice_random(void *buf, size_t size) | ||
{ | ||
esp_fill_random(buf, size); | ||
} | ||
|
||
void juice_random_str64(char *buf, size_t size) | ||
{ | ||
static const char chars64[] = | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
size_t i = 0; | ||
for (i = 0; i + 1 < size; ++i) { | ||
uint8_t byte = 0; | ||
juice_random(&byte, 1); | ||
buf[i] = chars64[byte & 0x3F]; | ||
} | ||
buf[i] = '\0'; | ||
} | ||
|
||
uint32_t juice_rand32(void) | ||
{ | ||
uint32_t r = 0; | ||
juice_random(&r, sizeof(r)); | ||
return r; | ||
} | ||
|
||
uint64_t juice_rand64(void) | ||
{ | ||
uint64_t r = 0; | ||
juice_random(&r, sizeof(r)); | ||
return r; | ||
} |
4 changes: 4 additions & 0 deletions
4
components/mosquitto/examples/serverless_mqtt/main/CMakeLists.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
idf_component_register(SRCS "serverless_mqtt.c" | ||
"wifi_connect.c" | ||
INCLUDE_DIRS "." | ||
REQUIRES libjuice nvs_flash mqtt json esp_wifi) |
85 changes: 85 additions & 0 deletions
85
components/mosquitto/examples/serverless_mqtt/main/Kconfig.projbuild
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
menu "Example Configuration" | ||
|
||
menu "AP Configuration" | ||
comment "AP Configuration" | ||
|
||
config EXAMPLE_AP_SSID | ||
string "Wi-Fi SSID" | ||
default "myssid" | ||
help | ||
Set the SSID of Wi-Fi ap interface. | ||
|
||
config EXAMPLE_AP_PASSWORD | ||
string "Wi-Fi Password" | ||
default "12345678" | ||
help | ||
Set the password of Wi-Fi ap interface. | ||
|
||
endmenu | ||
|
||
menu "STA Configuration" | ||
comment "STA Configuration" | ||
|
||
config EXAMPLE_STA_SSID | ||
string "WiFi Station SSID" | ||
default "mystationssid" | ||
help | ||
SSID for the example's sta to connect to. | ||
|
||
config EXAMPLE_STA_PASSWORD | ||
string "WiFi Station Password" | ||
default "mystationpassword" | ||
help | ||
WiFi station password for the example to use. | ||
endmenu | ||
|
||
config EXAMPLE_MQTT_BROKER_URI | ||
string "MQTT Broker URL" | ||
default "mqtt://mqtt.eclipseprojects.io" | ||
help | ||
URL of the mqtt broker use for synchronisation and exchanging | ||
ICE connect info (description and candidates). | ||
|
||
config EXAMPLE_MQTT_SYNC_TOPIC | ||
string "MQTT topic for synchronisation" | ||
default "/topic/serverless_mqtt" | ||
help | ||
MQTT topic used fo synchronisation. | ||
|
||
config EXAMPLE_STUN_SERVER | ||
string "Hostname of STUN server" | ||
default "stun.l.google.com" | ||
help | ||
STUN server hostname. | ||
|
||
config EXAMPLE_MQTT_CLIENT_STACK_SIZE | ||
int "Stack size for mqtt client" | ||
default 16384 | ||
help | ||
Set stack size for the mqtt client. | ||
Need more stack, since calling juice API from the handler. | ||
|
||
config EXAMPLE_MQTT_BROKER_PORT | ||
int "port for the mosquitto to listen to" | ||
default 1883 | ||
help | ||
This is a port which the local mosquitto uses. | ||
|
||
choice EXAMPLE_SERVERLESS_ROLE | ||
prompt "Choose your role" | ||
default EXAMPLE_SERVERLESS_ROLE_PEER1 | ||
help | ||
Choose either peer1 or peer2. | ||
It's not very important which device is peer1 | ||
(peer-1 sends sync messages, peer2 listens for them) | ||
It is important that we have two peers, | ||
one with peer1 config, another one with peer2 config | ||
|
||
config EXAMPLE_SERVERLESS_ROLE_PEER1 | ||
bool "peer1" | ||
|
||
config EXAMPLE_SERVERLESS_ROLE_PEER2 | ||
bool "peer2" | ||
endchoice | ||
|
||
endmenu |
5 changes: 5 additions & 0 deletions
5
components/mosquitto/examples/serverless_mqtt/main/idf_component.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
## IDF Component Manager Manifest File | ||
dependencies: | ||
espressif/mosquitto: | ||
override_path: ../../.. | ||
espressif/sock_utils: "*" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.