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