feat(wifi): scan wifi list handler
This commit is contained in:
parent
42536f1bad
commit
cf802569c9
@ -332,7 +332,7 @@
|
|||||||
|
|
||||||
<button class="save-btn" id="saveButton">💾 СОХРАНИТЬ УСТАНОВКИ</button>
|
<button class="save-btn" id="saveButton">💾 СОХРАНИТЬ УСТАНОВКИ</button>
|
||||||
</div>
|
</div>
|
||||||
<footer>⚡IoT контроллер давления | © Vladislav Kan <thek4n@yandex.ru></footer>
|
<footer>⚡IoT Pump pressure controller | © Vladislav Kan <thek4n@yandex.ru></footer>
|
||||||
</div>
|
</div>
|
||||||
<div id="toastMsg" class="toast-msg">✓ Пороги успешно сохранены</div>
|
<div id="toastMsg" class="toast-msg">✓ Пороги успешно сохранены</div>
|
||||||
|
|
||||||
|
|||||||
@ -197,8 +197,8 @@
|
|||||||
<path d="M12 2C7.6 2 3.7 3.9 1 7L12 20L23 7C20.3 3.9 16.4 2 12 2Z" fill="#6bcfb8" fill-opacity="0.4"/>
|
<path d="M12 2C7.6 2 3.7 3.9 1 7L12 20L23 7C20.3 3.9 16.4 2 12 2Z" fill="#6bcfb8" fill-opacity="0.4"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h1>Подключение к Wi‑Fi</h1>
|
<h1>Wi-Fi Connection</h1>
|
||||||
<div class="sub">настройте доступ к сети</div>
|
<div class="sub">Enter wifi ssid and password to connect device to local network</div>
|
||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<label>
|
<label>
|
||||||
@ -207,9 +207,9 @@
|
|||||||
<line x1="8" y1="21" x2="16" y2="21"></line>
|
<line x1="8" y1="21" x2="16" y2="21"></line>
|
||||||
<line x1="12" y1="17" x2="12" y2="21"></line>
|
<line x1="12" y1="17" x2="12" y2="21"></line>
|
||||||
</svg>
|
</svg>
|
||||||
SSID (имя сети)
|
SSID (Network name)
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="ssidInput" placeholder="Например: MyHomeWiFi" autocomplete="off">
|
<input type="text" id="ssidInput" placeholder="Example: MyHomeWiFi" autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@ -218,7 +218,7 @@
|
|||||||
<rect x="5" y="11" width="14" height="10" rx="2" ry="2"></rect>
|
<rect x="5" y="11" width="14" height="10" rx="2" ry="2"></rect>
|
||||||
<path d="M8 11V8a4 4 0 0 1 8 0v3"></path>
|
<path d="M8 11V8a4 4 0 0 1 8 0v3"></path>
|
||||||
</svg>
|
</svg>
|
||||||
Пароль
|
Password
|
||||||
</label>
|
</label>
|
||||||
<div style="position: relative;">
|
<div style="position: relative;">
|
||||||
<input type="password" id="passwordInput" placeholder="··········" autocomplete="off" style="padding-right: 50px;">
|
<input type="password" id="passwordInput" placeholder="··········" autocomplete="off" style="padding-right: 50px;">
|
||||||
@ -239,7 +239,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Save settings
|
Save settings
|
||||||
</button>
|
</button>
|
||||||
<footer>⚡IoT контроллер давления | © Vladislav Kan <thek4n@yandex.ru></footer>
|
<footer>⚡IoT Pump pressure controller | © Vladislav Kan <thek4n@yandex.ru></footer>
|
||||||
</div>
|
</div>
|
||||||
<div id="toastMsg" class="toast-msg">✓ Wi-Fi settings sent</div>
|
<div id="toastMsg" class="toast-msg">✓ Wi-Fi settings sent</div>
|
||||||
|
|
||||||
|
|||||||
192
main/main.c
192
main/main.c
@ -87,6 +87,8 @@
|
|||||||
#define DEFAULT_THRESHOLD_LOW 100
|
#define DEFAULT_THRESHOLD_LOW 100
|
||||||
#define DEFAULT_THRESHOLD_UP 300
|
#define DEFAULT_THRESHOLD_UP 300
|
||||||
|
|
||||||
|
#define MAX_AP_SCAN_RESULTS 20
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Error codes
|
// Error codes
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -507,6 +509,9 @@ static app_error_t wifi_softap_init(void) {
|
|||||||
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
|
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
|
||||||
CHECK_PTR(ap_netif, APP_ERR_WIFI_INIT_FAIL);
|
CHECK_PTR(ap_netif, APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
|
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
|
||||||
|
CHECK_PTR(sta_netif, APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
CHECK_ERROR(esp_wifi_init(&cfg), APP_ERR_WIFI_INIT_FAIL);
|
CHECK_ERROR(esp_wifi_init(&cfg), APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
@ -525,8 +530,23 @@ static app_error_t wifi_softap_init(void) {
|
|||||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_ERROR(esp_wifi_set_mode(WIFI_MODE_AP), APP_ERR_WIFI_INIT_FAIL);
|
CHECK_ERROR(esp_wifi_set_mode(WIFI_MODE_APSTA), APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
CHECK_ERROR(esp_wifi_set_config(WIFI_IF_AP, &wifi_config), APP_ERR_WIFI_INIT_FAIL);
|
CHECK_ERROR(esp_wifi_set_config(WIFI_IF_AP, &wifi_config), APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
|
wifi_config_t sta_config = {
|
||||||
|
.sta = {
|
||||||
|
.ssid = "",
|
||||||
|
.password = "",
|
||||||
|
.scan_method = WIFI_FAST_SCAN,
|
||||||
|
.sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
|
||||||
|
.threshold.rssi = -127,
|
||||||
|
.threshold.authmode = WIFI_AUTH_OPEN,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
CHECK_ERROR(esp_wifi_set_config(WIFI_IF_STA, &sta_config), APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
CHECK_ERROR(esp_wifi_start(), APP_ERR_WIFI_INIT_FAIL);
|
CHECK_ERROR(esp_wifi_start(), APP_ERR_WIFI_INIT_FAIL);
|
||||||
|
|
||||||
esp_netif_ip_info_t ip_info;
|
esp_netif_ip_info_t ip_info;
|
||||||
@ -599,15 +619,37 @@ static app_error_t mdns_init_service(void) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
static esp_err_t send_json_response(httpd_req_t *req, const char *format, ...) {
|
static esp_err_t send_json_response(httpd_req_t *req, const char *format, ...) {
|
||||||
char response[256];
|
esp_err_t ret = ESP_OK;
|
||||||
|
char *response = NULL;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
va_list args_copy;
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsnprintf(response, sizeof(response), format, args);
|
va_copy(args_copy, args);
|
||||||
|
int len = vsnprintf(NULL, 0, format, args_copy);
|
||||||
|
va_end(args_copy);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Format error");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = malloc(len + 1);
|
||||||
|
if (response == NULL) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Out of memory");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf(response, len + 1, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
httpd_resp_set_type(req, "application/json");
|
httpd_resp_set_type(req, "application/json");
|
||||||
httpd_resp_send(req, response, strlen(response));
|
ret = httpd_resp_send(req, response, len);
|
||||||
return ESP_OK;
|
|
||||||
|
free(response);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t receive_http_content(httpd_req_t *req, char **content) {
|
static esp_err_t receive_http_content(httpd_req_t *req, char **content) {
|
||||||
@ -796,6 +838,139 @@ static esp_err_t setup_set_settings_handler(httpd_req_t *req) {
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static esp_err_t setup_get_wifi_list_handler(httpd_req_t *req) {
|
||||||
|
esp_err_t ret;
|
||||||
|
uint16_t ap_count = 0;
|
||||||
|
wifi_ap_record_t ap_info[MAX_AP_SCAN_RESULTS];
|
||||||
|
memset(ap_info, 0, sizeof(ap_info));
|
||||||
|
|
||||||
|
// Получаем текущий режим Wi-Fi
|
||||||
|
wifi_mode_t current_mode;
|
||||||
|
ret = esp_wifi_get_mode(¤t_mode);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"Failed to get WiFi mode\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запускаем сканирование
|
||||||
|
wifi_scan_config_t scan_config = {
|
||||||
|
.ssid = NULL,
|
||||||
|
.bssid = NULL,
|
||||||
|
.channel = 0,
|
||||||
|
.show_hidden = true,
|
||||||
|
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
|
||||||
|
.scan_time = {
|
||||||
|
.active = {
|
||||||
|
.min = 100,
|
||||||
|
.max = 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = esp_wifi_scan_start(&scan_config, true);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"Failed to start WiFi scan\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp_wifi_scan_get_ap_num(&ap_count);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"Failed to get AP count\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_count > MAX_AP_SCAN_RESULTS) {
|
||||||
|
ap_count = MAX_AP_SCAN_RESULTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp_wifi_scan_get_ap_records(&ap_count, ap_info);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"Failed to get AP records\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON *root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"JSON creation failed\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddBoolToObject(root, "success", true);
|
||||||
|
|
||||||
|
cJSON *networks_array = cJSON_CreateArray();
|
||||||
|
if (networks_array == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"JSON array creation failed\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ap_count; i++) {
|
||||||
|
cJSON *network = cJSON_CreateObject();
|
||||||
|
if (network == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ssid_str[33];
|
||||||
|
memcpy(ssid_str, ap_info[i].ssid, 32);
|
||||||
|
ssid_str[32] = '\0';
|
||||||
|
cJSON_AddStringToObject(network, "ssid", ssid_str);
|
||||||
|
|
||||||
|
// RSSI (сигнал)
|
||||||
|
cJSON_AddNumberToObject(network, "rssi", ap_info[i].rssi);
|
||||||
|
|
||||||
|
// Тип шифрования (в читаемом виде)
|
||||||
|
const char *auth_mode_str;
|
||||||
|
switch (ap_info[i].authmode) {
|
||||||
|
case WIFI_AUTH_OPEN:
|
||||||
|
auth_mode_str = "Open";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WEP:
|
||||||
|
auth_mode_str = "WEP";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA_PSK:
|
||||||
|
auth_mode_str = "WPA-PSK";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA2_PSK:
|
||||||
|
auth_mode_str = "WPA2-PSK";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA_WPA2_PSK:
|
||||||
|
auth_mode_str = "WPA/WPA2-PSK";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA3_PSK:
|
||||||
|
auth_mode_str = "WPA3-PSK";
|
||||||
|
break;
|
||||||
|
case WIFI_AUTH_WPA2_WPA3_PSK:
|
||||||
|
auth_mode_str = "WPA2/WPA3-PSK";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
auth_mode_str = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cJSON_AddStringToObject(network, "auth_mode", auth_mode_str);
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(networks_array, network);
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_AddItemToObject(root, "networks", networks_array);
|
||||||
|
cJSON_AddNumberToObject(root, "count", ap_count);
|
||||||
|
|
||||||
|
char *json_string = cJSON_PrintUnformatted(root);
|
||||||
|
if (json_string == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
send_json_response(req, "{\"success\":false,\"error\":\"JSON string conversion failed\"}");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_json_response(req, json_string);
|
||||||
|
|
||||||
|
free(json_string);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// HTTP server tasks
|
// HTTP server tasks
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -831,7 +1006,7 @@ static app_error_t setup_http_server_start(void) {
|
|||||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||||
config.server_port = CONFIG_WEBINTERFACE_PORT;
|
config.server_port = CONFIG_WEBINTERFACE_PORT;
|
||||||
config.max_uri_handlers = 10;
|
config.max_uri_handlers = 10;
|
||||||
config.stack_size = 4096;
|
config.stack_size = 8192;
|
||||||
|
|
||||||
CHECK_ERROR(httpd_start(&server, &config), APP_ERR_HTTP_SERVER_START_FAIL);
|
CHECK_ERROR(httpd_start(&server, &config), APP_ERR_HTTP_SERVER_START_FAIL);
|
||||||
ESP_LOGI(TAG, "Setup HTTP server started on port %d", config.server_port);
|
ESP_LOGI(TAG, "Setup HTTP server started on port %d", config.server_port);
|
||||||
@ -846,6 +1021,11 @@ static app_error_t setup_http_server_start(void) {
|
|||||||
};
|
};
|
||||||
CHECK_ERROR(httpd_register_uri_handler(server, &settings), APP_ERR_HTTP_SERVER_START_FAIL);
|
CHECK_ERROR(httpd_register_uri_handler(server, &settings), APP_ERR_HTTP_SERVER_START_FAIL);
|
||||||
|
|
||||||
|
httpd_uri_t wifi_list = {
|
||||||
|
.uri = "/wifi_list", .method = HTTP_GET, .handler = setup_get_wifi_list_handler
|
||||||
|
};
|
||||||
|
CHECK_ERROR(httpd_register_uri_handler(server, &wifi_list), APP_ERR_HTTP_SERVER_START_FAIL);
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user