#include RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; LoRaTransmitter::LoRaTransmitter() : _radio(new Module(LORA_NSS, LORA_DIO0, LORA_RST, LORA_DIO1)), _node(&_radio, &EU868) { _prefs.begin("lorawan", true); _joinEUI = _prefs.getULong64("join_eui", 0); _devEUI = _prefs.getULong64("dev_eui", 0); _prefs.getBytes("nwk_key", _nwkKey, 16); _prefs.getBytes("app_key", _appKey, 16); _prefs.end(); memset(_noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); } TransmitError LoRaTransmitter::init() { _reset(); SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_NSS); Serial.print("[LoRaWAN] Init... "); int state = _radio.begin(); if (state != RADIOLIB_ERR_NONE) { Serial.printf("ERREUR %d\n", state); return TransmitError::INIT_FAILED; } Serial.println("OK"); return TransmitError::OK; } TransmitError LoRaTransmitter::join() { int16_t state = RADIOLIB_ERR_NETWORK_NOT_JOINED; _node.beginOTAA(_joinEUI, _devEUI, _nwkKey, _appKey); _restoreDevNonce(); if (_restoreSession() != RADIOLIB_LORAWAN_SESSION_RESTORED) { Serial.print("[LoRaWAN] Join complet..."); int16_t state = _fullJoin(); if (state != RADIOLIB_LORAWAN_NEW_SESSION) { Serial.printf("Echec : %d\n", state); return TransmitError::JOIN_FAILED; } } Serial.println("OK"); _saveSession(); return TransmitError::OK; } TransmitError LoRaTransmitter::send(uint8_t payload[], size_t size) { int state = _node.sendReceive(payload, size, 1); if (state == RADIOLIB_ERR_NONE || state == RADIOLIB_LORAWAN_NO_DOWNLINK) { Serial.println("[TX] OK"); _saveSession(); return TransmitError::OK; } else { Serial.printf("[TX] Erreur : %d\n", state); _saveSession(); return TransmitError::SEND_FAILED; } } void LoRaTransmitter::_reset() { pinMode(LORA_RST, OUTPUT); digitalWrite(LORA_RST, LOW); delay(10); digitalWrite(LORA_RST, HIGH); delay(10); } void LoRaTransmitter::_restoreDevNonce() { _prefs.begin("lorawan"); if (_prefs.isKey("nonces")) { _prefs.getBytes("nonces", _noncesBuffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); } else { Serial.println("[NVS] Aucune donnée trouvée, buffer initialisé à zéro"); memset(_noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); } _prefs.end(); _node.setBufferNonces(_noncesBuffer); } void LoRaTransmitter::_persistDevNonce() { _prefs.begin("lorawan"); uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; uint8_t *persist = _node.getBufferNonces(); memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); size_t result = _prefs.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); _prefs.end(); } int16_t LoRaTransmitter::_restoreSession() { Serial.print("[LoRaWAN] Tentative de restaurer la session..."); int16_t state = _node.setBufferSession(LWsession); if (state == RADIOLIB_ERR_NONE) { state = _node.activateOTAA(); } else { Serial.println("Echec"); } return state; } void LoRaTransmitter::_saveSession() { uint8_t *session = _node.getBufferSession(); memcpy(LWsession, session, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); Serial.println("[RTC] Session sauvegardée"); } int16_t LoRaTransmitter::_fullJoin() { _node.beginOTAA(_joinEUI, _devEUI, _nwkKey, _appKey); _restoreDevNonce(); int16_t state = _node.activateOTAA(); _persistDevNonce(); return state; }