mirror of
				https://github.com/manuelbl/ttn-esp32.git
				synced 2025-10-30 02:00:34 +01:00 
			
		
		
		
	Convert provisioning code to C++
This commit is contained in:
		
							
								
								
									
										2
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							| @ -28,7 +28,7 @@ | |||||||
|             ], |             ], | ||||||
|             "compilerPath": "/usr/bin/clang", |             "compilerPath": "/usr/bin/clang", | ||||||
|             "cStandard": "c11", |             "cStandard": "c11", | ||||||
|             "cppStandard": "c++17", |             "cppStandard": "c++11", | ||||||
|             "intelliSenseMode": "clang-x64" |             "intelliSenseMode": "clang-x64" | ||||||
|         } |         } | ||||||
|     ], |     ], | ||||||
|  | |||||||
| @ -89,7 +89,7 @@ extern "C" void app_main(void) | |||||||
|     if (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, nullptr); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -87,7 +87,7 @@ extern "C" void app_main(void) | |||||||
|     if (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, nullptr); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -82,7 +82,7 @@ extern "C" void app_main(void) | |||||||
|     if (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, nullptr); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -99,7 +99,7 @@ extern "C" void app_main(void) | |||||||
|     if (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, nullptr); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -16,12 +16,14 @@ | |||||||
| #include "esp_log.h" | #include "esp_log.h" | ||||||
| #include "esp_system.h" | #include "esp_system.h" | ||||||
| #include "nvs_flash.h" | #include "nvs_flash.h" | ||||||
| #include "provisioning.h" | #include "TTNProvisioning.h" | ||||||
| #include "lmic/lmic.h" | #include "lmic/lmic.h" | ||||||
| #include "hal/hal_esp32.h" | #include "hal/hal_esp32.h" | ||||||
| 
 | 
 | ||||||
| #define UART_NUM CONFIG_TTN_PROVISION_UART_NUM | #if !defined(CONFIG_TTN_PROVISION_UART_NONE) | ||||||
| #define MAX_LINE_LENGTH 128 | const uart_port_t UART_NUM = (uart_port_t) CONFIG_TTN_PROVISION_UART_NUM; | ||||||
|  | const int MAX_LINE_LENGTH = 128; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| static const char* TAG = "ttn_prov"; | static const char* TAG = "ttn_prov"; | ||||||
| static const char* NVS_FLASH_PARTITION = "ttn"; | static const char* NVS_FLASH_PARTITION = "ttn"; | ||||||
| @ -29,36 +31,11 @@ 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_EUI = "appEui"; | ||||||
| static const char* NVS_FLASH_KEY_APP_KEY = "appKey"; | static const char* NVS_FLASH_KEY_APP_KEY = "appKey"; | ||||||
| 
 | 
 | ||||||
| static bool provisioning_decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const char *app_key); |  | ||||||
| static void provisioning_task(void* pvParameter); |  | ||||||
| static void provisioning_add_line_data(int numBytes); |  | ||||||
| static void provisioning_detect_line_end(int start_at); |  | ||||||
| static void provisioning_process_line(); |  | ||||||
| static bool read_nvs_value(nvs_handle handle, const char* key, uint8_t* data, size_t expected_length, bool silent); |  | ||||||
| static bool write_nvs_value(nvs_handle handle, const char* key, const uint8_t* data, size_t len); |  | ||||||
| static bool hex_str_to_bin(const char *hex, uint8_t *buf, int len); |  | ||||||
| static int hex_tuple_to_byte(const char *hex); |  | ||||||
| static int hex_digit_to_val(char ch); |  | ||||||
| static void bin_to_hex_str(const uint8_t* buf, int len, char* hex); |  | ||||||
| static char val_to_hex_digit(int val); |  | ||||||
| static void swap_bytes(uint8_t* buf, int len); |  | ||||||
| static bool is_all_zeroes(const uint8_t* buf, int len); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static QueueHandle_t uart_queue = NULL; |  | ||||||
| static char* line_buf; |  | ||||||
| static int line_length; |  | ||||||
| static uint8_t last_line_end_char = 0; |  | ||||||
| static uint8_t global_dev_eui[8]; | static uint8_t global_dev_eui[8]; | ||||||
| static uint8_t global_app_eui[8]; | static uint8_t global_app_eui[8]; | ||||||
| static uint8_t global_app_key[16]; | static uint8_t global_app_key[16]; | ||||||
| static bool have_keys = false; |  | ||||||
| static bool quit_task = false; |  | ||||||
| 
 | 
 | ||||||
| 
 | void ttn_provisioning_task_caller(void* pvParameter); | ||||||
| #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) |  | ||||||
| static void provisioning_config_uart(); |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // --- LMIC callbacks
 | // --- LMIC callbacks
 | ||||||
| @ -86,22 +63,38 @@ void os_getDevKey (u1_t* buf) | |||||||
|     memcpy(buf, global_app_key, 16); |     memcpy(buf, global_app_key, 16); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // --- Constructor
 | ||||||
|  | 
 | ||||||
|  | TTNProvisioning::TTNProvisioning() | ||||||
|  |     : have_keys(false) | ||||||
|  | #if !defined(CONFIG_TTN_PROVISION_UART_NONE) | ||||||
|  |         , uart_queue(nullptr), line_buf(nullptr), line_length(0), last_line_end_char(0), quit_task(false) | ||||||
|  | #endif | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| // --- Provisioning task
 | // --- Provisioning task
 | ||||||
