kopia lustrzana https://github.com/jgromes/RadioLib
[LoRaWAN] Restore channel masks and flags within and outside of sessions
rodzic
ce8c84197d
commit
0dde18078b
|
@ -440,9 +440,6 @@ uint8_t* LoRaWANNode::getBufferSession() {
|
|||
LoRaWANNode::hton<uint32_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_FCNT_UP], this->fCntUp);
|
||||
LoRaWANNode::hton<uint8_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_CLASS], this->lwClass);
|
||||
|
||||
// store the enabled channels
|
||||
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_LINK_ADR] + 1, this->channelMasks, RADIOLIB_LORAWAN_MAX_NUM_SUBBANDS);
|
||||
|
||||
// store the unused channel flags
|
||||
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_AVAILABLE_CHANNELS], this->channelFlags, RADIOLIB_LORAWAN_MAX_NUM_SUBBANDS);
|
||||
|
||||
|
@ -478,6 +475,14 @@ int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) {
|
|||
// copy the whole buffer over
|
||||
memcpy(this->bufferSession, persistentBuffer, RADIOLIB_LORAWAN_SESSION_BUF_SIZE);
|
||||
|
||||
// always restore the channels, so as to adhere to channel hopping between JoinRequests
|
||||
memcpy(this->channelFlags, &this->bufferSession[RADIOLIB_LORAWAN_SESSION_AVAILABLE_CHANNELS], RADIOLIB_LORAWAN_MAX_NUM_SUBBANDS);
|
||||
|
||||
// check if the session is active, if not, don't restore anything else
|
||||
if((bool)this->bufferSession[RADIOLIB_LORAWAN_SESSION_ACTIVE] == false) {
|
||||
return(RADIOLIB_ERR_NETWORK_NOT_JOINED);
|
||||
}
|
||||
|
||||
//// this code can be used in case breaking chances must be caught:
|
||||
// uint8_t nvm_table_version = this->bufferNonces[RADIOLIB_LORAWAN_NONCES_VERSION];
|
||||
// if (RADIOLIB_LORAWAN_NONCES_VERSION_VAL > nvm_table_version) {
|
||||
|
@ -503,14 +508,10 @@ int16_t LoRaWANNode::setBufferSession(const uint8_t* persistentBuffer) {
|
|||
this->fCntUp = LoRaWANNode::ntoh<uint32_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_FCNT_UP]);
|
||||
|
||||
// restore the complete MAC state
|
||||
|
||||
uint8_t cOcts[14] = { 0 }; // see Wiki dev notes for this odd size
|
||||
uint8_t cid;
|
||||
uint8_t cLen = 0;
|
||||
|
||||
// setup the default channels
|
||||
this->addDefaultChannels();
|
||||
|
||||
// for dynamic bands, the additional channels must be restored per-channel
|
||||
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
|
||||
// all-zero buffer used for checking if MAC commands are set
|
||||
|
@ -836,12 +837,7 @@ int16_t LoRaWANNode::processJoinAccept(LoRaWANJoinEvent_t *joinEvent) {
|
|||
LoRaWANNode::hton<uint32_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_JOIN_NONCE], this->joinNonce, 3);
|
||||
|
||||
this->bufferNonces[RADIOLIB_LORAWAN_NONCES_ACTIVE] = (uint8_t)true;
|
||||
|
||||
// generate the signature of the Nonces buffer, and store it in the last two bytes of the Nonces buffer
|
||||
// also store this signature in the Session buffer to make sure these buffers match
|
||||
uint16_t signature = LoRaWANNode::checkSum16(this->bufferNonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE - 2);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_SIGNATURE], signature);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature);
|
||||
this->bufferSession[RADIOLIB_LORAWAN_SESSION_ACTIVE] = (uint8_t)true;
|
||||
|
||||
// store DevAddr and all keys
|
||||
LoRaWANNode::hton<uint32_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_DEV_ADDR], this->devAddr);
|
||||
|
@ -903,6 +899,12 @@ int16_t LoRaWANNode::activateOTAA(LoRaWANJoinEvent_t *joinEvent) {
|
|||
this->devNonce += 1;
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_DEV_NONCE], this->devNonce);
|
||||
|
||||
// generate the signature of the Nonces buffer, and store it in the last two bytes of the Nonces buffer
|
||||
// also store this signature in the Session buffer to make sure these buffers match
|
||||
uint16_t signature = LoRaWANNode::checkSum16(this->bufferNonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE - 2);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_SIGNATURE], signature);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature);
|
||||
|
||||
// configure Rx1 and Rx2 delay for JoinAccept message - these are re-configured once a valid JoinAccept is received
|
||||
this->rxDelays[1] = RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_1_MS;
|
||||
this->rxDelays[2] = RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_2_MS;
|
||||
|
@ -919,6 +921,11 @@ int16_t LoRaWANNode::activateOTAA(LoRaWANJoinEvent_t *joinEvent) {
|
|||
state = this->processJoinAccept(joinEvent);
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// regenerate the Nonces signature as we received new Nonces in the JoinAccept
|
||||
signature = LoRaWANNode::checkSum16(this->bufferNonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE - 2);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferNonces[RADIOLIB_LORAWAN_NONCES_SIGNATURE], signature);
|
||||
LoRaWANNode::hton<uint16_t>(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE], signature);
|
||||
|
||||
(void)this->calculateChannelFlags();
|
||||
|
||||
return(RADIOLIB_LORAWAN_NEW_SESSION);
|
||||
|
@ -938,6 +945,7 @@ int16_t LoRaWANNode::activateABP() {
|
|||
|
||||
// new session all good, so set active-bit to true
|
||||
this->bufferNonces[RADIOLIB_LORAWAN_NONCES_ACTIVE] = (uint8_t)true;
|
||||
this->bufferSession[RADIOLIB_LORAWAN_SESSION_ACTIVE] = (uint8_t)true;
|
||||
|
||||
// generate the signature of the Nonces buffer, and store it in the last two bytes of the Nonces buffer
|
||||
// also store this signature in the Session buffer to make sure these buffers match
|
||||
|
@ -964,6 +972,9 @@ int16_t LoRaWANNode::activateABP() {
|
|||
void LoRaWANNode::processCFList(const uint8_t* cfList) {
|
||||
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Processing CFList");
|
||||
|
||||
uint8_t cOcts[14] = { 0 }; // see Wiki for special length
|
||||
uint8_t cid;
|
||||
uint8_t cLen = 0;
|
||||
|
||||
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
|
||||
// retrieve number of default channels
|
||||
|
@ -975,9 +986,7 @@ void LoRaWANNode::processCFList(const uint8_t* cfList) {
|
|||
num++;
|
||||
}
|
||||
|
||||
uint8_t cOcts[5] = { 0 };
|
||||
uint8_t cid = RADIOLIB_LORAWAN_MAC_NEW_CHANNEL;
|
||||
uint8_t cLen = 0;
|
||||
cid = RADIOLIB_LORAWAN_MAC_NEW_CHANNEL;
|
||||
(void)this->getMacLen(cid, &cLen, RADIOLIB_LORAWAN_DOWNLINK);
|
||||
|
||||
const uint8_t freqZero[3] = { 0 };
|
||||
|
@ -994,8 +1003,14 @@ void LoRaWANNode::processCFList(const uint8_t* cfList) {
|
|||
(void)execMacCommand(cid, cOcts, cLen);
|
||||
}
|
||||
} else { // RADIOLIB_LORAWAN_BAND_FIXED
|
||||
// copy channel mask straight over
|
||||
memcpy(this->channelMasks, cfList, sizeof(this->channelMasks));
|
||||
// apply channel mask
|
||||
cid = RADIOLIB_LORAWAN_MAC_LINK_ADR;
|
||||
cLen = 14;
|
||||
cOcts[0] = 0xF0; // keep datarate the same
|
||||
cOcts[0] |= 0x0F; // keep Tx Power the same
|
||||
cOcts[13] = 0x01; // default NbTrans = 1
|
||||
memcpy(&cOcts[1], cfList, sizeof(this->channelMasks));
|
||||
(void)execMacCommand(cid, cOcts, cLen);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2442,16 +2457,20 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
|
|||
// downlink channel is identical to uplink channel
|
||||
this->dynamicChannels[RADIOLIB_LORAWAN_DOWNLINK][macChIndex] = this->dynamicChannels[RADIOLIB_LORAWAN_UPLINK][macChIndex];
|
||||
|
||||
// add the new channel
|
||||
this->channelMasks[0] |= (0x0001 << macChIndex);
|
||||
this->channelFlags[0] |= (0x0001 << macChIndex);
|
||||
// add the new channel (unless this happens during session restore)
|
||||
if(this->isActivated()) {
|
||||
this->channelMasks[0] |= (0x0001 << macChIndex);
|
||||
this->channelFlags[0] |= (0x0001 << macChIndex);
|
||||
}
|
||||
} else {
|
||||
this->dynamicChannels[RADIOLIB_LORAWAN_UPLINK][macChIndex] = RADIOLIB_LORAWAN_CHANNEL_NONE;
|
||||
this->dynamicChannels[RADIOLIB_LORAWAN_DOWNLINK][macChIndex] = RADIOLIB_LORAWAN_CHANNEL_NONE;
|
||||
|
||||
// remove this channel
|
||||
this->channelMasks[0] &= ~(0x0001 << macChIndex);
|
||||
this->channelFlags[0] &= ~(0x0001 << macChIndex);
|
||||
// remove this channel (unless this happens during session restore)
|
||||
if(this->isActivated()) {
|
||||
this->channelMasks[0] &= ~(0x0001 << macChIndex);
|
||||
this->channelFlags[0] &= ~(0x0001 << macChIndex);
|
||||
}
|
||||
}
|
||||
|
||||
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("UL: %3d %7.3f (%d - %d) | DL: %3d %7.3f (%d - %d)",
|
||||
|
@ -2467,6 +2486,11 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
|
|||
);
|
||||
|
||||
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_UL_CHANNELS] + macChIndex * lenIn, optIn, lenIn);
|
||||
// update the channel masks in the session buffer as we modified a channel
|
||||
if(this->isActivated()) {
|
||||
RADIOLIB_DEBUG_PROTOCOL_HEXDUMP((uint8_t*)this->channelMasks, 12);
|
||||
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_LINK_ADR] + 1, this->channelMasks, sizeof(this->channelMasks));
|
||||
}
|
||||
|
||||
return(true);
|
||||
} break;
|
||||
|
@ -3460,6 +3484,9 @@ int16_t LoRaWANNode::selectChannels() {
|
|||
}
|
||||
this->channels[RADIOLIB_LORAWAN_RX1].dr = rx1Dr;
|
||||
|
||||
RADIOLIB_DEBUG_PROTOCOL_HEXDUMP((uint8_t*)this->channelMasks, 12);
|
||||
RADIOLIB_DEBUG_PROTOCOL_HEXDUMP((uint8_t*)this->channelFlags, 12);
|
||||
|
||||
return(RADIOLIB_ERR_NONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,8 @@ enum LoRaWANSchemeBase_t {
|
|||
|
||||
enum LoRaWANSchemeSession_t {
|
||||
RADIOLIB_LORAWAN_SESSION_START = 0x00,
|
||||
RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY = RADIOLIB_LORAWAN_SESSION_START, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_ACTIVE = RADIOLIB_LORAWAN_SESSION_START, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY = RADIOLIB_LORAWAN_SESSION_ACTIVE + 1, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_APP_SKEY = RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY + RADIOLIB_AES128_KEY_SIZE, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY = RADIOLIB_LORAWAN_SESSION_APP_SKEY + RADIOLIB_AES128_KEY_SIZE, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY = RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY + RADIOLIB_AES128_KEY_SIZE, // 16 bytes
|
||||
|
|
Ładowanie…
Reference in New Issue