nopnop2002 / esp-idf-mqtt-broker

MQTT Broker for esp-idf
MIT License
129 stars 32 forks source link

AP+STA mode at same time... #18

Closed vadaliya closed 3 years ago

vadaliya commented 3 years ago

I want to know that, can we use use both AP mode as MQTT Broker and STA mode as MQTT Client at same time. Is it possible? If yes, then How? and if No, then Why?

vadaliya commented 3 years ago

@nopnop2002

nopnop2002 commented 3 years ago

I think you can do it with WIFI_MODE_APSTA, but I don't know how to do it.

Here is a reference:

https://esp32.com/viewtopic.php?t=538

https://www.esp32.com/viewtopic.php?t=10619

https://github.com/espressif/esp-idf/issues/2653

vadaliya commented 3 years ago

I think you can do it with WIFI_MODE_APSTA, but I don't know how to do it.

Here is a reference:

https://esp32.com/viewtopic.php?t=538

https://www.esp32.com/viewtopic.php?t=10619

espressif/esp-idf#2653

I tried using WIFI_MODE_APSTA but mqtt broker only works on STA mode Device IP address, when I tried same with AP mode Device IP address, The mqtt broker is not working.. The MQTT Client can't connect with AP mode IP address.

nopnop2002 commented 3 years ago

There is WIFI_MODE_APSTA example.

https://github.com/espressif/esp-idf/tree/master/examples/provisioning/legacy/custom_config

https://github.com/espressif/esp-idf/tree/master/examples/provisioning/legacy/softap_prov

vadaliya commented 3 years ago

@nopnop2002 I have attached my code... can you please check it... where I'm making a mistakes...

main.zip

nopnop2002 commented 3 years ago

Wifi mode cannot be run simultaneously in any of the following:

WIFI_MODE_STA WiFi station mode

WIFI_MODE_AP WiFi soft-AP mode

WIFI_MODE_APSTA WiFi station + soft-AP mode

vadaliya commented 3 years ago

Wifi mode cannot be run simultaneously in any of the following:

WIFI_MODE_STA WiFi station mode

WIFI_MODE_AP WiFi soft-AP mode

WIFI_MODE_APSTA WiFi station + soft-AP mode

Thanks for Reply... Did you check my code ???

So...what I have to do.. for Create esp32 AP mode as Broker and STA mode as Client(which Connect on Cloud or other MQTT Broker).

nopnop2002 commented 3 years ago

@vadaliya

You can choose either one:

if 0

    wifi_ap();
    wifi_sta(5000);

else

    wifi_apsta(5000);

endif

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

static const char *TAG = "wifi station";

static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;

static void event_handler(void* arg, esp_event_base_t event_base,
                                                                int32_t event_id, void* event_data)
{
        if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
                ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
                esp_wifi_connect();
                xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
                ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
                xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        }
}

static void initialise_wifi(void)
{
        esp_log_level_set("wifi", ESP_LOG_WARN);
        static bool initialized = false;
        if (initialized) {
                return;
        }
        ESP_ERROR_CHECK(esp_netif_init());
        wifi_event_group = xEventGroupCreate();
        ESP_ERROR_CHECK(esp_event_loop_create_default());
        esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
        assert(ap_netif);
        esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
        assert(sta_netif);
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
        ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL) );
        ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );

        ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
        ESP_ERROR_CHECK( esp_wifi_start() );

        initialized = true;
}

#define AP_SSID "ap_ssid"
#define AP_PASSWORD "ap_password"

static bool wifi_ap(void)
{
        wifi_config_t wifi_config = { 0 };
        strcpy((char *)wifi_config.ap.ssid,AP_SSID);
        strcpy((char *)wifi_config.ap.password, AP_PASSWORD);
        wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
        wifi_config.ap.ssid_len = strlen(AP_SSID);
        wifi_config.ap.max_connection = 2;
        wifi_config.ap.channel = 5;

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config) );
        ESP_ERROR_CHECK( esp_wifi_start() );
        ESP_LOGI(TAG, "Starting softAP");

        return ESP_OK;
}

#define STA_SSID "sta_ssid"
#define STA_PASSWORD "sta_password"

static bool wifi_sta(int timeout_ms)
{
        wifi_config_t wifi_config = { 0 };
        strcpy((char *)wifi_config.sta.ssid, STA_SSID);
        strcpy((char *)wifi_config.sta.password, STA_PASSWORD);

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
        ESP_ERROR_CHECK( esp_wifi_connect() );

        int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                                                                   pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
        ESP_LOGI(TAG, "bits=%x", bits);
        return (bits & CONNECTED_BIT) != 0;
}

