diff --git a/pkg/networkserver/mac/link_adr.go b/pkg/networkserver/mac/link_adr.go index b5deae483f..e576cd3ec3 100644 --- a/pkg/networkserver/mac/link_adr.go +++ b/pkg/networkserver/mac/link_adr.go @@ -331,7 +331,7 @@ func HandleLinkADRAns( // rejected. This behavior differs from when the uplink ADR bit is set, in which case the end- // device accepts or rejects the entire command. if macspec.UseADRBit(macState.LorawanVersion) { - rejected = (!adrEnabled && !pld.ChannelMaskAck) || + rejected = !pld.ChannelMaskAck || (adrEnabled && !pld.DataRateIndexAck) || (adrEnabled && !pld.TxPowerIndexAck) } else { diff --git a/pkg/networkserver/mac/link_adr_test.go b/pkg/networkserver/mac/link_adr_test.go index ce69986164..cd30d6b0e8 100644 --- a/pkg/networkserver/mac/link_adr_test.go +++ b/pkg/networkserver/mac/link_adr_test.go @@ -548,6 +548,37 @@ func TestHandleLinkADRAns(t *testing.T) { Error: ErrRequestNotFound.WithAttributes("cid", ttnpb.MACCommandIdentifier_CID_LINK_ADR), AdrEnabled: false, }, + { + Name: "1.0.4/channel mask off/adr disabled/rejected", + Device: &ttnpb.EndDevice{ + FrequencyPlanId: test.EUFrequencyPlanID, + LorawanPhyVersion: ttnpb.PHYVersion_RP002_V1_0_4, + MacState: &ttnpb.MACState{ + LorawanVersion: ttnpb.MACVersion_MAC_V1_0_4, + }, + }, + Expected: &ttnpb.EndDevice{ + FrequencyPlanId: test.EUFrequencyPlanID, + LorawanPhyVersion: ttnpb.PHYVersion_RP002_V1_0_4, + MacState: &ttnpb.MACState{ + LorawanVersion: ttnpb.MACVersion_MAC_V1_0_4, + }, + }, + Payload: &ttnpb.MACCommand_LinkADRAns{ + ChannelMaskAck: false, + DataRateIndexAck: false, + TxPowerIndexAck: false, + }, + Events: events.Builders{ + EvtReceiveLinkADRReject.With(events.WithData(&ttnpb.MACCommand_LinkADRAns{ + ChannelMaskAck: false, + DataRateIndexAck: false, + TxPowerIndexAck: false, + })), + }, + Error: ErrRequestNotFound.WithAttributes("cid", ttnpb.MACCommandIdentifier_CID_LINK_ADR), + AdrEnabled: false, + }, { Name: "1.0.4/channel mask on/adr enabled/rejected", Device: &ttnpb.EndDevice{ @@ -579,6 +610,37 @@ func TestHandleLinkADRAns(t *testing.T) { Error: ErrRequestNotFound.WithAttributes("cid", ttnpb.MACCommandIdentifier_CID_LINK_ADR), AdrEnabled: true, }, + { + Name: "1.0.4/channel mask off/adr enabled/rejected", + Device: &ttnpb.EndDevice{ + FrequencyPlanId: test.EUFrequencyPlanID, + LorawanPhyVersion: ttnpb.PHYVersion_RP002_V1_0_4, + MacState: &ttnpb.MACState{ + LorawanVersion: ttnpb.MACVersion_MAC_V1_0_4, + }, + }, + Expected: &ttnpb.EndDevice{ + FrequencyPlanId: test.EUFrequencyPlanID, + LorawanPhyVersion: ttnpb.PHYVersion_RP002_V1_0_4, + MacState: &ttnpb.MACState{ + LorawanVersion: ttnpb.MACVersion_MAC_V1_0_4, + }, + }, + Payload: &ttnpb.MACCommand_LinkADRAns{ + ChannelMaskAck: false, + DataRateIndexAck: false, + TxPowerIndexAck: false, + }, + Events: events.Builders{ + EvtReceiveLinkADRReject.With(events.WithData(&ttnpb.MACCommand_LinkADRAns{ + ChannelMaskAck: false, + DataRateIndexAck: false, + TxPowerIndexAck: false, + })), + }, + Error: ErrRequestNotFound.WithAttributes("cid", ttnpb.MACCommandIdentifier_CID_LINK_ADR), + AdrEnabled: true, + }, { Name: "1 request/all ack", Device: &ttnpb.EndDevice{