Skip to content

Commit aaa748e

Browse files
committed
Added NVS
1 parent 7090c5e commit aaa748e

File tree

14 files changed

+505
-68
lines changed

14 files changed

+505
-68
lines changed

main/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ idf_component_register(SRCS
22
"wrappers/task.cpp"
33
"wrappers/netif.cpp"
44
"wrappers/eventgroup.cpp"
5+
"wrappers/nvs.cpp"
56
"wifi.cpp"
67
"smartconfig.cpp"
78
"main.cpp"

main/main.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,42 @@
11
#include "driver/gpio.h"
22
#include "esp_log.h"
33
#include "esp_system.h"
4-
#include "freertos/FreeRTOS.h"
5-
#include "nvs_flash.h"
64

75
#include <vector>
86

97
#include "smartconfig.hpp"
108
#include "wifi.hpp"
9+
#include "wrappers/nvs.hpp"
1110
#include "wrappers/queue.hpp"
1211
#include "wrappers/task.hpp"
1312

1413
static const char *TAG = "main";
1514

1615
#define ESP_INTR_FLAG_DEFAULT 0
1716

18-
static auto gpio_evt_queue = queue::make_queue<uint32_t>(10);
17+
static auto gpio_evt_queue = queue::make_queue<gpio_num_t>(10);
1918

2019
static void IRAM_ATTR gpio_isr_handler(void *arg)
2120
{
22-
uint32_t gpio_num = (uint32_t)arg;
23-
xQueueSendFromISR(gpio_evt_queue->get(), &gpio_num, NULL);
21+
gpio_num_t gpio_num = *reinterpret_cast<const gpio_num_t *>(arg);
22+
auto success = gpio_evt_queue->send_from_isr(gpio_num);
23+
ESP_DRAM_LOGD("gpio_isr_handler", "GPIO[%d] ISR: %s", gpio_num, success ? "success" : "failure");
2424
}
2525

2626
static void gpio_task_example(void *arg)
2727
{
2828
using SmartConfig = sc::SmartConfig::Shared;
2929

30-
uint32_t io_num{};
3130
std::vector<SmartConfig> instances;
31+
wifi::Wifi::nvs_ssid_erase();
32+
wifi::Wifi::nvs_password_erase();
3233
auto wifiobj{wifi::Wifi::get_shared()};
3334

3435
while (true)
3536
{
36-
if (xQueueReceive(gpio_evt_queue->get(), &io_num, portMAX_DELAY))
37+
if (const auto result = gpio_evt_queue->receive())
3738
{
38-
ESP_LOGI(TAG, "GPIO[%lu] intr, val: %d", io_num, gpio_get_level((gpio_num_t)io_num));
39+
ESP_LOGI(TAG, "GPIO[%d] intr, val: %d", result.item, gpio_get_level(result.item));
3940

4041
if (instances.size() >= 5)
4142
{
@@ -55,8 +56,8 @@ static void gpio_task_example(void *arg)
5556
{
5657
ESP_LOGI(TAG, "GPIO task started");
5758

58-
constexpr auto pin = GPIO_NUM_34;
59-
constexpr auto pinmask = 1ULL << pin;
59+
static constexpr auto pin = GPIO_NUM_34;
60+
static constexpr auto pinmask = 1ULL << pin;
6061

6162
// zero-initialize the config structure.
6263
gpio_config_t io_conf = {};
@@ -70,21 +71,19 @@ static void gpio_task_example(void *arg)
7071
gpio_config(&io_conf);
7172

7273
// start gpio task
73-
xTaskCreate(gpio_task_example, "gpio_task_example", 4096, nullptr, 10, NULL);
74+
auto gpio_task = task::make_task(gpio_task_example, "gpio_task_example", 4096, nullptr, 10);
7475

7576
// install gpio isr service
7677
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
7778
// hook isr handler for specific gpio pin
78-
gpio_isr_handler_add(pin, gpio_isr_handler, (void *)pin);
79+
gpio_isr_handler_add(pin, gpio_isr_handler, const_cast<gpio_num_t *>(&pin));
7980

8081
while (true)
8182
vTaskDelay(portMAX_DELAY);
8283
}
8384

8485
int main()
8586
{
86-
ESP_ERROR_CHECK(nvs_flash_init());
87-
8887
auto gpio_task_handle = task::make_task(gpio_task, "gpio_task", 4096, nullptr, 3);
8988

9089
vTaskDelay(portMAX_DELAY);
@@ -93,6 +92,7 @@ int main()
9392

9493
extern "C" void app_main(void)
9594
{
95+
ESP_ERROR_CHECK(nvs::initialise_nvs());
9696
const int ret = main();
9797
ESP_LOGE(TAG, "main() returned %d", ret);
9898
}

main/smartconfig.cpp

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ namespace sc
1010
task::Task SmartConfig::taskhandle{};
1111
eventgroup::Eventgroup SmartConfig::event_group{};
1212

13+
[[nodiscard]] wifi_config_t ssid_pswd_to_config(const smartconfig_event_got_ssid_pswd_t &evt)
14+
{
15+
wifi_config_t wifi_config{};
16+
17+
std::copy(evt.ssid, evt.ssid + std::min(sizeof(evt.ssid), sizeof(wifi_config.sta.ssid)), wifi_config.sta.ssid);
18+
std::copy(evt.password, evt.password + std::min(sizeof(evt.password), sizeof(wifi_config.sta.password)), wifi_config.sta.password);
19+
20+
if (evt.bssid_set)
21+
{
22+
wifi_config.sta.bssid_set = evt.bssid_set;
23+
std::copy(evt.bssid, evt.bssid + std::min(sizeof(evt.bssid), sizeof(wifi_config.sta.bssid)), wifi_config.sta.bssid);
24+
}
25+
26+
return wifi_config;
27+
}
28+
1329
SmartConfig::EventHandlers::handle_success_t SmartConfig::EventHandlers::handle_sc_event(SmartConfig::EventHandlers::args_t args)
1430
{
1531
switch (args.event_id)
@@ -24,42 +40,27 @@ namespace sc
2440
{
2541
ESP_LOGI(TAG, "Got SSID and password");
2642

27-
const smartconfig_event_got_ssid_pswd_t *const evt = reinterpret_cast<const smartconfig_event_got_ssid_pswd_t *>(args.event_data);
28-
wifi_config_t wifi_config{};
43+
wifi_config_t wifi_config{ssid_pswd_to_config(*reinterpret_cast<const smartconfig_event_got_ssid_pswd_t *>(args.event_data))};
44+
45+
const auto [ssidview, passwordview] = wifi::config_to_ssidpasswordview(wifi_config);
46+
ESP_LOGI(TAG, "SSID:%.*s", ssidview.size(), ssidview.data());
47+
ESP_LOGI(TAG, "PASSWORD:%.*s", passwordview.size(), passwordview.data());
2948

30-
std::copy(evt->ssid, evt->ssid + std::min(sizeof(evt->ssid), sizeof(wifi_config.sta.ssid)), wifi_config.sta.ssid);
31-
std::copy(evt->password, evt->password + std::min(sizeof(evt->password), sizeof(wifi_config.sta.password)), wifi_config.sta.password);
32-
if (evt->bssid_set)
49+
if (ssidview.empty() or passwordview.empty())
3350
{
34-
wifi_config.sta.bssid_set = evt->bssid_set;
35-
std::copy(evt->bssid, evt->bssid + std::min(sizeof(evt->bssid), sizeof(wifi_config.sta.bssid)), wifi_config.sta.bssid);
51+
ESP_LOGW(TAG, "SSID or password is empty");
52+
return handle_success_t::FAIL;
3653
}
3754

38-
std::string_view ssid_view(reinterpret_cast<const char *>(wifi_config.sta.ssid), sizeof(wifi_config.sta.ssid));
39-
std::string_view password_view(reinterpret_cast<const char *>(wifi_config.sta.password), sizeof(wifi_config.sta.password));
40-
41-
ESP_LOGI(TAG, "SSID:%.*s", ssid_view.size(), ssid_view.data());
42-
ESP_LOGI(TAG, "PASSWORD:%.*s", password_view.size(), password_view.data());
43-
44-
if (SC_TYPE_ESPTOUCH_V2 == evt->type)
55+
if (not wifiobj->reconnect_to(wifi_config))
4556
{
46-
uint8_t rvd_data[33]{};
47-
ESP_ERROR_CHECK(esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)));
48-
ESP_LOGI(TAG, "RVD_DATA:");
49-
for (const auto i : rvd_data)
50-
{
51-
printf("%02x ", i);
52-
}
53-
printf("\n");
57+
ESP_LOGW(TAG, "Failed to reconnect");
58+
return handle_success_t::FAIL;
5459
}
55-
56-
ESP_ERROR_CHECK(esp_wifi_disconnect());
57-
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
58-
esp_wifi_connect();
5960
break;
6061
}
6162
case SC_EVENT_SEND_ACK_DONE:
62-
xEventGroupSetBits(event_group.get(), ESPTOUCH_DONE_BIT);
63+
eventgroup::set_bits(event_group, ESPTOUCH_DONE_BIT);
6364
break;
6465
[[unlikely]] default:
6566
ESP_LOGW(TAG, "Unhandled SC_EVENT %d", args.event_id);
@@ -72,10 +73,26 @@ namespace sc
7273
{
7374
while (true)
7475
{
75-
const auto uxBits = xEventGroupWaitBits(event_group.get(), ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
76+
// const auto uxBits = xEventGroupWaitBits(event_group.get(), ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
77+
const auto bits = eventgroup::wait_bits(event_group, ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
7678

77-
if (uxBits & ESPTOUCH_DONE_BIT)
79+
// if (uxBits & ESPTOUCH_DONE_BIT)
80+
if (bits)
7881
{
82+
const auto [ssidview, passwordview] = wifi::config_to_ssidpasswordview(wifiobj->config());
83+
84+
if (ssidview.empty() or passwordview.empty()) [[unlikely]]
85+
{
86+
ESP_LOGE(TAG, "SSID or password is empty!");
87+
}
88+
else
89+
{
90+
ESP_LOGI(TAG, "Saving creds to NVS");
91+
92+
wifiobj->nvs_ssid(ssidview);
93+
wifiobj->nvs_password(passwordview);
94+
}
95+
7996
ESP_LOGI(TAG, "Done!");
8097
esp_smartconfig_stop();
8198
state = state_t::DONE;

main/smartconfig.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
#include "esp_event.h"
44
#include "esp_log.h"
5-
#include "esp_netif.h"
65
#include "esp_smartconfig.h"
7-
#include "esp_wifi.h"
86
#include "freertos/FreeRTOS.h"
97

108
#include "singleton.hpp"
@@ -75,6 +73,7 @@ namespace sc
7573
ESP_ERROR_CHECK(esp_smartconfig_start(smartconfigcfg.get()));
7674
state = state_t::STARTED;
7775
}
76+
7877
SmartConfig(const SmartConfig &) = delete;
7978
SmartConfig &operator=(const SmartConfig &) = delete;
8079

@@ -89,6 +88,7 @@ namespace sc
8988
enum class handle_success_t
9089
{
9190
OK,
91+
FAIL,
9292
UNHANDLED
9393
};
9494

main/wifi.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
namespace wifi
44
{
55

6+
SsidPasswordView config_to_ssidpasswordview(const wifi_config_t &config)
7+
{
8+
return {std::string_view(reinterpret_cast<const char *>(config.sta.ssid), sizeof(config.sta.ssid)),
9+
std::string_view(reinterpret_cast<const char *>(config.sta.password), sizeof(config.sta.password))};
10+
}
11+
612
state_t Wifi::state{state_t::IDLE};
713
netif::Netif Wifi::sta_netif;
814
std::unique_ptr<wifi_init_config_t> Wifi::wifiinitcfg{new wifi_init_config_t(WIFI_INIT_CONFIG_DEFAULT())};
15+
nvs::Nvs Wifi::storage{nvs::make_nvs(TAG, NVS_READWRITE)};
916
task::Task Wifi::taskhandle{};
1017
eventgroup::Eventgroup Wifi::event_group{};
1118

main/wifi.hpp

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22

3-
#include "esp_event.h"
43
#include "esp_log.h"
54
#include "esp_netif.h"
65
#include "esp_smartconfig.h"
@@ -11,8 +10,13 @@
1110
#include "singleton.hpp"
1211
#include "wrappers/eventgroup.hpp"
1312
#include "wrappers/netif.hpp"
13+
#include "wrappers/nvs.hpp"
1414
#include "wrappers/task.hpp"
1515

16+
#include <algorithm>
17+
#include <string_view>
18+
#include <utility>
19+
1620
namespace wifi
1721
{
1822

@@ -29,6 +33,9 @@ namespace wifi
2933

3034
static constexpr auto CONNECTED_BIT{BIT0};
3135

36+
using SsidPasswordView = std::pair<std::string_view, std::string_view>;
37+
SsidPasswordView config_to_ssidpasswordview(const wifi_config_t &config);
38+
3239
class Wifi : public Singleton<Wifi> // NOTE: CRTP
3340
{
3441
friend Singleton<Wifi>; // NOTE: So Singleton can use our private/protected constructor
@@ -63,11 +70,70 @@ namespace wifi
6370

6471
static state_t get_state() { return state; }
6572

73+
std::string nvs_ssid() const
74+
{
75+
return nvs::get_string(storage, "ssid");
76+
}
77+
bool nvs_ssid(std::string_view ssid)
78+
{
79+
return nvs::set_string(storage, "ssid", ssid);
80+
}
81+
static bool nvs_ssid_erase()
82+
{
83+
return nvs::erase_key(storage, "ssid");
84+
}
85+
std::string nvs_password() const
86+
{
87+
return nvs::get_string(storage, "password");
88+
}
89+
bool nvs_password(std::string_view password)
90+
{
91+
return nvs::set_string(storage, "password", password);
92+
}
93+
static bool nvs_password_erase()
94+
{
95+
return nvs::erase_key(storage, "password");
96+
}
97+
98+
bool reconnect_to(wifi_config_t &wifi_config)
99+
{
100+
auto status = esp_wifi_disconnect();
101+
if (ESP_OK != status)
102+
{
103+
ESP_LOGW(TAG, "Failed to disconnect: %s", esp_err_to_name(status));
104+
return false;
105+
}
106+
107+
status = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
108+
if (ESP_OK != status)
109+
{
110+
ESP_LOGW(TAG, "Failed to set config: %s", esp_err_to_name(status));
111+
return false;
112+
}
113+
114+
status = esp_wifi_connect();
115+
if (ESP_OK != status)
116+
{
117+
ESP_LOGW(TAG, "Failed to connect: %s", esp_err_to_name(status));
118+
return false;
119+
}
120+
121+
return true;
122+
}
123+
124+
auto config() const
125+
{
126+
wifi_config_t wifi_config{};
127+
esp_wifi_get_config(WIFI_IF_STA, &wifi_config);
128+
return wifi_config;
129+
}
130+
66131
protected:
67132
static constexpr const char *const TAG{"Wifi"};
68133
static state_t state;
69134
static netif::Netif sta_netif;
70135
static std::unique_ptr<wifi_init_config_t> wifiinitcfg;
136+
static nvs::Nvs storage;
71137

72138
Wifi()
73139
{
@@ -86,7 +152,6 @@ namespace wifi
86152
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &EventHandlers::event_handler, nullptr));
87153
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &EventHandlers::event_handler, nullptr));
88154

89-
// wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
90155
ESP_ERROR_CHECK(esp_wifi_init(wifiinitcfg.get()));
91156

92157
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
@@ -95,6 +160,19 @@ namespace wifi
95160
event_group = eventgroup::make_eventgroup();
96161

97162
state = state_t::STARTED;
163+
164+
const auto ssid = nvs_ssid();
165+
const auto password = nvs_password();
166+
167+
if (not ssid.empty() and not password.empty())
168+
{
169+
ESP_LOGI(TAG, "Connecting to %s", ssid.c_str());
170+
wifi_config_t wifi_config{};
171+
std::copy(ssid.begin(), ssid.end(), wifi_config.sta.ssid);
172+
std::copy(password.begin(), password.end(), wifi_config.sta.password);
173+
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
174+
ESP_ERROR_CHECK(esp_wifi_connect());
175+
}
98176
}
99177

100178
struct EventHandlers
@@ -139,7 +217,7 @@ namespace wifi
139217

140218
static task::Task taskhandle;
141219
[[noreturn]] static void taskfn(void *param);
142-
static constexpr auto taskstacksize = 896 * sizeof(int);
220+
static constexpr auto taskstacksize = 640 * sizeof(int);
143221

144222
static eventgroup::Eventgroup event_group;
145223
};

0 commit comments

Comments
 (0)