Wifi_Onboarding/main/main.c
2025-02-13 04:53:25 +00:00

135 lines
4.2 KiB
C

#include <string.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_netif.h"
#include "esp_http_server.h"
#define AP_SSID "ESP32_Setup"
#define AP_PASS ""
static const char *TAG = "wifi_setup";
static esp_err_t save_credentials(const char *ssid, const char *password) {
nvs_handle_t nvs;
ESP_ERROR_CHECK(nvs_open("storage", NVS_READWRITE, &nvs));
ESP_ERROR_CHECK(nvs_set_str(nvs, "wifi_ssid", ssid));
ESP_ERROR_CHECK(nvs_set_str(nvs, "wifi_pass", password));
ESP_ERROR_CHECK(nvs_commit(nvs));
nvs_close(nvs);
return ESP_OK;
}
static esp_err_t load_credentials(char *ssid, char *password) {
nvs_handle_t nvs;
size_t ssid_len = 32, pass_len = 64;
ESP_ERROR_CHECK(nvs_open("storage", NVS_READWRITE, &nvs));
esp_err_t ssid_err = nvs_get_str(nvs, "wifi_ssid", ssid, &ssid_len);
esp_err_t pass_err = nvs_get_str(nvs, "wifi_pass", password, &pass_len);
nvs_close(nvs);
return (ssid_err == ESP_OK && pass_err == ESP_OK) ? ESP_OK : ESP_FAIL;
}
// HTML Page for input
const char *html_form = "<!DOCTYPE html>\
<html>\
<title>ESP32 Wi-Fi Setup</title>\
<body>\
<h2>Enter Wi-Fi Credentials</h2>\
<form action=\"/connect\" method=\"post\">\
SSID: <input type=\"text\" name=\"ssid\"><br><br>\
Password: <input type=\"password\" name=\"password\"><br><br>\
<input type=\"submit\" value=\"Connect\">\
</form></body></html>";
static esp_err_t handle_root(httpd_req_t *req) {
httpd_resp_send(req, html_form, HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
static esp_err_t handle_connect(httpd_req_t *req) {
char buf[512]; // Increase buffer size if needed
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
if (len <= 0) return ESP_FAIL;
buf[len] = '\0';
// Parse POST data from body
char ssid[32], password[64];
int ret = sscanf(buf, "ssid=%31[^&]&password=%63s", ssid, password);
if (ret != 2) {
ESP_LOGE(TAG, "Failed to parse form data");
httpd_resp_send(req, "Invalid data", HTTPD_RESP_USE_STRLEN);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Received SSID: %s, Password: %s", ssid, password);
save_credentials(ssid, password);
httpd_resp_send(req, "Saved! Rebooting...", HTTPD_RESP_USE_STRLEN);
vTaskDelay(2000 / portTICK_PERIOD_MS);
esp_restart(); // Restart to apply new credentials
return ESP_OK;
}
void start_webserver() {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_handle_t server = NULL;
if (httpd_start(&server, &config) == ESP_OK) {
httpd_uri_t root_uri = { .uri = "/", .method = HTTP_GET, .handler = handle_root };
httpd_uri_t connect_uri = { .uri = "/connect", .method = HTTP_POST, .handler = handle_connect };
httpd_register_uri_handler(server, &root_uri);
httpd_register_uri_handler(server, &connect_uri);
}
}
void start_ap_mode() {
esp_netif_create_default_wifi_ap();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_mode(WIFI_MODE_AP);
wifi_config_t ap_config = {
.ap = { .ssid = AP_SSID, .password = AP_PASS, .max_connection = 4, .authmode = WIFI_AUTH_WPA_WPA2_PSK }
};
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
esp_wifi_start();
start_webserver();
}
void connect_to_wifi() {
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_mode(WIFI_MODE_STA);
char ssid[32] = "", password[64] = "";
if (load_credentials(ssid, password) == ESP_OK) {
wifi_config_t sta_config = {};
strncpy((char *)sta_config.sta.ssid, ssid, sizeof(sta_config.sta.ssid));
strncpy((char *)sta_config.sta.password, password, sizeof(sta_config.sta.password));
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
esp_wifi_start();
esp_wifi_connect();
ESP_LOGI(TAG, "Connecting to SSID: %s", ssid);
} else {
ESP_LOGW(TAG, "No saved credentials, starting in AP mode.");
start_ap_mode();
}
}
void app_main() {
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
connect_to_wifi();
}