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