Bleeding edge development version of the mDot library for mbed 5. This version of the library is not guaranteed to be stable or well tested and should not be used in production or deployment scenarios.

Dependents:   mDot-IKS01A1 mDot-IKS01A1 mDot-Examples mDot-IKS01A1-Explora ... more

Fork of libmDot-dev-mbed2-deprecated by MultiTech

The Dot library provides a LoRaWan certified stack for LoRa communication using MultiTech mDot and xDot devices. The stack is compatible with mbed 5.

Dot Library Version 3 Updates

Dot Library versions 3.x.x require a channel plan to be injected into the stack. Channel plans are included with the 3.x.x Dot Library releases. The following code snippet demonstrates how to create a channel plan and inject it into the stack.

#include "mDot.h"
#include "channel_plans.h"

int main() {
    ChannelPlan* plan = new lora::ChannelPlan_US915();
    assert(plan);
    mDot* dot = mDot::getInstance(plan);
    assert(dot);

    // ...
}

Dot devices must not be deployed with software using a different channel plan than the Dot's default plan! This functionality is for development and testing only!

Multicast Sessions

Multicast sessions and packet rx events in library. When in Class C mode Multicast downlinks can be received. Recieved packets should be filtered on address, counter value will be maintained in the session or can be set explicitly depending on Application support to share Multicast Address, Keys and Counters.

mDot.h

        /**
         * Add a multicast session address and keys
         * Downlink counter is set to 0
         * Up to 3 MULTICAST_SESSIONS can be set
         */
        int32_t setMulticastSession(uint8_t index, uint32_t addr, const uint8_t* nsk, const uint8_t* dsk);
 
        /**
         * Set a multicast session counter
         * Up to 3 MULTICAST_SESSIONS can be set
         */
        int32_t setMulticastDownlinkCounter(uint8_t index, uint32_t count);

mDotEvent.h

The address field was added to PacketRx event.

        virtual void PacketRx(uint8_t port, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot, uint8_t retries, uint32_t address);

The name of the repository can be used to determine which device the stack was compiled for and if it's a development or production-ready build:

A changelog for the Dot library can be found here.

The Dot library version and the version of mbed-os it was compiled against can both be found in the commit message for that revision of the Dot library. Building your application with the same version of mbed-os as what was used to build the Dot library is highly recommended!

The Dot-Examples repository demonstrates how to use the Dot library in a custom application.

The mDot and xDot platform pages have lots of platform specific information and document potential issues, gotchas, etc, and provide instructions for getting started with development. Please take a look at the platform page before starting development as they should answer many questions you will have.