static bool wifi_apsta(int timeout_ms)
{
        wifi_config_t ap_config = { 0 };
        strcpy((char *)ap_config.ap.ssid,AP_SSID);
        strcpy((char *)ap_config.ap.password, AP_PASSWORD);
        ap_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
        ap_config.ap.ssid_len = strlen(AP_SSID);
        ap_config.ap.max_connection = 2;
        ap_config.ap.channel = 5;

        wifi_config_t sta_config = { 0 };
        strcpy((char *)sta_config.sta.ssid, STA_SSID);
        strcpy((char *)sta_config.sta.password, STA_PASSWORD);

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_APSTA) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_AP, &ap_config) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &sta_config) );
        ESP_ERROR_CHECK( esp_wifi_start() );
        ESP_LOGI(TAG, "Starting softAP");

        ESP_ERROR_CHECK( esp_wifi_connect() );
        int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                                                                   pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
        ESP_LOGI(TAG, "bits=%x", bits);
        return (bits & CONNECTED_BIT) != 0;
}

void app_main()
{
        esp_err_t err = nvs_flash_init();
        if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
                ESP_ERROR_CHECK( nvs_flash_erase() );
                err = nvs_flash_init();
        }
        ESP_ERROR_CHECK(err);

        initialise_wifi();

#if 0
        wifi_ap();
        wifi_sta(5000);
#else
        wifi_apsta(5000);
#endif
}
vadaliya commented 3 years ago

@vadaliya

You can choose either one:

if 0

wifi_ap(); wifi_sta(5000);

else

wifi_apsta(5000);

endif

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

static const char *TAG = "wifi station";

static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;

static void event_handler(void* arg, esp_event_base_t event_base,
                                                                int32_t event_id, void* event_data)
{
        if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
                ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
                esp_wifi_connect();
                xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
                ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
                xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        }
}

static void initialise_wifi(void)
{
        esp_log_level_set("wifi", ESP_LOG_WARN);
        static bool initialized = false;
        if (initialized) {
                return;
        }
        ESP_ERROR_CHECK(esp_netif_init());
        wifi_event_group = xEventGroupCreate();
        ESP_ERROR_CHECK(esp_event_loop_create_default());
        esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
        assert(ap_netif);
        esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
        assert(sta_netif);
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
        ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &event_handler, NULL) );
        ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );

        ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_NULL) );
        ESP_ERROR_CHECK( esp_wifi_start() );

        initialized = true;
}

#define AP_SSID "ap_ssid"
#define AP_PASSWORD "ap_password"

static bool wifi_ap(void)
{
        wifi_config_t wifi_config = { 0 };
        strcpy((char *)wifi_config.ap.ssid,AP_SSID);
        strcpy((char *)wifi_config.ap.password, AP_PASSWORD);
        wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
        wifi_config.ap.ssid_len = strlen(AP_SSID);
        wifi_config.ap.max_connection = 2;
        wifi_config.ap.channel = 5;

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config) );
        ESP_ERROR_CHECK( esp_wifi_start() );
        ESP_LOGI(TAG, "Starting softAP");

        return ESP_OK;
}

#define STA_SSID "sta_ssid"
#define STA_PASSWORD "sta_password"

static bool wifi_sta(int timeout_ms)
{
        wifi_config_t wifi_config = { 0 };
        strcpy((char *)wifi_config.sta.ssid, STA_SSID);
        strcpy((char *)wifi_config.sta.password, STA_PASSWORD);

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
        ESP_ERROR_CHECK( esp_wifi_connect() );

        int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                                                                   pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
        ESP_LOGI(TAG, "bits=%x", bits);
        return (bits & CONNECTED_BIT) != 0;
}

static bool wifi_apsta(int timeout_ms)
{
        wifi_config_t ap_config = { 0 };
        strcpy((char *)ap_config.ap.ssid,AP_SSID);
        strcpy((char *)ap_config.ap.password, AP_PASSWORD);
        ap_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
        ap_config.ap.ssid_len = strlen(AP_SSID);
        ap_config.ap.max_connection = 2;
        ap_config.ap.channel = 5;

        wifi_config_t sta_config = { 0 };
        strcpy((char *)sta_config.sta.ssid, STA_SSID);
        strcpy((char *)sta_config.sta.password, STA_PASSWORD);

        ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_APSTA) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_AP, &ap_config) );
        ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &sta_config) );
        ESP_ERROR_CHECK( esp_wifi_start() );
        ESP_LOGI(TAG, "Starting softAP");

        ESP_ERROR_CHECK( esp_wifi_connect() );
        int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                                                                   pdFALSE, pdTRUE, timeout_ms / portTICK_PERIOD_MS);
        ESP_LOGI(TAG, "bits=%x", bits);
        return (bits & CONNECTED_BIT) != 0;
}

void app_main()
{
        esp_err_t err = nvs_flash_init();
        if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
                ESP_ERROR_CHECK( nvs_flash_erase() );
                err = nvs_flash_init();
        }
        ESP_ERROR_CHECK(err);

        initialise_wifi();

#if 0
        wifi_ap();
        wifi_sta(5000);
#else
        wifi_apsta(5000);
#endif
}

Thanks.... It's working.... now I'm implementing this code in that MQTT Broker code....