diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino index 1b3e673e4..5e22d6a41 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_0_lora_struct.ino @@ -183,13 +183,13 @@ typedef struct LoraSettings_t { LoraEndNode_t end_node[TAS_LORAWAN_ENDNODES]; // End node parameters #endif // USE_LORAWAN_BRIDGE } LoraSettings_t; -LoraSettings_t* LoraSettings = nullptr; typedef struct Lora_t { bool (* Config)(void); bool (* Available)(void); int (* Receive)(char*); bool (* Send)(uint8_t*, uint32_t, bool); + LoraSettings_t settings; // Persistent settings uint32_t receive_time; float rssi; float snr; @@ -197,19 +197,15 @@ typedef struct Lora_t { volatile bool received_flag; // flag to indicate that a packet was received bool send_flag; bool raw; +#ifdef USE_LORAWAN_BRIDGE + uint32_t device_address; + uint8_t* send_buffer; + uint8_t send_buffer_step; + uint8_t send_buffer_len; + bool rx; +#endif // USE_LORAWAN_BRIDGE } Lora_t; Lora_t* Lora = nullptr; -#ifdef USE_LORAWAN_BRIDGE -typedef struct Lorawan_t { - uint32_t device_address; - uint32_t send_buffer_step; - size_t send_buffer_len; - uint8_t send_buffer[64]; - bool rx; -} Lorawan_t; -Lorawan_t* Lorawan = nullptr; -#endif // USE_LORAWAN_BRIDGE - #endif // USE_SPI_LORA #endif // USE_SPI diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx126x.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx126x.ino index 7d6f59a68..5a6c351c3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx126x.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx126x.ino @@ -29,7 +29,7 @@ //#define USE_LORA_SX126X_DEBUG #include -SX1262 LoRaRadio = nullptr; // Select LoRa support +SX1262 LoRaRadio = nullptr; // Select LoRa support bool LoraSx126xBusy(void) { // This is not consistently implemented in the used library @@ -49,12 +49,12 @@ void LoraSx126xOnInterrupt(void) { if (!Lora->send_flag && !Lora->received_flag && !Lora->receive_time) { Lora->receive_time = millis(); } - Lora->received_flag = true; // we got a packet, set the flag + Lora->received_flag = true; // we got a packet, set the flag } bool LoraSx126xAvailable(void) { if (Lora->send_flag) { - Lora->received_flag = false; // Reset receive flag as it was caused by send interrupt + Lora->received_flag = false; // Reset receive flag as it was caused by send interrupt uint32_t time = millis(); int state = LoRaRadio.startReceive(); // Put module back to listen mode @@ -73,14 +73,14 @@ bool LoraSx126xAvailable(void) { #endif // USE_LORA_SX126X_DEBUG if (0 == (irq_stat & RADIOLIB_SX126X_IRQ_RX_DONE)) { - Lora->received_flag = false; // Reset receive flag + Lora->received_flag = false; // Reset receive flag } } - return (Lora->received_flag); // Check if the receive flag is set + return (Lora->received_flag); // Check if the receive flag is set } int LoraSx126xReceive(char* data) { - Lora->received_flag = false; // Reset flag + Lora->received_flag = false; // Reset flag int packet_size = LoRaRadio.getPacketLength(); int state = LoRaRadio.readData((uint8_t*)data, TAS_LORA_MAX_PACKET_LENGTH -1); // LoRaWan downlink frames are sent without CRC, which will raise error on SX126x. We can ignore that error @@ -92,7 +92,7 @@ int LoraSx126xReceive(char* data) { Lora->rssi = LoRaRadio.getRSSI(); Lora->snr = LoRaRadio.getSNR(); } else { - packet_size = 0; // Some other error occurred + packet_size = 0; // Some other error occurred AddLog(LOG_LEVEL_DEBUG, PSTR("S6X: Receive error %d"), state); } return packet_size; @@ -107,7 +107,7 @@ bool LoraSx126xSend(uint8_t* data, uint32_t len, bool invert) { LoraSx126xBusy(); } int state = LoRaRadio.transmit(data, len); - Lora->send_flag = true; // Use this flag as LoRaRadio.transmit enable send interrupt + Lora->send_flag = true; // Use this flag as LoRaRadio.transmit enable send interrupt if (invert) { LoraSx126xBusy(); state2 = LoRaRadio.invertIQ(false); @@ -120,17 +120,17 @@ bool LoraSx126xSend(uint8_t* data, uint32_t len, bool invert) { } bool LoraSx126xConfig(void) { - LoRaRadio.setCodingRate(LoraSettings->coding_rate); - LoRaRadio.setSyncWord(LoraSettings->sync_word); - LoRaRadio.setPreambleLength(LoraSettings->preamble_length); - LoRaRadio.setCurrentLimit(LoraSettings->current_limit); - LoRaRadio.setCRC(LoraSettings->crc_bytes); - LoRaRadio.setSpreadingFactor(LoraSettings->spreading_factor); - LoRaRadio.setBandwidth(LoraSettings->bandwidth); - LoRaRadio.setFrequency(LoraSettings->frequency); - LoRaRadio.setOutputPower(LoraSettings->output_power); - if (LoraSettings->implicit_header) { - LoRaRadio.implicitHeader(LoraSettings->implicit_header); + LoRaRadio.setCodingRate(Lora->settings.coding_rate); + LoRaRadio.setSyncWord(Lora->settings.sync_word); + LoRaRadio.setPreambleLength(Lora->settings.preamble_length); + LoRaRadio.setCurrentLimit(Lora->settings.current_limit); + LoRaRadio.setCRC(Lora->settings.crc_bytes); + LoRaRadio.setSpreadingFactor(Lora->settings.spreading_factor); + LoRaRadio.setBandwidth(Lora->settings.bandwidth); + LoRaRadio.setFrequency(Lora->settings.frequency); + LoRaRadio.setOutputPower(Lora->settings.output_power); + if (Lora->settings.implicit_header) { + LoRaRadio.implicitHeader(Lora->settings.implicit_header); } else { LoRaRadio.explicitHeader(); } @@ -140,7 +140,7 @@ bool LoraSx126xConfig(void) { bool LoraSx126xInit(void) { LoRaRadio = new Module(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_DI1), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_BUSY)); - if (RADIOLIB_ERR_NONE == LoRaRadio.begin(LoraSettings->frequency)) { + if (RADIOLIB_ERR_NONE == LoRaRadio.begin(Lora->settings.frequency)) { LoraSx126xConfig(); LoRaRadio.setDio1Action(LoraSx126xOnInterrupt); if (RADIOLIB_ERR_NONE == LoRaRadio.startReceive()) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx127x.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx127x.ino index ca4a9b143..b35b71135 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx127x.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_3_lora_sx127x.ino @@ -38,11 +38,11 @@ void LoraSx127xOnReceive(int packet_size) { if (!Lora->receive_time) { Lora->receive_time = millis(); } - Lora->packet_size = packet_size; // we got a packet, set the flag + Lora->packet_size = packet_size; // we got a packet, set the flag } bool LoraSx127xAvailable(void) { - return (Lora->packet_size > 0); // check if the flag is set + return (Lora->packet_size > 0); // check if the flag is set } int LoraSx127xReceive(char* data) { @@ -55,7 +55,7 @@ int LoraSx127xReceive(char* data) { } Lora->rssi = LoRa.packetRssi(); Lora->snr = LoRa.packetSnr(); - Lora->packet_size = 0; // reset flag + Lora->packet_size = 0; // reset flag return packet_size; } @@ -63,7 +63,7 @@ bool LoraSx127xSend(uint8_t* data, uint32_t len, bool invert) { if (invert) { LoRa.enableInvertIQ(); // active invert I and Q signals } - LoRa.beginPacket(LoraSettings->implicit_header); // start packet + LoRa.beginPacket(Lora->settings.implicit_header); // start packet LoRa.write(data, len); // send message LoRa.endPacket(); // finish packet and send it if (invert) { @@ -74,21 +74,21 @@ bool LoraSx127xSend(uint8_t* data, uint32_t len, bool invert) { } bool LoraSx127xConfig(void) { - LoRa.setFrequency(LoraSettings->frequency * 1000 * 1000); - LoRa.setSignalBandwidth(LoraSettings->bandwidth * 1000); - LoRa.setSpreadingFactor(LoraSettings->spreading_factor); - LoRa.setCodingRate4(LoraSettings->coding_rate); - LoRa.setSyncWord(LoraSettings->sync_word); - LoRa.setTxPower(LoraSettings->output_power); - LoRa.setPreambleLength(LoraSettings->preamble_length); - LoRa.setOCP(LoraSettings->current_limit); - if (LoraSettings->crc_bytes) { + LoRa.setFrequency(Lora->settings.frequency * 1000 * 1000); + LoRa.setSignalBandwidth(Lora->settings.bandwidth * 1000); + LoRa.setSpreadingFactor(Lora->settings.spreading_factor); + LoRa.setCodingRate4(Lora->settings.coding_rate); + LoRa.setSyncWord(Lora->settings.sync_word); + LoRa.setTxPower(Lora->settings.output_power); + LoRa.setPreambleLength(Lora->settings.preamble_length); + LoRa.setOCP(Lora->settings.current_limit); + if (Lora->settings.crc_bytes) { LoRa.enableCrc(); } else { LoRa.disableCrc(); } /* - if (LoraSettings->implicit_header) { + if (Lora->settings.implicit_header) { LoRa.implicitHeaderMode(); } else { LoRa.explicitHeaderMode(); @@ -100,7 +100,7 @@ bool LoraSx127xConfig(void) { bool LoraSx127xInit(void) { LoRa.setPins(Pin(GPIO_LORA_CS), Pin(GPIO_LORA_RST), Pin(GPIO_LORA_DI0)); - if (LoRa.begin(LoraSettings->frequency * 1000 * 1000)) { + if (LoRa.begin(Lora->settings.frequency * 1000 * 1000)) { LoraSx127xConfig(); LoRa.onReceive(LoraSx127xOnReceive); LoRa.receive(); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_4_lorawan_cryptography.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_4_lorawan_cryptography.ino index bef707768..cbfa04b77 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_4_lorawan_cryptography.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_4_lorawan_cryptography.ino @@ -69,7 +69,7 @@ void _LoraWanDeriveLegacyAppSKey(uint8_t* key, uint32_t jn, uint32_t nid, uint16 } void LoraWanDeriveLegacyAppSKey(uint32_t node, uint8_t* AppSKey) { - _LoraWanDeriveLegacyAppSKey(LoraSettings->end_node[node].AppKey, TAS_LORAWAN_JOINNONCE +node, TAS_LORAWAN_NETID, LoraSettings->end_node[node].DevNonce, AppSKey); + _LoraWanDeriveLegacyAppSKey(Lora->settings.end_node[node].AppKey, TAS_LORAWAN_JOINNONCE +node, TAS_LORAWAN_NETID, Lora->settings.end_node[node].DevNonce, AppSKey); } // DeriveLegacyNwkSKey derives the LoRaWAN 1.0 Network Session Key. AppNonce is entered as JoinNonce. @@ -82,7 +82,7 @@ void _LoraWanDeriveLegacyNwkSKey(uint8_t* appKey, uint32_t jn, uint32_t nid, uin } void LoraWanDeriveLegacyNwkSKey(uint32_t node, uint8_t* NwkSKey) { - _LoraWanDeriveLegacyNwkSKey(LoraSettings->end_node[node].AppKey, TAS_LORAWAN_JOINNONCE +node, TAS_LORAWAN_NETID, LoraSettings->end_node[node].DevNonce, NwkSKey); + _LoraWanDeriveLegacyNwkSKey(Lora->settings.end_node[node].AppKey, TAS_LORAWAN_JOINNONCE +node, TAS_LORAWAN_NETID, Lora->settings.end_node[node].DevNonce, NwkSKey); } #ifdef USE_LORAWAN_TEST diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_6_lorawan_decode.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_6_lorawan_decode.ino index 9dc5774e6..90436a04b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_6_lorawan_decode.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_6_lorawan_decode.ino @@ -29,11 +29,11 @@ void LoraWanPublishHeader(uint32_t node) { } if (!Settings->flag5.zb_omit_json_addr) { // SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic - ResponseAppend_P(PSTR("{\"%s\":"), EscapeJSONString(LoraSettings->end_node[node].name.c_str()).c_str()); + ResponseAppend_P(PSTR("{\"%s\":"), EscapeJSONString(Lora->settings.end_node[node].name.c_str()).c_str()); } - ResponseAppend_P(PSTR("{\"Node\":%d,\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), node +1, LoraSettings->end_node[node].DevEUIl & 0x0000FFFF); - if (!LoraSettings->end_node[node].name.startsWith(F("0x"))) { - ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), EscapeJSONString(LoraSettings->end_node[node].name.c_str()).c_str()); + ResponseAppend_P(PSTR("{\"Node\":%d,\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), node +1, Lora->settings.end_node[node].DevEUIl & 0x0000FFFF); + if (!Lora->settings.end_node[node].name.startsWith(F("0x"))) { + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), EscapeJSONString(Lora->settings.end_node[node].name.c_str()).c_str()); } ResponseAppend_P(PSTR(",\"RSSI\":%1_f,\"SNR\":%1_f"), &Lora->rssi, &Lora->snr); } @@ -57,7 +57,7 @@ void LoraWanPublishFooter(uint32_t node) { char subtopic[TOPSZ]; // Clean special characters char stemp[TOPSZ]; - strlcpy(stemp, LoraSettings->end_node[node].name.c_str(), sizeof(stemp)); + strlcpy(stemp, Lora->settings.end_node[node].name.c_str(), sizeof(stemp)); MakeValidMqtt(0, stemp); if (Settings->flag5.zigbee_hide_bridge_topic) { // SetOption125 - (Zigbee) Hide bridge topic from zigbee topic (use with SetOption89) (1) snprintf_P(subtopic, sizeof(subtopic), PSTR("%s"), stemp); @@ -87,8 +87,8 @@ void LoraWanDecode(struct LoraNodeData_t* node_data) { uint8_t node; uint8_t FPort; */ - if (bitRead(LoraSettings->flags, TAS_LORA_FLAG_DECODE_ENABLED)) { // LoraOption3 1 - if (0x00161600 == LoraSettings->end_node[node_data->node].DevEUIh) { // MerryIoT + if (bitRead(Lora->settings.flags, TAS_LORA_FLAG_DECODE_ENABLED)) { // LoraOption3 1 + if (0x00161600 == Lora->settings.end_node[node_data->node].DevEUIh) { // MerryIoT if (120 == node_data->FPort) { // MerryIoT door/window Sensor (DW10) if (9 == node_data->payload_len) { // MerryIoT Sensor state // 1 2 3 4 5 6 7 8 9 @@ -102,7 +102,7 @@ void LoraWanDecode(struct LoraNodeData_t* node_data) { uint32_t events = node_data->payload[6] | (node_data->payload[7] << 8) | (node_data->payload[8] << 16); #ifdef USE_LORA_DEBUG AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Node %d, DevEUI %08X%08X, Events %d, LastEvent %d min, DoorOpen %d, Button %d, Tamper %d, Tilt %d, Battery %1_fV, Temp %d, Hum %d"), - node_data->node +1, LoraSettings->end_node[node_data->node].DevEUIh, LoraSettings->end_node[node_data->node].DevEUIl, + node_data->node +1, Lora->settings.end_node[node_data->node].DevEUIh, Lora->settings.end_node[node_data->node].DevEUIl, events, elapsed_time, bitRead(status, 0), bitRead(status, 1), bitRead(status, 2), bitRead(status, 3), &battery_volt, @@ -122,7 +122,7 @@ void LoraWanDecode(struct LoraNodeData_t* node_data) { } } - else if (0xA840410E == LoraSettings->end_node[node_data->node].DevEUIh) { // Dragino + else if (0xA840410E == Lora->settings.end_node[node_data->node].DevEUIh) { // Dragino if (10 == node_data->FPort) { // Dragino LDS02 // 8CD2 01 000010 000000 00 - Door Open, 3.282V // 0CD2 01 000011 000000 00 - Door Closed @@ -134,7 +134,7 @@ void LoraWanDecode(struct LoraNodeData_t* node_data) { uint8_t alarm = node_data->payload[9]; #ifdef USE_LORA_DEBUG AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Node %d, DevEUI %08X%08X, Events %d, LastEvent %d min, DoorOpen %d, Battery %3_fV, Alarm %d"), - node_data->node +1, LoraSettings->end_node[node_data->node].DevEUIh, LoraSettings->end_node[node_data->node].DevEUIl, + node_data->node +1, Lora->settings.end_node[node_data->node].DevEUIh, Lora->settings.end_node[node_data->node].DevEUIl, events, open_duration, bitRead(status, 7), &battery_volt, @@ -152,7 +152,7 @@ void LoraWanDecode(struct LoraNodeData_t* node_data) { // Joined device without decoding LoraWanPublishHeader(node_data->node); ResponseAppend_P(PSTR(",\"DevEUIh\":\"%08X\",\"DevEUIl\":\"%08X\",\"FPort\":%d,\"Payload\":["), - LoraSettings->end_node[node_data->node].DevEUIh, LoraSettings->end_node[node_data->node].DevEUIl, node_data->FPort); + Lora->settings.end_node[node_data->node].DevEUIh, Lora->settings.end_node[node_data->node].DevEUIl, node_data->FPort); for (uint32_t i = 0; i < node_data->payload_len; i++) { ResponseAppend_P(PSTR("%s%d"), (0==i)?"":",", node_data->payload[i]); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_8_lorawan_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_8_lorawan_bridge.ino index 3732310b2..e6b2ca852 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_8_lorawan_bridge.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_8_lorawan_bridge.ino @@ -93,18 +93,18 @@ bool LoraWanLoadData(void) { app_key = root.getStr(PSTR(D_JSON_APPKEY), nullptr); if (strlen(app_key)) { size_t out_len = TAS_LORAWAN_AES128_KEY_SIZE; - HexToBytes(app_key, LoraSettings->end_node[n].AppKey, &out_len); + HexToBytes(app_key, Lora->settings.end_node[n].AppKey, &out_len); } - LoraSettings->end_node[n].DevEUIh = root.getUInt(PSTR(D_JSON_DEVEUI "h"), LoraSettings->end_node[n].DevEUIh); - LoraSettings->end_node[n].DevEUIl = root.getUInt(PSTR(D_JSON_DEVEUI "l"), LoraSettings->end_node[n].DevEUIl); - LoraSettings->end_node[n].DevNonce = root.getUInt(PSTR(D_JSON_DEVNONCE), LoraSettings->end_node[n].DevNonce); - LoraSettings->end_node[n].FCntUp = root.getUInt(PSTR(D_JSON_FCNTUP), LoraSettings->end_node[n].FCntUp); - LoraSettings->end_node[n].FCntDown = root.getUInt(PSTR(D_JSON_FCNTDOWN), LoraSettings->end_node[n].FCntDown); - LoraSettings->end_node[n].flags = root.getUInt(PSTR(D_JSON_FLAGS), LoraSettings->end_node[n].flags); + Lora->settings.end_node[n].DevEUIh = root.getUInt(PSTR(D_JSON_DEVEUI "h"), Lora->settings.end_node[n].DevEUIh); + Lora->settings.end_node[n].DevEUIl = root.getUInt(PSTR(D_JSON_DEVEUI "l"), Lora->settings.end_node[n].DevEUIl); + Lora->settings.end_node[n].DevNonce = root.getUInt(PSTR(D_JSON_DEVNONCE), Lora->settings.end_node[n].DevNonce); + Lora->settings.end_node[n].FCntUp = root.getUInt(PSTR(D_JSON_FCNTUP), Lora->settings.end_node[n].FCntUp); + Lora->settings.end_node[n].FCntDown = root.getUInt(PSTR(D_JSON_FCNTDOWN), Lora->settings.end_node[n].FCntDown); + Lora->settings.end_node[n].flags = root.getUInt(PSTR(D_JSON_FLAGS), Lora->settings.end_node[n].flags); const char* name = nullptr; name = root.getStr(PSTR(D_JSON_NAME), nullptr); if (strlen(app_key)) { - LoraSettings->end_node[n].name = name; + Lora->settings.end_node[n].name = name; } } return true; @@ -113,7 +113,7 @@ bool LoraWanLoadData(void) { bool LoraWanSaveData(void) { bool result = false; for (uint32_t n = 0; n < TAS_LORAWAN_ENDNODES; n++) { - if (LoraSettings->end_node[n].AppKey[0] > 0) { // Only save used slots + if (Lora->settings.end_node[n].AppKey[0] > 0) { // Only save used slots Response_P(PSTR("{\"" XDRV_73_KEY "_%d\":{\"" D_JSON_APPKEY "\":\"%16_H\"" ",\"" D_JSON_DEVEUI "h\":%lu,\"" D_JSON_DEVEUI "l\":%lu" ",\"" D_JSON_DEVNONCE "\":%u" @@ -121,12 +121,12 @@ bool LoraWanSaveData(void) { ",\"" D_JSON_FLAGS "\":%u" ",\"" D_JSON_NAME "\":\"%s\"}}"), n +1, - LoraSettings->end_node[n].AppKey, - LoraSettings->end_node[n].DevEUIh,LoraSettings->end_node[n].DevEUIl, - LoraSettings->end_node[n].DevNonce, - LoraSettings->end_node[n].FCntUp, LoraSettings->end_node[n].FCntDown, - LoraSettings->end_node[n].flags, - LoraSettings->end_node[n].name.c_str()); + Lora->settings.end_node[n].AppKey, + Lora->settings.end_node[n].DevEUIh, Lora->settings.end_node[n].DevEUIl, + Lora->settings.end_node[n].DevNonce, + Lora->settings.end_node[n].FCntUp, Lora->settings.end_node[n].FCntDown, + Lora->settings.end_node[n].flags, + Lora->settings.end_node[n].name.c_str()); result = UfsJsonSettingsWrite(ResponseData()); } } @@ -148,21 +148,24 @@ void LoraWanDeleteData(void) { Ticker LoraWan_Send; void LoraWanTickerSend(void) { - Lorawan->send_buffer_step--; - if (1 == Lorawan->send_buffer_step) { - Lorawan->rx = true; // Always send during RX1 - Lora->receive_time = 0; // Reset receive timer + Lora->send_buffer_step--; + if (1 == Lora->send_buffer_step) { + Lora->rx = true; // Always send during RX1 + Lora->receive_time = 0; // Reset receive timer LoraWan_Send.once_ms(TAS_LORAWAN_RECEIVE_DELAY2, LoraWanTickerSend); // Retry after 1000 ms } - if (Lorawan->rx) { // If received in RX1 do not resend in RX2 - LoraSend(Lorawan->send_buffer, Lorawan->send_buffer_len, true); + if (Lora->rx) { // If received in RX1 do not resend in RX2 + LoraSend(Lora->send_buffer, Lora->send_buffer_len, true); } } void LoraWanSendResponse(uint8_t* buffer, size_t len, uint32_t lorawan_delay) { - memcpy(Lorawan->send_buffer, buffer, sizeof(Lorawan->send_buffer)); - Lorawan->send_buffer_len = len; - Lorawan->send_buffer_step = 2; + free(Lora->send_buffer); // Free previous buffer (if any) + Lora->send_buffer = (uint8_t*)malloc(len +1); + if (nullptr == Lora->send_buffer) { return; } + memcpy(Lora->send_buffer, buffer, len); + Lora->send_buffer_len = len; + Lora->send_buffer_step = 2; // Send at RX1 and RX2 LoraWan_Send.once_ms(lorawan_delay - TimePassedSince(Lora->receive_time), LoraWanTickerSend); } @@ -170,19 +173,19 @@ void LoraWanSendResponse(uint8_t* buffer, size_t len, uint32_t lorawan_delay) { uint32_t LoraWanSpreadingFactorToDataRate(void) { // Allow only JoinReq message datarates (125kHz bandwidth) - if (LoraSettings->spreading_factor > 12) { - LoraSettings->spreading_factor = 12; + if (Lora->settings.spreading_factor > 12) { + Lora->settings.spreading_factor = 12; } - if (LoraSettings->spreading_factor < 7) { - LoraSettings->spreading_factor = 7; + if (Lora->settings.spreading_factor < 7) { + Lora->settings.spreading_factor = 7; } - LoraSettings->bandwidth = 125; - return 12 - LoraSettings->spreading_factor; + Lora->settings.bandwidth = 125; + return 12 - Lora->settings.spreading_factor; } uint32_t LoraWanFrequencyToChannel(void) { // EU863-870 (EU868) JoinReq message frequencies are 868.1, 868.3 and 868.5 - uint32_t frequency = (LoraSettings->frequency * 10); + uint32_t frequency = (Lora->settings.frequency * 10); uint32_t channel = 250; if (8681 == frequency) { channel = 0; @@ -194,7 +197,7 @@ uint32_t LoraWanFrequencyToChannel(void) { channel = 2; } if (250 == channel) { - LoraSettings->frequency = 868.1; + Lora->settings.frequency = 868.1; Lora->Config(); channel = 0; } @@ -204,8 +207,8 @@ uint32_t LoraWanFrequencyToChannel(void) { /*********************************************************************************************/ void LoraWanSendLinkADRReq(uint32_t node) { - uint32_t DevAddr = Lorawan->device_address +node; - uint16_t FCnt = LoraSettings->end_node[node].FCntDown++; + uint32_t DevAddr = Lora->device_address +node; + uint16_t FCnt = Lora->settings.end_node[node].FCntDown++; uint8_t NwkSKey[TAS_LORAWAN_AES128_KEY_SIZE]; LoraWanDeriveLegacyNwkSKey(node, NwkSKey); @@ -236,7 +239,7 @@ void LoraWanSendLinkADRReq(uint32_t node) { bool LoraWanInput(uint8_t* data, uint32_t packet_size) { bool result = false; - uint32_t MType = data[0] >> 5; // Upper three bits (used to be called FType) + uint32_t MType = data[0] >> 5; // Upper three bits (used to be called FType) if (TAS_LORAWAN_MTYPE_JOIN_REQUEST == MType) { // 0007010000004140A8D64A89710E4140A82893A8AD137F - Dragino @@ -254,26 +257,26 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { ((uint32_t)data[21] << 16) | ((uint32_t)data[22] << 24); for (uint32_t node = 0; node < TAS_LORAWAN_ENDNODES; node++) { - uint32_t CalcMIC = LoraWanGenerateMIC(data, 19, LoraSettings->end_node[node].AppKey); - if (MIC == CalcMIC) { // Valid MIC based on LoraWanAppKey + uint32_t CalcMIC = LoraWanGenerateMIC(data, 19, Lora->settings.end_node[node].AppKey); + if (MIC == CalcMIC) { // Valid MIC based on LoraWanAppKey AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: JoinEUI %8_H, DevEUIh %08X, DevEUIl %08X, DevNonce %04X, MIC %08X"), (uint8_t*)&JoinEUI, DevEUIh, DevEUIl, DevNonce, MIC); - LoraSettings->end_node[node].DevEUIl = DevEUIl; - LoraSettings->end_node[node].DevEUIh = DevEUIh; - LoraSettings->end_node[node].DevNonce = DevNonce; - LoraSettings->end_node[node].FCntUp = 0; - LoraSettings->end_node[node].FCntDown = 0; - bitClear(LoraSettings->end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); - if (LoraSettings->end_node[node].name.equals(F("0x0000"))) { + Lora->settings.end_node[node].DevEUIl = DevEUIl; + Lora->settings.end_node[node].DevEUIh = DevEUIh; + Lora->settings.end_node[node].DevNonce = DevNonce; + Lora->settings.end_node[node].FCntUp = 0; + Lora->settings.end_node[node].FCntDown = 0; + bitClear(Lora->settings.end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); + if (Lora->settings.end_node[node].name.equals(F("0x0000"))) { char name[10]; - ext_snprintf_P(name, sizeof(name), PSTR("0x%04X"), LoraSettings->end_node[node].DevEUIl & 0x0000FFFF); - LoraSettings->end_node[node].name = name; + ext_snprintf_P(name, sizeof(name), PSTR("0x%04X"), Lora->settings.end_node[node].DevEUIl & 0x0000FFFF); + Lora->settings.end_node[node].name = name; } uint32_t JoinNonce = TAS_LORAWAN_JOINNONCE +node; - uint32_t DevAddr = Lorawan->device_address +node; + uint32_t DevAddr = Lora->device_address +node; uint32_t NetID = TAS_LORAWAN_NETID; uint8_t join_data[33] = { 0 }; join_data[0] = TAS_LORAWAN_MTYPE_JOIN_ACCEPT << 5; @@ -288,16 +291,16 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { join_data[9] = DevAddr >> 16; join_data[10] = DevAddr >> 24; join_data[11] = LoraWanSpreadingFactorToDataRate(); // DLSettings - join_data[12] = 1; // RXDelay; + join_data[12] = 1; // RXDelay; - uint32_t NewMIC = LoraWanGenerateMIC(join_data, 13, LoraSettings->end_node[node].AppKey); + uint32_t NewMIC = LoraWanGenerateMIC(join_data, 13, Lora->settings.end_node[node].AppKey); join_data[13] = NewMIC; join_data[14] = NewMIC >> 8; join_data[15] = NewMIC >> 16; join_data[16] = NewMIC >> 24; uint8_t EncData[33]; EncData[0] = join_data[0]; - LoraWanEncryptJoinAccept(LoraSettings->end_node[node].AppKey, &join_data[1], 16, &EncData[1]); + LoraWanEncryptJoinAccept(Lora->settings.end_node[node].AppKey, &join_data[1], 16, &EncData[1]); // AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Join %17_H"), join_data); @@ -335,12 +338,12 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { uint32_t DevAddr = (uint32_t)data[1] | ((uint32_t)data[2] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[4] << 24); for (uint32_t node = 0; node < TAS_LORAWAN_ENDNODES; node++) { - if (0 == LoraSettings->end_node[node].DevEUIh) { continue; } // No DevEUI so never joined - if ((Lorawan->device_address +node) != DevAddr) { continue; } // Not my device + if (0 == Lora->settings.end_node[node].DevEUIh) { continue; } // No DevEUI so never joined + if ((Lora->device_address +node) != DevAddr) { continue; } // Not my device uint32_t FCtrl = data[5]; uint32_t FOptsLen = FCtrl & 0x0F; - uint32_t FCnt = (LoraSettings->end_node[node].FCntUp & 0xFFFF0000) | data[6] | (data[7] << 8); + uint32_t FCnt = (Lora->settings.end_node[node].FCntUp & 0xFFFF0000) | data[6] | (data[7] << 8); uint8_t* FOpts = &data[8]; uint32_t FPort = data[8 +FOptsLen]; uint8_t* FRMPayload = &data[9 +FOptsLen]; @@ -372,11 +375,11 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { LoraWanDecryptUplink(Key, DevAddr, FCnt, FRMPayload, payload_len, 0, payload_decrypted); } - uint32_t org_payload_len = payload_len; // Save for logging - if ((0 == FOptsLen) && (0 == FOpts[0])) { // MAC response in payload only - FOptsLen = payload_len; // Payload length is MAC length - FOpts = payload_decrypted; // Payload is encrypted MAC - payload_len = 0; // Payload is MAC only + uint32_t org_payload_len = payload_len; // Save for logging + if ((0 == FOptsLen) && (0 == FOpts[0])) { // MAC response in payload only + FOptsLen = payload_len; // Payload length is MAC length + FOpts = payload_decrypted; // Payload is encrypted MAC + payload_len = 0; // Payload is MAC only } #ifdef USE_LORA_DEBUG @@ -384,17 +387,17 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { DevAddr, FCtrl, FOptsLen, FCnt, FOptsLen, FOpts, FPort, org_payload_len, FRMPayload, org_payload_len, payload_decrypted, MIC); #endif // USE_LORA_DEBUG - if (LoraSettings->end_node[node].FCntUp <= FCnt) { // Skip re-transmissions - Lorawan->rx = false; // Skip RX2 as this is a response from RX1 - LoraSettings->end_node[node].FCntUp++; - if (LoraSettings->end_node[node].FCntUp < FCnt) { // Report missed frames - uint32_t FCnt_missed = FCnt - LoraSettings->end_node[node].FCntUp; + if (Lora->settings.end_node[node].FCntUp <= FCnt) { // Skip re-transmissions + Lora->rx = false; // Skip RX2 as this is a response from RX1 + Lora->settings.end_node[node].FCntUp++; + if (Lora->settings.end_node[node].FCntUp < FCnt) { // Report missed frames + uint32_t FCnt_missed = FCnt - Lora->settings.end_node[node].FCntUp; AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: Missed frames %d"), FCnt_missed); - if (FCnt_missed > 1) { // Missed two or more frames - bitClear(LoraSettings->end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); // Resend LinkADRReq + if (FCnt_missed > 1) { // Missed two or more frames + bitClear(Lora->settings.end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); // Resend LinkADRReq } } - LoraSettings->end_node[node].FCntUp = FCnt; + Lora->settings.end_node[node].FCntUp = FCnt; if (FOptsLen) { uint32_t i = 0; @@ -408,7 +411,7 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { uint8_t status = FOpts[i]; AddLog(LOG_LEVEL_DEBUG, PSTR("LOR: MAC LinkADRAns PowerACK %d, DataRateACK %d, ChannelMaskACK %d"), bitRead(status, 2), bitRead(status, 1), bitRead(status, 0)); - bitSet(LoraSettings->end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); + bitSet(Lora->settings.end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); } else if (TAS_LORAWAN_CID_DUTY_CYCLE_ANS == FOpts[i]) { i++; @@ -450,20 +453,20 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { node_data.FPort = FPort; LoraWanDecode(&node_data); - if (0xA840410E == LoraSettings->end_node[node].DevEUIh) { // Dragino + if (0xA840410E == Lora->settings.end_node[node].DevEUIh) { // Dragino // Dragino v1.7 fails to set DR with ADR so set it using serial interface: // Password 123456 // AT+CHS=868100000 // Start join using reset button // AT+CADR=0 // AT+CDATARATE=3 - bitSet(LoraSettings->end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); + bitSet(Lora->settings.end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ); } if (TAS_LORAWAN_MTYPE_CONFIRMED_DATA_UPLINK == MType) { data[0] = TAS_LORAWAN_MTYPE_UNCONFIRMED_DATA_DOWNLINK << 5; - data[5] |= 0x20; // FCtrl Set ACK bit - uint16_t FCnt = LoraSettings->end_node[node].FCntDown++; + data[5] |= 0x20; // FCtrl Set ACK bit + uint16_t FCnt = Lora->settings.end_node[node].FCntDown++; data[6] = FCnt; data[7] = FCnt >> 8; uint32_t MIC = LoraWanComputeLegacyDownlinkMIC(NwkSKey, DevAddr, FCnt, data, packet_size -4); @@ -475,10 +478,10 @@ bool LoraWanInput(uint8_t* data, uint32_t packet_size) { } } if (TAS_LORAWAN_MTYPE_UNCONFIRMED_DATA_UPLINK == MType) { - if (!bitRead(LoraSettings->end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ) && + if (!bitRead(Lora->settings.end_node[node].flags, TAS_LORAWAN_FLAG_LINK_ADR_REQ) && FCtrl_ADR && !FCtrl_ACK) { // Try to fix single channel and datarate - LoraWanSendLinkADRReq(node); // Resend LinkADRReq + LoraWanSendLinkADRReq(node); // Resend LinkADRReq } } } @@ -509,14 +512,14 @@ void CmndLoraWanBridge(void) { // LoraWanBridge 1 - Set LoraOption1 1 = Enable LoraWanBridge uint32_t pindex = 0; if (XdrvMailbox.payload >= 0) { - bitWrite(LoraSettings->flags, pindex, XdrvMailbox.payload); + bitWrite(Lora->settings.flags, pindex, XdrvMailbox.payload); } #ifdef USE_LORAWAN_TEST LoraWanTestKeyDerivation(); LorWanTestUplinkDownlinkEncryption(); LorWanTestUplinkDownlinkMIC(); #endif // USE_LORAWAN_TEST - ResponseCmndChar(GetStateText(bitRead(LoraSettings->flags, pindex))); + ResponseCmndChar(GetStateText(bitRead(Lora->settings.flags, pindex))); } void CmndLoraWanAppKey(void) { @@ -526,16 +529,16 @@ void CmndLoraWanAppKey(void) { uint32_t node = XdrvMailbox.index -1; if (32 == XdrvMailbox.data_len) { size_t out_len = 16; - HexToBytes(XdrvMailbox.data, LoraSettings->end_node[node].AppKey, &out_len); - if (0 == LoraSettings->end_node[node].name.length()) { - LoraSettings->end_node[node].name = F("0x0000"); + HexToBytes(XdrvMailbox.data, Lora->settings.end_node[node].AppKey, &out_len); + if (0 == Lora->settings.end_node[node].name.length()) { + Lora->settings.end_node[node].name = F("0x0000"); } } else if (0 == XdrvMailbox.payload) { - memset(&LoraSettings->end_node[node], 0, sizeof(LoraEndNode_t)); + memset(&Lora->settings.end_node[node], 0, sizeof(LoraEndNode_t)); } char appkey[33]; - ext_snprintf_P(appkey, sizeof(appkey), PSTR("%16_H"), LoraSettings->end_node[node].AppKey); + ext_snprintf_P(appkey, sizeof(appkey), PSTR("%16_H"), Lora->settings.end_node[node].AppKey); ResponseCmndIdxChar(appkey); } } @@ -549,13 +552,13 @@ void CmndLoraWanName(void) { if (XdrvMailbox.data_len) { if (1 == XdrvMailbox.payload) { char name[10]; - ext_snprintf_P(name, sizeof(name), PSTR("0x%04X"), LoraSettings->end_node[node].DevEUIl & 0x0000FFFF); - LoraSettings->end_node[node].name = name; + ext_snprintf_P(name, sizeof(name), PSTR("0x%04X"), Lora->settings.end_node[node].DevEUIl & 0x0000FFFF); + Lora->settings.end_node[node].name = name; } else { - LoraSettings->end_node[node].name = XdrvMailbox.data; + Lora->settings.end_node[node].name = XdrvMailbox.data; } } - ResponseCmndIdxChar(LoraSettings->end_node[node].name.c_str()); + ResponseCmndIdxChar(Lora->settings.end_node[node].name.c_str()); } } @@ -563,16 +566,12 @@ void CmndLoraWanName(void) { * Interface \*********************************************************************************************/ -bool LoraWanInit(void) { - Lorawan = (Lorawan_t*)calloc(sizeof(Lorawan_t), 1); // Need calloc to reset registers to 0/false - if (nullptr == Lorawan) { return false; } - +void LoraWanInit(void) { // The Things Network has been assigned a 7-bits "device address prefix" a.k.a. NwkID // %0010011. Using that, TTN currently sends NetID 0x000013, and a TTN DevAddr always // starts with 0x26 or 0x27 // Private networks are supposed to used NetID 0x000000. - Lorawan->device_address = (TAS_LORAWAN_NETID << 25) | (ESP_getChipId() & 0x01FFFFFF); - return true; + Lora->device_address = (TAS_LORAWAN_NETID << 25) | (ESP_getChipId() & 0x01FFFFFF); } #endif // USE_LORAWAN_BRIDGE diff --git a/tasmota/tasmota_xdrv_driver/xdrv_73_9_lora.ino b/tasmota/tasmota_xdrv_driver/xdrv_73_9_lora.ino index ee6281eb5..c2f6d671f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_73_9_lora.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_73_9_lora.ino @@ -17,55 +17,55 @@ /*********************************************************************************************/ void LoraDefaults(void) { - LoraSettings->frequency = TAS_LORA_FREQUENCY; - LoraSettings->bandwidth = TAS_LORA_BANDWIDTH; - LoraSettings->spreading_factor = TAS_LORA_SPREADING_FACTOR; - LoraSettings->coding_rate = TAS_LORA_CODING_RATE; - LoraSettings->sync_word = TAS_LORA_SYNC_WORD; - LoraSettings->output_power = TAS_LORA_OUTPUT_POWER; - LoraSettings->preamble_length = TAS_LORA_PREAMBLE_LENGTH; - LoraSettings->current_limit = TAS_LORA_CURRENT_LIMIT; - LoraSettings->implicit_header = TAS_LORA_HEADER; - LoraSettings->crc_bytes = TAS_LORA_CRC_BYTES; + Lora->settings.frequency = TAS_LORA_FREQUENCY; + Lora->settings.bandwidth = TAS_LORA_BANDWIDTH; + Lora->settings.spreading_factor = TAS_LORA_SPREADING_FACTOR; + Lora->settings.coding_rate = TAS_LORA_CODING_RATE; + Lora->settings.sync_word = TAS_LORA_SYNC_WORD; + Lora->settings.output_power = TAS_LORA_OUTPUT_POWER; + Lora->settings.preamble_length = TAS_LORA_PREAMBLE_LENGTH; + Lora->settings.current_limit = TAS_LORA_CURRENT_LIMIT; + Lora->settings.implicit_header = TAS_LORA_HEADER; + Lora->settings.crc_bytes = TAS_LORA_CRC_BYTES; } void LoraWanDefaults(void) { - LoraSettings->frequency = TAS_LORAWAN_FREQUENCY; - LoraSettings->bandwidth = TAS_LORAWAN_BANDWIDTH; - LoraSettings->spreading_factor = TAS_LORAWAN_SPREADING_FACTOR; - LoraSettings->coding_rate = TAS_LORAWAN_CODING_RATE; - LoraSettings->sync_word = TAS_LORAWAN_SYNC_WORD; - LoraSettings->output_power = TAS_LORAWAN_OUTPUT_POWER; - LoraSettings->preamble_length = TAS_LORAWAN_PREAMBLE_LENGTH; - LoraSettings->current_limit = TAS_LORAWAN_CURRENT_LIMIT; - LoraSettings->implicit_header = TAS_LORAWAN_HEADER; - LoraSettings->crc_bytes = TAS_LORAWAN_CRC_BYTES; + Lora->settings.frequency = TAS_LORAWAN_FREQUENCY; + Lora->settings.bandwidth = TAS_LORAWAN_BANDWIDTH; + Lora->settings.spreading_factor = TAS_LORAWAN_SPREADING_FACTOR; + Lora->settings.coding_rate = TAS_LORAWAN_CODING_RATE; + Lora->settings.sync_word = TAS_LORAWAN_SYNC_WORD; + Lora->settings.output_power = TAS_LORAWAN_OUTPUT_POWER; + Lora->settings.preamble_length = TAS_LORAWAN_PREAMBLE_LENGTH; + Lora->settings.current_limit = TAS_LORAWAN_CURRENT_LIMIT; + Lora->settings.implicit_header = TAS_LORAWAN_HEADER; + Lora->settings.crc_bytes = TAS_LORAWAN_CRC_BYTES; } void LoraSettings2Json(void) { - ResponseAppend_P(PSTR("\"" D_JSON_FREQUENCY "\":%1_f"), &LoraSettings->frequency); // xxx.x MHz - ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":%1_f"), &LoraSettings->bandwidth); // xxx.x kHz - ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":%d"), LoraSettings->spreading_factor); - ResponseAppend_P(PSTR(",\"" D_JSON_CODINGRATE4 "\":%d"), LoraSettings->coding_rate); - ResponseAppend_P(PSTR(",\"" D_JSON_SYNCWORD "\":%d"), LoraSettings->sync_word); - ResponseAppend_P(PSTR(",\"" D_JSON_OUTPUT_POWER "\":%d"), LoraSettings->output_power); // dBm - ResponseAppend_P(PSTR(",\"" D_JSON_PREAMBLE_LENGTH "\":%d"), LoraSettings->preamble_length); // symbols - ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT_LIMIT "\":%1_f"), &LoraSettings->current_limit); // xx.x mA (Overcurrent Protection - OCP) - ResponseAppend_P(PSTR(",\"" D_JSON_IMPLICIT_HEADER "\":%d"), LoraSettings->implicit_header); // 0 = explicit - ResponseAppend_P(PSTR(",\"" D_JSON_CRC_BYTES "\":%d"), LoraSettings->crc_bytes); // bytes + ResponseAppend_P(PSTR("\"" D_JSON_FREQUENCY "\":%1_f"), &Lora->settings.frequency); // xxx.x MHz + ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":%1_f"), &Lora->settings.bandwidth); // xxx.x kHz + ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":%d"), Lora->settings.spreading_factor); + ResponseAppend_P(PSTR(",\"" D_JSON_CODINGRATE4 "\":%d"), Lora->settings.coding_rate); + ResponseAppend_P(PSTR(",\"" D_JSON_SYNCWORD "\":%d"), Lora->settings.sync_word); + ResponseAppend_P(PSTR(",\"" D_JSON_OUTPUT_POWER "\":%d"), Lora->settings.output_power); // dBm + ResponseAppend_P(PSTR(",\"" D_JSON_PREAMBLE_LENGTH "\":%d"), Lora->settings.preamble_length); // symbols + ResponseAppend_P(PSTR(",\"" D_JSON_CURRENT_LIMIT "\":%1_f"), &Lora->settings.current_limit); // xx.x mA (Overcurrent Protection - OCP) + ResponseAppend_P(PSTR(",\"" D_JSON_IMPLICIT_HEADER "\":%d"), Lora->settings.implicit_header); // 0 = explicit + ResponseAppend_P(PSTR(",\"" D_JSON_CRC_BYTES "\":%d"), Lora->settings.crc_bytes); // bytes } void LoraJson2Settings(JsonParserObject root) { - LoraSettings->frequency = root.getFloat(PSTR(D_JSON_FREQUENCY), LoraSettings->frequency); - LoraSettings->bandwidth = root.getFloat(PSTR(D_JSON_BANDWIDTH), LoraSettings->bandwidth); - LoraSettings->spreading_factor = root.getUInt(PSTR(D_JSON_SPREADING_FACTOR), LoraSettings->spreading_factor); - LoraSettings->coding_rate = root.getUInt(PSTR(D_JSON_CODINGRATE4), LoraSettings->coding_rate); - LoraSettings->sync_word = root.getUInt(PSTR(D_JSON_SYNCWORD), LoraSettings->sync_word); - LoraSettings->output_power = root.getUInt(PSTR(D_JSON_OUTPUT_POWER), LoraSettings->output_power); - LoraSettings->preamble_length = root.getUInt(PSTR(D_JSON_PREAMBLE_LENGTH), LoraSettings->preamble_length); - LoraSettings->current_limit = root.getFloat(PSTR(D_JSON_CURRENT_LIMIT), LoraSettings->current_limit); - LoraSettings->implicit_header = root.getUInt(PSTR(D_JSON_IMPLICIT_HEADER), LoraSettings->implicit_header); - LoraSettings->crc_bytes = root.getUInt(PSTR(D_JSON_CRC_BYTES), LoraSettings->crc_bytes); + Lora->settings.frequency = root.getFloat(PSTR(D_JSON_FREQUENCY), Lora->settings.frequency); + Lora->settings.bandwidth = root.getFloat(PSTR(D_JSON_BANDWIDTH), Lora->settings.bandwidth); + Lora->settings.spreading_factor = root.getUInt(PSTR(D_JSON_SPREADING_FACTOR), Lora->settings.spreading_factor); + Lora->settings.coding_rate = root.getUInt(PSTR(D_JSON_CODINGRATE4), Lora->settings.coding_rate); + Lora->settings.sync_word = root.getUInt(PSTR(D_JSON_SYNCWORD), Lora->settings.sync_word); + Lora->settings.output_power = root.getUInt(PSTR(D_JSON_OUTPUT_POWER), Lora->settings.output_power); + Lora->settings.preamble_length = root.getUInt(PSTR(D_JSON_PREAMBLE_LENGTH), Lora->settings.preamble_length); + Lora->settings.current_limit = root.getFloat(PSTR(D_JSON_CURRENT_LIMIT), Lora->settings.current_limit); + Lora->settings.implicit_header = root.getUInt(PSTR(D_JSON_IMPLICIT_HEADER), Lora->settings.implicit_header); + Lora->settings.crc_bytes = root.getUInt(PSTR(D_JSON_CRC_BYTES), Lora->settings.crc_bytes); } /*********************************************************************************************\ @@ -85,8 +85,8 @@ bool LoraLoadData(void) { JsonParserObject root = parser.getRootObject(); if (!root) { return false; } - LoraSettings->crc32 = root.getUInt(PSTR("Crc"), LoraSettings->crc32); - LoraSettings->flags = root.getUInt(PSTR("Flags"), LoraSettings->flags); + Lora->settings.crc32 = root.getUInt(PSTR("Crc"), Lora->settings.crc32); + Lora->settings.flags = root.getUInt(PSTR("Flags"), Lora->settings.flags); LoraJson2Settings(root); #ifdef USE_LORAWAN_BRIDGE @@ -102,8 +102,8 @@ bool LoraSaveData(void) { Response_P(PSTR("{\"" XDRV_73_KEY "\":{" "\"Crc\":%u," "\"Flags\":%u,"), - LoraSettings->crc32, - LoraSettings->flags); + Lora->settings.crc32, + Lora->settings.flags); LoraSettings2Json(); ResponseAppend_P(PSTR("}}")); @@ -134,7 +134,7 @@ void LoraSettingsLoad(bool erase) { // Called from FUNC_RESET_SETTINGS (erase = 1) after command reset 4, 5, or 6 // *** Start init default values in case key is not found *** - memset(LoraSettings, 0x00, sizeof(LoraSettings_t)); + memset(&Lora->settings, 0x00, sizeof(LoraSettings_t)); // Init any other parameter in struct LoraSettings LoraDefaults(); // *** End Init default values *** @@ -159,11 +159,9 @@ void LoraSettingsLoad(bool erase) { void LoraSettingsSave(void) { // Called from FUNC_SAVE_SETTINGS every SaveData second and at restart #ifdef USE_UFILESYS - uint32_t crc32 = GetCfgCrc32((uint8_t*)LoraSettings +4, sizeof(LoraSettings_t) -4); // Skip crc32 - if (crc32 != LoraSettings->crc32) { - // Try to save file /.drvset122 - LoraSettings->crc32 = crc32; - + uint32_t crc32 = GetCfgCrc32((uint8_t*)&Lora->settings +4, sizeof(LoraSettings_t) -4); // Skip crc32 + if (crc32 != Lora->settings.crc32) { + Lora->settings.crc32 = crc32; if (LoraSaveData()) { AddLog(LOG_LEVEL_DEBUG, PSTR("CFG: Lora saved to file")); } else { @@ -194,7 +192,7 @@ void LoraInput(void) { Lora->receive_time, packet_size, data, &Lora->rssi, &Lora->snr); #ifdef USE_LORAWAN_BRIDGE - if (bitRead(LoraSettings->flags, TAS_LORA_FLAG_BRIDGE_ENABLED)) { + if (bitRead(Lora->settings.flags, TAS_LORA_FLAG_BRIDGE_ENABLED)) { if (LoraWanInput((uint8_t*)data, packet_size)) { return; } @@ -255,16 +253,15 @@ void LoraInit(void) { Lora = (Lora_t*)calloc(sizeof(Lora_t), 1); // Need calloc to reset registers to 0/false if (nullptr == Lora) { return; } - LoraSettings = (LoraSettings_t*)calloc(sizeof(LoraSettings_t), 1); // Need calloc to reset registers to 0/false - if (nullptr == LoraSettings) { - free(Lora); - return; - } LoraSettingsLoad(0); +#ifdef USE_LORAWAN_BRIDGE + LoraWanInit(); +#endif // USE_LORAWAN_BRIDGE bool present = false; char hardware[20]; if (false) { + // Need this as following `else if`s may not be present } #ifdef USE_LORA_SX127X else if (PinUsed(GPIO_LORA_DI0)) { @@ -293,15 +290,9 @@ void LoraInit(void) { } #endif // USE_LORA_SX126X -#ifdef USE_LORAWAN_BRIDGE - if (present && !LoraWanInit()) { - present = false; - } -#endif // USE_LORAWAN_BRIDGE if (present) { AddLog(LOG_LEVEL_INFO, PSTR("LOR: %s initialized"), hardware); } else { - free(LoraSettings); free(Lora); Lora = nullptr; } @@ -330,9 +321,9 @@ void CmndLoraOption(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 8)) { uint32_t pindex = XdrvMailbox.index -1; if (XdrvMailbox.payload >= 0) { - bitWrite(LoraSettings->flags, pindex, XdrvMailbox.payload); + bitWrite(Lora->settings.flags, pindex, XdrvMailbox.payload); } - ResponseCmndIdxChar(GetStateText(bitRead(LoraSettings->flags, pindex))); + ResponseCmndIdxChar(GetStateText(bitRead(Lora->settings.flags, pindex))); } } @@ -369,7 +360,7 @@ void CmndLoraSend(void) { invert = true; } if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { - Lora->raw = (XdrvMailbox.index > 3); // Global flag set even without data + Lora->raw = (XdrvMailbox.index > 3); // Global flag set even without data if (XdrvMailbox.data_len > 0) { char data[TAS_LORA_MAX_PACKET_LENGTH] = { 0 }; uint32_t len = (XdrvMailbox.data_len < TAS_LORA_MAX_PACKET_LENGTH -1) ? XdrvMailbox.data_len : TAS_LORA_MAX_PACKET_LENGTH -2;