| 
 | 
 | ||||||
| void provisioning_start_task() | void TTNProvisioning::startTask() | ||||||
| { | { | ||||||
| #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) | #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) | ||||||
|     provisioning_config_uart(); |     configUART(); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     esp_err_t err = uart_driver_install(UART_NUM, 2048, 2048, 20, &uart_queue, 0); |     esp_err_t err = uart_driver_install(UART_NUM, 2048, 2048, 20, &uart_queue, 0); | ||||||
|     ESP_ERROR_CHECK(err); |     ESP_ERROR_CHECK(err); | ||||||
| 
 | 
 | ||||||
|     xTaskCreate(provisioning_task, "provisioning", 2048, NULL, 1, NULL); |     xTaskCreate(ttn_provisioning_task_caller, "provisioning", 2048, this, 1, nullptr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void provisioning_task(void* pvParameter) | void ttn_provisioning_task_caller(void* pvParameter) | ||||||
|  | { | ||||||
|  |     TTNProvisioning* provisioning = (TTNProvisioning*)pvParameter; | ||||||
|  |     provisioning->provisioningTask(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TTNProvisioning::provisioningTask() | ||||||
| { | { | ||||||
|     line_buf = (char*)malloc(MAX_LINE_LENGTH + 1); |     line_buf = (char*)malloc(MAX_LINE_LENGTH + 1); | ||||||
|     line_length = 0; |     line_length = 0; | ||||||
| @ -118,7 +111,7 @@ void provisioning_task(void* pvParameter) | |||||||
|         switch (event.type) |         switch (event.type) | ||||||
|         { |         { | ||||||
|             case UART_DATA: |             case UART_DATA: | ||||||
|                 provisioning_add_line_data(event.size); |                 addLineData(event.size); | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             case UART_FIFO_OVF: |             case UART_FIFO_OVF: | ||||||
| @ -134,10 +127,10 @@ void provisioning_task(void* pvParameter) | |||||||
| 
 | 
 | ||||||
|     free(line_buf); |     free(line_buf); | ||||||
|     uart_driver_delete(UART_NUM); |     uart_driver_delete(UART_NUM); | ||||||
|     vTaskDelete(NULL); |     vTaskDelete(nullptr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void provisioning_add_line_data(int numBytes) | void TTNProvisioning::addLineData(int numBytes) | ||||||
| { | { | ||||||
|     int n; |     int n; | ||||||
| top: | top: | ||||||
| @ -149,7 +142,7 @@ top: | |||||||
|     int start_at = line_length; |     int start_at = line_length; | ||||||
|     line_length += n; |     line_length += n; | ||||||
| 
 | 
 | ||||||
|     provisioning_detect_line_end(start_at); |     detectLineEnd(start_at); | ||||||
| 
 | 
 | ||||||
|     if (n < numBytes) |     if (n < numBytes) | ||||||
|     { |     { | ||||||
| @ -158,7 +151,7 @@ top: | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void provisioning_detect_line_end(int start_at) | void TTNProvisioning::detectLineEnd(int start_at) | ||||||
| { | { | ||||||
| top: | top: | ||||||
|     for (int p = start_at; p < line_length; p++) |     for (int p = start_at; p < line_length; p++) | ||||||
| @ -175,7 +168,7 @@ top: | |||||||
|             last_line_end_char = ch; |             last_line_end_char = ch; | ||||||
| 
 | 
 | ||||||
|             if (p > 0) |             if (p > 0) | ||||||
|                 provisioning_process_line(); |                 processLine(); | ||||||
| 
 | 
 | ||||||
|             memcpy(line_buf, line_buf + p + 1, line_length - p - 1); |             memcpy(line_buf, line_buf + p + 1, line_length - p - 1); | ||||||
|             line_length -= p + 1; |             line_length -= p + 1; | ||||||
| @ -191,7 +184,7 @@ top: | |||||||
|         line_length = 0; // Line too long; flush it
 |         line_length = 0; // Line too long; flush it
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void provisioning_process_line() | void TTNProvisioning::processLine() | ||||||
| { | { | ||||||
|     bool is_ok = true; |     bool is_ok = true; | ||||||
|     bool reset_needed = false; |     bool reset_needed = false; | ||||||
| @ -209,14 +202,14 @@ void provisioning_process_line() | |||||||
|         char hexbuf[16]; |         char hexbuf[16]; | ||||||
| 
 | 
 | ||||||
|         memcpy(binbuf, global_dev_eui, 8); |         memcpy(binbuf, global_dev_eui, 8); | ||||||
|         swap_bytes(binbuf, 8); |         swapBytes(binbuf, 8); | ||||||
|         bin_to_hex_str(binbuf, 8, hexbuf); |         binToHexStr(binbuf, 8, hexbuf); | ||||||
|         uart_write_bytes(UART_NUM, hexbuf, 16); |         uart_write_bytes(UART_NUM, hexbuf, 16); | ||||||
|         uart_write_bytes(UART_NUM, "-", 1); |         uart_write_bytes(UART_NUM, "-", 1); | ||||||
| 
 | 
 | ||||||
|         memcpy(binbuf, global_app_eui, 8); |         memcpy(binbuf, global_app_eui, 8); | ||||||
|         swap_bytes(binbuf, 8); |         swapBytes(binbuf, 8); | ||||||
|         bin_to_hex_str(binbuf, 8, hexbuf); |         binToHexStr(binbuf, 8, hexbuf); | ||||||
|         uart_write_bytes(UART_NUM, hexbuf, 16); |         uart_write_bytes(UART_NUM, hexbuf, 16); | ||||||
| 
 | 
 | ||||||
|         uart_write_bytes(UART_NUM, "-00000000000000000000000000000000\r\n", 35); |         uart_write_bytes(UART_NUM, "-00000000000000000000000000000000\r\n", 35); | ||||||
| @ -228,7 +221,7 @@ void provisioning_process_line() | |||||||
|         { |         { | ||||||
|             line_buf[24] = 0; |             line_buf[24] = 0; | ||||||
|             line_buf[41] = 0; |             line_buf[41] = 0; | ||||||
|             is_ok = provisioning_decode_keys(line_buf + 8, line_buf + 25, line_buf + 42); |             is_ok = decodeKeys(line_buf + 8, line_buf + 25, line_buf + 42); | ||||||
|             reset_needed = is_ok; |             reset_needed = is_ok; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -238,7 +231,7 @@ void provisioning_process_line() | |||||||
|         if (is_ok) |         if (is_ok) | ||||||
|         { |         { | ||||||
|             line_buf[25] = 0; |             line_buf[25] = 0; | ||||||
|             is_ok = provisioning_from_mac(line_buf + 9, line_buf + 26); |             is_ok = fromMAC(line_buf + 9, line_buf + 26); | ||||||
|             reset_needed = is_ok; |             reset_needed = is_ok; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -250,7 +243,7 @@ void provisioning_process_line() | |||||||
|         esp_err_t err = esp_efuse_mac_get_default(mac); |         esp_err_t err = esp_efuse_mac_get_default(mac); | ||||||
|         ESP_ERROR_CHECK(err); |         ESP_ERROR_CHECK(err); | ||||||
| 
 | 
 | ||||||
|         bin_to_hex_str(mac, 6, hexbuf); |         binToHexStr(mac, 6, hexbuf); | ||||||
|         for (int i = 0; i < 12; i += 2) { |         for (int i = 0; i < 12; i += 2) { | ||||||
|             if (i > 0) |             if (i > 0) | ||||||
|                 uart_write_bytes(UART_NUM, ":", 1); |                 uart_write_bytes(UART_NUM, ":", 1); | ||||||
| @ -266,7 +259,7 @@ void provisioning_process_line() | |||||||
|         esp_err_t err = esp_efuse_mac_get_default(mac); |         esp_err_t err = esp_efuse_mac_get_default(mac); | ||||||
|         ESP_ERROR_CHECK(err); |         ESP_ERROR_CHECK(err); | ||||||
| 
 | 
 | ||||||
|         bin_to_hex_str(mac, 6, hexbuf); |         binToHexStr(mac, 6, hexbuf); | ||||||
|         for (int i = 0; i < 12; i += 2) { |         for (int i = 0; i < 12; i += 2) { | ||||||
|             uart_write_bytes(UART_NUM, hexbuf + i, 2); |             uart_write_bytes(UART_NUM, hexbuf + i, 2); | ||||||
|             if (i == 4) |             if (i == 4) | ||||||
| @ -296,7 +289,7 @@ void provisioning_process_line() | |||||||
| 
 | 
 | ||||||
| #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) | #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) | ||||||
| 
 | 
 | ||||||
| void provisioning_config_uart() | void TTNProvisioning::configUART() | ||||||
| { | { | ||||||
|     esp_err_t err; |     esp_err_t err; | ||||||
| 
 | 
 | ||||||
| @ -305,7 +298,9 @@ void provisioning_config_uart() | |||||||
|         .data_bits = UART_DATA_8_BITS, |         .data_bits = UART_DATA_8_BITS, | ||||||
|         .parity = UART_PARITY_DISABLE, |         .parity = UART_PARITY_DISABLE, | ||||||
|         .stop_bits = UART_STOP_BITS_1, |         .stop_bits = UART_STOP_BITS_1, | ||||||
|         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE |         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, | ||||||
|  |         .rx_flow_ctrl_thresh = 0, | ||||||
|  |         .use_ref_tick = false | ||||||
|     }; |     }; | ||||||
|     err = uart_param_config(UART_NUM, &uart_config); |     err = uart_param_config(UART_NUM, &uart_config); | ||||||
|     ESP_ERROR_CHECK(err); |     ESP_ERROR_CHECK(err); | ||||||
| @ -319,17 +314,17 @@ void provisioning_config_uart() | |||||||
| 
 | 
 | ||||||
| // --- Key handling
 | // --- Key handling
 | ||||||
| 
 | 
 | ||||||
| bool provisioning_have_keys() | bool TTNProvisioning::haveKeys() | ||||||
| { | { | ||||||
|     return have_keys; |     return have_keys; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool provisioning_decode_keys(const char *dev_eui, const char *app_eui, const char *app_key) | bool TTNProvisioning::decodeKeys(const char *dev_eui, const char *app_eui, const char *app_key) | ||||||
| { | { | ||||||
|     return provisioning_decode(true, dev_eui, app_eui, app_key); |     return decode(true, dev_eui, app_eui, app_key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool provisioning_from_mac(const char *app_eui, const char *app_key) | bool TTNProvisioning::fromMAC(const char *app_eui, const char *app_key) | ||||||
| { | { | ||||||
|     uint8_t mac[6]; |     uint8_t mac[6]; | ||||||
|     esp_err_t err = esp_efuse_mac_get_default(mac); |     esp_err_t err = esp_efuse_mac_get_default(mac); | ||||||
| @ -344,33 +339,33 @@ bool provisioning_from_mac(const char *app_eui, const char *app_key) | |||||||
|     global_dev_eui[1] = mac[4]; |     global_dev_eui[1] = mac[4]; | ||||||
|     global_dev_eui[0] = mac[5]; |     global_dev_eui[0] = mac[5]; | ||||||
| 
 | 
 | ||||||
|     return provisioning_decode(false, NULL, app_eui, app_key); |     return decode(false, nullptr, app_eui, app_key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool provisioning_decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const char *app_key) | bool TTNProvisioning::decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const char *app_key) | ||||||
| { | { | ||||||
|     uint8_t buf_dev_eui[8]; |     uint8_t buf_dev_eui[8]; | ||||||
|     uint8_t buf_app_eui[8]; |     uint8_t buf_app_eui[8]; | ||||||
|     uint8_t buf_app_key[16]; |     uint8_t buf_app_key[16]; | ||||||
| 
 | 
 | ||||||
|     if (incl_dev_eui && (strlen(dev_eui) != 16 || !hex_str_to_bin(dev_eui, buf_dev_eui, 8))) |     if (incl_dev_eui && (strlen(dev_eui) != 16 || !hexStrToBin(dev_eui, buf_dev_eui, 8))) | ||||||
|     { |     { | ||||||
|         ESP_LOGW(TAG, "Invalid device EUI: %s", dev_eui); |         ESP_LOGW(TAG, "Invalid device EUI: %s", dev_eui); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (incl_dev_eui) |     if (incl_dev_eui) | ||||||
|         swap_bytes(buf_dev_eui, 8); |         swapBytes(buf_dev_eui, 8); | ||||||
| 
 | 
 | ||||||
|     if (strlen(app_eui) != 16 || !hex_str_to_bin(app_eui, buf_app_eui, 8)) |     if (strlen(app_eui) != 16 || !hexStrToBin(app_eui, buf_app_eui, 8)) | ||||||
|     { |     { | ||||||
|         ESP_LOGW(TAG, "Invalid application EUI: %s", app_eui); |         ESP_LOGW(TAG, "Invalid application EUI: %s", app_eui); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     swap_bytes(buf_app_eui, 8); |     swapBytes(buf_app_eui, 8); | ||||||
| 
 | 
 | ||||||
|     if (strlen(app_key) != 32 || !hex_str_to_bin(app_key, buf_app_key, 16)) |     if (strlen(app_key) != 32 || !hexStrToBin(app_key, buf_app_key, 16)) | ||||||
|     { |     { | ||||||
|         ESP_LOGW(TAG, "Invalid application key: %s", app_key); |         ESP_LOGW(TAG, "Invalid application key: %s", app_key); | ||||||
|         return false; |         return false; | ||||||
| @ -381,11 +376,11 @@ bool provisioning_decode(bool incl_dev_eui, const char *dev_eui, const char *app | |||||||
|     memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui)); |     memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui)); | ||||||
|     memcpy(global_app_key, buf_app_key, sizeof(global_app_key)); |     memcpy(global_app_key, buf_app_key, sizeof(global_app_key)); | ||||||
| 
 | 
 | ||||||
|     have_keys = !is_all_zeroes(global_dev_eui, sizeof(global_dev_eui)) |     have_keys = !isAllZeros(global_dev_eui, sizeof(global_dev_eui)) | ||||||
|         && !is_all_zeroes(global_app_eui, sizeof(global_app_eui)) |         && !isAllZeros(global_app_eui, sizeof(global_app_eui)) | ||||||
|         && !is_all_zeroes(global_app_key, sizeof(global_app_key)); |         && !isAllZeros(global_app_key, sizeof(global_app_key)); | ||||||
| 
 | 
 | ||||||
|     if (!provisioning_save_keys()) |     if (!saveKeys()) | ||||||
|         return false; |         return false; | ||||||
|      |      | ||||||
|     return true; |     return true; | ||||||
| @ -394,7 +389,7 @@ bool provisioning_decode(bool incl_dev_eui, const char *dev_eui, const char *app | |||||||
| 
 | 
 | ||||||
| // --- Non-volatile storage
 | // --- Non-volatile storage
 | ||||||
| 
 | 
 | ||||||
| bool provisioning_save_keys() | bool TTNProvisioning::saveKeys() | ||||||
| { | { | ||||||
|     bool result = false; |     bool result = false; | ||||||
| 
 | 
 | ||||||
| @ -409,13 +404,13 @@ bool provisioning_save_keys() | |||||||
|     if (res != ESP_OK) |     if (res != ESP_OK) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     if (!write_nvs_value(handle, NVS_FLASH_KEY_DEV_EUI, global_dev_eui, sizeof(global_dev_eui))) |     if (!writeNvsValue(handle, NVS_FLASH_KEY_DEV_EUI, global_dev_eui, sizeof(global_dev_eui))) | ||||||
|         goto done; |         goto done; | ||||||
|          |          | ||||||
|     if (!write_nvs_value(handle, NVS_FLASH_KEY_APP_EUI, global_app_eui, sizeof(global_app_eui))) |     if (!writeNvsValue(handle, NVS_FLASH_KEY_APP_EUI, global_app_eui, sizeof(global_app_eui))) | ||||||
|         goto done; |         goto done; | ||||||
|          |          | ||||||
|     if (!write_nvs_value(handle, NVS_FLASH_KEY_APP_KEY, global_app_key, sizeof(global_app_key))) |     if (!writeNvsValue(handle, NVS_FLASH_KEY_APP_KEY, global_app_key, sizeof(global_app_key))) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     res = nvs_commit(handle); |     res = nvs_commit(handle); | ||||||
| @ -429,7 +424,7 @@ done: | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool provisioning_restore_keys(bool silent) | bool TTNProvisioning::restoreKeys(bool silent) | ||||||
| { | { | ||||||
|     uint8_t buf_dev_eui[8]; |     uint8_t buf_dev_eui[8]; | ||||||
|     uint8_t buf_app_eui[8]; |     uint8_t buf_app_eui[8]; | ||||||
| @ -448,22 +443,22 @@ bool provisioning_restore_keys(bool silent) | |||||||
|     if (res != ESP_OK) |     if (res != ESP_OK) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     if (!read_nvs_value(handle, NVS_FLASH_KEY_DEV_EUI, buf_dev_eui, sizeof(global_dev_eui), silent)) |     if (!readNvsValue(handle, NVS_FLASH_KEY_DEV_EUI, buf_dev_eui, sizeof(global_dev_eui), silent)) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     if (!read_nvs_value(handle, NVS_FLASH_KEY_APP_EUI, buf_app_eui, sizeof(global_app_eui), silent)) |     if (!readNvsValue(handle, NVS_FLASH_KEY_APP_EUI, buf_app_eui, sizeof(global_app_eui), silent)) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     if (!read_nvs_value(handle, NVS_FLASH_KEY_APP_KEY, buf_app_key, sizeof(global_app_key), silent)) |     if (!readNvsValue(handle, NVS_FLASH_KEY_APP_KEY, buf_app_key, sizeof(global_app_key), silent)) | ||||||
|         goto done; |         goto done; | ||||||
| 
 | 
 | ||||||
|     memcpy(global_dev_eui, buf_dev_eui, sizeof(global_dev_eui)); |     memcpy(global_dev_eui, buf_dev_eui, sizeof(global_dev_eui)); | ||||||
|     memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui)); |     memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui)); | ||||||
|     memcpy(global_app_key, buf_app_key, sizeof(global_app_key)); |     memcpy(global_app_key, buf_app_key, sizeof(global_app_key)); | ||||||
| 
 | 
 | ||||||
|     have_keys = !is_all_zeroes(global_dev_eui, sizeof(global_dev_eui)) |     have_keys = !isAllZeros(global_dev_eui, sizeof(global_dev_eui)) | ||||||
|         && !is_all_zeroes(global_app_eui, sizeof(global_app_eui)) |         && !isAllZeros(global_app_eui, sizeof(global_app_eui)) | ||||||
|         && !is_all_zeroes(global_app_key, sizeof(global_app_key)); |         && !isAllZeros(global_app_key, sizeof(global_app_key)); | ||||||
| 
 | 
 | ||||||
|     if (have_keys) |     if (have_keys) | ||||||
|     { |     { | ||||||
| @ -479,7 +474,7 @@ done: | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool read_nvs_value(nvs_handle handle, const char* key, uint8_t* data, size_t expected_length, bool silent) | bool TTNProvisioning::readNvsValue(nvs_handle handle, const char* key, uint8_t* data, size_t expected_length, bool silent) | ||||||
| { | { | ||||||
|     size_t size = expected_length; |     size_t size = expected_length; | ||||||
|     esp_err_t res = nvs_get_blob(handle, key, data, &size); |     esp_err_t res = nvs_get_blob(handle, key, data, &size); | ||||||
| @ -504,10 +499,10 @@ bool read_nvs_value(nvs_handle handle, const char* key, uint8_t* data, size_t ex | |||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool write_nvs_value(nvs_handle handle, const char* key, const uint8_t* data, size_t len) | bool TTNProvisioning::writeNvsValue(nvs_handle handle, const char* key, const uint8_t* data, size_t len) | ||||||
| { | { | ||||||
|     uint8_t buf[16]; |     uint8_t buf[16]; | ||||||
|     if (read_nvs_value(handle, key, buf, len, true) && memcmp(buf, data, len) == 0) |     if (readNvsValue(handle, key, buf, len, true) && memcmp(buf, data, len) == 0) | ||||||
|         return true; // unchanged
 |         return true; // unchanged
 | ||||||
|      |      | ||||||
|     esp_err_t res = nvs_set_blob(handle, key, data, len); |     esp_err_t res = nvs_set_blob(handle, key, data, len); | ||||||
| @ -519,12 +514,12 @@ bool write_nvs_value(nvs_handle handle, const char* key, const uint8_t* data, si | |||||||
| 
 | 
 | ||||||
| // --- Helper functions ---
 | // --- Helper functions ---
 | ||||||
| 
 | 
 | ||||||
| bool hex_str_to_bin(const char *hex, uint8_t *buf, int len) | bool TTNProvisioning::hexStrToBin(const char *hex, uint8_t *buf, int len) | ||||||
| { | { | ||||||
|     const char* ptr = hex; |     const char* ptr = hex; | ||||||
|     for (int i = 0; i < len; i++) |     for (int i = 0; i < len; i++) | ||||||
|     { |     { | ||||||
|         int val = hex_tuple_to_byte(ptr); |         int val = hexTupleToByte(ptr); | ||||||
|         if (val < 0) |         if (val < 0) | ||||||
|             return false; |             return false; | ||||||
|         buf[i] = val; |         buf[i] = val; | ||||||
| @ -533,18 +528,18 @@ bool hex_str_to_bin(const char *hex, uint8_t *buf, int len) | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int hex_tuple_to_byte(const char *hex) | int TTNProvisioning::hexTupleToByte(const char *hex) | ||||||
| { | { | ||||||
|     int nibble1 = hex_digit_to_val(hex[0]); |     int nibble1 = hexDigitToVal(hex[0]); | ||||||
|     if (nibble1 < 0) |     if (nibble1 < 0) | ||||||
|         return -1; |         return -1; | ||||||
|     int nibble2 = hex_digit_to_val(hex[1]); |     int nibble2 = hexDigitToVal(hex[1]); | ||||||
|     if (nibble2 < 0) |     if (nibble2 < 0) | ||||||
|         return -1; |         return -1; | ||||||
|     return (nibble1 << 4) | nibble2; |     return (nibble1 << 4) | nibble2; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int hex_digit_to_val(char ch) | int TTNProvisioning::hexDigitToVal(char ch) | ||||||
| { | { | ||||||
|     if (ch >= '0' && ch <= '9') |     if (ch >= '0' && ch <= '9') | ||||||
|         return ch - '0'; |         return ch - '0'; | ||||||
| @ -555,24 +550,24 @@ int hex_digit_to_val(char ch) | |||||||
|     return -1; |     return -1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bin_to_hex_str(const uint8_t* buf, int len, char* hex) | void TTNProvisioning::binToHexStr(const uint8_t* buf, int len, char* hex) | ||||||
| { | { | ||||||
|     for (int i = 0; i < len; i++) |     for (int i = 0; i < len; i++) | ||||||
|     { |     { | ||||||
|         uint8_t b = buf[i]; |         uint8_t b = buf[i]; | ||||||
|         *hex = val_to_hex_digit((b & 0xf0) >> 4); |         *hex = valToHexDigit((b & 0xf0) >> 4); | ||||||
|         hex++; |         hex++; | ||||||
|         *hex = val_to_hex_digit(b & 0x0f); |         *hex = valToHexDigit(b & 0x0f); | ||||||
|         hex++; |         hex++; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char val_to_hex_digit(int val) | char TTNProvisioning::valToHexDigit(int val) | ||||||
| { | { | ||||||
|     return "0123456789ABCDEF"[val]; |     return "0123456789ABCDEF"[val]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void swap_bytes(uint8_t* buf, int len) | void TTNProvisioning::swapBytes(uint8_t* buf, int len) | ||||||
| { | { | ||||||
|     uint8_t* p1 = buf; |     uint8_t* p1 = buf; | ||||||
|     uint8_t* p2 = buf + len - 1; |     uint8_t* p2 = buf + len - 1; | ||||||
| @ -586,7 +581,7 @@ void swap_bytes(uint8_t* buf, int len) | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool is_all_zeroes(const uint8_t* buf, int len) | bool TTNProvisioning::isAllZeros(const uint8_t* buf, int len) | ||||||
| { | { | ||||||
|     for (int i = 0; i < len; i++) |     for (int i = 0; i < len; i++) | ||||||
|         if (buf[i] != 0) |         if (buf[i] != 0) | ||||||
							
								
								
									
										67
									
								
								src/TTNProvisioning.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/TTNProvisioning.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  *  | ||||||
|  |  * ttn-esp32 - The Things Network device library for ESP-IDF / SX127x | ||||||
|  |  *  | ||||||
|  |  * Copyright (c) 2018 Manuel Bleichenbacher | ||||||
|  |  *  | ||||||
|  |  * Licensed under MIT License | ||||||
|  |  * https://opensource.org/licenses/MIT | ||||||
|  |  * | ||||||
|  |  * Task listening on a UART port for provisioning commands. | ||||||
|  |  *******************************************************************************/ | ||||||
|  |  | ||||||
|  | #ifndef _ttnprovisioning_h_ | ||||||
|  | #define _ttnprovisioning_h_ | ||||||
|  |  | ||||||
|  | #include "lmic/oslmic.h" | ||||||
|  | #include "nvs_flash.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TTNProvisioning | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     TTNProvisioning(); | ||||||
|  |  | ||||||
|  |     void startTask(); | ||||||
|  |     bool haveKeys(); | ||||||
|  |     bool decodeKeys(const char *dev_eui, const char *app_eui, const char *app_key); | ||||||
|  |     bool fromMAC(const char *app_eui, const char *app_key); | ||||||
|  |     bool saveKeys(); | ||||||
|  |     bool restoreKeys(bool silent); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     void provisioningTask(); | ||||||
|  |     bool decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const char *app_key); | ||||||
|  |     void addLineData(int numBytes); | ||||||
|  |     void detectLineEnd(int start_at); | ||||||
|  |     void processLine(); | ||||||
|  |     bool readNvsValue(nvs_handle handle, const char* key, uint8_t* data, size_t expected_length, bool silent); | ||||||
|  |     bool writeNvsValue(nvs_handle handle, const char* key, const uint8_t* data, size_t len); | ||||||
|  |  | ||||||
|  | #if defined(CONFIG_TTN_PROVISION_UART_CONFIG_YES) | ||||||
|  |     void configUART(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     static bool hexStrToBin(const char *hex, uint8_t *buf, int len); | ||||||
|  |     static int hexTupleToByte(const char *hex); | ||||||
|  |     static int hexDigitToVal(char ch); | ||||||
|  |     static void binToHexStr(const uint8_t* buf, int len, char* hex); | ||||||
|  |     static char valToHexDigit(int val); | ||||||
|  |     static void swapBytes(uint8_t* buf, int len); | ||||||
|  |     static bool isAllZeros(const uint8_t* buf, int len); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     bool have_keys = false; | ||||||
|  |  | ||||||
|  | #if !defined(CONFIG_TTN_PROVISION_UART_NONE) | ||||||
|  |     QueueHandle_t uart_queue; | ||||||
|  |     char* line_buf; | ||||||
|  |     int line_length; | ||||||
|  |     uint8_t last_line_end_char; | ||||||
|  |     bool quit_task; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     friend void ttn_provisioning_task_caller(void* pvParameter); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @ -16,7 +16,7 @@ | |||||||
| #include "TheThingsNetwork.h" | #include "TheThingsNetwork.h" | ||||||
| #include "hal/hal_esp32.h" | #include "hal/hal_esp32.h" | ||||||
| #include "lmic/lmic.h" | #include "lmic/lmic.h" | ||||||
| #include "provisioning.h" | #include "TTNProvisioning.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| enum ClientAction | enum ClientAction | ||||||
| @ -31,10 +31,11 @@ static const char *TAG = "ttn"; | |||||||
| static TheThingsNetwork* ttnInstance; | static TheThingsNetwork* ttnInstance; | ||||||
| static QueueHandle_t resultQueue; | static QueueHandle_t resultQueue; | ||||||
| static ClientAction clientAction = eActionUnrelated; | static ClientAction clientAction = eActionUnrelated; | ||||||
|  | static TTNProvisioning provisioning; | ||||||
|  |  | ||||||
|  |  | ||||||
| TheThingsNetwork::TheThingsNetwork() | TheThingsNetwork::TheThingsNetwork() | ||||||
|     : messageCallback(NULL) |     : messageCallback(nullptr) | ||||||
| { | { | ||||||
| #if defined(TTN_IS_DISABLED) | #if defined(TTN_IS_DISABLED) | ||||||
|     ESP_LOGE(TAG, "TTN is disabled. Configure a frequency plan using 'make menuconfig'"); |     ESP_LOGE(TAG, "TTN is disabled. Configure a frequency plan using 'make menuconfig'"); | ||||||
| @ -42,7 +43,7 @@ TheThingsNetwork::TheThingsNetwork() | |||||||
|     esp_restart(); |     esp_restart(); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     ASSERT(ttnInstance == NULL); |     ASSERT(ttnInstance == nullptr); | ||||||
|     ttnInstance = this; |     ttnInstance = this; | ||||||
|     hal_initCriticalSection(); |     hal_initCriticalSection(); | ||||||
| } | } | ||||||
| @ -65,7 +66,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 != nullptr); | ||||||
|     hal_startBgTask(); |     hal_startBgTask(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -78,24 +79,24 @@ 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) | ||||||
| { | { | ||||||
|     if (!provisioning_decode_keys(devEui, appEui, appKey)) |     if (!provisioning.decodeKeys(devEui, appEui, appKey)) | ||||||
|         return false; |         return false; | ||||||
|      |      | ||||||
|     return provisioning_save_keys(); |     return provisioning.saveKeys(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool TheThingsNetwork::provisionWithMAC(const char *appEui, const char *appKey) | bool TheThingsNetwork::provisionWithMAC(const char *appEui, const char *appKey) | ||||||
| { | { | ||||||
|     if (!provisioning_from_mac(appEui, appKey)) |     if (!provisioning.fromMAC(appEui, appKey)) | ||||||
|         return false; |         return false; | ||||||
|      |      | ||||||
|     return provisioning_save_keys(); |     return provisioning.saveKeys(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void TheThingsNetwork::startProvisioningTask() | void TheThingsNetwork::startProvisioningTask() | ||||||
| { | { | ||||||
| #if !defined(CONFIG_TTN_PROVISION_UART_NONE) | #if !defined(CONFIG_TTN_PROVISION_UART_NONE) | ||||||
|     provisioning_start_task(); |     provisioning.startTask(); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -108,7 +109,7 @@ void TheThingsNetwork::waitForProvisioning() | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     while (!provisioning_have_keys()) |     while (!provisioning.haveKeys()) | ||||||
|         vTaskDelay(1000 / portTICK_PERIOD_MS); |         vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||||
|  |  | ||||||
|     ESP_LOGI(TAG, "Device successfully provisioned"); |     ESP_LOGI(TAG, "Device successfully provisioned"); | ||||||
| @ -117,7 +118,7 @@ void TheThingsNetwork::waitForProvisioning() | |||||||
|  |  | ||||||
| bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char *appKey) | bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char *appKey) | ||||||
| { | { | ||||||
|     if (!provisioning_decode_keys(devEui, appEui, appKey)) |     if (!provisioning.decodeKeys(devEui, appEui, appKey)) | ||||||
|         return false; |         return false; | ||||||
|      |      | ||||||
|     return joinCore(); |     return joinCore(); | ||||||
| @ -125,9 +126,9 @@ bool TheThingsNetwork::join(const char *devEui, const char *appEui, const char * | |||||||
|  |  | ||||||
| bool TheThingsNetwork::join() | bool TheThingsNetwork::join() | ||||||
| { | { | ||||||
|     if (!provisioning_have_keys()) |     if (!provisioning.haveKeys()) | ||||||
|     { |     { | ||||||
|         if (!provisioning_restore_keys(false)) |         if (!provisioning.restoreKeys(false)) | ||||||
|             return false; |             return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -136,7 +137,7 @@ bool TheThingsNetwork::join() | |||||||
|  |  | ||||||
| bool TheThingsNetwork::joinCore() | bool TheThingsNetwork::joinCore() | ||||||
| { | { | ||||||
|     if (!provisioning_have_keys()) |     if (!provisioning.haveKeys()) | ||||||
|     { |     { | ||||||
|         ESP_LOGW(TAG, "Device EUI, App EUI and/or App key have not been provided"); |         ESP_LOGW(TAG, "Device EUI, App EUI and/or App key have not been provided"); | ||||||
|         return false; |         return false; | ||||||
| @ -173,12 +174,12 @@ TTNResponseCode TheThingsNetwork::transmitMessage(const uint8_t *payload, size_t | |||||||
|     if (result == EV_TXCOMPLETE) |     if (result == EV_TXCOMPLETE) | ||||||
|     { |     { | ||||||
|         bool hasRecevied = (LMIC.txrxFlags & (TXRX_DNW1 | TXRX_DNW2)) != 0; |         bool hasRecevied = (LMIC.txrxFlags & (TXRX_DNW1 | TXRX_DNW2)) != 0; | ||||||
|         if (hasRecevied && messageCallback != NULL) |         if (hasRecevied && messageCallback != nullptr) | ||||||
|         { |         { | ||||||
|             port_t port = 0; |             port_t port = 0; | ||||||
|             if ((LMIC.txrxFlags & TXRX_PORT)) |             if ((LMIC.txrxFlags & TXRX_PORT)) | ||||||
|                 port = LMIC.frame[LMIC.dataBeg - 1]; |                 port = LMIC.frame[LMIC.dataBeg - 1]; | ||||||
|             const uint8_t* msg = NULL; |             const uint8_t* msg = nullptr; | ||||||
|             if (LMIC.dataLen > 0) |             if (LMIC.dataLen > 0) | ||||||
|                 msg = LMIC.frame + LMIC.dataBeg; |                 msg = LMIC.frame + LMIC.dataBeg; | ||||||
|             messageCallback(msg, LMIC.dataLen, port); |             messageCallback(msg, LMIC.dataLen, port); | ||||||
| @ -198,12 +199,12 @@ void TheThingsNetwork::onMessage(TTNMessageCallback callback) | |||||||
|  |  | ||||||
| bool TheThingsNetwork::isProvisioned() | bool TheThingsNetwork::isProvisioned() | ||||||
| { | { | ||||||
|     if (provisioning_have_keys()) |     if (provisioning.haveKeys()) | ||||||
|         return true; |         return true; | ||||||
|      |      | ||||||
|     provisioning_restore_keys(true); |     provisioning.restoreKeys(true); | ||||||
|  |  | ||||||
|     return provisioning_have_keys(); |     return provisioning.haveKeys(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -211,7 +212,7 @@ bool TheThingsNetwork::isProvisioned() | |||||||
|  |  | ||||||
| #if CONFIG_LOG_DEFAULT_LEVEL >= 3 | #if CONFIG_LOG_DEFAULT_LEVEL >= 3 | ||||||
| static const char *eventNames[] = { | static const char *eventNames[] = { | ||||||
|     NULL, |     nullptr, | ||||||
|     "EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", |     "EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", | ||||||
|     "EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", |     "EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", | ||||||
|     "EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", |     "EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", | ||||||
|  | |||||||
| @ -1,36 +0,0 @@ | |||||||
| /******************************************************************************* |  | ||||||
|  *  |  | ||||||
|  * ttn-esp32 - The Things Network device library for ESP-IDF / SX127x |  | ||||||
|  *  |  | ||||||
|  * Copyright (c) 2018 Manuel Bleichenbacher |  | ||||||
|  *  |  | ||||||
|  * Licensed under MIT License |  | ||||||
|  * https://opensource.org/licenses/MIT |  | ||||||
|  * |  | ||||||
|  * Task listening on a UART port for provisioning commands. |  | ||||||
|  *******************************************************************************/ |  | ||||||
|  |  | ||||||
| #ifndef _provision_task_h_ |  | ||||||
| #define _provision_task_h_ |  | ||||||
|  |  | ||||||
| #include "lmic/oslmic.h" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| extern "C" { |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void provisioning_start_task(); |  | ||||||
| bool provisioning_have_keys(); |  | ||||||
| bool provisioning_decode_keys(const char *dev_eui, const char *app_eui, const char *app_key); |  | ||||||
| bool provisioning_from_mac(const char *app_eui, const char *app_key); |  | ||||||
| bool provisioning_save_keys(); |  | ||||||
| bool provisioning_restore_keys(bool silent); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
		Reference in New Issue
	
	Block a user