2018-07-30 16:10:10 +00:00
|
|
|
/* SoftAP based Provisioning 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* This file is mostly a boiler-plate code that applications can use without much change */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <esp_err.h>
|
|
|
|
#include <esp_log.h>
|
|
|
|
|
|
|
|
#include <esp_wifi.h>
|
|
|
|
#include <tcpip_adapter.h>
|
|
|
|
|
|
|
|
#include <wifi_provisioning/wifi_config.h>
|
|
|
|
|
|
|
|
#include "app_prov.h"
|
|
|
|
|
|
|
|
static const char* TAG = "app_prov_handler";
|
|
|
|
|
2019-01-28 09:51:28 +00:00
|
|
|
/* Provide definition of wifi_prov_ctx_t */
|
|
|
|
struct wifi_prov_ctx {
|
|
|
|
wifi_config_t wifi_cfg;
|
|
|
|
};
|
|
|
|
|
|
|
|
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
|
|
|
{
|
|
|
|
return (*ctx ? &(*ctx)->wifi_cfg : NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
|
|
|
{
|
|
|
|
free(*ctx);
|
|
|
|
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
|
|
|
return get_config(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_config(wifi_prov_ctx_t **ctx)
|
|
|
|
{
|
|
|
|
free(*ctx);
|
|
|
|
*ctx = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
2018-07-30 16:10:10 +00:00
|
|
|
{
|
2019-01-28 09:51:28 +00:00
|
|
|
/* Initialize to zero */
|
2018-07-30 16:10:10 +00:00
|
|
|
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
|
|
|
|
|
|
|
if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
|
|
|
ESP_LOGW(TAG, "Prov app not running");
|
|
|
|
return ESP_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) {
|
|
|
|
ESP_LOGI(TAG, "Connected state");
|
|
|
|
|
|
|
|
/* IP Addr assigned to STA */
|
|
|
|
tcpip_adapter_ip_info_t ip_info;
|
|
|
|
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
|
|
|
|
char *ip_addr = ip4addr_ntoa(&ip_info.ip);
|
|
|
|
strcpy(resp_data->conn_info.ip_addr, ip_addr);
|
|
|
|
|
|
|
|
/* AP information to which STA is connected */
|
|
|
|
wifi_ap_record_t ap_info;
|
|
|
|
esp_wifi_sta_get_ap_info(&ap_info);
|
|
|
|
memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid));
|
|
|
|
memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid));
|
|
|
|
resp_data->conn_info.channel = ap_info.primary;
|
|
|
|
resp_data->conn_info.auth_mode = ap_info.authmode;
|
|
|
|
} else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) {
|
|
|
|
ESP_LOGI(TAG, "Disconnected state");
|
|
|
|
|
|
|
|
/* If disconnected, convey reason */
|
|
|
|
app_prov_get_wifi_disconnect_reason(&resp_data->fail_reason);
|
|
|
|
} else {
|
|
|
|
ESP_LOGI(TAG, "Connecting state");
|
|
|
|
}
|
|
|
|
return ESP_OK;
|
|
|
|
}
|
|
|
|
|
2019-01-28 09:51:28 +00:00
|
|
|
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
2018-07-30 16:10:10 +00:00
|
|
|
{
|
2019-01-28 09:51:28 +00:00
|
|
|
wifi_config_t *wifi_cfg = get_config(ctx);
|
2018-07-30 16:10:10 +00:00
|
|
|
if (wifi_cfg) {
|
2019-01-28 09:51:28 +00:00
|
|
|
free_config(ctx);
|
2018-07-30 16:10:10 +00:00
|
|
|
}
|
|
|
|
|
2019-01-28 09:51:28 +00:00
|
|
|
wifi_cfg = new_config(ctx);
|
2018-07-30 16:10:10 +00:00
|
|
|
if (!wifi_cfg) {
|
|
|
|
ESP_LOGE(TAG, "Unable to alloc wifi config");
|
|
|
|
return ESP_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "WiFi Credentials Received : \n\tssid %s \n\tpassword %s",
|
|
|
|
req_data->ssid, req_data->password);
|
2019-06-10 11:53:53 +00:00
|
|
|
|
|
|
|
/* Using strncpy allows the max SSID length to be 32 bytes (as per 802.11 standard).
|
|
|
|
* But this doesn't guarantee that the saved SSID will be null terminated, because
|
|
|
|
* wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character).
|
|
|
|
* Although, this is not a matter for concern because esp_wifi library reads the SSID
|
|
|
|
* upto 32 bytes in absence of null termination */
|
|
|
|
strncpy((char *) wifi_cfg->sta.ssid, req_data->ssid, sizeof(wifi_cfg->sta.ssid));
|
|
|
|
strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password));
|
2018-07-30 16:10:10 +00:00
|
|
|
return ESP_OK;
|
|
|
|
}
|
|
|
|
|
2019-01-28 09:51:28 +00:00
|
|
|
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
2018-07-30 16:10:10 +00:00
|
|
|
{
|
2019-01-28 09:51:28 +00:00
|
|
|
wifi_config_t *wifi_cfg = get_config(ctx);
|
2018-07-30 16:10:10 +00:00
|
|
|
if (!wifi_cfg) {
|
|
|
|
ESP_LOGE(TAG, "WiFi config not set");
|
|
|
|
return ESP_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
app_prov_configure_sta(wifi_cfg);
|
|
|
|
ESP_LOGI(TAG, "WiFi Credentials Applied");
|
|
|
|
|
2019-01-28 09:51:28 +00:00
|
|
|
free_config(ctx);
|
2018-07-30 16:10:10 +00:00
|
|
|
return ESP_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
wifi_prov_config_handlers_t wifi_prov_handlers = {
|
|
|
|
.get_status_handler = get_status_handler,
|
|
|
|
.set_config_handler = set_config_handler,
|
|
|
|
.apply_config_handler = apply_config_handler,
|
2019-01-28 09:51:28 +00:00
|
|
|
.ctx = NULL
|
2018-07-30 16:10:10 +00:00
|
|
|
};
|