diff --git a/lib/RN2483-Arduino-Library/src/rn2xx3.cpp b/lib/RN2483-Arduino-Library/src/rn2xx3.cpp index fb3a07a11..28fc4b462 100644 --- a/lib/RN2483-Arduino-Library/src/rn2xx3.cpp +++ b/lib/RN2483-Arduino-Library/src/rn2xx3.cpp @@ -34,7 +34,7 @@ bool rn2xx3::getAsyncMode() const { bool rn2xx3::autobaud() { // FIXME TD-er: Must fix this, as it is not working well. - String response = ""; + String response; // Try a maximum of 10 times with a 1 second delay for (uint8_t i = 0; i < 10 && response.length() == 0; i++) diff --git a/lib/RN2483-Arduino-Library/src/rn2xx3_handler.cpp b/lib/RN2483-Arduino-Library/src/rn2xx3_handler.cpp index 8e033dfd5..e111bae66 100644 --- a/lib/RN2483-Arduino-Library/src/rn2xx3_handler.cpp +++ b/lib/RN2483-Arduino-Library/src/rn2xx3_handler.cpp @@ -9,6 +9,11 @@ rn2xx3_handler::rn2xx3_handler(Stream& serial) : _serial(serial) clearSerialBuffer(); } +String rn2xx3_handler::sendRawCommand(const __FlashStringHelper* command) +{ + return sendRawCommand(String(command)); +} + String rn2xx3_handler::sendRawCommand(const String& command) { unsigned long timer = millis(); @@ -254,14 +259,16 @@ bool rn2xx3_handler::init() // may not be successful after a factory reset if not all fields are set. // Set OTAA keys - sendMacSet(F("deveui"), _deveui); - sendMacSet(F("appeui"), _appeui); - sendMacSet(F("appkey"), _appkey); - - // Set ABP keys - sendMacSet(F("nwkskey"), _nwkskey); - sendMacSet(F("appskey"), _appskey); - sendMacSet(F("devaddr"), _devaddr); + if (_otaa) { + sendMacSet(F("deveui"), _deveui); + sendMacSet(F("appeui"), _appeui); + sendMacSet(F("appkey"), _appkey); + } else { + // Set ABP keys + sendMacSet(F("nwkskey"), _nwkskey); + sendMacSet(F("appskey"), _appskey); + sendMacSet(F("devaddr"), _devaddr); + } // Set max. allowed power. // 868 MHz EU : 1 -> 14 dBm @@ -272,14 +279,14 @@ bool rn2xx3_handler::init() // Switch off automatic replies, because this library can not // handle more than one mac_rx per tx. See RN2483 datasheet, // 2.4.8.14, page 27 and the scenario on page 19. - setAutomaticReply(false); + setAutomaticReply(true); // Semtech and TTN both use a non default RX2 window freq and SF. // Maybe we should not specify this for other networks. - // if (_moduleType == RN2xx3_datatypes::Model::RN2483) - // { - // set2ndRecvWindow(3, 869525000); - // } + if (_moduleType == RN2xx3_datatypes::Model::RN2483) + { + set2ndRecvWindow(3, 869525000); + } // Disabled for now because an OTAA join seems to work fine without. if (_asyncMode) { @@ -366,6 +373,16 @@ bool rn2xx3_handler::initABP(const String& devAddr, const String& AppSKey, const return init(); } +RN2xx3_datatypes::TX_return_type rn2xx3_handler::txCommand( + const __FlashStringHelper* command, + const String& data, + bool shouldEncode, + uint8_t port) +{ + return txCommand(String(command), data, shouldEncode, port); +} + + RN2xx3_datatypes::TX_return_type rn2xx3_handler::txCommand(const String& command, const String& data, bool shouldEncode, uint8_t port) { if (get_state() == RN_state::must_perform_init) { @@ -710,6 +727,11 @@ String rn2xx3_handler::getLastError() return res; } +void rn2xx3_handler::setLastError(const __FlashStringHelper* error) +{ + setLastError(String(error)); +} + void rn2xx3_handler::setLastError(const String& error) { if (_extensive_debug) { @@ -1207,6 +1229,11 @@ void rn2xx3_handler::handle_reply_received() { } } +int rn2xx3_handler::readIntValue(const __FlashStringHelper* command) +{ + return readIntValue(String(command)); +} + int rn2xx3_handler::readIntValue(const String& command) { String value = sendRawCommand(command); @@ -1215,6 +1242,11 @@ int rn2xx3_handler::readIntValue(const String& command) return value.toInt(); } +bool rn2xx3_handler::readUIntMacGet(const __FlashStringHelper* param, uint32_t& value) +{ + return readUIntMacGet(String(param), value); +} + bool rn2xx3_handler::readUIntMacGet(const String& param, uint32_t& value) { String command; @@ -1232,6 +1264,11 @@ bool rn2xx3_handler::readUIntMacGet(const String& param, uint32_t& value) return true; } +bool rn2xx3_handler::sendMacSet(const __FlashStringHelper* param, const String& value) +{ + return sendMacSet(String(param), value); +} + bool rn2xx3_handler::sendMacSet(const String& param, const String& value) { String command; @@ -1249,7 +1286,7 @@ bool rn2xx3_handler::sendMacSet(const String& param, const String& value) return RN2xx3_received_types::determineReceivedDataType(sendRawCommand(command)) == RN2xx3_received_types::ok; } -bool rn2xx3_handler::sendMacSetEnabled(const String& param, bool enabled) +bool rn2xx3_handler::sendMacSetEnabled(const __FlashStringHelper* param, bool enabled) { return sendMacSet(param, enabled ? F("on") : F("off")); } @@ -1272,6 +1309,14 @@ bool rn2xx3_handler::sendMacSetCh(const String& param, unsigned int channel, uin return sendMacSetCh(param, channel, String(value)); } +bool rn2xx3_handler::sendMacSetCh(const __FlashStringHelper* param, + unsigned int channel, + uint32_t value) +{ + return sendMacSetCh(String(param), channel, String(value)); +} + + bool rn2xx3_handler::setChannelDutyCycle(unsigned int channel, unsigned int dutyCycle) { return sendMacSetCh(F("dcycle"), channel, dutyCycle); @@ -1394,7 +1439,7 @@ bool rn2xx3_handler::check_set_keys() { // The default address to use on TTN if no address is defined. // This one falls in the "testing" address space. - _devaddr = F("03FFBEEF"); + _devaddr = F("00000000"); } } return true; diff --git a/lib/RN2483-Arduino-Library/src/rn2xx3_handler.h b/lib/RN2483-Arduino-Library/src/rn2xx3_handler.h index c50de9378..5f31bea88 100644 --- a/lib/RN2483-Arduino-Library/src/rn2xx3_handler.h +++ b/lib/RN2483-Arduino-Library/src/rn2xx3_handler.h @@ -31,6 +31,7 @@ public: rn2xx3_handler(Stream& serial); + String sendRawCommand(const __FlashStringHelper* command); String sendRawCommand(const String& command); bool prepare_raw_command(const String& command); @@ -113,6 +114,12 @@ public: uint8_t *DevEui); + RN2xx3_datatypes::TX_return_type txCommand(const __FlashStringHelper* command, + const String& data, + bool shouldEncode, + uint8_t port); + + RN2xx3_datatypes::TX_return_type txCommand(const String&, const String&, bool, @@ -180,6 +187,7 @@ public: String getLastError(); // Set specific error string. + void setLastError(const __FlashStringHelper* error); void setLastError(const String& error); RN_state get_state() const; @@ -282,15 +290,21 @@ public: // Convenience functions + int readIntValue(const __FlashStringHelper* command); int readIntValue(const String& command); + + bool readUIntMacGet(const __FlashStringHelper* param, + uint32_t & value); bool readUIntMacGet(const String& param, uint32_t & value); // All "mac set ..." commands return either "ok" or "invalid_param" + bool sendMacSet(const __FlashStringHelper* param, + const String& value); bool sendMacSet(const String& param, const String& value); - bool sendMacSetEnabled(const String& param, + bool sendMacSetEnabled(const __FlashStringHelper* param, bool enabled); bool sendMacSetCh(const String& param, unsigned int channel, @@ -298,6 +312,9 @@ public: bool sendMacSetCh(const String& param, unsigned int channel, uint32_t value); + bool sendMacSetCh(const __FlashStringHelper* param, + unsigned int channel, + uint32_t value); bool setChannelDutyCycle(unsigned int channel, unsigned int dutyCycle); bool setChannelFrequency(unsigned int channel, diff --git a/src/_C018.cpp b/src/_C018.cpp index 38a72fb64..30ab6c503 100644 --- a/src/_C018.cpp +++ b/src/_C018.cpp @@ -100,14 +100,7 @@ struct C018_data_struct { return isInitialized(); } - bool isInitialized() const { - if ((C018_easySerial != nullptr) && (myLora != nullptr)) { - if (autobaud_success) { - return true; - } - } - return false; - } + bool isInitialized() const; bool hasJoined() const { if (!isInitialized()) { return false; } @@ -183,6 +176,7 @@ struct C018_data_struct { bool initOTAA(const String& AppEUI, const String& AppKey, const String& DevEUI) { if (myLora == nullptr) { return false; } bool success = myLora->initOTAA(AppEUI, AppKey, DevEUI); + cacheDevAddr = String(); C018_logError(F("initOTAA()")); updateCacheOnInit(); @@ -192,6 +186,7 @@ struct C018_data_struct { bool initABP(const String& addr, const String& AppSKey, const String& NwkSKey) { if (myLora == nullptr) { return false; } bool success = myLora->initABP(addr, AppSKey, NwkSKey); + cacheDevAddr = addr; C018_logError(F("initABP()")); updateCacheOnInit(); @@ -199,7 +194,7 @@ struct C018_data_struct { } String sendRawCommand(const String& command) { - if (!isInitialized()) { return ""; } + if (!isInitialized()) { return EMPTY_STRING; } if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log = F("sendRawCommand: "); @@ -218,17 +213,17 @@ struct C018_data_struct { } String peekLastError() { - if (!isInitialized()) { return ""; } + if (!isInitialized()) { return EMPTY_STRING; } return myLora->peekLastError(); } String getLastError() { - if (!isInitialized()) { return ""; } + if (!isInitialized()) { return EMPTY_STRING; } return myLora->getLastError(); } String getDataRate() { - if (!isInitialized()) { return ""; } + if (!isInitialized()) { return EMPTY_STRING; } String res = myLora->getDataRate(); C018_logError(F("getDataRate()")); @@ -336,36 +331,9 @@ struct C018_data_struct { private: - void C018_logError(const String& command) const { - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String error = myLora->peekLastError(); + void C018_logError(const __FlashStringHelper* command) const; - // String error = myLora->getLastError(); - - if (error.length() > 0) { - String log = F("RN2483: "); - log += command; - log += F(": "); - log += error; - addLogMove(LOG_LEVEL_INFO, log); - } - } - } - - void updateCacheOnInit() { - cacheDevAddr = String(); - - if (isInitialized()) { - if (myLora->getStatus().Joined) - { - cacheDevAddr = myLora->sendRawCommand(F("mac get devaddr")); - - if (cacheDevAddr == F("00000000")) { - cacheDevAddr = String(); - } - } - } - } + void updateCacheOnInit(); void triggerAutobaud() { if ((C018_easySerial == nullptr) || (myLora == nullptr)) { @@ -429,6 +397,46 @@ private: bool autobaud_success = false; }; + + bool C018_data_struct::isInitialized() const { + if ((C018_easySerial != nullptr) && (myLora != nullptr)) { + if (autobaud_success) { + return true; + } + } + return false; + } + + void C018_data_struct::C018_logError(const __FlashStringHelper* command) const { + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String error = myLora->peekLastError(); + + // String error = myLora->getLastError(); + + if (error.length() > 0) { + String log = F("RN2483: "); + log += command; + log += F(": "); + log += error; + addLogMove(LOG_LEVEL_INFO, log); + } + } + } + + void C018_data_struct::updateCacheOnInit() { + if (isInitialized()) { + if (cacheDevAddr.isEmpty() && myLora->getStatus().Joined) + { + cacheDevAddr = myLora->sendRawCommand(F("mac get devaddr")); + + if (cacheDevAddr == F("00000000")) { + cacheDevAddr = String(); + } + } + } + } + + C018_data_struct *C018_data = nullptr; # define C018_DEVICE_EUI_LEN 17 @@ -453,7 +461,7 @@ struct C018_ConfigStruct reset(); } if (stackVersion >= RN2xx3_datatypes::TTN_stack_version::TTN_NOT_SET) { - stackVersion = RN2xx3_datatypes::TTN_stack_version::TTN_v2; + stackVersion = RN2xx3_datatypes::TTN_stack_version::TTN_v3; } } @@ -462,13 +470,13 @@ struct C018_ConfigStruct ZERO_FILL(DeviceAddr); ZERO_FILL(NetworkSessionKey); ZERO_FILL(AppSessionKey); - baudrate = 9600; - rxpin = 12; - txpin = 14; + baudrate = 57600; + rxpin = -1; + txpin = -1; resetpin = -1; sf = 7; frequencyplan = RN2xx3_datatypes::Freq_plan::TTN_EU; - stackVersion = RN2xx3_datatypes::TTN_stack_version::TTN_v2; + stackVersion = RN2xx3_datatypes::TTN_stack_version::TTN_v3; joinmethod = C018_USE_OTAA; } @@ -694,7 +702,7 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& addRowLabel(F("Voltage")); addHtmlFloat(static_cast(C018_data->getVbat()) / 1000.0f, 3); - addRowLabel(F("Dev Addr")); + addRowLabel(F("Device Addr")); addHtml(C018_data->getDevaddr()); uint32_t dnctr, upctr; diff --git a/src/src/WebServer/ControllerPage.cpp b/src/src/WebServer/ControllerPage.cpp index 502182c93..94a989530 100644 --- a/src/src/WebServer/ControllerPage.cpp +++ b/src/src/WebServer/ControllerPage.cpp @@ -139,6 +139,9 @@ void handle_controllers_clearLoadDefaults(uint8_t controllerindex, ControllerSet // Load some templates from the controller. struct EventStruct TempEvent; + // Hand over the controller settings in the Data pointer, so the controller can set some defaults. + TempEvent.Data = (uint8_t*)(&ControllerSettings); + if (Protocol[ProtocolIndex].usesTemplate) { String dummy; CPluginCall(ProtocolIndex, CPlugin::Function::CPLUGIN_PROTOCOL_TEMPLATE, &TempEvent, dummy);