WIP meteostation with ESP8266
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
esp8266-meteo/main/cmd_wifi.c

285 lines
8.3 KiB

/* Console example — WiFi commands
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.
*/
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "tcpip_adapter.h"
#include "esp_event_loop.h"
#include "cmd_wifi.h"
#include "nvs.h"
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(__func__, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
void initialise_wifi(void)
{
esp_err_t rv;
esp_log_level_set("wifi", ESP_LOG_WARN);
static bool initialized = false;
if (initialized) {
return;
}
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_FLASH) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
nvs_handle_t hnvs;
ESP_ERROR_CHECK( nvs_open("wifi", NVS_READONLY, &hnvs) );
uint8_t use_dhcpc;
rv = nvs_get_u8(hnvs, "use_dhcpc", &use_dhcpc);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to read 'use_dhcpc'");
}
if (!use_dhcpc) {
char ip[16], gw[16], mask[16];
size_t iplen = 16;
size_t gwlen = 16;
size_t masklen = 16;
rv = nvs_get_str(hnvs, "static_ip", ip, &iplen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_ip'");
}
rv = nvs_get_str(hnvs, "static_gw", gw, &gwlen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_gw'");
}
rv = nvs_get_str(hnvs, "static_mask", mask, &masklen);
if (rv != ESP_OK) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to load 'static_mask'");
}
printf("Static IP config: IP: %s, GW: %s, Mask: %s\n", ip, gw, mask);
tcpip_adapter_ip_info_t ip_info;
if (!use_dhcpc) {
ip_info.ip.addr = ipaddr_addr(ip);
ip_info.gw.addr = ipaddr_addr(gw);
ip_info.netmask.addr = ipaddr_addr(mask);
if (ip_info.ip.addr == IPADDR_NONE || ip_info.gw.addr == IPADDR_NONE || ip_info.netmask.addr == IPADDR_NONE) {
use_dhcpc = 1;
ESP_LOGW(__func__, "Fail to parse static IP config");
}
}
if (!use_dhcpc) {
tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
}
}
nvs_commit(hnvs);
nvs_close(hnvs);
ESP_ERROR_CHECK( esp_wifi_connect() );
initialized = true;
}
static bool wifi_join(const char* ssid, const char* pass, int timeout_ms)
{
initialise_wifi();
wifi_config_t wifi_config = { 0 };
strncpy((char*) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
if (pass) {
strncpy((char*) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password));
}
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_connect() );
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
1, 1, timeout_ms / portTICK_PERIOD_MS);
return (bits & CONNECTED_BIT) != 0;
}
/** Arguments used by 'join' function */
static struct {
struct arg_int *timeout;
struct arg_str *ssid;
struct arg_str *password;
struct arg_end *end;
} join_args;
static int connect(int argc, char** argv)
{
int nerrors = arg_parse(argc, argv, (void**) &join_args);
if (nerrors != 0) {
arg_print_errors(stderr, join_args.end, argv[0]);
return 1;
}
ESP_LOGI(__func__, "Connecting to '%s'",
join_args.ssid->sval[0]);
bool connected = wifi_join(join_args.ssid->sval[0],
join_args.password->sval[0],
join_args.timeout->ival[0]);
if (!connected) {
ESP_LOGW(__func__, "Connection timed out");
return 1;
}
ESP_LOGI(__func__, "Connected");
return 0;
}
void console_register_wifi()
{
join_args.timeout = arg_int0(NULL, "timeout", "<t>", "Connection timeout, ms");
join_args.timeout->ival[0] = 5000; // set default value
join_args.ssid = arg_str1(NULL, NULL, "<ssid>", "SSID of AP");
join_args.password = arg_str0(NULL, NULL, "<pass>", "PSK of AP");
join_args.end = arg_end(2);
const esp_console_cmd_t join_cmd = {
.command = "join",
.help = "Join WiFi AP as a station",
.hint = NULL,
.func = &connect,
.argtable = &join_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&join_cmd) );
}
/** Arguments used by 'join' function */
static struct {
struct arg_lit *dhcp_on;
struct arg_lit *dhcp_off;
struct arg_str *static_ip;
struct arg_str *static_gw;
struct arg_str *static_mask;
struct arg_end *end;
} ip_args;
static int ipcmd(int argc, char** argv)
{
esp_err_t rv;
int nerrors = arg_parse(argc, argv, (void**) &ip_args);
if (nerrors != 0) {
arg_print_errors(stderr, ip_args.end, argv[0]);
return 1;
}
nvs_handle_t hnvs;
ESP_ERROR_CHECK( nvs_open("wifi", NVS_READWRITE, &hnvs) );
if (ip_args.dhcp_on->count) {
nvs_set_u8(hnvs, "use_dhcpc", 1);
} else if (ip_args.dhcp_off->count) {
nvs_set_u8(hnvs, "use_dhcpc", 0);
}
if (ip_args.static_ip->count) {
nvs_set_str(hnvs, "static_ip", ip_args.static_ip->sval[0]);
}
if (ip_args.static_gw->count) {
nvs_set_str(hnvs, "static_gw", ip_args.static_gw->sval[0]);
}
if (ip_args.static_mask->count) {
nvs_set_str(hnvs, "static_mask", ip_args.static_mask->sval[0]);
}
// read current config
uint8_t use_dhcpc;
rv = nvs_get_u8(hnvs, "use_dhcpc", &use_dhcpc);
if (rv != ESP_OK) {
use_dhcpc = 1;
}
char ip[16], gw[16], mask[16];
size_t iplen = 16;
size_t gwlen = 16;
size_t masklen = 16;
ip[0] = gw[0] = mask[0] = 0;
nvs_get_str(hnvs, "static_ip", ip, &iplen);
nvs_get_str(hnvs, "static_gw", gw, &gwlen);
nvs_get_str(hnvs, "static_mask", mask, &masklen);
printf("DHCP = %s\n", use_dhcpc ? "Yes (dynamic IP)" : "No (static IP)");
printf("Saved static IP = %s\n", ip);
printf("Saved static GW = %s\n", gw);
printf("Saved static MASK = %s\n", mask);
nvs_close(hnvs);
printf("Any changes are applied after restart.\n");
return 0;
}
void console_register_ip()
{
ip_args.dhcp_on = arg_lit0("d", "dhcp", "Enable DHCP");
ip_args.dhcp_off = arg_lit0("s", "no-dhcp", "Disable DHCP (use static)");
ip_args.static_ip = arg_str0("a", NULL, "<IP>", "Set static IP");
ip_args.static_gw = arg_str0("g", NULL, "<IP>", "Set static GW");
ip_args.static_mask = arg_str0("m", NULL, "<IP>", "Set static MASK (e.g. 255.255.255.0)");
ip_args.end = arg_end(5);
const esp_console_cmd_t ip_cmd = {
.command = "ip",
.help = "Configure TCP/IP",
.hint = NULL,
.func = &ipcmd,
.argtable = &ip_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&ip_cmd) );
}