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:
Thu Aug 30 09:05:16 2018 -0500
Revision:
172:7ec44396a51b
Parent:
153:7c00843e4bba
Child:
178:8f7d93f3bbb5
mdot-library revision 3.1.0-class-b-alpha-1-15-g0c33f0a and mbed-os revision mbed-os-5.7.7

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