Skip to content

ESP-IDF wifi example does not compile due to missing definitions #576

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

Closed
RoscoeTheDog opened this issue Jun 28, 2021 · 4 comments
Closed

Comments

@RoscoeTheDog
Copy link

RoscoeTheDog commented Jun 28, 2021

I have been reviewing some examples for how to configure wifi in my project. The smartconfig featured seems nice but I wanted to test it before integrating it. I copied the main example from espressif's github repo and tried compiling it. It seems to be missing references to SC_TYPE_ESPTOUCH_V2 and esp_smartconfig_get_rvd_data.

Now, it is my understanding that the examples in the main espressif esp-idf repository and the platformIO espressif32 repository may be different because platformIO uses a different build system. It seems that platformIO's espressif32 branch does not include an example for connecting to an AP using purly the esp-idf framework, and the examples provided use the Arduino framework instead which is not supported on the esp32s2-saola1 board.

I know there is a feature branch of the esp32s2-saola that works with the Arduino framework.. But during my earlier testing it seems there are still some unresolved bugs such as the Hardware Timers API not functioning. And this prevents me from using it with my application. Additionally, you cannot seem to mix the featured branch with the esp-idf branch and use the two together, as the board definition and support for this does not exist and does not compile either.

I am not sure why why these two declarations are missing from the appropriate headers. Is smartconfig supported under platformIO's branch? Could we get an example or something?

Here is the example code pulled from espressif32's repo:

/* Esptouch example
   This example code is in the Public Domain (or CC0 licensed, at your option.)
   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

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

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t s_wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "smartconfig_example";

static void smartconfig_example_task(void * parm);

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_START) {
        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
        ESP_LOGI(TAG, "Scan done");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
        ESP_LOGI(TAG, "Found channel");
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
        ESP_LOGI(TAG, "Got SSID and password");

        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        wifi_config_t wifi_config;
        uint8_t ssid[33] = { 0 };
        uint8_t password[65] = { 0 };
        uint8_t rvd_data[33] = { 0 };

        bzero(&wifi_config, sizeof(wifi_config_t));
        memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
        memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
        wifi_config.sta.bssid_set = evt->bssid_set;
        if (wifi_config.sta.bssid_set == true) {
            memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
        }

        memcpy(ssid, evt->ssid, sizeof(evt->ssid));
        memcpy(password, evt->password, sizeof(evt->password));
        ESP_LOGI(TAG, "SSID:%s", ssid);
        ESP_LOGI(TAG, "PASSWORD:%s", password);
        if (evt->type == SC_TYPE_ESPTOUCH_V2) {
            ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)) );
            ESP_LOGI(TAG, "RVD_DATA:");
            for (int i=0; i<33; i++) {
                printf("%02x ", rvd_data[i]);
            }
            printf("\n");
        }

        ESP_ERROR_CHECK( esp_wifi_disconnect() );
        ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
        esp_wifi_connect();
    } else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
        xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
    }
}

static void initialise_wifi(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    s_wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    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, ESP_EVENT_ANY_ID, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
    ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL) );

    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}

static void smartconfig_example_task(void * parm)
{
    EventBits_t uxBits;
    ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
    smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) );
    while (1) {
        uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
        if(uxBits & CONNECTED_BIT) {
            ESP_LOGI(TAG, "WiFi Connected to ap");
        }
        if(uxBits & ESPTOUCH_DONE_BIT) {
            ESP_LOGI(TAG, "smartconfig over");
            esp_smartconfig_stop();
            vTaskDelete(NULL);
        }
    }
}

void app_main(void)
{
    ESP_ERROR_CHECK( nvs_flash_init() );
    initialise_wifi();
}
@RoscoeTheDog
Copy link
Author

Since I was copying pasting code within a older project, I had forgotten that I changed main.c to main.cpp. The compiler was expecting cplusplus conventions for the c code. Interestingly, when I wrapped it using extern "C", it was still not working. Changing the file back to main.c got it to compile again. I'll have to check as to why extern "C" wasn't working a bit later after exploring these wifi options for a bit.

Closing.

@RoscoeTheDog
Copy link
Author

RoscoeTheDog commented Jun 29, 2021

Reporting back again. I seem to have incidentally mixed things up and this issue still exists I believe. When the example for smartconfig wasn't working, I moved onto compiling the basic Wifi AP example instead which is not what is posted here.

The two methods SC_TYPE_ESPTOUCH_V2 and esp_smartconfig_get_rvd_data do not exist in the headers of the platformIO which prevents compiling the example. This can be seen in the header which is posted below:

esp_smartconfig.h

// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef __ESP_SMARTCONFIG_H__
#define __ESP_SMARTCONFIG_H__

#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_event_base.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    SC_TYPE_ESPTOUCH = 0,       /**< protocol: ESPTouch */
    SC_TYPE_AIRKISS,            /**< protocol: AirKiss */
    SC_TYPE_ESPTOUCH_AIRKISS,   /**< protocol: ESPTouch and AirKiss */
} smartconfig_type_t;

