Skip to content

Commit

Permalink
Fix #739: fix #740: improve JoinAccept CFList processing
Browse files Browse the repository at this point in the history
  • Loading branch information
terrillmoore committed May 31, 2021
1 parent f35e6e3 commit acdb503
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 17 deletions.
18 changes: 3 additions & 15 deletions src/lmic/lmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1621,21 +1621,9 @@ static bit_t processJoinAccept (void) {
// initDefaultChannels(0) for EU-like, nothing otherwise
LMICbandplan_joinAcceptChannelClear();

if (!LMICbandplan_hasJoinCFlist() && dlen > LEN_JA) {
// if no JoinCFList, we're supposed to continue
// the join per 2.2.5 of LoRaWAN regional 2.2.4
// https://github.com/mcci-catena/arduino-lmic/issues/19
} else if ( LMICbandplan_hasJoinCFlist() && dlen > LEN_JA ) {
dlen = OFF_CFLIST;
for( u1_t chidx=3; chidx<8; chidx++, dlen+=3 ) {
u4_t freq = LMICbandplan_convFreq(&LMIC.frame[dlen]);
if( freq ) {
LMIC_setupChannel(chidx, freq, 0, -1);
#if LMIC_DEBUG_LEVEL > 1
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Setup channel, idx=%d, freq=%"PRIu32"\n", os_getTime(), chidx, freq);
#endif
}
}
// process the CFList if present
if (dlen == LEN_JAEXT) {
LMICbandplan_processJoinAcceptCFList();
}

// already incremented when JOIN REQ got sent off
Expand Down
4 changes: 4 additions & 0 deletions src/lmic/lmic_bandplan.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@
# error "LMICbandplan_validDR() not defined by bandplan"
#endif

#if !defined(LMICbandplan_processJoinAcceptCFList)
# error "LMICbandplan_processJoinAcceptCFList() not defined by bandplan"
#endif

//
// Things common to lmic.c code
//
Expand Down
20 changes: 20 additions & 0 deletions src/lmic/lmic_eu_like.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,26 @@ ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
}
#endif // !DISABLE_JOIN

#if !defined(DISABLE_JOIN)
void LMICeulike_processJoinAcceptCFList(void) {
if ( LMICbandplan_hasJoinCFlist() &&
LMIC.frame[OFF_CFLIST + 15] == LORAWAN_JoinAccept_CFListType_FREQUENCIES) {
u1_t dlen;
u1_t nDefault = LMIC_queryNumDefaultChannels();

dlen = OFF_CFLIST;
for( u1_t chidx = nDefault; chidx < nDefault + 5; chidx++, dlen+=3 ) {
u4_t freq = LMICbandplan_convFreq(&LMIC.frame[dlen]);
if( freq ) {
LMIC_setupChannel(chidx, freq, 0, -1);
#if LMIC_DEBUG_LEVEL > 1
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Setup channel, idx=%d, freq=%"PRIu32"\n", os_getTime(), chidx, freq);
#endif
}
}
}
#endif // !DISABLE_JOIN

void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
os_copyMem(
pStateBuffer->channelFreq,
Expand Down
5 changes: 5 additions & 0 deletions src/lmic/lmic_eu_like.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ enum { BAND_MILLI = 0, BAND_CENTI = 1, BAND_DECI = 2, BAND_AUX = 3 };
// there's a CFList on joins for EU-like plans
#define LMICbandplan_hasJoinCFlist() (1)

/// \brief process CFLists from JoinAccept for EU-like regions
void LMICeulike_processJoinAcceptCFList(void);
/// \brief by default, EU-like plans use LMICeulike_processJoinAcceptCFList
#define LMICbandplan_processJoinAcceptCFList LMICeulike_processJoinAcceptCFList

#define LMICbandplan_advanceBeaconChannel() \
do { /* nothing */ } while (0)

Expand Down
26 changes: 26 additions & 0 deletions src/lmic/lmic_us_like.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,32 @@ ostime_t LMICuslike_nextJoinState(void) {
}
#endif

#if !defined(DISABLE_JOIN)
void LMICuslike_processJoinAcceptCFList(void) {
if ( LMICbandplan_hasJoinCFlist() &&
LMIC.frame[OFF_CFLIST + 15] == LORAWAN_JoinAccept_CFListType_MASK ) {
u1_t dlen;

dlen = OFF_CFLIST;
for( u1_t chidx = 0; chidx < 8 * sizeof(LMIC.channelMap); chidx += 16, dlen += 2 ) {
u2_t mask = os_rlsbf2(&LMIC.frame[dlen]);
#if LMIC_DEBUG_LEVEL > 1
LMIC_DEBUG_PRINTF("%"LMIC_PRId_ostime_t": Setup channel mask, group=%u, mask=%04x\n", os_getTime(), chidx, mask);
#endif
for ( u1_t chnum = chidx; chnum < chidx + 16; ++chnum, mask >>= 1) {
if (chnum >= 72) {
break;
} else if (mask & 1) {
LMIC_enableChannel(chnum);
} else {
LMIC_disableChannel(chnum);
}
}
}
}
}
#endif // !DISABLE_JOIN

void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
os_copyMem(
pStateBuffer->channelMap,
Expand Down
10 changes: 8 additions & 2 deletions src/lmic/lmic_us_like.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,14 @@ LMICuslike_isValidBeacon1(const uint8_t *d) {
// provide a default LMICbandplan_joinAcceptChannelClear()
#define LMICbandplan_joinAcceptChannelClear() do { } while (0)

// no CFList on joins for US-like plans
#define LMICbandplan_hasJoinCFlist() (0)
/// \brief there's a CFList on joins for US-like plans
#define LMICbandplan_hasJoinCFlist() (1)

/// \brief process CFLists from JoinAccept for EU-like regions
void LMICuslike_processJoinAcceptCFList(void);
/// \brief by default, EU-like plans use LMICuslike_processJoinAcceptCFList
#define LMICbandplan_processJoinAcceptCFList LMICuslike_processJoinAcceptCFList


#define LMICbandplan_advanceBeaconChannel() \
do { LMIC.bcnChnl = (LMIC.bcnChnl+1) & 7; } while (0)
Expand Down
7 changes: 7 additions & 0 deletions src/lmic/lorabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,13 @@ enum {
LEN_JA = 17,
LEN_JAEXT = 17+16
};

enum {
// JoinAccept CFList types
LORAWAN_JoinAccept_CFListType_FREQUENCIES = 0, ///< the CFList contains 5 frequencies
LORAWAN_JoinAccept_CFListType_MASK = 1, ///< the CFList contains channel-mask data
};

enum {
// Data frame format
OFF_DAT_HDR = 0,
Expand Down

0 comments on commit acdb503

Please sign in to comment.