diff --git a/include/lorawan.h b/include/lorawan.h index 58b0f3e2..e5af3504 100644 --- a/include/lorawan.h +++ b/include/lorawan.h @@ -4,7 +4,7 @@ #include "globals.h" #include "rcommand.h" #include "timekeeper.h" -#if(TIME_SYNC_LORASERVER) +#if (TIME_SYNC_LORASERVER) #include "timesync.h" #endif @@ -37,6 +37,9 @@ void switch_lora(uint8_t sf, uint8_t tx); void lora_send(void *pvParameters); void lora_enqueuedata(MessageBuffer_t *message); void lora_queuereset(void); +void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, + size_t nMsg); +void myTxCallback(void *pUserData, int fSuccess); #if (TIME_SYNC_LORAWAN) void user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess); diff --git a/include/rcommand.h b/include/rcommand.h index e964eb85..7895c257 100644 --- a/include/rcommand.h +++ b/include/rcommand.h @@ -23,7 +23,7 @@ typedef struct { const bool store; } cmd_t; -void rcommand(uint8_t cmd[], uint8_t cmdlength); +void rcommand(const uint8_t cmd[], const uint8_t cmdlength); void do_reset(); #endif diff --git a/include/timesync.h b/include/timesync.h index 7a0013ec..c102c1c4 100644 --- a/include/timesync.h +++ b/include/timesync.h @@ -12,7 +12,7 @@ void timesync_init(void); void send_timesync_req(void); -int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len); +int recv_timesync_ans(const uint8_t seq_no, const uint8_t buf[], const uint8_t buf_len); void process_timesync_req(void *taskparameter); void store_time_sync_req(uint32_t t_millisec); diff --git a/src/lmic_config.h b/src/lmic_config.h index f4ddf4ab..fb6fc771 100644 --- a/src/lmic_config.h +++ b/src/lmic_config.h @@ -19,10 +19,15 @@ // LMIC LORAWAN STACK SETTINGS // --> adapt to your device only if necessary +// use interrupts only if LORA_IRQ and LORA_DIO are connected to interrupt +// capable GPIO pins on your board, if not disable interrupts //#define LMIC_USE_INTERRUPTS 1 -//time sync via LoRaWAN network, is not yet supported by TTN (LoRaWAN spec v1.0.3) -//#define LMIC_ENABLE_DeviceTimeReq 1 +// needed for paxcounter code +#define LMIC_ENABLE_user_events 1 + +// time sync via LoRaWAN network, note: not supported by TTNv2 +// #define LMIC_ENABLE_DeviceTimeReq 1 // 16 μs per tick // LMIC requires ticks to be 15.5μs - 100 μs long @@ -33,7 +38,7 @@ // This tells LMIC to make the receive windows bigger, in case your clock is // faster or slower. This causes the transceiver to be earlier switched on, // so consuming more power. You may sharpen (reduce) this value if you are -// limited on battery. +// limited on battery. // ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES #define CLOCK_ERROR_PROCENTAGE 7 diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 2329eed3..ae019276 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -244,38 +244,6 @@ void onEvent(ev_t ev) { strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") : PSTR("TX COMPLETE")); sprintf(display_line6, " "); // clear previous lmic status - - if (LMIC.dataLen) { // did we receive payload data -> display info - ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", - LMIC.dataLen, LMIC.rssi, LMIC.snr / 4); - sprintf(display_line6, "RSSI %d SNR %d", LMIC.rssi, LMIC.snr / 4); - - if (LMIC.txrxFlags & TXRX_PORT) { // FPort -> use to switch - - switch (LMIC.frame[LMIC.dataBeg - 1]) { - - case RCMDPORT: // opcode -> call rcommand interpreter - rcommand(LMIC.frame + LMIC.dataBeg, LMIC.dataLen); - break; - - default: - -#if (TIME_SYNC_LORASERVER) - // timesync answer -> call timesync processor - if ((LMIC.frame[LMIC.dataBeg - 1] >= TIMEANSWERPORT_MIN) && - (LMIC.frame[LMIC.dataBeg - 1] <= TIMEANSWERPORT_MAX)) { - recv_timesync_ans(LMIC.frame[LMIC.dataBeg - 1], - LMIC.frame + LMIC.dataBeg, LMIC.dataLen); - break; - } -#endif - // unknown port -> display info - ESP_LOGI(TAG, "Received data on unsupported port #%d", - LMIC.frame[LMIC.dataBeg - 1]); - break; - } - } - } break; case EV_LOST_TSYNC: @@ -402,9 +370,10 @@ void lora_send(void *pvParameters) { // attempt to transmit payload else { - switch (LMIC_setTxData2(SendBuffer.MessagePort, SendBuffer.Message, - SendBuffer.MessageSize, - (cfg.countermode & 0x02))) { + switch (LMIC_sendWithCallback( + SendBuffer.MessagePort, SendBuffer.Message, SendBuffer.MessageSize, + (cfg.countermode & 0x02), myTxCallback, NULL)) { + case 0: ESP_LOGI(TAG, "%d byte(s) delivered to LMIC", SendBuffer.MessageSize); break; @@ -554,6 +523,9 @@ void lmictask(void *pvParameters) { // rate for 125 kHz channels, and it minimizes air time and battery power. // Set the transmission power to 14 dBi (25 mW). LMIC_setDrTxpow(DR_SF7, 14); + // register a callback for downlink messages. We aren't trying to write + // reentrant code, so pUserData is NULL. + LMIC_registerRxMessageCb(myRxCallback, NULL); #if defined(CFG_US915) || defined(CFG_au921) // in the US, with TTN, it saves join time if we start on subband 1 @@ -569,4 +541,41 @@ void lmictask(void *pvParameters) { } } // lmictask -#endif // HAS_LORA +// receive message handler +void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, + size_t nMsg) { + + // did we receive payload data -> display info + if (nMsg) + ESP_LOGI(TAG, "Received %d bytes of payload on port %d", nMsg, port); + + switch (port) { + + // ignore mac messages + case MACPORT: + break; + + // rcommand received -> call interpreter + case RCMDPORT: + rcommand(pMsg, nMsg); + break; + + default: + +#if (TIME_SYNC_LORASERVER) + // valid timesync answer -> call timesync processor + if ((port >= TIMEANSWERPORT_MIN) && (port <= TIMEANSWERPORT_MAX)) + recv_timesync_ans(port, pMsg, nMsg); + break; +#endif + + // unknown port -> display info + ESP_LOGI(TAG, "Received data on unsupported port %d", port); + break; + } // switch +} + +// transmit complete message handler +void myTxCallback(void *pUserData, int fSuccess) { /* currently unused */ } + +#endif // HAS_LORA \ No newline at end of file diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 7382d8d8..d78d0035 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -85,6 +85,7 @@ // Ports on which the device sends and listenes on LoRaWAN and SPI #define COUNTERPORT 1 // counts +#define MACPORT 0 // network commands #define RCMDPORT 2 // remote commands #define STATUSPORT 2 // remote command results #define CONFIGPORT 3 // config query results diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 33acf703..2f2e14ca 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -353,7 +353,7 @@ const uint8_t cmdtablesize = sizeof(table) / sizeof(table[0]); // number of commands in command table // check and execute remote command -void rcommand(uint8_t cmd[], uint8_t cmdlength) { +void rcommand(const uint8_t cmd[], const uint8_t cmdlength) { if (cmdlength == 0) return; diff --git a/src/timesync.cpp b/src/timesync.cpp index 524ac10f..8ce3238f 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -154,7 +154,7 @@ void store_time_sync_req(uint32_t timestamp) { } // process timeserver timestamp answer, called from lorawan.cpp -int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { +int recv_timesync_ans(const uint8_t seq_no, const uint8_t buf[], const uint8_t buf_len) { // if no timesync handshake is pending then exit if (!timeSyncPending)