cryptnox-sdk-esp32 1.0.0
ESP32 SDK for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: LGPL-3.0-or-later
3 * Copyright (c) 2026 Cryptnox SA
4 */
5
27
28#include <string.h>
29#include "freertos/FreeRTOS.h"
30#include "freertos/task.h"
31#include "freertos/event_groups.h"
32#include "driver/spi_master.h"
33#include "esp_log.h"
34#include "esp_wifi.h"
35#include "esp_netif.h"
36#include "esp_event.h"
37#include "nvs_flash.h"
38#include "pn532.h"
39#include "CryptnoxWallet.h"
40#include "Pn532NfcTransport.h"
41#include "ESP32Logger.h"
43#include "ESP32Platform.h"
44#include "config.h"
45
46/* ── SPI wiring — ESP32-S3 dev kit + Keyestudio PN532 breakout ──── */
47#define SPI_MOSI 11
48#define SPI_MISO 13
49#define SPI_SCLK 12
50#define SPI_MAX_TRANSFER_SZ 4096
51#define SPI_PIN_UNUSED (-1)
52#define NFC_CS 10
53
54static const char *const TAG = "connect";
55static const uint32_t LOOP_DELAY_MS = 1000U;
56static const uint32_t WIFI_TIMEOUT_MS = 10000U;
57static const int WIFI_MAX_RETRY = 5;
58
59#define WIFI_CONNECTED_BIT BIT0
60#define WIFI_FAIL_BIT BIT1
61
62static EventGroupHandle_t s_wifi_event_group;
63static int s_retry_num = 0;
64
77static void wifi_event_handler(void *arg, esp_event_base_t event_base,
78 int32_t event_id, void *event_data)
79{
80 (void)arg;
81 (void)event_data;
82 if ((event_base == WIFI_EVENT) && (event_id == WIFI_EVENT_STA_START)) {
83 esp_wifi_connect();
84 } else if ((event_base == WIFI_EVENT) &&
85 (event_id == WIFI_EVENT_STA_DISCONNECTED)) {
87 esp_wifi_connect();
89 } else {
90 xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
91 }
92 } else if ((event_base == IP_EVENT) && (event_id == IP_EVENT_STA_GOT_IP)) {
93 s_retry_num = 0;
94 xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
95 } else {
96 /* other events ignored */
97 }
98}
99
112static void wifi_start(void)
113{
114 s_wifi_event_group = xEventGroupCreate();
115 s_retry_num = 0;
116 ESP_ERROR_CHECK(esp_netif_init());
117 ESP_ERROR_CHECK(esp_event_loop_create_default());
118 (void)esp_netif_create_default_wifi_sta();
119 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
120 ESP_ERROR_CHECK(esp_wifi_init(&cfg));
121 esp_event_handler_instance_t h_any;
122 esp_event_handler_instance_t h_ip;
123 ESP_ERROR_CHECK(esp_event_handler_instance_register(
124 WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &h_any));
125 ESP_ERROR_CHECK(esp_event_handler_instance_register(
126 IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, &h_ip));
127 wifi_config_t wifi_cfg;
128 (void)memset(&wifi_cfg, 0, sizeof(wifi_cfg));
129 (void)strncpy((char *)wifi_cfg.sta.ssid, WIFI_SSID,
130 sizeof(wifi_cfg.sta.ssid) - 1U);
131 (void)strncpy((char *)wifi_cfg.sta.password, WIFI_PASSWORD,
132 sizeof(wifi_cfg.sta.password) - 1U);
133 wifi_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
134 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
135 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg));
136 ESP_ERROR_CHECK(esp_wifi_start());
137 EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
139 pdFALSE, pdFALSE,
140 pdMS_TO_TICKS(WIFI_TIMEOUT_MS));
141 if ((bits & WIFI_CONNECTED_BIT) != 0U) {
142 ESP_LOGI(TAG, "WiFi connected");
143 } else {
144 ESP_LOGW(TAG, "WiFi connect failed — TRNG entropy may be reduced");
145 }
146 (void)esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, h_ip);
147 (void)esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, h_any);
148 vEventGroupDelete(s_wifi_event_group);
149}
150
160static void run_connect_loop(CryptnoxWallet &wallet)
161{
162 while (true) {
163 CW_SecureSession session{};
164 bool connected = wallet.connect(session);
165
166 if (connected) {
167 ESP_LOGI(TAG, "Card connected, secure channel established");
168
169 CW_CardInfo info{};
170 bool infoOk = wallet.getCardInfo(session, &info);
171 if (infoOk) {
172 ESP_LOGI(TAG, "Owner name : %s", info.name);
173 ESP_LOGI(TAG, "Owner email: %s", info.email);
174 } else {
175 ESP_LOGW(TAG, "getCardInfo failed");
176 }
177 } else {
178 ESP_LOGW(TAG, "Card not detected or secure channel failed");
179 }
180
181 wallet.disconnect(session);
182 vTaskDelay(pdMS_TO_TICKS(LOOP_DELAY_MS));
183 }
184}
185
192extern "C" void app_main(void)
193{
194 esp_err_t nvs_ret = nvs_flash_init();
195 if ((nvs_ret == ESP_ERR_NVS_NO_FREE_PAGES) ||
196 (nvs_ret == ESP_ERR_NVS_NEW_VERSION_FOUND)) {
197 ESP_ERROR_CHECK(nvs_flash_erase());
198 nvs_ret = nvs_flash_init();
199 }
200 ESP_ERROR_CHECK(nvs_ret);
201 wifi_start();
202
203 spi_bus_config_t buscfg = {};
204 buscfg.mosi_io_num = SPI_MOSI;
205 buscfg.miso_io_num = SPI_MISO;
206 buscfg.sclk_io_num = SPI_SCLK;
207 buscfg.quadwp_io_num = SPI_PIN_UNUSED;
208 buscfg.quadhd_io_num = SPI_PIN_UNUSED;
209 buscfg.max_transfer_sz = SPI_MAX_TRANSFER_SZ;
210 ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO));
211
212 pn532_t nfc = {};
213 pn532_config_t nfc_cfg = {};
214 nfc_cfg.spi_host = SPI2_HOST;
215 nfc_cfg.pin_cs = NFC_CS;
216 nfc_cfg.skip_bus_init = true;
217 esp_err_t nfc_ret = pn532_init(&nfc, &nfc_cfg);
218
219 if (nfc_ret == ESP_OK) {
220 ESP32Logger logger;
221 (void)logger.begin(115200UL);
222
223 ESP32CryptoProvider cryptoProvider;
224 ESP32Platform platform;
225 Pn532NfcTransport nfcTransport(&nfc, logger);
226 CryptnoxWallet wallet(nfcTransport, logger, cryptoProvider, platform);
227
228 if (wallet.begin()) {
229 (void)nfcTransport.printFirmwareVersion();
230 run_connect_loop(wallet);
231 } else {
232 ESP_LOGE(TAG, "Wallet init failed");
233 }
234 } else {
235 ESP_LOGE(TAG, "PN532 init failed");
236 }
237}
#define WIFI_SSID
#define WIFI_PASSWORD
#define NFC_CS
Definition main.cpp:59
void app_main(void)
ESP-IDF application entry point.
Definition main.cpp:284
static EventGroupHandle_t s_wifi_event_group
Definition main.cpp:80
#define SPI_MAX_TRANSFER_SZ
Definition main.cpp:57
#define WIFI_FAIL_BIT
Definition main.cpp:78
#define SPI_MOSI
Definition main.cpp:54
#define SPI_PIN_UNUSED
Definition main.cpp:58
static const uint32_t LOOP_DELAY_MS
Definition main.cpp:73
#define SPI_MISO
Definition main.cpp:55
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
FreeRTOS event handler driving the Wi-Fi station state machine.
Definition main.cpp:95
#define WIFI_CONNECTED_BIT
Definition main.cpp:77
static int s_retry_num
Definition main.cpp:81
#define SPI_SCLK
Definition main.cpp:56
static void wifi_start(void)
Initialise Wi-Fi station mode and block until connected or timeout.
Definition main.cpp:130
static void run_connect_loop(CryptnoxWallet &wallet)
Main application loop: connect, fetch card info, and disconnect.
Definition main.cpp:160
CW_Logger implementation that writes to ESP32 UART0 via printf.
CW_Platform implementation for ESP32 using FreeRTOS.
CW_NfcTransport adapter wrapping the ESP-IDF PN532 NFC driver.
CW_CryptoProvider backed by mbedTLS and the ESP32 hardware TRNG.
CW_Logger backed by ESP32 UART0.
Definition ESP32Logger.h:48
bool begin(unsigned long baudRate=115200UL) override
Initialise UART0 at the given baud rate.
CW_Platform backed by FreeRTOS vTaskDelay.
CW_NfcTransport implementation backed by the ESP-IDF PN532 driver.
bool printFirmwareVersion() override
Query and log the PN532 firmware version.
CW_CryptoProvider implementation for ESP32 using mbedTLS and the hardware TRNG.
static const char *const TAG
#define WIFI_TIMEOUT_MS
Definition eth_rpc.cpp:28
#define WIFI_MAX_RETRY
Definition eth_rpc.cpp:27
esp_err_t pn532_init(pn532_t *dev, const pn532_config_t *config)
Initialise the PN532 and bring it to a ready state.
Definition pn532.c:657
Low-level PN532 NFC controller driver for ESP-IDF (SPI and I²C).
Compile-time configuration passed to pn532_init.
Definition pn532.h:111
spi_host_device_t spi_host
Definition pn532.h:115
bool skip_bus_init
Definition pn532.h:120
Opaque-like runtime state for a single PN532 instance.
Definition pn532.h:141