/** Smartconfig event declarations */
typedef enum {
    SC_EVENT_SCAN_DONE,                /*!< ESP32 station smartconfig has finished to scan for APs */
    SC_EVENT_FOUND_CHANNEL,            /*!< ESP32 station smartconfig has found the channel of the target AP */
    SC_EVENT_GOT_SSID_PSWD,            /*!< ESP32 station smartconfig got the SSID and password */
    SC_EVENT_SEND_ACK_DONE,            /*!< ESP32 station smartconfig has sent ACK to cellphone */
} smartconfig_event_t;

/** @brief smartconfig event base declaration */
ESP_EVENT_DECLARE_BASE(SC_EVENT);

/** Argument structure for SC_EVENT_GOT_SSID_PSWD event */
typedef struct {
    uint8_t ssid[32];           /**< SSID of the AP. Null terminated string. */
    uint8_t password[64];       /**< Password of the AP. Null terminated string. */
    bool bssid_set;             /**< whether set MAC address of target AP or not. */
    uint8_t bssid[6];           /**< MAC address of target AP. */
    smartconfig_type_t type;    /**< Type of smartconfig(ESPTouch or AirKiss). */
    uint8_t token;              /**< Token from cellphone which is used to send ACK to cellphone. */
    uint8_t cellphone_ip[4];    /**< IP address of cellphone. */
} smartconfig_event_got_ssid_pswd_t;

/** Configure structure for esp_smartconfig_start */
typedef struct {
    bool enable_log;            /**< Enable smartconfig logs. */
} smartconfig_start_config_t;

#define SMARTCONFIG_START_CONFIG_DEFAULT() { \
    .enable_log = false \
};

/**
  * @brief  Get the version of SmartConfig.
  *
  * @return
  *     - SmartConfig version const char.
  */
const char *esp_smartconfig_get_version(void);

/**
  * @brief     Start SmartConfig, config ESP device to connect AP. You need to broadcast information by phone APP.
  *            Device sniffer special packets from the air that containing SSID and password of target AP.
  *
  * @attention 1. This API can be called in station or softAP-station mode.
  * @attention 2. Can not call esp_smartconfig_start twice before it finish, please call
  *               esp_smartconfig_stop first.
  *
  * @param     config pointer to smartconfig start configure structure
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_start(const smartconfig_start_config_t *config);

/**
  * @brief     Stop SmartConfig, free the buffer taken by esp_smartconfig_start.
  *
  * @attention Whether connect to AP succeed or not, this API should be called to free
  *            memory taken by smartconfig_start.
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_stop(void);

/**
  * @brief     Set timeout of SmartConfig process.
  *
  * @attention Timing starts from SC_STATUS_FIND_CHANNEL status. SmartConfig will restart if timeout.
  *
  * @param     time_s  range 15s~255s, offset:45s.
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_esptouch_set_timeout(uint8_t time_s);

/**
  * @brief     Set protocol type of SmartConfig.
  *
  * @attention If users need to set the SmartConfig type, please set it before calling
  *            esp_smartconfig_start.
  *
  * @param     type  Choose from the smartconfig_type_t.
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_set_type(smartconfig_type_t type);

/**
  * @brief     Set mode of SmartConfig. default normal mode.
  *
  * @attention 1. Please call it before API esp_smartconfig_start.
  * @attention 2. Fast mode have corresponding APP(phone).
  * @attention 3. Two mode is compatible.
  *
  * @param     enable  false-disable(default); true-enable;
  *
  * @return
  *     - ESP_OK: succeed
  *     - others: fail
  */
esp_err_t esp_smartconfig_fast_mode(bool enable);

#ifdef __cplusplus
}
#endif

#endif

@valeros
Copy link
Member

valeros commented Jun 29, 2021

Hi @RoscoeTheDog ! What version of the ESP-IDF you pulled the example from?

@valeros
Copy link
Member

valeros commented Apr 18, 2022

Closing as no further info provided.

@valeros valeros closed this as completed Apr 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants