esp-idf/examples/provisioning/ble_prov/main/app_prov_handlers.c
Mahavir Jain 04b8564249 provisioning: use memcpy instead of strncpy for copying SSID
Per WiFi library requirement, SSID can be non-null terminated string
if its length goes to 32 bytes (maximum). Use of strncpy in this case,
along with compiler optimization level -O2 results in some warnings
for potential use of non-null terminated strings.

Fix here ensures use of memcpy to copy SSID string upto appropriate
desired length. This helps to avoid compiler specific workaround
flags added earlier.

Closes https://github.com/espressif/esp-idf/issues/5866
Closes IDFGH-3983
2020-09-17 15:54:23 +05:30

136 lines
4.3 KiB
C

/* 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 <esp_netif.h>
#include <wifi_provisioning/wifi_config.h>
#include "app_prov.h"
static const char* TAG = "app_prov_handler";
/* 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)
{
/* Initialize to zero */
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 */
esp_netif_ip_info_t ip_info;
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info);
esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.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;
}
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
{
wifi_config_t *wifi_cfg = get_config(ctx);
if (wifi_cfg) {
free_config(ctx);
}
wifi_cfg = new_config(ctx);
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);
/* Using memcpy 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 */
const size_t ssid_len = strnlen(req_data->ssid, sizeof(wifi_cfg->sta.ssid));
/* Ensure SSID less than 32 bytes is null terminated */
memset(wifi_cfg->sta.ssid, 0, sizeof(wifi_cfg->sta.ssid));
memcpy(wifi_cfg->sta.ssid, req_data->ssid, ssid_len);
strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password));
return ESP_OK;
}
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
{
wifi_config_t *wifi_cfg = get_config(ctx);
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");
free_config(ctx);
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,
.ctx = NULL
};