Skip to content

Commit

Permalink
Pass KR920 tests (individually)
Browse files Browse the repository at this point in the history
  • Loading branch information
terrillmoore committed Aug 17, 2019
1 parent bfe662a commit 4a1839c
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 55 deletions.
75 changes: 52 additions & 23 deletions src/lmic/lmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

DEFINE_LMIC;

#define LMIC_ENABLE_TRACE 1
//#define LMIC_ENABLE_TRACE 1

#ifndef LMIC_ENABLE_TRACE
# define LMIC_ENABLE_TRACE 0
Expand Down Expand Up @@ -750,37 +750,60 @@ applyAdrRequests(
u1_t p1 = 0;
u1_t p4 = 0;
bit_t response_fit = 1;
bit_t map_ok = 1;

LMICbandplan_saveAdrState(&initialState);

for (oidx = 0; oidx < olen && response_fit; ) {
if (adrAns == MCMD_LinkADRAns_PowerACK | MCMD_LinkADRAns_DataRateACK | MCMD_LinkADRAns_ChannelACK) {
// compute the changes
if (adrAns == MCMD_LinkADRAns_PowerACK | MCMD_LinkADRAns_DataRateACK | MCMD_LinkADRAns_ChannelACK) {
for (oidx = 0; oidx < olen; oidx += kAdrReqSize) {
// can we advance?
if (olen - oidx < kAdrReqSize) {
// ignore the malformed one at the end
break;
}
u2_t chmap = os_rlsbf2(&opts[oidx+2]);// list of enabled channels

p1 = opts[oidx+1]; // txpow + DR, in case last
p4 = opts[oidx+4]; // ChMaskCtl, NbTrans
u1_t chpage = p4 & MCMD_LinkADRReq_Redundancy_ChMaskCntl_MASK; // channel page

LMICbandplan_mapChannels(chpage, chmap);
map_ok = LMICbandplan_mapChannels(chpage, chmap);
ArduinoLMIC_putEventDatum("applyAdrRequests: mapChannels", (chpage << 16)|(chmap << 0));
}
}

oidx += kAdrReqSize;
if (! map_ok) {
adrAns &= ~MCMD_LinkADRAns_ChannelACK;
LMICbandplan_restoreAdrState(&initialState);
}

// now put all the options
for (oidx = 0; oidx < olen && response_fit; oidx += kAdrReqSize) {
// can we advance?
if (olen - oidx < kAdrReqSize) {
// ignore the malformed one at the end
break;
}
response_fit = put_mac_uplink_byte2(MCMD_LinkADRAns, adrAns);
}

// all done scanning options
bit_t changes = LMICbandplan_compareAdrState(&initialState);

// handle uplink repeat count
u1_t uprpt = p4 & MCMD_LinkADRReq_Redundancy_NbTrans_MASK; // up repeat count
if (LMIC.upRepeat != uprpt) {
LMIC.upRepeat = uprpt;
changes = 1;
}
// handle the final options
if (adrAns == (MCMD_LinkADRAns_PowerACK | MCMD_LinkADRAns_DataRateACK | MCMD_LinkADRAns_ChannelACK)) {
// handle uplink repeat count
u1_t uprpt = p4 & MCMD_LinkADRReq_Redundancy_NbTrans_MASK; // up repeat count
if (LMIC.upRepeat != uprpt) {
LMIC.upRepeat = uprpt;
changes = 1;
}

if (adrAns & MCMD_LinkADRAns_DataRateACK) {
dr_t dr = (dr_t)(p1>>MCMD_LinkADRReq_DR_SHIFT);

ArduinoLMIC_putEventDatum("applyAdrRequests: setDrTxPow", (adrAns << 16)|(dr << 8)|(p1 << 0));

// handle power changes here, too.
changes |= setDrTxpow(DRCHG_NWKCMD, dr, pow2dBm(p1));
}
Expand All @@ -798,6 +821,8 @@ scan_mac_cmds_link_adr(
bit_t *presponse_fit
)
{
ArduinoLMIC_putEventDatum("scan_mac_cmds_link_adr", olen);

if (olen == 0)
return 0;

Expand Down Expand Up @@ -867,6 +892,15 @@ scan_mac_cmds(

response_fit = 1;
cmd = opts[oidx];

/* compute length, and exit for illegal commands */
int const cmdlen = getMacCmdSize(cmd);
if (cmdlen > olen - oidx) {
// "the first unknown command terminates processing"
olen = oidx;
break;
}

switch( cmd ) {
case MCMD_LinkCheckAns: {
// TODO([email protected]) capture these, reliably..
Expand Down Expand Up @@ -1119,17 +1153,12 @@ scan_mac_cmds(
} /* end case */
} /* end switch */

/* compute length, and exit for illegal commands */
int const cmdlen = getMacCmdSize(cmd);
if (cmdlen == 0) {
// "the first unknown command terminates processing"
// force olen to current oidx so we'll exit the while().
olen = oidx;
} else if (! response_fit) {
olen = oidx;
}

oidx += cmdlen;
/* if we're out of spce for responses, skip to end. */
if (! response_fit) {
olen = oidx;
} else {
oidx += cmdlen;
}
} /* end while */

return oidx;
Expand Down
2 changes: 2 additions & 0 deletions src/lmic/lmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are imm

struct lmic_saved_adr_state_s {
u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits
u2_t activeChannels125khz;
u2_t activeChannels500khz;
};

#endif // ==========================================================================
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 @@ -158,6 +158,10 @@
# error "LMICbandplan_compareAdrState() not defined by bandplan"
#endif

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

//
// Things common to lmic.c code
//
Expand Down
2 changes: 1 addition & 1 deletion src/lmic/lmic_eu868.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {

int8_t LMICeu868_pow2dBm(uint8_t mcmd_ladr_p1) {
uint8_t const pindex = (mcmd_ladr_p1&MCMD_LinkADRReq_POW_MASK)>>MCMD_LinkADRReq_POW_SHIFT;
if (pindex < sizeof(constant_table_TXPOWLEVELS)) {
if (pindex < LENOF_TABLE(TXPOWLEVELS)) {
return TABLE_GET_S1(TXPOWLEVELS, pindex);
} else {
return -128;
Expand Down
46 changes: 27 additions & 19 deletions src/lmic/lmic_eu_like.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,11 @@ bit_t LMICeulike_canMapChannels(u1_t chpage, u2_t chmap) {
}
}

// assumes that LMICeulike_canMapChannels passed. Return true if something changed.
// chpage is 0 or 6; 6 turns all on; 0 selects channels 0..15 via mask.
// assumes that LMICeulike_canMapChannels passed. Return true if this would
// be a valid final configuration.
// chpage is 0 or 0x60; 0x60 turns all on; 0 selects channels 0..15 via mask.
// Assumes canMapChannels has already approved this change.
bit_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {
u2_t const old_chmap = LMIC.channelMap;

switch (chpage) {
case MCMD_LinkADRReq_ChMaskCntl_EULIKE_DIRECT:
LMIC.channelMap = chmap;
Expand All @@ -106,7 +105,7 @@ bit_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {
// do nothing.
break;
}
return old_chmap != chmap;
return LMIC.channelMap != 0;
}

#if !defined(DISABLE_JOIN)
Expand Down Expand Up @@ -159,12 +158,12 @@ ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
LMIC.txChnl = 0;
if ((++LMIC.txCnt % nDefaultChannels) == 0) {
// Lower DR every nth try (having all default channels with same DR)
//
// TODO([email protected]) add new DR_REGIN_JOIN_MIN instead of LORAWAN_DR0;
// then we can eliminate the LMIC_REGION_as923 below because we'll set
// the failed flag here. This will cause the outer caller to take the
// appropriate join path. Or add new LMICeulike_GetLowestJoinDR()
//
//
// TODO([email protected]) add new DR_REGIN_JOIN_MIN instead of LORAWAN_DR0;
// then we can eliminate the LMIC_REGION_as923 below because we'll set
// the failed flag here. This will cause the outer caller to take the
// appropriate join path. Or add new LMICeulike_GetLowestJoinDR()
//
if (LMIC.datarate == LORAWAN_DR0)
failed = 1; // we have tried all DR - signal EV_JOIN_FAILED
else
Expand All @@ -185,12 +184,12 @@ ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
// Duty cycle is based on txend.
ostime_t const time = LMICbandplan_nextJoinTime(os_getTime());

// TODO([email protected]): change delay to (0:1) secs + a known t0, but randomized;
// TODO([email protected]): change delay to (0:1) secs + a known t0, but randomized;
// starting adding a bias after 1 hour, 25 hours, etc.; and limit the duty
// cycle on power up. For testability, add a way to set the join start time
// externally (a test API) so we can check this feature.
// See https://github.com/mcci-catena/arduino-lmic/issues/2
// Current code doesn't match LoRaWAN 1.0.2 requirements.
// Current code doesn't match LoRaWAN 1.0.2 requirements.

LMIC.txend = time +
(isTESTMODE()
Expand All @@ -206,12 +205,12 @@ ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
#endif // !DISABLE_JOIN

void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
memcpy(
pStateBuffer->channelFreq,
LMIC.channelFreq,
sizeof(LMIC.channelFreq)
);
pStateBuffer->channelMap = LMIC.channelMap;
os_copyMem(
pStateBuffer->channelFreq,
LMIC.channelFreq,
sizeof(LMIC.channelFreq)
);
pStateBuffer->channelMap = LMIC.channelMap;
}

bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
Expand All @@ -220,6 +219,15 @@ bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
return pStateBuffer->channelMap != LMIC.channelMap;
}

void LMICeulike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
os_copyMem(
LMIC.channelFreq,
pStateBuffer->channelFreq,
sizeof(LMIC.channelFreq)
);
LMIC.channelMap = pStateBuffer->channelMap;
}

void LMICeulike_setRx1Freq(void) {
#if !defined(DISABLE_MCMD_DlChannelReq)
uint32_t dlFreq = LMIC.channelDlFreq[LMIC.txChnl];
Expand Down
3 changes: 3 additions & 0 deletions src/lmic/lmic_eu_like.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ void LMICeulike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer);
bit_t LMICeulike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer);
#define LMICbandplan_compareAdrState(pState) LMICeulike_compareAdrState(pState)

void LMICeulike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer);
#define LMICbandplan_restoreAdrState(pState) LMICeulike_restoreAdrState(pState)

// set Rx1 frequency (might be different than uplink).
void LMICeulike_setRx1Freq(void);

Expand Down
2 changes: 1 addition & 1 deletion src/lmic/lmic_in866.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {

int8_t LMICin866_pow2dBm(uint8_t mcmd_ladr_p1) {
uint8_t const pindex = (mcmd_ladr_p1&MCMD_LinkADRReq_POW_MASK)>>MCMD_LinkADRReq_POW_SHIFT;
if (pindex < sizeof(constant_table_TXPOWLEVELS)) {
if (pindex < LENOF_TABLE(TXPOWLEVELS)) {
return TABLE_GET_S1(TXPOWLEVELS, pindex);
} else {
return -128;
Expand Down
2 changes: 1 addition & 1 deletion src/lmic/lmic_kr920.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {

int8_t LMICkr920_pow2dBm(uint8_t mcmd_ladr_p1) {
uint8_t const pindex = (mcmd_ladr_p1&MCMD_LinkADRReq_POW_MASK)>>MCMD_LinkADRReq_POW_SHIFT;
if (pindex < sizeof(constant_table_TXPOWLEVELS)) {
if (pindex < LENOF_TABLE(TXPOWLEVELS)) {
return TABLE_GET_S1(TXPOWLEVELS, pindex);
} else {
return -128;
Expand Down
33 changes: 23 additions & 10 deletions src/lmic/lmic_us_like.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ bit_t LMICuslike_canMapChannels(u1_t chpage, u2_t chmap) {
return 1;
}

// map channels. return true if configuration looks valid.
bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
/*
|| MCMD_LinkADRReq_ChMaskCntl_USLIKE_125ON and MCMD_LinkADRReq_ChMaskCntl_USLIKE_125OFF are special. The
Expand All @@ -138,19 +139,18 @@ bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
|| is also special, in that it enables subbands.
*/
u1_t base, top;
bit_t result = 0;

if (chpage == MCMD_LinkADRReq_ChMaskCntl_USLIKE_BANK) {
// each bit enables a bank of channels
for (u1_t subband = 0; subband < 8; ++subband, chmap >>= 1) {
if (chmap & 1) {
result |= LMIC_enableSubBand(subband);
LMIC_enableSubBand(subband);
} else {
result |= LMIC_disableSubBand(subband);
LMIC_disableSubBand(subband);
}
}

return result;
return LMIC.activeChannels125khz || LMIC.activeChannels500khz;
}

if (chpage < MCMD_LinkADRReq_ChMaskCntl_USLIKE_SPECIAL) {
Expand All @@ -167,9 +167,9 @@ bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
// enable or disable all 125kHz channels
for (u1_t chnl = 0; chnl < 64; ++chnl) {
if (en125)
result |= LMIC_enableChannel(chnl);
LMIC_enableChannel(chnl);
else
result |= LMIC_disableChannel(chnl);
LMIC_disableChannel(chnl);
}

// then apply mask to top 8 channels.
Expand All @@ -181,11 +181,11 @@ bit_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
// Use enable/disable channel to keep activeChannel counts in sync.
for (u1_t chnl = base; chnl < top; ++chnl, chmap >>= 1) {
if (chmap & 0x0001)
result |= LMIC_enableChannel(chnl);
LMIC_enableChannel(chnl);
else
result |= LMIC_disableChannel(chnl);
LMIC_disableChannel(chnl);
}
return result;
return LMIC.activeChannels125khz || LMIC.activeChannels500khz;
}

// US does not have duty cycling - return now as earliest TX time
Expand Down Expand Up @@ -288,13 +288,26 @@ ostime_t LMICuslike_nextJoinState(void) {
#endif

void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer) {
memcpy(
os_copyMem(
pStateBuffer->channelMap,
LMIC.channelMap,
sizeof(LMIC.channelMap)
);
pStateBuffer->activeChannels125khz = LMIC.activeChannels125khz;
pStateBuffer->activeChannels500khz = LMIC.activeChannels500khz;
}

void LMICuslike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
os_copyMem(
LMIC.channelMap,
pStateBuffer->channelMap,
sizeof(LMIC.channelMap)
);
LMIC.activeChannels125khz = pStateBuffer->activeChannels125khz;
LMIC.activeChannels500khz = pStateBuffer->activeChannels500khz;
}


bit_t LMICuslike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer) {
return memcmp(pStateBuffer->channelMap, LMIC.channelMap, sizeof(LMIC.channelMap)) != 0;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lmic/lmic_us_like.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,7 @@ void LMICuslike_saveAdrState(lmic_saved_adr_state_t *pStateBuffer);
bit_t LMICuslike_compareAdrState(const lmic_saved_adr_state_t *pStateBuffer);
#define LMICbandplan_compareAdrState(pState) LMICuslike_compareAdrState(pState)

void LMICuslike_restoreAdrState(const lmic_saved_adr_state_t *pStateBuffer);
#define LMICbandplan_restoreAdrState(pState) LMICuslike_restoreAdrState(pState)

#endif // _lmic_us_like_h_

0 comments on commit 4a1839c

Please sign in to comment.