147 lines
3.4 KiB
C++
147 lines
3.4 KiB
C++
|
|
#include <LoRaTransmitter.h>
|
||
|
|
|
||
|
|
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;
|
||
|
|
}
|