Committer:
Jenkins@KEILDM1.dc.multitech.prv
Date:
Fri Oct 26 16:14:07 2018 -0500
Revision:
183:f205b2eea7c2
Parent:
181:220e42003ef7
mdot-library revision 3.1.0-49-g926b83a and mbed-os revision mbed-os-5.9.6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1 /**********************************************************************
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 2 * COPYRIGHT 2016 MULTI-TECH SYSTEMS, INC.
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 3 *
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 4 * ALL RIGHTS RESERVED BY AND FOR THE EXCLUSIVE BENEFIT OF
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 5 * MULTI-TECH SYSTEMS, INC.
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 6 *
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 7 * MULTI-TECH SYSTEMS, INC. - CONFIDENTIAL AND PROPRIETARY
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 8 * INFORMATION AND/OR TRADE SECRET.
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 9 *
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 10 * NOTICE: ALL CODE, PROGRAM, INFORMATION, SCRIPT, INSTRUCTION,
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 11 * DATA, AND COMMENT HEREIN IS AND SHALL REMAIN THE CONFIDENTIAL
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 12 * INFORMATION AND PROPERTY OF MULTI-TECH SYSTEMS, INC.
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 13 * USE AND DISCLOSURE THEREOF, EXCEPT AS STRICTLY AUTHORIZED IN A
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 14 * WRITTEN AGREEMENT SIGNED BY MULTI-TECH SYSTEMS, INC. IS PROHIBITED.
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 15 *
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 16 ***********************************************************************/
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 17
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 18 #include "ChannelPlan_RU864.h"
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 19 #include "limits.h"
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 20
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 21 using namespace lora;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 22
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 23 // MWF - changed RU864_TX_POWERS to match final 1.0.2 regional spec
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 24 const uint8_t ChannelPlan_RU864::RU864_TX_POWERS[] = { 16, 14, 12, 10, 8, 6, 4, 2 };
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 25 const uint8_t ChannelPlan_RU864::RU864_RADIO_POWERS[] = { 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20 };
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 26 const uint8_t ChannelPlan_RU864::RU864_MAX_PAYLOAD_SIZE[] = { 51, 51, 51, 115, 242, 242, 242, 242, 0, 0, 0, 0, 0, 0, 0, 0 };
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 27 const uint8_t ChannelPlan_RU864::RU864_MAX_PAYLOAD_SIZE_REPEATER[] = { 51, 51, 51, 115, 222, 222, 222, 222, 0, 0, 0, 0, 0, 0, 0, 0 };
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 28
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 29 ChannelPlan_RU864::ChannelPlan_RU864()
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 30 :
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 31 ChannelPlan(NULL, NULL)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 32 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 33
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 34 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 35
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 36 ChannelPlan_RU864::ChannelPlan_RU864(Settings* settings)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 37 :
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 38 ChannelPlan(NULL, settings)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 39 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 40
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 41 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 42
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 43 ChannelPlan_RU864::ChannelPlan_RU864(SxRadio* radio, Settings* settings)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 44 :
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 45 ChannelPlan(radio, settings)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 46 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 47
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 48 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 49
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 50 ChannelPlan_RU864::~ChannelPlan_RU864() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 51
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 52 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 53
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 54 void ChannelPlan_RU864::Init() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 55
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 56 _datarates.clear();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 57 _channels.clear();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 58 _dutyBands.clear();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 59
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 60 DutyBand band;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 61
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 62 band.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 63 band.DutyCycle = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 64
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 65 Datarate dr;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 66
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 67 _plan = RU864;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 68 _planName = "RU864";
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 69 _maxTxPower = 27;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 70 _minTxPower = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 71
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 72 _minFrequency = RU864_FREQ_MIN;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 73 _maxFrequency = RU864_FREQ_MAX;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 74
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 75 TX_POWERS = RU864_TX_POWERS;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 76 RADIO_POWERS = RU864_RADIO_POWERS;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 77 MAX_PAYLOAD_SIZE = RU864_MAX_PAYLOAD_SIZE;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 78 MAX_PAYLOAD_SIZE_REPEATER = RU864_MAX_PAYLOAD_SIZE_REPEATER;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 79
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 80 _minDatarate = RU864_MIN_DATARATE;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 81 _maxDatarate = RU864_MAX_DATARATE;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 82
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 83 _minRx2Datarate = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 84 _maxRx2Datarate = DR_7;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 85
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 86 _minDatarateOffset = RU864_MIN_DATARATE_OFFSET;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 87 _maxDatarateOffset = RU864_MAX_DATARATE_OFFSET;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 88
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 89 _numChans125k = RU864_125K_NUM_CHANS;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 90 _numChans500k = 0;
Jenkins@KEILDM1.dc.multitech.prv 183:f205b2eea7c2 91 _numDefaultChans = RU864_DEFAULT_NUM_CHANS;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 92
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 93 GetSettings()->Session.Rx2Frequency = RU864_RX2_FREQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 94 GetSettings()->Session.Rx2DatarateIndex = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 95
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 96 GetSettings()->Session.BeaconFrequency = RU864_BEACON_FREQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 97 GetSettings()->Session.BeaconFreqHop = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 98 GetSettings()->Session.PingSlotFrequency = RU864_PING_SLOT_FREQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 99 GetSettings()->Session.PingSlotDatarateIndex = RU864_BEACON_DR;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 100 GetSettings()->Session.PingSlotFreqHop = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 101
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 102 logInfo("Initialize datarates...");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 103
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 104 dr.SpreadingFactor = SF_12;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 105
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 106 // Add DR0-5
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 107 while (dr.SpreadingFactor >= SF_7) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 108 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 109 dr.SpreadingFactor--;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 110 dr.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 111 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 112
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 113 // Add DR6
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 114 dr.SpreadingFactor = SF_7;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 115 dr.Bandwidth = BW_250;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 116 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 117 dr.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 118
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 119 // Add DR7
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 120 dr.SpreadingFactor = SF_FSK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 121 dr.Bandwidth = BW_FSK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 122 dr.PreambleLength = 10;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 123 dr.Coderate = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 124 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 125 dr.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 126
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 127 _maxDatarate = DR_7;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 128
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 129 // Skip DR8-15 RFU
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 130 dr.SpreadingFactor = SF_INVALID;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 131 while (dr.Index++ <= DR_15) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 132 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 133 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 134
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 135 GetSettings()->Session.TxDatarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 136
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 137 logInfo("Initialize channels...");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 138
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 139 Channel chan;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 140 chan.DrRange.Fields.Min = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 141 chan.DrRange.Fields.Max = DR_5;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 142 chan.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 143 chan.Frequency = RU864_125K_FREQ_BASE;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 144 SetNumberOfChannels(RU864_125K_NUM_CHANS);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 145
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 146 for (uint8_t i = 0; i < RU864_DEFAULT_NUM_CHANS; i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 147 chan.DrRange.Fields.Max = DR_5;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 148
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 149 AddChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 150 chan.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 151 chan.Frequency += RU864_125K_FREQ_STEP;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 152 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 153
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 154 chan.DrRange.Value = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 155 chan.Frequency = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 156
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 157 for (uint8_t i = RU864_DEFAULT_NUM_CHANS; i < RU864_125K_NUM_CHANS; i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 158 AddChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 159 chan.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 160 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 161
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 162 // Add downlink channel defaults
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 163 chan.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 164 _dlChannels.resize(16);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 165 for (uint8_t i = 0; i < 16; i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 166 AddDownlinkChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 167 chan.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 168 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 169
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 170 SetChannelMask(0, 0x07);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 171
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 172 band.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 173 band.FrequencyMin = RU864_MILLI_FREQ_MIN;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 174 band.FrequencyMax = RU864_MILLI_FREQ_MAX;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 175 band.PowerMax = 14;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 176 band.TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 177
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 178 band.DutyCycle = 1000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 179
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 180 AddDutyBand(-1, band);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 181
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 182 band.Index++;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 183 band.FrequencyMin = RU864_MILLI_FREQ_MAX;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 184 band.FrequencyMax = RU864_FREQ_MAX;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 185 band.PowerMax = 14;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 186 band.TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 187 band.DutyCycle = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 188
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 189 AddDutyBand(-1, band);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 190
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 191 GetSettings()->Session.TxPower = GetSettings()->Network.TxPower;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 192 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 193
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 194 uint8_t ChannelPlan_RU864::AddChannel(int8_t index, Channel channel) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 195 logTrace("Add Channel %d : %lu : %02x %d", index, channel.Frequency, channel.DrRange.Value, _channels.size());
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 196
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 197 assert(index < (int) _channels.size());
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 198
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 199 if (index >= 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 200 _channels[index] = channel;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 201 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 202 _channels.push_back(channel);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 203 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 204
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 205 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 206 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 207
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 208 uint8_t ChannelPlan_RU864::HandleJoinAccept(const uint8_t* buffer, uint8_t size) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 209
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 210 if (size == 33) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 211 Channel ch;
Jenkins@KEILDM1.dc.multitech.prv 181:220e42003ef7 212 int index = 2;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 213 for (int i = 13; i < size - 5; i += 3) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 214
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 215 ch.Frequency = ((buffer[i]) | (buffer[i + 1] << 8) | (buffer[i + 2] << 16)) * 100u;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 216
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 217 if (ch.Frequency > 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 218 ch.Index = index;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 219 ch.DrRange.Fields.Min = static_cast<int8_t>(DR_0);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 220 ch.DrRange.Fields.Max = static_cast<int8_t>(DR_5);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 221 AddChannel(index, ch);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 222
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 223 if (GetDutyBand(ch.Frequency) > -1)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 224 _channelMask[0] |= (1 << index);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 225 else
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 226 _channelMask[0] |= ~(1 << index);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 227
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 228 index += 1;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 229 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 230 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 231 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 232
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 233 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 234 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 235
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 236 uint8_t ChannelPlan_RU864::SetTxConfig() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 237
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 238 logInfo("Configure radio for TX");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 239
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 240 uint8_t band = GetDutyBand(GetChannel(_txChannel).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 241 Datarate txDr = GetDatarate(GetSettings()->Session.TxDatarate);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 242 int8_t max_pwr = _dutyBands[band].PowerMax;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 243
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 244 int8_t pwr = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 245
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 246 pwr = std::min < int8_t > (GetSettings()->Session.TxPower, max_pwr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 247 pwr -= GetSettings()->Network.AntennaGain;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 248
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 249 for (int i = 20; i >= 0; i--) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 250 if (RADIO_POWERS[i] <= pwr) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 251 pwr = i;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 252 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 253 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 254 if (i == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 255 pwr = i;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 256 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 257 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 258
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 259 logDebug("Session pwr: %d ant: %d max: %d", GetSettings()->Session.TxPower, GetSettings()->Network.AntennaGain, max_pwr);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 260 logDebug("Radio Power index: %d output: %d total: %d", pwr, RADIO_POWERS[pwr], RADIO_POWERS[pwr] + GetSettings()->Network.AntennaGain);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 261
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 262 uint32_t bw = txDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 263 uint32_t sf = txDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 264 uint8_t cr = txDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 265 uint8_t pl = txDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 266 uint16_t fdev = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 267 bool crc = txDr.Crc;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 268 bool iq = txDr.TxIQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 269
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 270 if (GetSettings()->Network.DisableCRC == true)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 271 crc = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 272
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 273 SxRadio::RadioModems_t modem = SxRadio::MODEM_LORA;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 274
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 275 if (sf == SF_FSK) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 276 modem = SxRadio::MODEM_FSK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 277 sf = 50e3;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 278 fdev = 25e3;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 279 bw = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 280 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 281
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 282 GetRadio()->SetTxConfig(modem, pwr, fdev, bw, sf, cr, pl, false, crc, false, 0, iq, 3e3);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 283
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 284 logDebug("TX PWR: %u DR: %u SF: %u BW: %u CR: %u PL: %u CRC: %d IQ: %d", pwr, txDr.Index, sf, bw, cr, pl, crc, iq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 285
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 286 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 287 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 288
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 289 uint8_t ChannelPlan_RU864::SetRxConfig(uint8_t window, bool continuous, uint16_t wnd_growth) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 290
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 291 RxWindow rxw = GetRxWindow(window);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 292
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 293 if (_dlChannels[_txChannel].Frequency != 0 && window == 1)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 294 GetRadio()->SetChannel(_dlChannels[_txChannel].Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 295 else
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 296 GetRadio()->SetChannel(rxw.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 297
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 298 Datarate rxDr = GetDatarate(rxw.DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 299 uint32_t bw = rxDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 300 uint32_t sf = rxDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 301 uint8_t cr = rxDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 302 uint8_t pl = rxDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 303 uint16_t sto = rxDr.SymbolTimeout() * wnd_growth;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 304 uint32_t afc = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 305 bool fixLen = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 306 uint8_t payloadLen = 0U;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 307 bool crc = false; // downlink does not use CRC according to LORAWAN
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 308
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 309 if (GetSettings()->Network.DisableCRC == true)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 310 crc = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 311
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 312 Datarate txDr = GetDatarate(GetSettings()->Session.TxDatarate);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 313 bool iq = txDr.RxIQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 314
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 315 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 316 iq = txDr.TxIQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 317 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 318
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 319 // Beacon modifications - no I/Q inversion, fixed length rx, preamble
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 320 if (window == RX_BEACON) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 321 iq = txDr.TxIQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 322 fixLen = true;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 323 payloadLen = sizeof(BCNPayload);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 324 pl = BEACON_PREAMBLE_LENGTH;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 325 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 326
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 327 SxRadio::RadioModems_t modem = SxRadio::MODEM_LORA;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 328
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 329 if (sf == SF_FSK) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 330 modem = SxRadio::MODEM_FSK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 331 sf = 50e3;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 332 cr = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 333 bw = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 334 afc = 83333;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 335 iq = false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 336 crc = true; // FSK must use CRC
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 337 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 338
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 339 // Disable printf's to actually receive packets, printing to debug may mess up the timing
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 340 // logTrace("Configure radio for RX%d on freq: %lu", window, rxw.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 341 // logTrace("RX SF: %u BW: %u CR: %u PL: %u STO: %u CRC: %d IQ: %d", sf, bw, cr, pl, sto, crc, iq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 342
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 343 GetRadio()->SetRxConfig(modem, bw, sf, cr, afc, pl, sto, fixLen, payloadLen, crc, false, 0, iq, continuous);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 344
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 345 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 346 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 347
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 348 Channel ChannelPlan_RU864::GetChannel(int8_t index) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 349 Channel chan;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 350 memset(&chan, 0, sizeof(Channel));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 351
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 352 chan = _channels[index];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 353
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 354 return chan;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 355 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 356
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 357 uint8_t ChannelPlan_RU864::SetFrequencySubBand(uint8_t sub_band) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 358 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 359 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 360
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 361 void ChannelPlan_RU864::LogRxWindow(uint8_t wnd) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 362
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 363 RxWindow rxw = GetRxWindow(wnd);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 364 Datarate rxDr = GetDatarate(rxw.DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 365 uint8_t bw = rxDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 366 uint8_t sf = rxDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 367 uint8_t cr = rxDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 368 uint8_t pl = rxDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 369 uint16_t sto = rxDr.SymbolTimeout();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 370 bool crc = false; // downlink does not use CRC according to LORAWAN
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 371 bool iq = GetTxDatarate().RxIQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 372 uint32_t freq = rxw.Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 373
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 374 if (wnd == 1 && _dlChannels[_txChannel].Frequency != 0)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 375 freq = _dlChannels[_txChannel].Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 376
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 377 logTrace("RX%d on freq: %lu", wnd, freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 378 logTrace("RX DR: %u SF: %u BW: %u CR: %u PL: %u STO: %u CRC: %d IQ: %d", rxDr.Index, sf, bw, cr, pl, sto, crc, iq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 379 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 380
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 381 RxWindow ChannelPlan_RU864::GetRxWindow(uint8_t window) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 382 RxWindow rxw;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 383 int index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 384
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 385 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 386 rxw.Frequency = GetSettings()->Network.TxFrequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 387 index = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 388 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 389 switch (window) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 390 case RX_1:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 391 rxw.Frequency = _channels[_txChannel].Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 392
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 393 if (GetSettings()->Session.TxDatarate > GetSettings()->Session.Rx1DatarateOffset) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 394 index = GetSettings()->Session.TxDatarate - GetSettings()->Session.Rx1DatarateOffset;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 395 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 396 index = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 397 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 398
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 399 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 400
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 401 case RX_BEACON:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 402 rxw.Frequency = GetSettings()->Session.BeaconFrequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 403 index = RU864_BEACON_DR;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 404 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 405
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 406 case RX_SLOT:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 407 rxw.Frequency = GetSettings()->Session.PingSlotFrequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 408 index = GetSettings()->Session.PingSlotDatarateIndex;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 409 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 410
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 411 // RX2, RXC, RX_TEST, etc..
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 412 default:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 413 rxw.Frequency = GetSettings()->Session.Rx2Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 414 index = GetSettings()->Session.Rx2DatarateIndex;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 415 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 416 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 417
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 418 rxw.DatarateIndex = index;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 419
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 420 return rxw;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 421 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 422
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 423 uint8_t ChannelPlan_RU864::HandleRxParamSetup(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 424 status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 425 int8_t datarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 426 int8_t drOffset = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 427 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 428
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 429 drOffset = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 430 datarate = drOffset & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 431 drOffset = (drOffset >> 4) & 0x07;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 432
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 433 freq = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 434 freq |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 435 freq |= payload[index++] << 16;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 436 freq *= 100;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 437
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 438 if (!CheckRfFrequency(freq)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 439 logInfo("Freq KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 440 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 441 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 442
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 443 if (datarate < _minRx2Datarate || datarate > _maxRx2Datarate) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 444 logInfo("DR KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 445 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 446 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 447
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 448 if (drOffset < 0 || drOffset > _maxDatarateOffset) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 449 logInfo("DR Offset KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 450 status &= 0xFB; // Rx1DrOffset range KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 451 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 452
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 453 if ((status & 0x07) == 0x07) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 454 logInfo("RxParamSetup accepted Rx2DR: %d Rx2Freq: %d Rx1Offset: %d", datarate, freq, drOffset);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 455 SetRx2DatarateIndex(datarate);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 456 SetRx2Frequency(freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 457 SetRx1Offset(drOffset);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 458 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 459 logInfo("RxParamSetup rejected Rx2DR: %d Rx2Freq: %d Rx1Offset: %d", datarate, freq, drOffset);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 460 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 461
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 462 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 463 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 464
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 465 uint8_t ChannelPlan_RU864::HandleNewChannel(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 466
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 467 status = 0x03;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 468 uint8_t channelIndex = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 469 Channel chParam;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 470
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 471 channelIndex = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 472 lora::CopyFreqtoInt(payload + index, chParam.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 473 index += 3;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 474 chParam.DrRange.Value = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 475
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 476 if (channelIndex < 3 || channelIndex > _channels.size() - 1) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 477 logError("New Channel index KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 478 status &= 0xFE; // Channel index KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 479 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 480
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 481 if (chParam.Frequency == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 482 chParam.DrRange.Value = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 483 } else if (chParam.Frequency < _minFrequency || chParam.Frequency > _maxFrequency) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 484 logError("New Channel frequency KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 485 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 486 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 487
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 488 if (chParam.DrRange.Fields.Min > chParam.DrRange.Fields.Max && chParam.Frequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 489 logError("New Channel datarate min/max KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 490 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 491 } else if ((chParam.DrRange.Fields.Min < _minDatarate || chParam.DrRange.Fields.Min > _maxDatarate) &&
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 492 chParam.Frequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 493 logError("New Channel datarate min KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 494 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 495 } else if ((chParam.DrRange.Fields.Max < _minDatarate || chParam.DrRange.Fields.Max > _maxDatarate) &&
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 496 chParam.Frequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 497 logError("New Channel datarate max KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 498 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 499 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 500
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 501 if ((status & 0x03) == 0x03) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 502 logInfo("New Channel accepted index: %d freq: %lu drRange: %02x", channelIndex, chParam.Frequency, chParam.DrRange.Value);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 503 AddChannel(channelIndex, chParam);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 504 SetChannelMask(0, _channelMask[0] | 1 << (channelIndex));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 505 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 506
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 507 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 508 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 509
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 510 uint8_t ChannelPlan_RU864::HandlePingSlotChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 511 uint8_t datarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 512 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 513
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 514 status = 0x03;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 515
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 516 freq = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 517 freq |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 518 freq |= payload[index++] << 16;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 519 freq *= 100;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 520
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 521 datarate = payload[index] & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 522
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 523 if (freq == 0U) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 524 logInfo("Received request to reset ping slot frequency to default");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 525 freq = RU864_PING_SLOT_FREQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 526 } else if (!CheckRfFrequency(freq)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 527 logInfo("Freq KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 528 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 529 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 530
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 531 if (datarate < _minRx2Datarate || datarate > _maxRx2Datarate) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 532 logInfo("DR KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 533 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 534 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 535
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 536 if ((status & 0x03) == 0x03) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 537 logInfo("PingSlotChannelReq accepted DR: %d Freq: %d", datarate, freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 538 GetSettings()->Session.PingSlotFrequency = freq;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 539 GetSettings()->Session.PingSlotDatarateIndex = datarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 540 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 541 logInfo("PingSlotChannelReq rejected DR: %d Freq: %d", datarate, freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 542 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 543
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 544 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 545 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 546
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 547 uint8_t ChannelPlan_RU864::HandleBeaconFrequencyReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 548 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 549 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 550
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 551 status = 0x01;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 552
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 553 freq = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 554 freq |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 555 freq |= payload[index] << 16;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 556 freq *= 100;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 557
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 558 if (freq == 0U) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 559 logInfo("Received request to reset beacon frequency to default");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 560 freq = RU864_BEACON_FREQ;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 561 } else if (!CheckRfFrequency(freq)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 562 logInfo("Freq KO");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 563 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 564 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 565
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 566 if (status & 0x01) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 567 logInfo("BeaconFrequencyReq accepted Freq: %d", freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 568 GetSettings()->Session.BeaconFrequency = freq;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 569 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 570 logInfo("BeaconFrequencyReq rejected Freq: %d", freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 571 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 572
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 573 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 574 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 575
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 576 uint8_t ChannelPlan_RU864::HandleAdrCommand(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 577
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 578 uint8_t power = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 579 uint8_t datarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 580 uint16_t mask = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 581 uint16_t new_mask = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 582 uint8_t ctrl = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 583 uint8_t nbRep = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 584
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 585 status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 586 datarate = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 587 power = datarate & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 588 datarate = (datarate >> 4) & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 589
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 590 mask = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 591 mask |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 592
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 593 nbRep = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 594 ctrl = (nbRep >> 4) & 0x07;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 595 nbRep &= 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 596
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 597 if (nbRep == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 598 nbRep = 1;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 599 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 600
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 601 if (datarate > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 602 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 603 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 604 //
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 605 // Remark MaxTxPower = 0 and MinTxPower = 7
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 606 //
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 607 if (power > 7) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 608 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 609 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 610
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 611 switch (ctrl) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 612 case 0:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 613 SetChannelMask(0, mask);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 614 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 615
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 616 case 6:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 617 // enable all currently defined channels
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 618 // set bits 0 - N of a number by (2<<N)-1
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 619 new_mask = (1 << _channels.size()) - 1;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 620 SetChannelMask(0, new_mask);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 621 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 622
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 623 default:
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 624 logWarning("rejecting RFU or unknown control value %d", ctrl);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 625 status &= 0xFE; // ChannelMask KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 626 return LORA_ERROR;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 627 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 628
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 629 if (GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 630 GetSettings()->Session.TxDatarate = datarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 631 GetSettings()->Session.TxPower = TX_POWERS[power];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 632 GetSettings()->Session.Redundancy = nbRep;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 633 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 634 logDebug("ADR is disabled, DR and Power not changed.");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 635 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 636 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 637 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 638
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 639 logDebug("ADR DR: %u PWR: %u Ctrl: %02x Mask: %04x NbRep: %u Stat: %02x", datarate, power, ctrl, mask, nbRep, status);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 640
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 641 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 642 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 643
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 644 uint8_t ChannelPlan_RU864::ValidateAdrConfiguration() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 645 uint8_t status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 646 uint8_t datarate = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 647 uint8_t power = GetSettings()->Session.TxPower;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 648
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 649 if (!GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 650 logDebug("ADR disabled - no applied changes to validate");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 651 return status;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 652 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 653
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 654 if (datarate > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 655 logWarning("ADR Datarate KO - outside allowed range");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 656 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 657 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 658 if (power < _minTxPower || power > _maxTxPower) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 659 logWarning("ADR TX Power KO - outside allowed range");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 660 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 661 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 662
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 663 // mask must not contain any undefined channels
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 664 for (int i = 3; i < 16; i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 665 if ((_channelMask[0] & (1 << i)) && (_channels[i].Frequency == 0)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 666 logWarning("ADR Channel Mask KO - cannot enable undefined channel");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 667 status &= 0xFE; // ChannelMask KO
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 668 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 669 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 670 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 671
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 672 return status;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 673 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 674
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 675 uint8_t ChannelPlan_RU864::HandleAckTimeout() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 676
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 677 if (!GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 678 return LORA_ADR_OFF;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 679 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 680
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 681 if ((++(GetSettings()->Session.AckCounter) % 2) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 682 if (GetSettings()->Session.TxPower < GetSettings()->Network.TxPowerMax) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 683 logTrace("ADR Setting power to maximum");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 684 GetSettings()->Session.TxPower = GetSettings()->Network.TxPowerMax;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 685 } else if (GetSettings()->Session.TxDatarate > 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 686 logTrace("ADR Lowering datarate");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 687 (GetSettings()->Session.TxDatarate)--;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 688 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 689 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 690
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 691 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 692 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 693
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 694
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 695 uint32_t ChannelPlan_RU864::GetTimeOffAir()
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 696 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 697 if (GetSettings()->Test.DisableDutyCycle == lora::ON || _LBT_TimeUs > 0)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 698 return 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 699
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 700 uint32_t min = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 701 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 702
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 703
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 704 min = UINT_MAX;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 705 int8_t band = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 706
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 707 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 708 int8_t band = GetDutyBand(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 709 if (_dutyBands[band].TimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 710 min = _dutyBands[band].TimeOffEnd - now;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 711 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 712 min = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 713 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 714 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 715 for (size_t i = 0; i < _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 716 if (IsChannelEnabled(i) && GetChannel(i).Frequency != 0 &&
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 717 !(GetSettings()->Session.TxDatarate < GetChannel(i).DrRange.Fields.Min ||
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 718 GetSettings()->Session.TxDatarate > GetChannel(i).DrRange.Fields.Max)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 719
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 720 band = GetDutyBand(GetChannel(i).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 721 if (band != -1) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 722 // logDebug("band: %d time-off: %d now: %d", band, _dutyBands[band].TimeOffEnd, now);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 723 if (_dutyBands[band].TimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 724 min = std::min < uint32_t > (min, _dutyBands[band].TimeOffEnd - now);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 725 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 726 min = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 727 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 728 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 729 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 730 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 731 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 732 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 733
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 734
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 735 if (GetSettings()->Session.AggregatedTimeOffEnd > 0 && GetSettings()->Session.AggregatedTimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 736 min = std::max < uint32_t > (min, GetSettings()->Session.AggregatedTimeOffEnd - now);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 737 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 738
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 739 now = time(NULL);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 740 uint32_t join_time = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 741
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 742 if (GetSettings()->Session.JoinFirstAttempt != 0 && now < GetSettings()->Session.JoinTimeOffEnd) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 743 join_time = (GetSettings()->Session.JoinTimeOffEnd - now) * 1000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 744 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 745
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 746 min = std::max < uint32_t > (join_time, min);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 747
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 748 return min;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 749 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 750
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 751
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 752 void ChannelPlan_RU864::UpdateDutyCycle(uint32_t freq, uint32_t time_on_air_ms) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 753 if (GetSettings()->Test.DisableDutyCycle == lora::ON || _LBT_TimeUs > 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 754 _dutyCycleTimer.stop();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 755 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 756 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 757 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 758 return;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 759 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 760
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 761 _dutyCycleTimer.start();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 762
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 763 if (GetSettings()->Session.MaxDutyCycle > 0 && GetSettings()->Session.MaxDutyCycle <= 15) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 764 GetSettings()->Session.AggregatedTimeOffEnd = _dutyCycleTimer.read_ms() + time_on_air_ms * GetSettings()->Session.AggregateDutyCycle;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 765 logDebug("Updated Aggregate DCycle Time-off: %lu DC: %f%%", GetSettings()->Session.AggregatedTimeOffEnd, 1 / float(GetSettings()->Session.AggregateDutyCycle));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 766 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 767 GetSettings()->Session.AggregatedTimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 768 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 769
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 770
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 771 uint32_t time_off_air = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 772 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 773
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 774 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 775 if (_dutyBands[i].TimeOffEnd < now) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 776 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 777 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 778 _dutyBands[i].TimeOffEnd -= now;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 779 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 780
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 781 if (freq >= _dutyBands[i].FrequencyMin && freq <= _dutyBands[i].FrequencyMax) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 782 logDebug("update TOE: freq: %d i:%d toa: %d DC:%d", freq, i, time_on_air_ms, _dutyBands[i].DutyCycle);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 783 time_off_air = time_on_air_ms * _dutyBands[i].DutyCycle;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 784 _dutyBands[i].TimeOffEnd = time_off_air;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 785 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 786 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 787
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 788 ResetDutyCycleTimer();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 789 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 790
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 791 std::vector<uint32_t> lora::ChannelPlan_RU864::GetChannels() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 792 std::vector < uint32_t > chans;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 793
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 794 for (int8_t i = 0; i < (int) _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 795 chans.push_back(_channels[i].Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 796 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 797 chans.push_back(GetRxWindow(2).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 798
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 799 return chans;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 800 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 801
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 802 std::vector<uint8_t> lora::ChannelPlan_RU864::GetChannelRanges() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 803 std::vector < uint8_t > ranges;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 804
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 805 for (int8_t i = 0; i < (int) _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 806 ranges.push_back(_channels[i].DrRange.Value);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 807 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 808
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 809 ranges.push_back(GetRxWindow(2).DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 810
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 811 return ranges;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 812
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 813 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 814
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 815 void lora::ChannelPlan_RU864::EnableDefaultChannels() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 816 _channelMask[0] |= 0x0007;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 817 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 818
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 819 uint8_t ChannelPlan_RU864::GetNextChannel()
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 820 {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 821 if (GetSettings()->Session.AggregatedTimeOffEnd != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 822 return LORA_AGGREGATED_DUTY_CYCLE;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 823 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 824
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 825 if (P2PEnabled() || GetSettings()->Network.TxFrequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 826 logDebug("Using frequency %d", GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 827
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 828 if (GetSettings()->Test.DisableDutyCycle != lora::ON && _LBT_TimeUs == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 829 int8_t band = GetDutyBand(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 830 logDebug("band: %d freq: %d", band, GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 831 if (band != -1 && _dutyBands[band].TimeOffEnd != 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 832 return LORA_NO_CHANS_ENABLED;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 833 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 834 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 835
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 836 GetRadio()->SetChannel(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 837 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 838 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 839
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 840 uint8_t start = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 841 uint8_t maxChannels = _numChans125k;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 842 uint8_t nbEnabledChannels = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 843 uint8_t *enabledChannels = new uint8_t[maxChannels];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 844
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 845 if (GetTxDatarate().Bandwidth == BW_500) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 846 maxChannels = _numChans500k;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 847 start = _numChans125k;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 848 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 849
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 850 // Search how many channels are enabled
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 851 DatarateRange range;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 852 uint8_t dr_index = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 853 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 854
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 855 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 856 if (_dutyBands[i].TimeOffEnd < now || GetSettings()->Test.DisableDutyCycle == lora::ON || _LBT_TimeUs > 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 857 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 858 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 859 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 860
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 861 for (uint8_t i = start; i < start + maxChannels; i++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 862 range = GetChannel(i).DrRange;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 863 // logDebug("chan: %d freq: %d range:%02x", i, GetChannel(i).Frequency, range.Value);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 864
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 865 if (IsChannelEnabled(i) && (dr_index >= range.Fields.Min && dr_index <= range.Fields.Max)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 866 int8_t band = GetDutyBand(GetChannel(i).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 867 // logDebug("band: %d freq: %d", band, _channels[i].Frequency);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 868 if (band != -1 && _dutyBands[band].TimeOffEnd == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 869 enabledChannels[nbEnabledChannels++] = i;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 870 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 871 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 872 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 873
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 874 logTrace("Number of available channels: %d", nbEnabledChannels);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 875
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 876 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 877 uint8_t sf = GetTxDatarate().SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 878 uint8_t bw = GetTxDatarate().Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 879 int16_t thres = DEFAULT_FREE_CHAN_RSSI_THRESHOLD;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 880
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 881 if (nbEnabledChannels == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 882 delete [] enabledChannels;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 883 return LORA_NO_CHANS_ENABLED;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 884 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 885
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 886
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 887 if (GetSettings()->Network.CADEnabled) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 888 // Search for free channel with ms timeout
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 889 int16_t timeout = 10000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 890 Timer tmr;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 891 tmr.start();
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 892
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 893 for (uint8_t j = rand_r(0, nbEnabledChannels - 1); tmr.read_ms() < timeout; j++) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 894 freq = GetChannel(enabledChannels[j]).Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 895
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 896 if (GetRadio()->IsChannelFree(SxRadio::MODEM_LORA, freq, sf, thres, bw)) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 897 _txChannel = enabledChannels[j];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 898 break;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 899 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 900 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 901 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 902 uint8_t j = rand_r(0, nbEnabledChannels - 1);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 903 _txChannel = enabledChannels[j];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 904 freq = GetChannel(_txChannel).Frequency;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 905 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 906
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 907 assert(freq != 0);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 908
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 909 logDebug("Using channel %d : %d", _txChannel, freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 910 GetRadio()->SetChannel(freq);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 911
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 912
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 913 delete [] enabledChannels;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 914 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 915 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 916
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 917
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 918 uint8_t lora::ChannelPlan_RU864::GetJoinDatarate() {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 919 uint8_t dr = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 920 static uint8_t cnt = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 921
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 922 if (GetSettings()->Test.DisableRandomJoinDatarate == lora::OFF) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 923 if ((cnt++ % 20) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 924 dr = lora::DR_0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 925 } else if ((cnt % 16) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 926 dr = lora::DR_1;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 927 } else if ((cnt % 12) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 928 dr = lora::DR_2;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 929 } else if ((cnt % 8) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 930 dr = lora::DR_3;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 931 } else if ((cnt % 4) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 932 dr = lora::DR_4;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 933 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 934 dr = lora::DR_5;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 935 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 936 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 937
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 938 return dr;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 939 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 940
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 941 uint8_t ChannelPlan_RU864::CalculateJoinBackoff(uint8_t size) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 942
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 943 time_t now = time(NULL);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 944 uint32_t time_on_max = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 945 static uint32_t time_off_max = 15;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 946 uint32_t rand_time_off = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 947
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 948 // TODO: calc time-off-max based on RTC time from JoinFirstAttempt, time-off-max is lost over sleep
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 949
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 950 if ((time_t)GetSettings()->Session.JoinTimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 951 return LORA_JOIN_BACKOFF;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 952 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 953
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 954 uint32_t secs_since_first_attempt = (now - GetSettings()->Session.JoinFirstAttempt);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 955 uint16_t hours_since_first_attempt = secs_since_first_attempt / (60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 956
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 957 static uint8_t join_cnt = 0;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 958
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 959 join_cnt = (join_cnt+1) % 8;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 960
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 961 if (GetSettings()->Session.JoinFirstAttempt == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 962 /* 1 % duty-cycle for first hour
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 963 * 0.1 % next 10 hours
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 964 * 0.01 % upto 24 hours */
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 965 GetSettings()->Session.JoinFirstAttempt = now;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 966 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 967 GetSettings()->Session.JoinTimeOffEnd = now + (GetTimeOnAir(size) / 10);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 968 } else if (join_cnt == 0) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 969 if (hours_since_first_attempt < 1) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 970 time_on_max = 36000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 971 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 972 // time off max 1 hour
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 973 time_off_max = std::min < uint32_t > (time_off_max * 2, 60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 974
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 975 if (GetSettings()->Session.JoinTimeOnAir < time_on_max) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 976 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 977 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 978 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 979 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 980 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 981 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 982 } else if (hours_since_first_attempt < 11) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 983 if (GetSettings()->Session.JoinTimeOnAir < 36000) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 984 GetSettings()->Session.JoinTimeOnAir = 36000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 985 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 986 time_on_max = 72000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 987 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 988 // time off max 1 hour
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 989 time_off_max = std::min < uint32_t > (time_off_max * 2, 60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 990
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 991 if (GetSettings()->Session.JoinTimeOnAir < time_on_max) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 992 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 993 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 994 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 995 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 996 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + 11 * 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 997 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 998 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 999 if (GetSettings()->Session.JoinTimeOnAir < 72000) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1000 GetSettings()->Session.JoinTimeOnAir = 72000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1001 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1002 uint32_t join_time = 1200;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1003
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1004 time_on_max = 80700;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1005 time_off_max = 1 * 60 * 60; // 1 hour
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1006 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1007
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1008 // allow one final join attempt as long as it doesn't start past the max time on air
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1009 if (GetSettings()->Session.JoinTimeOnAir < time_on_max - join_time) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1010 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1011 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1012 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1013 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1014 // Reset the join time on air and set end of restriction to the next 24 hour period
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1015 GetSettings()->Session.JoinTimeOnAir = 72000;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1016 uint16_t days = (now - GetSettings()->Session.JoinFirstAttempt) / (24 * 60 * 60) + 1;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1017 logWarning("days : %d", days);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1018 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + ((days * 24) + 11) * 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1019 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1020 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1021
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1022 logWarning("JoinBackoff: %lu seconds Time On Air: %lu / %lu", GetSettings()->Session.JoinTimeOffEnd - now, GetSettings()->Session.JoinTimeOnAir, time_on_max);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1023 } else {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1024 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1025 GetSettings()->Session.JoinTimeOffEnd = now + (GetTimeOnAir(size) / 10);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1026 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1027
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1028 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1029 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1030
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1031 bool ChannelPlan_RU864::DecodeBeacon(const uint8_t* payload, size_t size, BeaconData_t& data) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1032 uint16_t crc1, crc1_rx, crc2, crc2_rx;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1033 const BCNPayload* beacon = (const BCNPayload*)payload;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1034
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1035 // First check the size of the packet
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1036 if (size != sizeof(BCNPayload))
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1037 return false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1038
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1039 // Next we verify the CRCs are correct
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1040 crc1 = CRC16(beacon->RFU, sizeof(beacon->RFU) + sizeof(beacon->Time));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1041 memcpy((uint8_t*)&crc1_rx, beacon->CRC1, sizeof(uint16_t));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1042
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1043 if (crc1 != crc1_rx)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1044 return false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1045
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1046 crc2 = CRC16(beacon->GwSpecific, sizeof(beacon->GwSpecific));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1047 memcpy((uint8_t*)&crc2_rx, beacon->CRC2, sizeof(uint16_t));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1048
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1049 if (crc2 != crc2_rx)
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1050 return false;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1051
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1052 // Now that we have confirmed this packet is a beacon, parse and complete the output struct
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1053 memcpy(&data.Time, beacon->Time, sizeof(beacon->Time));
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1054 data.InfoDesc = beacon->GwSpecific[0];
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1055
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1056 // Update the GPS fields if we have a gps info descriptor
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1057 if (data.InfoDesc == GPS_FIRST_ANTENNA ||
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1058 data.InfoDesc == GPS_SECOND_ANTENNA ||
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1059 data.InfoDesc == GPS_THIRD_ANTENNA) {
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1060 // Latitude and Longitude 3 bytes in length
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1061 memcpy(&data.Latitude, &beacon->GwSpecific[1], 3);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1062 memcpy(&data.Longitude, &beacon->GwSpecific[4], 3);
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1063 }
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1064
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1065 return true;
Jenkins@KEILDM1.dc.multitech.prv 179:578d8030ba57 1066 }