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