0
0
Fork 0

feat(wifi ap) ap ssid and password can be changed and saved to flash

This commit is contained in:
kerms 2024-07-12 17:00:24 +08:00
parent 7d4d3484f5
commit c3f4e8f651
10 changed files with 199 additions and 44 deletions

View File

@ -1,6 +1,7 @@
#include "wifi_api.h"
#include "wifi_manager.h"
#include "wifi_configuration.h"
#include "wifi_storage.h"
#include <esp_wifi.h>
void wifi_api_sta_get_ap_info(wifi_api_ap_info_t *ap_info)
@ -10,6 +11,7 @@ void wifi_api_sta_get_ap_info(wifi_api_ap_info_t *ap_info)
strncpy(ap_info->ssid, (char *)ap_record.ssid, sizeof(ap_info->ssid));
strncpy(ap_info->mac, (char *)ap_record.bssid, sizeof(ap_info->mac));
ap_info->rssi = ap_record.rssi;
ap_info->password[0] = '\0';
esp_netif_t *sta_netif = wifi_manager_get_sta_netif();
esp_netif_ip_info_t ip_info;
@ -21,7 +23,15 @@ void wifi_api_sta_get_ap_info(wifi_api_ap_info_t *ap_info)
void wifi_api_ap_get_info(wifi_api_ap_info_t *ap_info)
{
wifi_credential_t credential;
int err = wifi_data_get_ap_credential(&credential);
if (err) {
strncpy(ap_info->ssid, WIFI_DEFAULT_AP_SSID, strlen(WIFI_DEFAULT_AP_SSID)+1);
strncpy(ap_info->password, WIFI_DEFAULT_AP_PASS, strlen(WIFI_DEFAULT_AP_PASS)+1);
} else {
strncpy(ap_info->ssid, credential.ssid, sizeof(ap_info->ssid));
strncpy(ap_info->password, credential.password, sizeof(ap_info->password));
}
esp_wifi_get_mac(WIFI_IF_AP, (uint8_t *) &ap_info->mac);
IP4_ADDR_EXPAND(&ap_info->ip, WIFI_DEFAULT_AP_IP);
IP4_ADDR_EXPAND(&ap_info->gateway, WIFI_DEFAULT_AP_GATEWAY);
@ -31,15 +41,15 @@ void wifi_api_ap_get_info(wifi_api_ap_info_t *ap_info)
static int rssi_comp(const void *a, const void *b)
{
const wifi_api_ap_info_t *r1 = a;
const wifi_api_ap_info_t *r2 = b;
const wifi_api_ap_scan_info_t *r1 = a;
const wifi_api_ap_scan_info_t *r2 = b;
return r2->rssi - r1->rssi;
}
/**
* @brief blocking function
*/
int wifi_api_get_scan_list(uint16_t *number, wifi_api_ap_info_t *ap_info)
int wifi_api_get_scan_list(uint16_t *number, wifi_api_ap_scan_info_t *ap_info)
{
wifi_ap_record_t *records;
int err;
@ -64,7 +74,7 @@ int wifi_api_get_scan_list(uint16_t *number, wifi_api_ap_info_t *ap_info)
}
free(records);
qsort(ap_info, *number, sizeof(wifi_api_ap_info_t), rssi_comp);
qsort(ap_info, *number, sizeof(wifi_api_ap_scan_info_t), rssi_comp);
return 0;
}
@ -72,9 +82,9 @@ static wifi_api_scan_done_cb scan_done_cb;
static void wifi_manager_scan_done(uint16_t ap_found, wifi_ap_record_t *records, void *arg)
{
wifi_api_ap_info_t *ap_info;
wifi_api_ap_scan_info_t *ap_info;
ap_info = malloc(ap_found * sizeof(wifi_api_ap_info_t));
ap_info = malloc(ap_found * sizeof(wifi_api_ap_scan_info_t));
for (int i = 0; i < ap_found; ++i) {
strncpy(ap_info[i].ssid, (char *) records[i].ssid, sizeof(ap_info[i].ssid));
strncpy(ap_info[i].mac, (char *) records[i].bssid, sizeof(ap_info[i].mac));

View File

@ -14,17 +14,28 @@ typedef enum wifi_api_json_cmd_t {
WIFI_API_JSON_AP_GET_INFO = 5,
WIFI_API_JSON_GET_MODE = 6, /* req:{ }, ret:{mode, [delay_off], [delay_on]} */
WIFI_API_JSON_SET_MODE = 7, /* req:{mode, [delay_off], [delay_on]} */
WIFI_API_JSON_SET_AP_CRED = 8, /* ssid[32] + password[64] */
} wifi_api_json_cmd_t;
typedef struct wifi_api_ap_info_t {
ip4_addr_t ip;
ip4_addr_t gateway;
ip4_addr_t netmask;
char ssid[33];
char ssid[32+1];
char password[64+1];
char mac[6];
signed char rssi;
} wifi_api_ap_info_t;
typedef struct wifi_api_ap_scan_info_t {
ip4_addr_t ip;
ip4_addr_t gateway;
ip4_addr_t netmask;
char ssid[32+1];
char mac[6];
signed char rssi;
} wifi_api_ap_scan_info_t;
typedef enum wifi_apsta_mode_e {
/* permanent */
WIFI_AP_AUTO_STA_ON = 0,
@ -45,11 +56,11 @@ void wifi_api_sta_get_ap_info(wifi_api_ap_info_t *ap_info);
void wifi_api_ap_get_info(wifi_api_ap_info_t *ap_info);
typedef void (*wifi_api_scan_done_cb)(uint16_t found, wifi_api_ap_info_t *aps, void *arg);
typedef void (*wifi_api_scan_done_cb)(uint16_t found, wifi_api_ap_scan_info_t *aps, void *arg);
int wifi_api_trigger_scan(uint16_t *max_ap_count, wifi_api_scan_done_cb cb, void *cb_arg);
int wifi_api_get_scan_list(uint16_t *number, wifi_api_ap_info_t *ap_info);
int wifi_api_get_scan_list(uint16_t *number, wifi_api_ap_scan_info_t *ap_info);
int wifi_api_connect(const char *ssid, const char *password);

View File

@ -6,6 +6,8 @@
#include <stdio.h>
#include <esp_log.h>
#include "wifi_storage.h"
#define TAG __FILENAME__
static int wifi_api_json_sta_get_ap_info(api_json_req_t *req);
@ -21,6 +23,7 @@ static int wifi_api_json_ap_get_info(api_json_req_t *req);
static int wifi_api_json_set_mode(api_json_req_t *req);
static int wifi_api_json_get_mode(api_json_req_t *req);
static int wifi_api_json_set_ap_cred(api_json_req_t *req);
/* the upper caller call cb() with void *, this let us use custom function arg */
static int async_helper_cb(void *arg)
@ -59,12 +62,27 @@ static int on_json_req(uint16_t cmd, api_json_req_t *req, api_json_module_async_
return wifi_api_json_get_mode(req);
case WIFI_API_JSON_SET_MODE:
return wifi_api_json_set_mode(req);
case WIFI_API_JSON_SET_AP_CRED:
return wifi_api_json_set_ap_cred(req);
}
ESP_LOGI(TAG, "cmd %d not executed\n", cmd);
return API_JSON_UNSUPPORTED_CMD;
}
/* ****
* register module
* */
static int wifi_api_json_init(api_json_module_cfg_t *cfg)
{
cfg->on_req = on_json_req;
cfg->module_id = WIFI_MODULE_ID;
return 0;
}
API_JSON_MODULE_REGISTER(wifi_api_json_init)
static int wifi_api_json_sta_get_ap_info(api_json_req_t *req)
{
wifi_api_ap_info_t ap_info;
@ -83,7 +101,7 @@ static int wifi_api_json_ap_get_info(api_json_req_t *req)
static int wifi_api_json_get_scan(api_json_req_t *req)
{
wifi_api_ap_info_t ap_info[20];
wifi_api_ap_scan_info_t ap_info[20];
uint16_t max_count = 20;
int err;
@ -133,7 +151,6 @@ int wifi_api_json_set_mode(api_json_req_t *req)
return API_JSON_OK;
}
wifi_apsta_mode_e mode = value;
wifi_mode_t status;
err = wifi_manager_change_mode(mode);
if (err) {
@ -181,15 +198,27 @@ int wifi_api_json_disconnect(api_json_req_t *req)
return wifi_api_disconnect();
}
/* ****
* register module
* */
static int wifi_api_json_init(api_json_module_cfg_t *cfg)
int wifi_api_json_set_ap_cred(api_json_req_t *req)
{
cfg->on_req = on_json_req;
cfg->module_id = WIFI_MODULE_ID;
wifi_credential_t credential;
int err;
err = wifi_api_json_get_credential(req->in, (char *)&credential.ssid, (char *)&credential.password);
if (err) {
return API_JSON_PROPERTY_ERR;
}
if (strlen(credential.password) < 8) {
req->out = wifi_api_json_create_err_rsp(req->in, "password < 8");
return API_JSON_OK;
}
err = wifi_data_save_ap_credential(&credential);
if (err) {
return API_JSON_INTERNAL_ERR;
}
wifi_manager_set_ap_credential(&credential);
return 0;
}
API_JSON_MODULE_REGISTER(wifi_api_json_init)

View File

@ -21,6 +21,9 @@ cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info, wifi_api_jso
cJSON_AddStringToObject(root, "netmask", ip4addr_ntoa(&ap_info->netmask));
cJSON_AddNumberToObject(root, "rssi", ap_info->rssi);
cJSON_AddStringToObject(root, "ssid", ap_info->ssid);
if (ap_info->password[0]) {
cJSON_AddStringToObject(root, "password", ap_info->password);
}
char mac_str[18];
char *m = ap_info->mac;
@ -31,7 +34,7 @@ cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info, wifi_api_jso
return root;
}
cJSON *wifi_api_json_serialize_scan_list(wifi_api_ap_info_t *aps_info, uint16_t count)
cJSON *wifi_api_json_serialize_scan_list(wifi_api_ap_scan_info_t *aps_info, uint16_t count)
{
cJSON *root;
char mac_str[18];
@ -110,3 +113,20 @@ cJSON *wifi_api_json_add_int_item(cJSON *root, const char *name, int item)
cJSON_AddNumberToObject(root, name, item);
return root;
}
int wifi_api_json_get_credential(cJSON *root, char *ssid, char *password)
{
cJSON *json_ssid = cJSON_GetObjectItem(root, "ssid");
cJSON *json_password = cJSON_GetObjectItem(root, "password");
if (!cJSON_IsString(json_ssid) || !cJSON_IsString(json_password)) {
return 1;
}
strncpy(ssid, cJSON_GetStringValue(json_ssid), 31);
strncpy(password, cJSON_GetStringValue(json_password), 63);
ssid[31] = '\0';
password[64] = '\0';
return 0;
}

View File

@ -4,7 +4,7 @@
#include "wifi_api.h"
cJSON *wifi_api_json_serialize_ap_info(wifi_api_ap_info_t *ap_info, wifi_api_json_cmd_t cmd);
cJSON *wifi_api_json_serialize_scan_list(wifi_api_ap_info_t *aps_info, uint16_t count);
cJSON *wifi_api_json_serialize_scan_list(wifi_api_ap_scan_info_t *aps_info, uint16_t count);
cJSON *wifi_api_json_serialize_ap_auto(wifi_apsta_mode_e mode, int ap_on_delay, int ap_off_delay);
cJSON *wifi_api_json_serialize_get_mode(wifi_apsta_mode_e mode, int status, int ap_on_delay, int ap_off_delay);
@ -13,5 +13,6 @@ cJSON *wifi_api_json_create_err_rsp(cJSON *req, const char *msg);
cJSON *wifi_api_json_add_int_item(cJSON *root, const char *name, int item);
int wifi_api_json_utils_get_int(cJSON *req, const char *name, int *out_value);
int wifi_api_json_get_credential(cJSON *root, char *ssid, char *password);
#endif //WIFI_JSON_UTILS_H_GUARD

View File

@ -94,29 +94,33 @@ void wifi_manager_init(void)
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL, NULL));
ctx.is_sta_connected = false;
ctx.permanent_mode = WIFI_AP_AUTO_STA_ON;
ctx.mode = WIFI_MODE_APSTA;
ctx.ap_on_delay_tick = pdMS_TO_TICKS(5000);
ctx.ap_off_delay_tick = pdMS_TO_TICKS(10000);
ctx.delayed_stopAP_task = NULL;
ctx.delayed_startAP_task = NULL;
ctx.try_connect_count = 0;
err = wifi_data_get_wifi_mode(&ctx.permanent_mode);
if (err) {
ESP_LOGI(TAG, "use default mode: %d", ctx.permanent_mode);
ctx.permanent_mode = WIFI_AP_AUTO_STA_ON;
ctx.mode = WIFI_MODE_APSTA;
} else {
ctx.mode = ctx.permanent_mode & 0x3; /* 0b1XX */
}
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(ctx.mode));
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
{
wifi_config_t ap_config = {0};
strncpy((char *)ap_config.ap.ssid, WIFI_DEFAULT_AP_SSID, 32);
strncpy((char *)ap_config.ap.password, WIFI_DEFAULT_AP_PASS, 64);
ap_config.ap.authmode = WIFI_AUTH_WPA2_WPA3_PSK;
ap_config.ap.max_connection = 4;
ap_config.ap.channel = 6;
ap_config.ap.ssid_hidden = 0;
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
wifi_credential_t cred;
err = wifi_data_get_ap_credential(&cred);
if (err || strlen(cred.password) < 8) {
ESP_LOGI(TAG, "used default AP credential");
strncpy((char *)cred.ssid, WIFI_DEFAULT_AP_SSID, 32);
strncpy((char *)cred.password, WIFI_DEFAULT_AP_PASS, 64);
}
wifi_manager_set_ap_credential(&cred);
if (set_default_sta_cred() == 0) {
ESP_LOGI(TAG, "STA connect to saved cred");
@ -318,7 +322,7 @@ int set_default_sta_cred()
{
int err;
wifi_credential_t credential;
err = wifi_data_get_last_conn_cred(&credential);
err = wifi_data_get_sta_last_conn_cred(&credential);
if (err) {
return err;
}
@ -362,7 +366,7 @@ int wifi_manager_connect(const char *ssid, const char *password)
wifi_credential_t credential;
memcpy(credential.ssid, ssid, 32);
memcpy(credential.password, password, 64);
ret = wifi_save_ap_credential(&credential);
ret = wifi_data_save_sta_ap_credential(&credential);
if (ret) {
ESP_LOGE(TAG, "nvs save error: %s", esp_err_to_name(ret));
}
@ -632,3 +636,16 @@ int wifi_manager_get_mode(wifi_apsta_mode_e *mode, wifi_mode_t *status)
*status = ctx.mode;
return 0;
}
int wifi_manager_set_ap_credential(wifi_credential_t *cred)
{
wifi_config_t ap_config = {0};
strncpy((char *)ap_config.ap.ssid, cred->ssid, 32);
strncpy((char *)ap_config.ap.password, cred->password, 64);
ap_config.ap.authmode = WIFI_AUTH_WPA2_WPA3_PSK;
ap_config.ap.max_connection = 4;
ap_config.ap.channel = 6;
ap_config.ap.ssid_hidden = 0;
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
return 0;
}

View File

@ -3,6 +3,7 @@
#include <esp_wifi_types.h>
#include "wifi_api.h"
#include "wifi_storage.h"
void wifi_manager_init();
@ -18,7 +19,7 @@ int wifi_manager_change_mode(wifi_apsta_mode_e mode);
int wifi_manager_get_mode(wifi_apsta_mode_e *mode, wifi_mode_t *status);
int wifi_manager_get_ap_auto_delay(int *ap_on_delay, int *ap_off_delay);
int wifi_manager_set_ap_auto_delay(int *ap_on_delay, int *ap_off_delay);
int wifi_manager_set_ap_credential(wifi_credential_t *cred);
#endif //WIFI_MANAGER_H_GUARD

View File

@ -7,7 +7,7 @@
#define WIFI_NVS_NAMESPACE "wt_wifi"
int wifi_data_get_last_conn_cred(wifi_credential_t *ap_credential)
int wifi_data_get_sta_last_conn_cred(wifi_credential_t *ap_credential)
{
uint32_t ap_bitmap = 0;
nvs_handle_t handle;
@ -36,7 +36,7 @@ int wifi_data_get_last_conn_cred(wifi_credential_t *ap_credential)
/*
* Called when connect to an AP,
*/
int wifi_save_ap_credential(wifi_credential_t *ap_credential)
int wifi_data_save_sta_ap_credential(wifi_credential_t *ap_credential)
{
uint32_t ap_bitmap;
int err;
@ -97,3 +97,63 @@ int wifi_data_save_wifi_mode(wifi_apsta_mode_e mode)
wt_nvs_close(handle);
return WT_NVS_OK;
}
int wifi_data_get_wifi_mode(wifi_apsta_mode_e *mode)
{
nvs_handle_t handle;
int err;
uint8_t mode_u8;
err = wt_nvs_open(WIFI_NVS_NAMESPACE, &handle);
if (err) {
return err;
}
err = wt_nvs_get(handle, KEY_WIFI_APSTA_MODE, &mode_u8, sizeof(mode_u8));
if (err) {
return err;
}
*mode = mode_u8;
wt_nvs_close(handle);
return WT_NVS_OK;
}
int wifi_data_save_ap_credential(wifi_credential_t *ap_credential)
{
nvs_handle_t handle;
int err;
err = wt_nvs_open(WIFI_NVS_NAMESPACE, &handle);
if (err) {
return err;
}
err = wt_nvs_set(handle, KEY_WIFI_AP_CRED, ap_credential, sizeof(wifi_credential_t));
if (err) {
return err;
}
wt_nvs_close(handle);
return 0;
}
int wifi_data_get_ap_credential(wifi_credential_t *ap_credential)
{
nvs_handle_t handle;
int err;
err = wt_nvs_open(WIFI_NVS_NAMESPACE, &handle);
if (err) {
return err;
}
err = wt_nvs_get(handle, KEY_WIFI_AP_CRED, ap_credential, sizeof(wifi_credential_t));
if (err) {
return err;
}
wt_nvs_close(handle);
return 0;
}

View File

@ -9,10 +9,16 @@ typedef struct nvs_wifi_credential_t {
char password[64];
} wifi_credential_t;
int wifi_data_get_last_conn_cred(wifi_credential_t *ap_credential);
int wifi_data_get_sta_last_conn_cred(wifi_credential_t *ap_credential);
int wifi_save_ap_credential(wifi_credential_t *ap_credential);
int wifi_data_save_sta_ap_credential(wifi_credential_t *ap_credential);
int wifi_data_save_wifi_mode(wifi_apsta_mode_e mode);
int wifi_data_get_wifi_mode(wifi_apsta_mode_e *mode);
int wifi_data_get_ap_credential(wifi_credential_t *ap_credential);
int wifi_data_save_ap_credential(wifi_credential_t *ap_credential);
#endif //WIFI_STORAGE_H_GUARD

View File

@ -11,8 +11,8 @@ typedef struct w_cache_t {
typedef enum wt_wifi_key_enum {
KEY_WIFI_RESERVED = 0x000,
/* WIFI */
KEY_WIFI_AP_SSID = 0x1,
KEY_WIFI_AP_PASSWORD = 0x02,
KEY_WIFI_AP_CRED = 0x1,
/* TODO: should have 1 for each AP */
KEY_WIFI_STA_USE_STATIC = 0x03, /* bit[0:31]=[IP, MASK, GATEWAY, DNS] */
@ -25,7 +25,7 @@ typedef enum wt_wifi_key_enum {
KEY_WIFI_STA_LAST_AP_CRED = 0x08, /*!< ssid[32] + password[64] */
KEY_WIFI_STA_AP_BITMAP = 0x09, /* 32 bit */
KEY_UNUSED_100 = 0x0100,
KEY_UNUSED_100 = 0x0100, /* avoid: same as 0x1 */
KEY_WIFI_APSTA_MODE = 0x0101, /* 1B */
} wt_wifi_key;