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