mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-06-22 06:54:28 +02:00
Store app/dev EUI/key in NVS
This commit is contained in:
parent
fc34fed6de
commit
2c998f5acc
1
.vscode/c_cpp_properties.json
vendored
1
.vscode/c_cpp_properties.json
vendored
@ -12,6 +12,7 @@
|
|||||||
"${IDF_PATH}/components/log/include",
|
"${IDF_PATH}/components/log/include",
|
||||||
"${IDF_PATH}/components/lwip/include/lwip",
|
"${IDF_PATH}/components/lwip/include/lwip",
|
||||||
"${IDF_PATH}/components/lwip/include/lwip/port",
|
"${IDF_PATH}/components/lwip/include/lwip/port",
|
||||||
|
"${IDF_PATH}/components/nvs_flash/include",
|
||||||
"${IDF_PATH}/components/soc/include",
|
"${IDF_PATH}/components/soc/include",
|
||||||
"${IDF_PATH}/components/soc/esp32/include",
|
"${IDF_PATH}/components/soc/esp32/include",
|
||||||
"${IDF_PATH}/components/tcpip_adapter/include",
|
"${IDF_PATH}/components/tcpip_adapter/include",
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
#include "TheThingsNetwork.h"
|
#include "TheThingsNetwork.h"
|
||||||
|
|
||||||
@ -33,15 +34,12 @@ const unsigned TX_INTERVAL = 30;
|
|||||||
static uint8_t msgData[] = "Hello, world";
|
static uint8_t msgData[] = "Hello, world";
|
||||||
|
|
||||||
|
|
||||||
void send_messages(void* pvParameter)
|
void sendMessages(void* pvParameter)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
printf("Sending message...\n");
|
printf("Sending message...\n");
|
||||||
TTNResponseCode res = ttn.transmitBytes(msgData, sizeof(msgData) - 1);
|
TTNResponseCode res = ttn.transmitBytes(msgData, sizeof(msgData) - 1);
|
||||||
if (res == kTTNSuccessfulTransmission)
|
printf(res == kTTNSuccessfulTransmission ? "Message sent.\n" : "Transmission failed.\n");
|
||||||
printf("Message sent.\n");
|
|
||||||
else
|
|
||||||
printf("Transmission failed.\n");
|
|
||||||
|
|
||||||
vTaskDelay(TX_INTERVAL * 1000 / portTICK_PERIOD_MS);
|
vTaskDelay(TX_INTERVAL * 1000 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
@ -49,7 +47,13 @@ void send_messages(void* pvParameter)
|
|||||||
|
|
||||||
extern "C" void app_main(void)
|
extern "C" void app_main(void)
|
||||||
{
|
{
|
||||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
esp_err_t err;
|
||||||
|
// Initialize the GPIO ISR handler service
|
||||||
|
err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
// Initialize the NVS (non-volatile storage) for saving and restoring the keys
|
||||||
|
err = nvs_flash_init();
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
// Initialize SPI bus
|
// Initialize SPI bus
|
||||||
spi_bus_config_t spi_bus_config;
|
spi_bus_config_t spi_bus_config;
|
||||||
@ -61,15 +65,21 @@ extern "C" void app_main(void)
|
|||||||
spi_bus_config.max_transfer_sz = 0;
|
spi_bus_config.max_transfer_sz = 0;
|
||||||
|
|
||||||
esp_err_t ret = spi_bus_initialize(HSPI_HOST, &spi_bus_config, 1);
|
esp_err_t ret = spi_bus_initialize(HSPI_HOST, &spi_bus_config, 1);
|
||||||
assert(ret == ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
ttn.configurePins(HSPI_HOST, 18, TTN_NOT_CONNECTED, 14, 26, 33);
|
ttn.configurePins(HSPI_HOST, 18, TTN_NOT_CONNECTED, 14, 26, 33);
|
||||||
|
|
||||||
|
// The below line can be commented after the first run as the data is saved in NVS
|
||||||
ttn.provision(devEui, appEui, appKey);
|
ttn.provision(devEui, appEui, appKey);
|
||||||
|
|
||||||
printf("Joining...\n");
|
printf("Joining...\n");
|
||||||
ttn.join();
|
if (ttn.join())
|
||||||
printf("Joined.\n");
|
{
|
||||||
|
printf("Joined.\n");
|
||||||
xTaskCreate(send_messages, "send_messages", 1024 * 4, (void* )0, 3, NULL);
|
xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void* )0, 3, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Join failed. Goodbye\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
PROJECT_NAME := hello_world
|
PROJECT_NAME := send_recv
|
||||||
|
|
||||||
include $(IDF_PATH)/make/project.mk
|
include $(IDF_PATH)/make/project.mk
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Sample program showing how to send a test message every 30 second.
|
* Sample program showing how to send and receive messages.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
#include "TheThingsNetwork.h"
|
#include "TheThingsNetwork.h"
|
||||||
|
|
||||||
@ -38,10 +39,7 @@ void sendMessages(void* pvParameter)
|
|||||||
while (1) {
|
while (1) {
|
||||||
printf("Sending message...\n");
|
printf("Sending message...\n");
|
||||||
TTNResponseCode res = ttn.transmitBytes(msgData, sizeof(msgData) - 1);
|
TTNResponseCode res = ttn.transmitBytes(msgData, sizeof(msgData) - 1);
|
||||||
if (res == kTTNSuccessfulTransmission)
|
printf(res == kTTNSuccessfulTransmission ? "Message sent.\n" : "Transmission failed.\n");
|
||||||
printf("Message sent.\n");
|
|
||||||
else
|
|
||||||
printf("Transmission failed.\n");
|
|
||||||
|
|
||||||
vTaskDelay(TX_INTERVAL * 1000 / portTICK_PERIOD_MS);
|
vTaskDelay(TX_INTERVAL * 1000 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
@ -57,7 +55,13 @@ void messageReceived(const uint8_t* message, size_t length, port_t port)
|
|||||||
|
|
||||||
extern "C" void app_main(void)
|
extern "C" void app_main(void)
|
||||||
{
|
{
|
||||||
gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
esp_err_t err;
|
||||||
|
// Initialize the GPIO ISR handler service
|
||||||
|
err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
// Initialize the NVS (non-volatile storage) for saving and restoring the keys
|
||||||
|
err = nvs_flash_init();
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
// Initialize SPI bus
|
// Initialize SPI bus
|
||||||
spi_bus_config_t spi_bus_config;
|
spi_bus_config_t spi_bus_config;
|
||||||
@ -68,18 +72,24 @@ extern "C" void app_main(void)
|
|||||||
spi_bus_config.quadhd_io_num = -1;
|
spi_bus_config.quadhd_io_num = -1;
|
||||||
spi_bus_config.max_transfer_sz = 0;
|
spi_bus_config.max_transfer_sz = 0;
|
||||||
|
|
||||||
esp_err_t ret = spi_bus_initialize(HSPI_HOST, &spi_bus_config, 1);
|
err = spi_bus_initialize(HSPI_HOST, &spi_bus_config, 1);
|
||||||
assert(ret == ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
ttn.configurePins(HSPI_HOST, 18, TTN_NOT_CONNECTED, 14, 26, 33);
|
ttn.configurePins(HSPI_HOST, 18, TTN_NOT_CONNECTED, 14, 26, 33);
|
||||||
|
|
||||||
|
// The below line can be commented after the first run as the data is saved in NVS
|
||||||
ttn.provision(devEui, appEui, appKey);
|
ttn.provision(devEui, appEui, appKey);
|
||||||
|
|
||||||
ttn.onMessage(messageReceived);
|
ttn.onMessage(messageReceived);
|
||||||
|
|
||||||
printf("Joining...\n");
|
printf("Joining...\n");
|
||||||
ttn.join();
|
if (ttn.join())
|
||||||
printf("Joined.\n");
|
{
|
||||||
|
printf("Joined.\n");
|
||||||
xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void* )0, 3, NULL);
|
xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void* )0, 3, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Join failed. Goodbye\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Sets the information needed to activate the device via OTAA, without actually activating.
|
* @brief Sets the information needed to activate the device via OTAA, without actually activating.
|
||||||
*
|
*
|
||||||
* The provided EUIs and key are saved in non-volatile memory. Call join() without arguments to activate.
|
* The provided device EUI, app EUI and app key are saved in non-volatile memory. Before
|
||||||
|
* this function is called, 'nvs_flash_init' must have been called once.
|
||||||
|
*
|
||||||
|
* Call join() without arguments to activate.
|
||||||
*
|
*
|
||||||
* @param devEui Device EUI (16 character string with hexadecimal data)
|
* @param devEui Device EUI (16 character string with hexadecimal data)
|
||||||
* @param appEui Application EUI of the device (16 character string with hexadecimal data)
|
* @param appEui Application EUI of the device (16 character string with hexadecimal data)
|
||||||
@ -101,9 +104,9 @@ public:
|
|||||||
bool provision(const char *devEui, const char *appEui, const char *appKey);
|
bool provision(const char *devEui, const char *appEui, const char *appKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the EUIs and keys and activate the device via OTAA.
|
* @brief Set the device EUI, app EUI and app key and activate the device via OTAA.
|
||||||
*
|
*
|
||||||
* The EUIs and key are NOT saved in non-volatile memory.
|
* The device EUI, app EUI and app key are NOT saved in non-volatile memory.
|
||||||
*
|
*
|
||||||
* The function blocks until the activation has completed or failed.
|
* The function blocks until the activation has completed or failed.
|
||||||
*
|
*
|
||||||
@ -119,6 +122,7 @@ public:
|
|||||||
* @brief Activate the device via OTAA.
|
* @brief Activate the device via OTAA.
|
||||||
*
|
*
|
||||||
* The app EUI, app key and dev EUI must already have been provisioned by a call to 'provision()'.
|
* The app EUI, app key and dev EUI must already have been provisioned by a call to 'provision()'.
|
||||||
|
* Before this function is called, 'nvs_flash_init' must have been called once.
|
||||||
*
|
*
|
||||||
* The function blocks until the activation has completed or failed.
|
* The function blocks until the activation has completed or failed.
|
||||||
*
|
*
|
||||||
@ -160,11 +164,23 @@ public:
|
|||||||
*/
|
*/
|
||||||
void onMessage(TTNMessageCallback callback);
|
void onMessage(TTNMessageCallback callback);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if device EUI, app EUI and app key have been stored in non-volatile storage
|
||||||
|
* or have been provided as by a call to 'join(const char*, const char*, const char*)'.
|
||||||
|
*
|
||||||
|
* @return true if they are stored, complete and of the correct size
|
||||||
|
* @return false otherwise
|
||||||
|
*/
|
||||||
|
bool isProvisioned();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TTNMessageCallback messageCallback;
|
TTNMessageCallback messageCallback;
|
||||||
|
bool haveKeys;
|
||||||
|
|
||||||
|
bool joinCore();
|
||||||
bool decodeKeys(const char *devEui, const char *appEui, const char *appKey);
|
bool decodeKeys(const char *devEui, const char *appEui, const char *appKey);
|
||||||
|
bool saveKeys();
|
||||||
|
bool restoreKeys(bool silent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
#include "TheThingsNetwork.h"
|
#include "TheThingsNetwork.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "oslmic.h"
|
#include "oslmic.h"
|
||||||
@ -26,6 +27,10 @@ enum ClientAction
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char *TAG = "ttn";
|
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 TheThingsNetwork* ttnInstance;
|
||||||
static uint8_t devEui[8];
|
static uint8_t devEui[8];
|
||||||
@ -35,6 +40,8 @@ static QueueHandle_t resultQueue;
|
|||||||
static ClientAction clientAction = eActionUnrelated;
|
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 bool hexStringToBin(const char *hex, uint8_t *buf, int len);
|
||||||
static int hexTupleToByte(const char *hex);
|
static int hexTupleToByte(const char *hex);
|
||||||
static int hexDigitToVal(char ch);
|
static int hexDigitToVal(char ch);
|
||||||
@ -42,6 +49,7 @@ static void swapByteOrder(uint8_t* buf, int len);
|
|||||||
|
|
||||||
|
|
||||||
TheThingsNetwork::TheThingsNetwork()
|
TheThingsNetwork::TheThingsNetwork()
|
||||||
|
: messageCallback(NULL), haveKeys(false)
|
||||||
{
|
{
|
||||||
ASSERT(ttnInstance == NULL);
|
ASSERT(ttnInstance == NULL);
|
||||||
ttnInstance = this;
|
ttnInstance = this;
|
||||||
@ -67,7 +75,7 @@ void TheThingsNetwork::configurePins(spi_host_device_t spi_host, uint8_t nss, ui
|
|||||||
reset();
|
reset();
|
||||||
|
|
||||||
resultQueue = xQueueCreate(12, sizeof(int));
|
resultQueue = xQueueCreate(12, sizeof(int));
|
||||||
assert(resultQueue != NULL);
|
ASSERT(resultQueue != NULL);
|
||||||
hal_startBgTask();
|
hal_startBgTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,11 +88,16 @@ void TheThingsNetwork::reset()
|
|||||||
|
|
||||||
bool TheThingsNetwork::provision(const char *devEui, const char *appEui, const char *appKey)
|
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)
|
bool TheThingsNetwork::decodeKeys(const char *devEui, const char *appEui, const char *appKey)
|
||||||
{
|
{
|
||||||
|
haveKeys = false;
|
||||||
|
|
||||||
if (strlen(devEui) != 16 || !hexStringToBin(devEui, ::devEui, 8))
|
if (strlen(devEui) != 16 || !hexStringToBin(devEui, ::devEui, 8))
|
||||||
{
|
{
|
||||||
ESP_LOGW(TAG, "Invalid device EUI: %s", devEui);
|
ESP_LOGW(TAG, "Invalid device EUI: %s", devEui);
|
||||||
@ -107,6 +120,7 @@ bool TheThingsNetwork::decodeKeys(const char *devEui, const char *appEui, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
haveKeys = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,11 +129,28 @@ bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char *
|
|||||||
if (!decodeKeys(devEui, appEui, appKey))
|
if (!decodeKeys(devEui, appEui, appKey))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return join();
|
return joinCore();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TheThingsNetwork::join()
|
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();
|
hal_enterCriticalSection();
|
||||||
clientAction = eActionJoining;
|
clientAction = eActionJoining;
|
||||||
LMIC_startJoining();
|
LMIC_startJoining();
|
||||||
@ -173,6 +204,120 @@ void TheThingsNetwork::onMessage(TTNMessageCallback callback)
|
|||||||
messageCallback = 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 ---
|
// --- LMIC functions ---
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ static void hal_io_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
dio_queue = xQueueCreate(12, sizeof(queue_item_t));
|
dio_queue = xQueueCreate(12, sizeof(queue_item_t));
|
||||||
assert(dio_queue != NULL);
|
ASSERT(dio_queue != NULL);
|
||||||
|
|
||||||
gpio_pad_select_gpio(lmic_pins.dio0);
|
gpio_pad_select_gpio(lmic_pins.dio0);
|
||||||
gpio_set_direction(lmic_pins.dio0, GPIO_MODE_INPUT);
|
gpio_set_direction(lmic_pins.dio0, GPIO_MODE_INPUT);
|
||||||
@ -151,8 +151,8 @@ static void collect_spi_result()
|
|||||||
|
|
||||||
spi_transaction_t* trx;
|
spi_transaction_t* trx;
|
||||||
esp_err_t err = spi_device_get_trans_result(spi_handle, &trx, 100 / portTICK_PERIOD_MS);
|
esp_err_t err = spi_device_get_trans_result(spi_handle, &trx, 100 / portTICK_PERIOD_MS);
|
||||||
assert(err == ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
assert(trx == spi_trx_queue + tail);
|
ASSERT(trx == spi_trx_queue + tail);
|
||||||
spi_num_outstanding_trx--;
|
spi_num_outstanding_trx--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ static void submit_spi_trx()
|
|||||||
|
|
||||||
int head = spi_trx_queue_head;
|
int head = spi_trx_queue_head;
|
||||||
esp_err_t err = spi_device_queue_trans(spi_handle, spi_trx_queue + head, 100 / portTICK_PERIOD_MS);
|
esp_err_t err = spi_device_queue_trans(spi_handle, spi_trx_queue + head, 100 / portTICK_PERIOD_MS);
|
||||||
assert(err == ESP_OK);
|
ESP_ERROR_CHECK(err);
|
||||||
spi_num_outstanding_trx++;
|
spi_num_outstanding_trx++;
|
||||||
|
|
||||||
head++;
|
head++;
|
||||||
@ -185,7 +185,7 @@ static void hal_spi_init()
|
|||||||
};
|
};
|
||||||
|
|
||||||
esp_err_t ret = spi_bus_add_device(lmic_pins.spi_host, &spi_device_intf_config, &spi_handle);
|
esp_err_t ret = spi_bus_add_device(lmic_pins.spi_host, &spi_device_intf_config, &spi_handle);
|
||||||
assert(ret == ESP_OK);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "SPI initialized");
|
ESP_LOGI(TAG, "SPI initialized");
|
||||||
}
|
}
|
||||||
@ -459,5 +459,5 @@ void hal_startBgTask() {
|
|||||||
void hal_failed(const char *file, u2_t line)
|
void hal_failed(const char *file, u2_t line)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "%s:%d", file, line);
|
ESP_LOGE(TAG, "%s:%d", file, line);
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user