#include RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; LoRaTransmitter::LoRaTransmitter( uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey ) : _joinEUI(joinEUI), _devEUI(devEUI), _radio(new Module(LORA_NSS, LORA_DIO0, LORA_RST, LORA_DIO1)), _node(&_radio, &EU868) { memcpy(_nwkKey, nwkKey, 16); memcpy(_appKey, appKey, 16); memset(_noncesBuffer, 0, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); } void 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); while (true) { delay(1000); } } Serial.println("OK"); } void 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); while (true) { delay(1000); } } } Serial.println("OK"); _saveSession(); } void 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"); } else { Serial.printf("[TX] Erreur : %d\n", state); } _saveSession(); } 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; }