mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-07-16 07:32:52 +02:00
Store app/dev EUI/key in NVS
This commit is contained in:
@ -11,6 +11,7 @@
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_event.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "TheThingsNetwork.h"
|
||||
#include "esp_log.h"
|
||||
#include "oslmic.h"
|
||||
@ -26,6 +27,10 @@ enum ClientAction
|
||||
};
|
||||
|
||||
static const char *TAG = "ttn";
|
||||
static const char *NVS_FLASH_PARTITION = "ttn";
|
||||
static const char *NVS_FLASH_KEY_DEV_EUI = "devEui";
|
||||
static const char *NVS_FLASH_KEY_APP_EUI = "appEui";
|
||||
static const char *NVS_FLASH_KEY_APP_KEY = "appKey";
|
||||
|
||||
static TheThingsNetwork* ttnInstance;
|
||||
static uint8_t devEui[8];
|
||||
@ -35,6 +40,8 @@ static QueueHandle_t resultQueue;
|
||||
static ClientAction clientAction = eActionUnrelated;
|
||||
|
||||
|
||||
static bool readNvsValue(nvs_handle handle, const char* key, uint8_t* data, size_t expectedLength, bool silent);
|
||||
static bool writeNvsValue(nvs_handle handle, const char* key, const uint8_t* data, size_t len);
|
||||
static bool hexStringToBin(const char *hex, uint8_t *buf, int len);
|
||||
static int hexTupleToByte(const char *hex);
|
||||
static int hexDigitToVal(char ch);
|
||||
@ -42,6 +49,7 @@ static void swapByteOrder(uint8_t* buf, int len);
|
||||
|
||||
|
||||
TheThingsNetwork::TheThingsNetwork()
|
||||
: messageCallback(NULL), haveKeys(false)
|
||||
{
|
||||
ASSERT(ttnInstance == NULL);
|
||||
ttnInstance = this;
|
||||
@ -67,7 +75,7 @@ void TheThingsNetwork::configurePins(spi_host_device_t spi_host, uint8_t nss, ui
|
||||
reset();
|
||||
|
||||
resultQueue = xQueueCreate(12, sizeof(int));
|
||||
assert(resultQueue != NULL);
|
||||
ASSERT(resultQueue != NULL);
|
||||
hal_startBgTask();
|
||||
}
|
||||
|
||||
@ -80,11 +88,16 @@ void TheThingsNetwork::reset()
|
||||
|
||||
bool TheThingsNetwork::provision(const char *devEui, const char *appEui, const char *appKey)
|
||||
{
|
||||
return decodeKeys(devEui, appEui, appKey);
|
||||
if (!decodeKeys(devEui, appEui, appKey))
|
||||
return false;
|
||||
|
||||
return saveKeys();
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::decodeKeys(const char *devEui, const char *appEui, const char *appKey)
|
||||
{
|
||||
haveKeys = false;
|
||||
|
||||
if (strlen(devEui) != 16 || !hexStringToBin(devEui, ::devEui, 8))
|
||||
{
|
||||
ESP_LOGW(TAG, "Invalid device EUI: %s", devEui);
|
||||
@ -107,6 +120,7 @@ bool TheThingsNetwork::decodeKeys(const char *devEui, const char *appEui, const
|
||||
return false;
|
||||
}
|
||||
|
||||
haveKeys = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -115,11 +129,28 @@ bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char *
|
||||
if (!decodeKeys(devEui, appEui, appKey))
|
||||
return false;
|
||||
|
||||
return join();
|
||||
return joinCore();
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::join()
|
||||
{
|
||||
if (!haveKeys)
|
||||
{
|
||||
if (!restoreKeys(false))
|
||||
return false;
|
||||
}
|
||||
|
||||
return joinCore();
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::joinCore()
|
||||
{
|
||||
if (!haveKeys)
|
||||
{
|
||||
ESP_LOGW(TAG, "Device EUI, App EUI and/or App key have not been provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
hal_enterCriticalSection();
|
||||
clientAction = eActionJoining;
|
||||
LMIC_startJoining();
|
||||
@ -173,6 +204,120 @@ void TheThingsNetwork::onMessage(TTNMessageCallback callback)
|
||||
messageCallback = callback;
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::saveKeys()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
nvs_handle handle = 0;
|
||||
esp_err_t res = nvs_open(NVS_FLASH_PARTITION, NVS_READWRITE, &handle);
|
||||
if (res == ESP_ERR_NVS_NOT_INITIALIZED)
|
||||
{
|
||||
ESP_LOGW(TAG, "NVS storage is not initialized. Call 'nvs_flash_init()' first.");
|
||||
goto done;
|
||||
}
|
||||
ESP_ERROR_CHECK(res);
|
||||
if (res != ESP_OK)
|
||||
goto done;
|
||||
|
||||
if (!writeNvsValue(handle, NVS_FLASH_KEY_DEV_EUI, ::devEui, sizeof(::devEui)))
|
||||
goto done;
|
||||
|
||||
if (!writeNvsValue(handle, NVS_FLASH_KEY_APP_EUI, ::appEui, sizeof(::appEui)))
|
||||
goto done;
|
||||
|
||||
if (!writeNvsValue(handle, NVS_FLASH_KEY_APP_KEY, ::appKey, sizeof(::appKey)))
|
||||
goto done;
|
||||
|
||||
res = nvs_commit(handle);
|
||||
ESP_ERROR_CHECK(res);
|
||||
|
||||
result = true;
|
||||
ESP_LOGI(TAG, "Dev and app EUI and app key saved in NVS storage");
|
||||
|
||||
done:
|
||||
nvs_close(handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::restoreKeys(bool silent)
|
||||
{
|
||||
haveKeys = false;
|
||||
|
||||
nvs_handle handle = 0;
|
||||
esp_err_t res = nvs_open(NVS_FLASH_PARTITION, NVS_READONLY, &handle);
|
||||
if (res == ESP_ERR_NVS_NOT_FOUND)
|
||||
return false; // partition does not exist yet
|
||||
if (res == ESP_ERR_NVS_NOT_INITIALIZED)
|
||||
{
|
||||
ESP_LOGW(TAG, "NVS storage is not initialized. Call 'nvs_flash_init()' first.");
|
||||
goto done;
|
||||
}
|
||||
ESP_ERROR_CHECK(res);
|
||||
if (res != ESP_OK)
|
||||
goto done;
|
||||
|
||||
if (!readNvsValue(handle, NVS_FLASH_KEY_DEV_EUI, ::devEui, sizeof(::devEui), silent))
|
||||
goto done;
|
||||
|
||||
if (!readNvsValue(handle, NVS_FLASH_KEY_APP_EUI, ::appEui, sizeof(::appEui), silent))
|
||||
goto done;
|
||||
|
||||
if (!readNvsValue(handle, NVS_FLASH_KEY_APP_KEY, ::appKey, sizeof(::appKey), silent))
|
||||
goto done;
|
||||
|
||||
haveKeys = true;
|
||||
ESP_LOGI(TAG, "Dev and app EUI and app key have been restored from NVS storage");
|
||||
|
||||
done:
|
||||
nvs_close(handle);
|
||||
return haveKeys;
|
||||
}
|
||||
|
||||
bool TheThingsNetwork::isProvisioned()
|
||||
{
|
||||
if (haveKeys)
|
||||
return true;
|
||||
|
||||
return restoreKeys(true);
|
||||
}
|
||||
|
||||
bool readNvsValue(nvs_handle handle, const char* key, uint8_t* data, size_t expectedLength, bool silent)
|
||||
{
|
||||
size_t size = expectedLength;
|
||||
esp_err_t res = nvs_get_blob(handle, key, data, &size);
|
||||
if (res == ESP_OK && size == expectedLength)
|
||||
return true;
|
||||
|
||||
if (res == ESP_OK && size != expectedLength)
|
||||
{
|
||||
if (!silent)
|
||||
ESP_LOGW(TAG, "Invalid size of NVS data for %s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (res == ESP_ERR_NVS_NOT_FOUND)
|
||||
{
|
||||
if (!silent)
|
||||
ESP_LOGW(TAG, "No NVS data found for %s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool writeNvsValue(nvs_handle handle, const char* key, const uint8_t* data, size_t len)
|
||||
{
|
||||
uint8_t buf[16];
|
||||
if (readNvsValue(handle, key, buf, len, true) && memcmp(buf, data, len) == 0)
|
||||
return true; // unchanged
|
||||
|
||||
esp_err_t res = nvs_set_blob(handle, key, data, len);
|
||||
ESP_ERROR_CHECK(res);
|
||||
|
||||
return res == ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// --- LMIC functions ---
|
||||
|
||||
|
Reference in New Issue
Block a user