Adapted code formatting

This commit is contained in:
Manuel Bleichenbacher
2021-07-31 17:03:00 +02:00
parent e34dbcb467
commit 8fa345a5d4
10 changed files with 1076 additions and 1112 deletions

View File

@ -1,9 +1,9 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
@ -12,7 +12,6 @@
#include "TheThingsNetwork.h"
TTNRFSettings TheThingsNetwork::getRFSettings(TTNRxTxWindow window)
{
ttn_rf_settings_t settings = ttn_get_rf_settings(static_cast<ttn_rx_tx_window_t>(window));

View File

@ -1,9 +1,9 @@
/*******************************************************************************
*
*
* 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
*
@ -17,7 +17,8 @@
#elif defined(CONFIG_TTN_LORA_FREQ_US_915)
#define CFG_us915 1
#elif defined(CONFIG_TTN_LORA_FREQ_AU_921)
# warning "CONFIG_TTN_LORA_FREQ_AU_921 was deprecated in favour of CONFIG_TTN_LORA_FREQ_AU_921. Support for CONFIG_TTN_LORA_FREQ_AU_921 will be removed in the future."
#warning \
"CONFIG_TTN_LORA_FREQ_AU_921 was deprecated in favour of CONFIG_TTN_LORA_FREQ_AU_921. Support for CONFIG_TTN_LORA_FREQ_AU_921 will be removed in the future."
#define CFG_au915 1
#elif defined(CONFIG_TTN_LORA_FREQ_AU_915)
#define CFG_au915 1
@ -50,7 +51,6 @@
#endif
#endif
// 16 μs per tick
// LMIC requires ticks to be 15.5μs - 100 μs long
#define US_PER_OSTICK 16

132
src/ttn.c
View File

@ -1,24 +1,23 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
* High-level C API for ttn-esp32.
*******************************************************************************/
#include "lmic/lmic.h"
#include "ttn.h"
#include "ttn_provisioning.h"
#include "ttn_logging.h"
#include "hal/hal_esp32.h"
#include "freertos/FreeRTOS.h"
#include "esp_event.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "hal/hal_esp32.h"
#include "lmic/lmic.h"
#include "ttn_logging.h"
#include "ttn_provisioning.h"
#define TAG "ttn"
@ -37,7 +36,8 @@ typedef enum
/**
* @brief Event type
*/
typedef enum {
typedef enum
{
TTN_EVENT_NONE,
TTN_EVNT_JOIN_COMPLETED,
TTN_EVENT_JOIN_FAILED,
@ -49,10 +49,11 @@ typedef enum {
/**
* @brief Event message sent from LMIC task to waiting client task
*/
typedef struct {
typedef struct
{
ttn_event_t event;
uint8_t port;
const uint8_t* message;
const uint8_t *message;
size_t message_size;
} ttn_lmic_event_t;
@ -68,12 +69,11 @@ static int max_tx_power = DEFAULT_MAX_TX_POWER;
static bool join_core(void);
static void config_rf_params(void);
static void event_callback(void* user_data, ev_t event);
static void event_callback(void *user_data, ev_t event);
static void message_received_callback(void *user_data, uint8_t port, const uint8_t *message, size_t message_size);
static void message_transmitted_callback(void *user_data, int success);
static void save_rf_settings(ttn_rf_settings_t* rf_settings);
static void clear_rf_settings(ttn_rf_settings_t* rf_settings);
static void save_rf_settings(ttn_rf_settings_t *rf_settings);
static void clear_rf_settings(ttn_rf_settings_t *rf_settings);
void ttn_init(void)
{
@ -140,7 +140,7 @@ bool ttn_provision(const char *dev_eui, const char *app_eui, const char *app_key
{
if (!ttn_provisioning_decode_keys(dev_eui, app_eui, app_key))
return false;
return ttn_provisioning_save_keys();
}
@ -148,11 +148,10 @@ bool ttn_provision_with_mac(const char *app_eui, const char *app_key)
{
if (!ttn_provisioning_from_mac(app_eui, app_key))
return false;
return ttn_provisioning_save_keys();
}
void ttn_start_provisioning_task(void)
{
#if defined(TTN_HAS_AT_COMMANDS)
@ -188,7 +187,7 @@ bool ttn_join(const char *dev_eui, const char *app_eui, const char *app_key)
{
if (!ttn_provisioning_decode_keys(dev_eui, app_eui, app_key))
return false;
return join_core();
}
@ -267,19 +266,19 @@ ttn_response_code_t ttn_transmit_message(const uint8_t *payload, size_t length,
switch (result.event)
{
case TTN_EVENT_MESSAGE_RECEIVED:
if (message_callback != NULL)
message_callback(result.message, result.message_size, result.port);
break;
case TTN_EVENT_MESSAGE_RECEIVED:
if (message_callback != NULL)
message_callback(result.message, result.message_size, result.port);
break;
case TTN_EVENT_TRANSMISSION_COMPLETED:
return TTN_SUCCESSFUL_TRANSMISSION;
case TTN_EVENT_TRANSMISSION_COMPLETED:
return TTN_SUCCESSFUL_TRANSMISSION;
case TTN_EVENT_TRANSMISSION_FAILED:
return TTN_ERROR_TRANSMISSION_FAILED;
case TTN_EVENT_TRANSMISSION_FAILED:
return TTN_ERROR_TRANSMISSION_FAILED;
default:
ASSERT(0);
default:
ASSERT(0);
}
}
}
@ -289,12 +288,11 @@ void ttn_on_message(ttn_message_cb callback)
message_callback = callback;
}
bool ttn_is_provisioned(void)
{
if (ttn_provisioning_have_keys())
return true;
ttn_provisioning_restore_keys(true);
return ttn_provisioning_have_keys();
@ -376,43 +374,41 @@ int ttn_rssi(void)
return LMIC.rssi;
}
// --- Callbacks ---
#if CONFIG_LOG_DEFAULT_LEVEL >= 3 || LMIC_ENABLE_event_logging
static const char *event_names[] = { LMIC_EVENT_NAME_TABLE__INIT };
static const char *event_names[] = {LMIC_EVENT_NAME_TABLE__INIT};
#endif
// Called by LMIC when an LMIC event (join, join failed, reset etc.) occurs
void event_callback(void* user_data, ev_t event)
void event_callback(void *user_data, ev_t event)
{
// update monitoring information
switch(event)
switch (event)
{
case EV_TXSTART:
current_rx_tx_window = TTN_WINDOW_TX;
save_rf_settings(&last_rf_settings[TTN_WINDOW_TX]);
clear_rf_settings(&last_rf_settings[TTN_WINDOW_RX1]);
clear_rf_settings(&last_rf_settings[TTN_WINDOW_RX2]);
break;
case EV_TXSTART:
current_rx_tx_window = TTN_WINDOW_TX;
save_rf_settings(&last_rf_settings[TTN_WINDOW_TX]);
clear_rf_settings(&last_rf_settings[TTN_WINDOW_RX1]);
clear_rf_settings(&last_rf_settings[TTN_WINDOW_RX2]);
break;
case EV_RXSTART:
if (current_rx_tx_window != TTN_WINDOW_RX1)
{
current_rx_tx_window = TTN_WINDOW_RX1;
save_rf_settings(&last_rf_settings[TTN_WINDOW_RX1]);
}
else
{
current_rx_tx_window = TTN_WINDOW_RX2;
save_rf_settings(&last_rf_settings[TTN_WINDOW_RX2]);
}
break;
case EV_RXSTART:
if (current_rx_tx_window != TTN_WINDOW_RX1)
{
current_rx_tx_window = TTN_WINDOW_RX1;
save_rf_settings(&last_rf_settings[TTN_WINDOW_RX1]);
}
else
{
current_rx_tx_window = TTN_WINDOW_RX2;
save_rf_settings(&last_rf_settings[TTN_WINDOW_RX2]);
}
break;
default:
current_rx_tx_window = TTN_WINDOW_IDLE;
break;
default:
current_rx_tx_window = TTN_WINDOW_IDLE;
break;
};
#if LMIC_ENABLE_event_logging
@ -438,9 +434,7 @@ void event_callback(void* user_data, ev_t event)
if (ttn_event == TTN_EVENT_NONE)
return;
ttn_lmic_event_t result = {
.event = ttn_event
};
ttn_lmic_event_t result = {.event = ttn_event};
waiting_reason = TTN_WAITING_NONE;
xQueueSend(lmic_event_queue, &result, pdMS_TO_TICKS(100));
}
@ -449,11 +443,7 @@ void event_callback(void* user_data, ev_t event)
void message_received_callback(void *user_data, uint8_t port, const uint8_t *message, size_t message_size)
{
ttn_lmic_event_t result = {
.event = TTN_EVENT_MESSAGE_RECEIVED,
.port = port,
.message = message,
.message_size = message_size
};
.event = TTN_EVENT_MESSAGE_RECEIVED, .port = port, .message = message, .message_size = message_size};
xQueueSend(lmic_event_queue, &result, pdMS_TO_TICKS(100));
}
@ -461,24 +451,20 @@ void message_received_callback(void *user_data, uint8_t port, const uint8_t *mes
void message_transmitted_callback(void *user_data, int success)
{
waiting_reason = TTN_WAITING_NONE;
ttn_lmic_event_t result = {
.event = success ? TTN_EVENT_TRANSMISSION_COMPLETED : TTN_EVENT_TRANSMISSION_FAILED
};
ttn_lmic_event_t result = {.event = success ? TTN_EVENT_TRANSMISSION_COMPLETED : TTN_EVENT_TRANSMISSION_FAILED};
xQueueSend(lmic_event_queue, &result, pdMS_TO_TICKS(100));
}
// --- Helpers
void save_rf_settings(ttn_rf_settings_t* rf_settings)
void save_rf_settings(ttn_rf_settings_t *rf_settings)
{
rf_settings->spreading_factor = (ttn_spreading_factor_t)(getSf(LMIC.rps) + 1);
rf_settings->bandwidth = (ttn_bandwidth_t)(getBw(LMIC.rps) + 1);
rf_settings->frequency = LMIC.freq;
}
void clear_rf_settings(ttn_rf_settings_t* rf_settings)
void clear_rf_settings(ttn_rf_settings_t *rf_settings)
{
memset(rf_settings, 0, sizeof(*rf_settings));
}

View File

@ -1,82 +1,80 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
* Circular buffer for detailed logging without affecting LMIC timing.
*******************************************************************************/
#if LMIC_ENABLE_event_logging
#include "ttn_logging.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "lmic/lmic.h"
#include <string.h>
#define NUM_RINGBUF_MSG 50
#define TAG "lmic"
/**
* @brief Message structure used in ring buffer
*
*
* The structure is sent from the LMIC task to the logging task.
*/
typedef struct {
const char* message;
uint32_t datum;
ev_t event;
ostime_t time;
ostime_t txend;
ostime_t globalDutyAvail;
u4_t freq;
u2_t opmode;
u2_t fcntDn;
u2_t fcntUp;
u2_t rxsyms;
rps_t rps;
u1_t txChnl;
u1_t datarate;
u1_t txrxFlags;
u1_t saveIrqFlags;
typedef struct
{
const char *message;
uint32_t datum;
ev_t event;
ostime_t time;
ostime_t txend;
ostime_t globalDutyAvail;
u4_t freq;
u2_t opmode;
u2_t fcntDn;
u2_t fcntUp;
u2_t rxsyms;
rps_t rps;
u1_t txChnl;
u1_t datarate;
u1_t txrxFlags;
u1_t saveIrqFlags;
} TTNLogMessage;
static void loggingTask(void* param);
static void logFatal(const char* const file, const uint16_t line);
static void loggingTask(void *param);
static void logFatal(const char *const file, const uint16_t line);
static void printMessage(TTNLogMessage* log);
static void printFatalError(TTNLogMessage* log);
static void printEvent(TTNLogMessage* log);
static void printEvtJoined(TTNLogMessage* log);
static void printEvtJoinFailed(TTNLogMessage* log);
static void printEvtTxComplete(TTNLogMessage* log);
static void printEvtTxStart(TTNLogMessage* log);
static void printEvtRxStart(TTNLogMessage* log);
static void printEvtJoinTxComplete(TTNLogMessage* log);
static void bin2hex(const uint8_t* bin, unsigned len, char* buf, char sep);
static void printMessage(TTNLogMessage *log);
static void printFatalError(TTNLogMessage *log);
static void printEvent(TTNLogMessage *log);
static void printEvtJoined(TTNLogMessage *log);
static void printEvtJoinFailed(TTNLogMessage *log);
static void printEvtTxComplete(TTNLogMessage *log);
static void printEvtTxStart(TTNLogMessage *log);
static void printEvtRxStart(TTNLogMessage *log);
static void printEvtJoinTxComplete(TTNLogMessage *log);
static void bin2hex(const uint8_t *bin, unsigned len, char *buf, char sep);
// Constants for formatting LORA values
static const char* const SF_NAMES[] = { "FSK", "SF7", "SF8", "SF9", "SF10", "SF11", "SF12", "SFrfu" };
static const char* const BW_NAMES[] = { "BW125", "BW250", "BW500", "BWrfu" };
static const char* const CR_NAMES[] = { "CR 4/5", "CR 4/6", "CR 4/7", "CR 4/8" };
static const char* const CRC_NAMES[] = { "NoCrc", "Crc" };
static const char *const SF_NAMES[] = {"FSK", "SF7", "SF8", "SF9", "SF10", "SF11", "SF12", "SFrfu"};
static const char *const BW_NAMES[] = {"BW125", "BW250", "BW500", "BWrfu"};
static const char *const CR_NAMES[] = {"CR 4/5", "CR 4/6", "CR 4/7", "CR 4/8"};
static const char *const CRC_NAMES[] = {"NoCrc", "Crc"};
static RingbufHandle_t ringBuffer;
// Initialize logging
void ttn_log_init(void)
{
ringBuffer = xRingbufferCreate(NUM_RINGBUF_MSG * sizeof(TTNLogMessage), RINGBUF_TYPE_NOSPLIT);
if (ringBuffer == NULL) {
if (ringBuffer == NULL)
{
ESP_LOGE(TAG, "Failed to create ring buffer");
ASSERT(0);
}
@ -86,7 +84,7 @@ void ttn_log_init(void)
}
// Record a logging event for later output
void ttn_log_event(int event, const char* message, uint32_t datum)
void ttn_log_event(int event, const char *message, uint32_t datum)
{
if (ringBuffer == NULL)
return;
@ -101,8 +99,8 @@ void ttn_log_event(int event, const char* message, uint32_t datum)
.event = (ev_t)event,
.freq = LMIC.freq,
.opmode = LMIC.opmode,
.fcntDn = (u2_t) LMIC.seqnoDn,
.fcntUp = (u2_t) LMIC.seqnoUp,
.fcntDn = (u2_t)LMIC.seqnoDn,
.fcntUp = (u2_t)LMIC.seqnoUp,
.rxsyms = LMIC.rxsyms,
.rps = LMIC.rps,
.txChnl = LMIC.txChnl,
@ -115,7 +113,7 @@ void ttn_log_event(int event, const char* message, uint32_t datum)
}
// record a fatal event (failed assert) for later output
void logFatal(const char* const file, const uint16_t line)
void logFatal(const char *const file, const uint16_t line)
{
ttn_log_event(-3, file, line);
}
@ -125,7 +123,6 @@ void logFatal(const char* const file, const uint16_t line)
void LMICOS_logEvent(const char *pMessage)
{
ttn_log_event(-1, pMessage, 0);
}
// Record an information message with an integer value for later output
@ -135,18 +132,18 @@ void LMICOS_logEventUint32(const char *pMessage, uint32_t datum)
ttn_log_event(-2, pMessage, datum);
}
// ---------------------------------------------------------------------------
// Log output
// Tasks that receiveds the recorded messages, formats and outputs them.
void loggingTask(void* param)
void loggingTask(void *param)
{
RingbufHandle_t ringBuffer = (RingbufHandle_t)param;
while (true) {
while (true)
{
size_t size;
TTNLogMessage* log = (TTNLogMessage*) xRingbufferReceive(ringBuffer, &size, portMAX_DELAY);
TTNLogMessage *log = (TTNLogMessage *)xRingbufferReceive(ringBuffer, &size, portMAX_DELAY);
if (log == NULL)
continue;
@ -156,107 +153,79 @@ void loggingTask(void* param)
}
}
// Format and output a log message
void printMessage(TTNLogMessage* log)
void printMessage(TTNLogMessage *log)
{
switch((int)log->event)
switch ((int)log->event)
{
case -1:
ESP_LOGI(TAG, "%u (%d ms) - %s: opmode=%x",
log->time, osticks2ms(log->time),
log->message, log->opmode
);
break;
case -1:
ESP_LOGI(TAG, "%u (%d ms) - %s: opmode=%x", log->time, osticks2ms(log->time), log->message, log->opmode);
break;
case -2:
ESP_LOGI(TAG, "%u (%d ms) - %s: datum=0x%x, opmode=%x)",
log->time, osticks2ms(log->time),
log->message, log->datum, log->opmode
);
break;
case -2:
ESP_LOGI(TAG, "%u (%d ms) - %s: datum=0x%x, opmode=%x)", log->time, osticks2ms(log->time), log->message,
log->datum, log->opmode);
break;
case -3:
printFatalError(log);
break;
case -3:
printFatalError(log);
break;
default:
printEvent(log);
break;
default:
printEvent(log);
break;
}
}
void printFatalError(TTNLogMessage* log)
void printFatalError(TTNLogMessage *log)
{
ESP_LOGE(TAG, "%u (%d ms) - %s, %d",
log->time, osticks2ms(log->time),
log->message, log->datum
);
ESP_LOGE(TAG, "- freq=%d.%d, txend=%u, avail=%u, ch=%u",
log->freq / 1000000, (log->freq % 1000000) / 100000,
log->txend, log->globalDutyAvail,
(unsigned)log->txChnl
);
ESP_LOGE(TAG, "%u (%d ms) - %s, %d", log->time, osticks2ms(log->time), log->message, log->datum);
ESP_LOGE(TAG, "- freq=%d.%d, txend=%u, avail=%u, ch=%u", log->freq / 1000000, (log->freq % 1000000) / 100000,
log->txend, log->globalDutyAvail, (unsigned)log->txChnl);
rps_t rps = log->rps;
ESP_LOGE(TAG, "- rps=0x%02x (%s, %s, %s, %s, IH=%d)",
rps,
SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)],
getIh(rps)
);
ESP_LOGE(TAG, "- opmode=%x, txrxFlags=0x%02x%s, saveIrqFlags=0x%02x",
log->opmode,
log->txrxFlags,
(log->txrxFlags & TXRX_ACK) != 0 ? "; received ack" : "",
log->saveIrqFlags
);
ESP_LOGE(TAG, "- rps=0x%02x (%s, %s, %s, %s, IH=%d)", rps, SF_NAMES[getSf(rps)], BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)], CRC_NAMES[getNocrc(rps)], getIh(rps));
ESP_LOGE(TAG, "- opmode=%x, txrxFlags=0x%02x%s, saveIrqFlags=0x%02x", log->opmode, log->txrxFlags,
(log->txrxFlags & TXRX_ACK) != 0 ? "; received ack" : "", log->saveIrqFlags);
}
void printEvent(TTNLogMessage* log)
void printEvent(TTNLogMessage *log)
{
ESP_LOGI(TAG, "%u (%d ms) - %s",
log->time, osticks2ms(log->time),
log->message
);
ESP_LOGI(TAG, "%u (%d ms) - %s", log->time, osticks2ms(log->time), log->message);
switch((int)log->event)
switch ((int)log->event)
{
case EV_JOINED:
printEvtJoined(log);
break;
case EV_JOINED:
printEvtJoined(log);
break;
case EV_JOIN_FAILED:
printEvtJoinFailed(log);
break;
case EV_JOIN_FAILED:
printEvtJoinFailed(log);
break;
case EV_TXCOMPLETE:
printEvtTxComplete(log);
break;
case EV_TXCOMPLETE:
printEvtTxComplete(log);
break;
case EV_TXSTART:
printEvtTxStart(log);
break;
case EV_TXSTART:
printEvtTxStart(log);
break;
case EV_RXSTART:
printEvtRxStart(log);
break;
case EV_RXSTART:
printEvtRxStart(log);
break;
case EV_JOIN_TXCOMPLETE:
printEvtJoinTxComplete(log);
break;
case EV_JOIN_TXCOMPLETE:
printEvtJoinTxComplete(log);
break;
default:
break;
default:
break;
};
}
// Format and output the detail of a successful network join
void printEvtJoined(TTNLogMessage* log)
void printEvtJoined(TTNLogMessage *log)
{
ESP_LOGI(TAG, "- ch=%d", (unsigned)log->txChnl);
@ -271,111 +240,68 @@ void printEvtJoined(TTNLogMessage* log)
ESP_LOGI(TAG, "- devaddr: %08x", devaddr);
char hexBuf[48];
bin2hex((uint8_t*)&artKey, sizeof(artKey), hexBuf, '-');
bin2hex((uint8_t *)&artKey, sizeof(artKey), hexBuf, '-');
ESP_LOGI(TAG, "- artKey: %s", hexBuf);
bin2hex((uint8_t*)&nwkKey, sizeof(nwkKey), hexBuf, '-');
bin2hex((uint8_t *)&nwkKey, sizeof(nwkKey), hexBuf, '-');
ESP_LOGI(TAG, "- nwkKey: %s", hexBuf);
}
// Format and output the detail of a failed network join
void printEvtJoinFailed(TTNLogMessage* log)
void printEvtJoinFailed(TTNLogMessage *log)
{
rps_t rps = log->rps;
ESP_LOGE(TAG, "- freq=%d.%d, opmode=%x, rps=0x%02x (%s, %s, %s, %s, IH=%d)",
log->freq / 1000000, (log->freq % 1000000) / 100000,
log->opmode,
rps,
SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)],
getIh(rps)
);
ESP_LOGE(TAG, "- freq=%d.%d, opmode=%x, rps=0x%02x (%s, %s, %s, %s, IH=%d)", log->freq / 1000000,
(log->freq % 1000000) / 100000, log->opmode, rps, SF_NAMES[getSf(rps)], BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)], CRC_NAMES[getNocrc(rps)], getIh(rps));
}
void printEvtTxComplete(TTNLogMessage* log)
void printEvtTxComplete(TTNLogMessage *log)
{
rps_t rps = log->rps;
ESP_LOGI(TAG, "- ch=%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)",
(unsigned)log->txChnl,
rps,
SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)],
getIh(rps)
);
ESP_LOGI(TAG, "- txrxFlags=0x%02x%s, FcntUp=%04x, FcntDn=%04x, txend=%u",
log->txrxFlags,
(log->txrxFlags & TXRX_ACK) != 0 ? "; received ack" : "",
log->fcntUp, log->fcntDn,
log->txend
);
ESP_LOGI(TAG, "- ch=%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)", (unsigned)log->txChnl, rps, SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)], CR_NAMES[getCr(rps)], CRC_NAMES[getNocrc(rps)], getIh(rps));
ESP_LOGI(TAG, "- txrxFlags=0x%02x%s, FcntUp=%04x, FcntDn=%04x, txend=%u", log->txrxFlags,
(log->txrxFlags & TXRX_ACK) != 0 ? "; received ack" : "", log->fcntUp, log->fcntDn, log->txend);
}
void printEvtTxStart(TTNLogMessage* log)
void printEvtTxStart(TTNLogMessage *log)
{
rps_t rps = log->rps;
ESP_LOGI(TAG, "- ch=%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)",
(unsigned)log->txChnl,
rps,
SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)],
getIh(rps)
);
ESP_LOGI(TAG, "- datarate=%u, opmode=%x, txend=%u",
log->datarate,
log->opmode,
log->txend
);
ESP_LOGI(TAG, "- ch=%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)", (unsigned)log->txChnl, rps, SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)], CR_NAMES[getCr(rps)], CRC_NAMES[getNocrc(rps)], getIh(rps));
ESP_LOGI(TAG, "- datarate=%u, opmode=%x, txend=%u", log->datarate, log->opmode, log->txend);
}
void printEvtRxStart(TTNLogMessage* log)
void printEvtRxStart(TTNLogMessage *log)
{
rps_t rps = log->rps;
ESP_LOGI(TAG, "- freq=%d.%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)",
log->freq / 1000000, (log->freq % 1000000) / 100000,
rps,
SF_NAMES[getSf(rps)],
BW_NAMES[getBw(rps)],
CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)],
getIh(rps)
);
ESP_LOGI(TAG, "- delta=%dms, rxsysm=%u",
osticks2ms(log->time - log->txend),
log->rxsyms
);
ESP_LOGI(TAG, "- freq=%d.%d, rps=0x%02x (%s, %s, %s, %s, IH=%d)", log->freq / 1000000,
(log->freq % 1000000) / 100000, rps, SF_NAMES[getSf(rps)], BW_NAMES[getBw(rps)], CR_NAMES[getCr(rps)],
CRC_NAMES[getNocrc(rps)], getIh(rps));
ESP_LOGI(TAG, "- delta=%dms, rxsysm=%u", osticks2ms(log->time - log->txend), log->rxsyms);
}
void printEvtJoinTxComplete(TTNLogMessage* log)
void printEvtJoinTxComplete(TTNLogMessage *log)
{
ESP_LOGI(TAG, "- saveIrqFlags=0x%02x",
log->saveIrqFlags
);
ESP_LOGI(TAG, "- saveIrqFlags=0x%02x", log->saveIrqFlags);
}
static const char* HEX_DIGITS = "0123456789ABCDEF";
static const char *HEX_DIGITS = "0123456789ABCDEF";
/**
* @brief Convert binary data to hexadecimal representation.
*
*
* @param bin start of binary data
* @param len length of binary data (in bytes)
* @param buf buffer for hexadecimal result
* @param sep separator used between bytes (or 0 for none)
*/
void bin2hex(const uint8_t* bin, unsigned len, char* buf, char sep)
void bin2hex(const uint8_t *bin, unsigned len, char *buf, char sep)
{
int tgt = 0;
for (int i = 0; i < len; i++) {
for (int i = 0; i < len; i++)
{
if (sep != 0 && i != 0)
buf[tgt++] = sep;
buf[tgt++] = HEX_DIGITS[bin[i] >> 4];
@ -384,5 +310,4 @@ void bin2hex(const uint8_t* bin, unsigned len, char* buf, char sep)
buf[tgt] = 0;
}
#endif

View File

@ -1,9 +1,9 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
@ -13,42 +13,38 @@
#ifndef TTN_LOGGING_H
#define TTN_LOGGING_H
#if LMIC_ENABLE_event_logging
#include <freertos/FreeRTOS.h>
#include <freertos/ringbuf.h>
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
/**
* @brief Logging functions.
*
* Logs internal information from LMIC in an asynchrnous fashion in order
* not to distrub the sensitive LORA timing.
*
* A ring buffer and a separate logging task is ued. The LMIC core records
* relevant values from the current LORA settings and writes them to a ring
* buffer. The logging tasks receives the message and the values, formats
* them and outputs them via the regular ESP-IDF logging mechanism.
*
* In order to activate the detailed logging, set the macro
* `LMIC_ENABLE_event_logging` to 1.
*/
/**
* @brief Logging functions.
*
* Logs internal information from LMIC in an asynchrnous fashion in order
* not to distrub the sensitive LORA timing.
*
* A ring buffer and a separate logging task is ued. The LMIC core records
* relevant values from the current LORA settings and writes them to a ring
* buffer. The logging tasks receives the message and the values, formats
* them and outputs them via the regular ESP-IDF logging mechanism.
*
* In order to activate the detailed logging, set the macro
* `LMIC_ENABLE_event_logging` to 1.
*/
void ttn_log_init(void);
void ttn_log_event(int event, const char* message, uint32_t datum);
void ttn_log_init(void);
void ttn_log_event(int event, const char *message, uint32_t datum);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -1,9 +1,9 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
@ -11,14 +11,14 @@
*******************************************************************************/
#include "ttn_provisioning.h"
#include "freertos/FreeRTOS.h"
#include "driver/uart.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "lmic/lmic.h"
#include "freertos/FreeRTOS.h"
#include "hal/hal_esp32.h"
#include "lmic/lmic.h"
#include "nvs_flash.h"
#if defined(TTN_HAS_AT_COMMANDS)
#define UART_NUM CONFIG_TTN_PROVISION_UART_NUM
@ -32,7 +32,7 @@
#define NVS_FLASH_KEY_APP_KEY "appKey"
#if defined(TTN_HAS_AT_COMMANDS)
static void provisioning_task(void* pvParameter);
static void provisioning_task(void *pvParameter);
static void add_line_data(int num_bytes);
static void detect_line_end(int start_at);
static void process_line(void);
@ -43,16 +43,16 @@ static void config_uart(void);
#endif
static bool decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const char *app_key);
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 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 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_zeros(const uint8_t* buf, int len);
static void swap_bytes(uint8_t *buf, int len);
static bool is_all_zeros(const uint8_t *buf, int len);
static uint8_t global_dev_eui[8];
static uint8_t global_app_eui[8];
@ -62,26 +62,25 @@ static bool have_keys = false;
#if defined(TTN_HAS_AT_COMMANDS)
static QueueHandle_t uart_queue;
static char* line_buf;
static char *line_buf;
static int line_length;
static uint8_t last_line_end_char;
static bool quit_task;
#endif
// --- LMIC callbacks
// This EUI must be in little-endian format, so least-significant-byte first.
// When copying an EUI from ttnctl output, this means to reverse the bytes.
// For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 0x70.
// The order is swapped in provisioning_decode_keys().
void os_getArtEui (u1_t* buf)
void os_getArtEui(u1_t *buf)
{
memcpy(buf, global_app_eui, 8);
}
// This should also be in little endian format, see above.
void os_getDevEui (u1_t* buf)
void os_getDevEui(u1_t *buf)
{
memcpy(buf, global_dev_eui, 8);
}
@ -89,7 +88,7 @@ void os_getDevEui (u1_t* buf)
// This key should be in big endian format (or, since it is not really a number
// but a block of memory, endianness does not really apply). In practice, a key
// taken from ttnctl can be copied as-is.
void os_getDevKey (u1_t* buf)
void os_getDevKey(u1_t *buf)
{
memcpy(buf, global_app_key, 16);
}
@ -100,7 +99,6 @@ void ttn_provisioning_init(void)
{
}
// --- Provisioning task
#if defined(TTN_HAS_AT_COMMANDS)
@ -117,9 +115,9 @@ void ttn_provisioning_start_task(void)
xTaskCreate(provisioning_task, "ttn_provision", 2048, NULL, 1, NULL);
}
void provisioning_task(void* pvParameter)
void provisioning_task(void *pvParameter)
{
line_buf = (char*)malloc(MAX_LINE_LENGTH + 1);
line_buf = (char *)malloc(MAX_LINE_LENGTH + 1);
line_length = 0;
uart_event_t event;
@ -133,18 +131,18 @@ void provisioning_task(void* pvParameter)
switch (event.type)
{
case UART_DATA:
add_line_data(event.size);
break;
case UART_DATA:
add_line_data(event.size);
break;
case UART_FIFO_OVF:
case UART_BUFFER_FULL:
uart_flush_input(UART_NUM);
xQueueReset(uart_queue);
break;
case UART_FIFO_OVF:
case UART_BUFFER_FULL:
uart_flush_input(UART_NUM);
xQueueReset(uart_queue);
break;
default:
break;
default:
break;
}
}
@ -160,8 +158,8 @@ top:
n = num_bytes;
if (line_length + n > MAX_LINE_LENGTH)
n = MAX_LINE_LENGTH - line_length;
uart_read_bytes(UART_NUM, (uint8_t*)line_buf + line_length, n, portMAX_DELAY);
uart_read_bytes(UART_NUM, (uint8_t *)line_buf + line_length, n, portMAX_DELAY);
int start_at = line_length;
line_length += n;
@ -239,7 +237,7 @@ void process_line(void)
}
else if (strncmp(line_buf, "AT+PROV=", 8) == 0)
{
is_ok = strlen(line_buf) == 74 && line_buf[24] == '-' && line_buf[41] == '-';
is_ok = strlen(line_buf) == 74 && line_buf[24] == '-' && line_buf[41] == '-';
if (is_ok)
{
line_buf[24] = 0;
@ -271,7 +269,8 @@ void process_line(void)
ESP_ERROR_CHECK(err);
bin_to_hex_str(mac, 6, hexbuf);
for (int i = 0; i < 12; i += 2) {
for (int i = 0; i < 12; i += 2)
{
if (i > 0)
uart_write_bytes(UART_NUM, ":", 1);
uart_write_bytes(UART_NUM, hexbuf + i, 2);
@ -287,10 +286,11 @@ void process_line(void)
ESP_ERROR_CHECK(err);
bin_to_hex_str(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);
if (i == 4)
uart_write_bytes(UART_NUM, "FFFE", 4);
uart_write_bytes(UART_NUM, "FFFE", 4);
}
uart_write_bytes(UART_NUM, "\r\n", 2);
}
@ -316,30 +316,27 @@ void process_line(void)
#endif
#if defined(TTN_CONFIG_UART)
void config_uart(void)
{
esp_err_t err;
uart_config_t uart_config = {
.baud_rate = CONFIG_TTN_PROVISION_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_config_t uart_config = {.baud_rate = CONFIG_TTN_PROVISION_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
err = uart_param_config(UART_NUM, &uart_config);
ESP_ERROR_CHECK(err);
err = uart_set_pin(UART_NUM, CONFIG_TTN_PROVISION_UART_TX_GPIO, CONFIG_TTN_PROVISION_UART_RX_GPIO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
err = uart_set_pin(UART_NUM, CONFIG_TTN_PROVISION_UART_TX_GPIO, CONFIG_TTN_PROVISION_UART_RX_GPIO,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
ESP_ERROR_CHECK(err);
}
#endif
// --- Key handling
bool ttn_provisioning_have_keys(void)
@ -357,7 +354,7 @@ bool ttn_provisioning_from_mac(const char *app_eui, const char *app_key)
uint8_t mac[6];
esp_err_t err = esp_efuse_mac_get_default(mac);
ESP_ERROR_CHECK(err);
global_dev_eui[7] = mac[0];
global_dev_eui[6] = mac[1];
global_dev_eui[5] = mac[2];
@ -404,13 +401,12 @@ bool decode(bool incl_dev_eui, const char *dev_eui, const char *app_eui, const c
memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui));
memcpy(global_app_key, buf_app_key, sizeof(global_app_key));
have_keys = !is_all_zeros(global_dev_eui, sizeof(global_dev_eui))
&& !is_all_zeros(global_app_key, sizeof(global_app_key));
have_keys =
!is_all_zeros(global_dev_eui, sizeof(global_dev_eui)) && !is_all_zeros(global_app_key, sizeof(global_app_key));
return true;
}
// --- Non-volatile storage
bool ttn_provisioning_save_keys()
@ -430,16 +426,16 @@ bool ttn_provisioning_save_keys()
if (!write_nvs_value(handle, NVS_FLASH_KEY_DEV_EUI, global_dev_eui, sizeof(global_dev_eui)))
goto done;
if (!write_nvs_value(handle, NVS_FLASH_KEY_APP_EUI, global_app_eui, sizeof(global_app_eui)))
goto done;
if (!write_nvs_value(handle, NVS_FLASH_KEY_APP_KEY, global_app_key, sizeof(global_app_key)))
goto done;
res = nvs_commit(handle);
ESP_ERROR_CHECK(res);
result = true;
ESP_LOGI(TAG, "DevEUI, AppEUI/JoinEUI and AppKey saved in NVS storage");
@ -453,7 +449,7 @@ bool ttn_provisioning_restore_keys(bool silent)
uint8_t buf_dev_eui[8];
uint8_t buf_app_eui[8];
uint8_t buf_app_key[16];
nvs_handle handle = 0;
esp_err_t res = nvs_open(NVS_FLASH_PARTITION, NVS_READONLY, &handle);
if (res == ESP_ERR_NVS_NOT_FOUND)
@ -480,12 +476,12 @@ bool ttn_provisioning_restore_keys(bool silent)
memcpy(global_app_eui, buf_app_eui, sizeof(global_app_eui));
memcpy(global_app_key, buf_app_key, sizeof(global_app_key));
have_keys = !is_all_zeros(global_dev_eui, sizeof(global_dev_eui))
&& !is_all_zeros(global_app_key, sizeof(global_app_key));
have_keys =
!is_all_zeros(global_dev_eui, sizeof(global_dev_eui)) && !is_all_zeros(global_app_key, sizeof(global_app_key));
if (have_keys)
{
ESP_LOGI(TAG, "DevEUI, AppEUI/JoinEUI and AppKey have been restored from NVS storage");
ESP_LOGI(TAG, "DevEUI, AppEUI/JoinEUI and AppKey have been restored from NVS storage");
}
else
{
@ -497,7 +493,7 @@ done:
return true;
}
bool read_nvs_value(nvs_handle handle, const char* key, uint8_t* data, size_t expected_length, bool silent)
bool read_nvs_value(nvs_handle handle, const char *key, uint8_t *data, size_t expected_length, bool silent)
{
size_t size = expected_length;
esp_err_t res = nvs_get_blob(handle, key, data, &size);
@ -517,29 +513,28 @@ bool read_nvs_value(nvs_handle handle, const char* key, uint8_t* data, size_t ex
ESP_LOGW(TAG, "No NVS data found for %s", key);
return false;
}
ESP_ERROR_CHECK(res);
return false;
}
bool write_nvs_value(nvs_handle handle, const char* key, const uint8_t* data, size_t len)
bool write_nvs_value(nvs_handle handle, const char *key, const uint8_t *data, size_t len)
{
uint8_t buf[16];
if (read_nvs_value(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;
}
// --- Helper functions ---
bool hex_str_to_bin(const char *hex, uint8_t *buf, int len)
{
const char* ptr = hex;
const char *ptr = hex;
for (int i = 0; i < len; i++)
{
int val = hex_tuple_to_byte(ptr);
@ -573,7 +568,7 @@ int hex_digit_to_val(char ch)
return -1;
}
void bin_to_hex_str(const uint8_t* buf, int len, char* hex)
void bin_to_hex_str(const uint8_t *buf, int len, char *hex)
{
for (int i = 0; i < len; i++)
{
@ -590,10 +585,10 @@ char val_to_hex_digit(int val)
return "0123456789ABCDEF"[val];
}
void swap_bytes(uint8_t* buf, int len)
void swap_bytes(uint8_t *buf, int len)
{
uint8_t* p1 = buf;
uint8_t* p2 = buf + len - 1;
uint8_t *p1 = buf;
uint8_t *p2 = buf + len - 1;
while (p1 < p2)
{
uint8_t t = *p1;
@ -604,7 +599,7 @@ void swap_bytes(uint8_t* buf, int len)
}
}
bool is_all_zeros(const uint8_t* buf, int len)
bool is_all_zeros(const uint8_t *buf, int len)
{
for (int i = 0; i < len; i++)
if (buf[i] != 0)

View File

@ -1,9 +1,9 @@
/*******************************************************************************
*
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
*
* Copyright (c) 2018-2021 Manuel Bleichenbacher
*
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
@ -16,20 +16,20 @@
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
void ttn_provisioning_init(void);
void ttn_provisioning_init(void);
bool ttn_provisioning_have_keys(void);
bool ttn_provisioning_decode_keys(const char *dev_eui, const char *app_eui, const char *app_key);
bool ttn_provisioning_from_mac(const char *app_eui, const char *app_key);
bool ttn_provisioning_save_keys(void);
bool ttn_provisioning_restore_keys(bool silent);
bool ttn_provisioning_have_keys(void);
bool ttn_provisioning_decode_keys(const char *dev_eui, const char *app_eui, const char *app_key);
bool ttn_provisioning_from_mac(const char *app_eui, const char *app_key);
bool ttn_provisioning_save_keys(void);
bool ttn_provisioning_restore_keys(bool silent);
#if defined(TTN_HAS_AT_COMMANDS)
void ttn_provisioning_start_task(void);
void ttn_provisioning_start_task(void);
#endif
#ifdef __cplusplus