diff --git a/components/mosquitto/examples/serverless_mqtt/README.md b/components/mosquitto/examples/serverless_mqtt/README.md index 5fca6a46b4..5ee8369e67 100644 --- a/components/mosquitto/examples/serverless_mqtt/README.md +++ b/components/mosquitto/examples/serverless_mqtt/README.md @@ -1,9 +1,9 @@ -# Serverless MQTT Example +# Brokerless MQTT Example MQTT served by (two) mosquitto's running on two ESP chips. -* Leverages MQTT connectivity between private two 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). +* 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 diff --git a/components/mosquitto/examples/serverless_mqtt/main/Kconfig.projbuild b/components/mosquitto/examples/serverless_mqtt/main/Kconfig.projbuild index 6985678018..7e0e97de03 100644 --- a/components/mosquitto/examples/serverless_mqtt/main/Kconfig.projbuild +++ b/components/mosquitto/examples/serverless_mqtt/main/Kconfig.projbuild @@ -52,6 +52,19 @@ menu "Example Configuration" 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 diff --git a/components/mosquitto/examples/serverless_mqtt/main/serverless_mqtt.c b/components/mosquitto/examples/serverless_mqtt/main/serverless_mqtt.c index 6afb644ac0..8dd0bee7c7 100644 --- a/components/mosquitto/examples/serverless_mqtt/main/serverless_mqtt.c +++ b/components/mosquitto/examples/serverless_mqtt/main/serverless_mqtt.c @@ -7,7 +7,9 @@ #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" #include "mqtt_client.h" +#include "esp_wifi.h" #include "esp_log.h" +#include "esp_random.h" #include "esp_check.h" #include "esp_sleep.h" #include "mosq_broker.h" @@ -50,6 +52,7 @@ static cJSON *s_peer_desc_json = NULL; static char *s_peer_desc = NULL; static esp_mqtt_client_handle_t s_local_mqtt = NULL; +char *wifi_get_ipv4(wifi_interface_t interface); esp_err_t wifi_connect(void); static esp_err_t sync_peers(void); static esp_err_t create_candidates(void); @@ -62,8 +65,8 @@ void app_main(void) ESP_GOTO_ON_ERROR(wifi_connect(), err, TAG, "Failed to initialize WiFi"); ESP_GOTO_ON_ERROR(create_local_broker(), err, TAG, "Failed to create local broker"); ESP_GOTO_ON_ERROR(create_candidates(), err, TAG, "Failed to create juice candidates"); - ESP_GOTO_ON_ERROR(sync_peers(), err, TAG, "Failed to sync with the ohter peer"); - EventBits_t bits = xEventGroupWaitBits(s_state, PEER_FAIL | PEER_CONNECTED, pdFALSE, pdFALSE, pdMS_TO_TICKS(20000)); + ESP_GOTO_ON_ERROR(sync_peers(), err, TAG, "Failed to sync with the other peer"); + EventBits_t bits = xEventGroupWaitBits(s_state, PEER_FAIL | PEER_CONNECTED, pdFALSE, pdFALSE, pdMS_TO_TICKS(90000)); if (bits & PEER_CONNECTED) { ESP_LOGI(TAG, "Peer is connected!"); ESP_GOTO_ON_ERROR(create_local_client(), err, TAG, "Failed to create forwarding mqtt client"); @@ -71,8 +74,8 @@ void app_main(void) return; } err: - ESP_LOGE(TAG, "Non recoverable error, going to sleep for some time"); - esp_deep_sleep(1000000LL * 30); + ESP_LOGE(TAG, "Non recoverable error, going to sleep for some time (random, max 20s)"); + esp_deep_sleep(1000000LL * (esp_random() % 20)); } static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) @@ -161,7 +164,7 @@ static esp_err_t sync_peers(void) esp_err_t ret = ESP_OK; esp_mqtt_client_config_t mqtt_cfg = { .broker.address.uri = CONFIG_EXAMPLE_MQTT_BROKER_URI, - .task.stack_size = 16384, + .task.stack_size = CONFIG_EXAMPLE_MQTT_CLIENT_STACK_SIZE, }; esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); ESP_GOTO_ON_FALSE(client, ESP_ERR_NO_MEM, err, TAG, "Failed to create mqtt client"); @@ -256,6 +259,7 @@ static esp_err_t create_candidates(void) esp_err_t ret = ESP_OK; juice_set_log_level(JUICE_LOG_LEVEL_INFO); juice_config_t config = { .stun_server_host = CONFIG_EXAMPLE_STUN_SERVER, + .bind_address = wifi_get_ipv4(WIFI_IF_STA), .stun_server_port = 19302, .cb_state_changed = juice_state, .cb_candidate = juice_candidate, @@ -310,8 +314,10 @@ static esp_err_t create_local_client(void) { esp_err_t ret = ESP_OK; esp_mqtt_client_config_t mqtt_cfg = { - .broker.address.uri = "mqtt://192.168.4.1:3333", - .task.stack_size = 16384, + .broker.address.transport = MQTT_TRANSPORT_OVER_TCP, + .broker.address.hostname = wifi_get_ipv4(WIFI_IF_AP), + .broker.address.port = CONFIG_EXAMPLE_MQTT_BROKER_PORT, + .task.stack_size = CONFIG_EXAMPLE_MQTT_CLIENT_STACK_SIZE, .credentials.client_id = "local_mqtt" }; s_local_mqtt = esp_mqtt_client_init(&mqtt_cfg); @@ -356,7 +362,7 @@ static void handle_message(char *client, char *topic, char *payload, int len, in static void broker_task(void *ctx) { - struct mosq_broker_config config = { .host = "192.168.4.1", .port = 3333, .handle_message_cb = handle_message }; + struct mosq_broker_config config = { .host = wifi_get_ipv4(WIFI_IF_AP), .port = CONFIG_EXAMPLE_MQTT_BROKER_PORT, .handle_message_cb = handle_message }; mosq_broker_run(&config); vTaskDelete(NULL); } diff --git a/components/mosquitto/examples/serverless_mqtt/main/wifi_connect.c b/components/mosquitto/examples/serverless_mqtt/main/wifi_connect.c index 3d27c969e7..aeb3af7599 100644 --- a/components/mosquitto/examples/serverless_mqtt/main/wifi_connect.c +++ b/components/mosquitto/examples/serverless_mqtt/main/wifi_connect.c @@ -71,7 +71,8 @@ esp_err_t wifi_connect(void) wifi_config_t wifi_ap_config = { .ap = { .ssid = CONFIG_EXAMPLE_AP_SSID, - .password = CONFIG_EXAMPLE_AP_SSID, + .password = CONFIG_EXAMPLE_AP_PASSWORD, + .authmode = WIFI_AUTH_WPA2_PSK, .max_connection = 4, }, }; @@ -107,3 +108,15 @@ esp_err_t wifi_connect(void) return ret; } + +_Thread_local char s_ipv4_addr[4 * 4]; // 4 octets + '.'/term + +char *wifi_get_ipv4(wifi_interface_t interface) +{ + esp_netif_t *netif = esp_netif_get_handle_from_ifkey(interface == WIFI_IF_AP ? "WIFI_AP_DEF" : "WIFI_STA_DEF"); + ESP_RETURN_ON_FALSE(netif, NULL, TAG, "Failed to find default Wi-Fi netif"); + esp_netif_ip_info_t ip_info; + ESP_RETURN_ON_FALSE(esp_netif_get_ip_info(netif, &ip_info) == ESP_OK, NULL, TAG, "Failed to get IP from netif"); + ESP_RETURN_ON_FALSE(esp_ip4addr_ntoa(&ip_info.ip, s_ipv4_addr, sizeof(s_ipv4_addr)) != NULL, NULL, TAG, "Failed to convert IP"); + return s_ipv4_addr; +} diff --git a/components/mosquitto/port/include/mosq_broker.h b/components/mosquitto/port/include/mosq_broker.h index 4817d6735a..d9b858b8c4 100644 --- a/components/mosquitto/port/include/mosq_broker.h +++ b/components/mosquitto/port/include/mosq_broker.h @@ -25,7 +25,10 @@ struct mosq_broker_config { * You can open the respective docs with this idf.py command: * `idf.py docs -sp api-reference/protocols/esp_tls.html` */ - void (*handle_message_cb)(char *client, char *topic, char *data, int len, int qos, int retain); + void (*handle_message_cb)(char *client, char *topic, char *data, int len, int qos, int retain); /*!< + * On message callback. If configured, user function is called + * whenever mosquitto processes a message. + */ }; /**