MultiTech / libmDot-dev-mbed5-deprecated

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 Feb 28 10:30:44 2018 -0600
Revision:
139:b2e9d643eef9
Parent:
118:64f20bc150dd
Child:
151:2242ecfd733a
mdot-library revision 3.1.0-rc1 and mbed-os revision mbed-os-5.7.5

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_KR920.h"
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 19 #include "limits.h"
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 20
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 21 using namespace lora;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 22
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 23 // MWF - changed KR920 to match final 1.0.2 regional spec
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 24 const uint8_t ChannelPlan_KR920::KR920_TX_POWERS[] = { 14, 12, 10, 8, 6, 4, 2, 0 };
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 25 const uint8_t ChannelPlan_KR920::KR920_RADIO_POWERS[] = { 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20 };
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 26 const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE[] = { 65, 151, 242, 242, 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 27 const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE_REPEATER[] = { 45, 131, 222, 222, 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 28
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 29 ChannelPlan_KR920::ChannelPlan_KR920()
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 30 :
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 31 ChannelPlan(NULL, NULL)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 32 {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 33
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 34 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 35
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 36 ChannelPlan_KR920::ChannelPlan_KR920(Settings* settings)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 37 :
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 38 ChannelPlan(NULL, settings)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 39 {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 40
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 41 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 42
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 43 ChannelPlan_KR920::ChannelPlan_KR920(SxRadio* radio, Settings* settings)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 44 :
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 45 ChannelPlan(radio, settings)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 46 {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 47
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 48 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 49
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 50 ChannelPlan_KR920::~ChannelPlan_KR920() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 51
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 52 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 53
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 54 void ChannelPlan_KR920::Init() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 55
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 56 _datarates.clear();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 57 _channels.clear();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 58 _dutyBands.clear();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 59
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 60 DutyBand band;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 61
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 62 band.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 63 band.DutyCycle = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 64
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 65 Datarate dr;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 66
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 67 _plan = KR920;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 68 _planName = "KR920";
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 69 _maxTxPower = 14;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 70 _minTxPower = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 71
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 72 _minFrequency = 920900000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 73 _maxFrequency = 923300000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 74
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 75 DefaultLBT();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 76
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 77 TX_POWERS = KR920_TX_POWERS;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 78 RADIO_POWERS = KR920_RADIO_POWERS;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 79 MAX_PAYLOAD_SIZE = KR920_MAX_PAYLOAD_SIZE;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 80 MAX_PAYLOAD_SIZE_REPEATER = KR920_MAX_PAYLOAD_SIZE_REPEATER;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 81
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 82 _minDatarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 83 _maxDatarate = 5;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 84
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 85 _minRx2Datarate = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 86 _maxRx2Datarate = DR_5;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 87
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 88 _minDatarateOffset = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 89 _maxDatarateOffset = 5;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 90
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 91 _numChans125k = 16;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 92 _numChans500k = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 93
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 94 GetSettings()->Session.Rx2Frequency = 921900000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 95 GetSettings()->Session.Rx2DatarateIndex = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 96
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 97 logInfo("Initialize datarates...");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 98
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 99 dr.SpreadingFactor = SF_12;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 100
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 101 // Add DR0-5
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 102 while (dr.SpreadingFactor >= SF_7) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 103 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 104 dr.SpreadingFactor--;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 105 dr.Index++;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 106 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 107
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 108 // Skip DR6-15 RFU
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 109 dr.SpreadingFactor = SF_INVALID;
Jenkins@KEILDM1.dc.multitech.prv 118:64f20bc150dd 110 while (dr.Index++ <= DR_15) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 111 AddDatarate(-1, dr);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 112 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 113
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 114 GetSettings()->Session.TxDatarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 115
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 116 logInfo("Initialize channels...");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 117
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 118 Channel chan;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 119 chan.DrRange.Fields.Min = DR_0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 120 chan.DrRange.Fields.Max = DR_5;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 121 chan.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 122 chan.Frequency = 922100000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 123 SetNumberOfChannels(16);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 124
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 125 uint8_t numDefaultChannels = 3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 126
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 127 for (uint8_t i = 0; i < numDefaultChannels; i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 128 AddChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 129 chan.Index++;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 130 chan.Frequency += 200000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 131 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 132
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 133 chan.DrRange.Value = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 134 chan.Frequency = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 135
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 136 for (uint8_t i = numDefaultChannels; i < 16; i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 137 AddChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 138 chan.Index++;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 139 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 140
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 141 // Add downlink channel defaults
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 142 chan.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 143 _dlChannels.resize(16);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 144 for (uint8_t i = 0; i < 16; i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 145 AddDownlinkChannel(i, chan);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 146 chan.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 SetChannelMask(0, 0x07);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 150
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 151 band.Index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 152 band.FrequencyMin = _minFrequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 153 band.FrequencyMax = _maxFrequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 154 band.PowerMax = 14;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 155 band.TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 156
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 157 // Disable duty-cycle limits
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 158 band.DutyCycle = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 159
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 160 AddDutyBand(-1, band);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 161
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 162 GetSettings()->Session.TxPower = GetSettings()->Network.TxPower;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 163 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 164
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 165 uint8_t ChannelPlan_KR920::AddChannel(int8_t index, Channel channel) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 166 logTrace("Add Channel %d : %lu : %02x %d", index, channel.Frequency, channel.DrRange.Value, _channels.size());
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 167
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 168 assert(index < (int) _channels.size());
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 169
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 170 if (index >= 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 171 _channels[index] = channel;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 172 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 173 _channels.push_back(channel);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 174 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 175
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 176 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 177 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 178
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 179 uint8_t ChannelPlan_KR920::HandleJoinAccept(const uint8_t* buffer, uint8_t size) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 180
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 181 if (size == 33) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 182 Channel ch;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 183 int index = 3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 184 for (int i = 13; i < size - 5; i += 3) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 185
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 186 ch.Frequency = ((buffer[i]) | (buffer[i + 1] << 8) | (buffer[i + 2] << 16)) * 100u;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 187
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 188 if (ch.Frequency > 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 189 ch.Index = index;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 190 ch.DrRange.Fields.Min = static_cast<int8_t>(DR_0);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 191 ch.DrRange.Fields.Max = static_cast<int8_t>(DR_5);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 192 AddChannel(index, ch);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 193
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 194 if (GetDutyBand(ch.Frequency) > -1)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 195 _channelMask[0] |= (1 << index);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 196 else
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 197 _channelMask[0] |= ~(1 << index);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 198
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 199 index += 1;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 200 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 201 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 202 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 203
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 204 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 205 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 206
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 207 uint8_t ChannelPlan_KR920::SetTxConfig() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 208
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 209 logInfo("Configure radio for TX");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 210
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 211 uint8_t band = GetDutyBand(GetChannel(_txChannel).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 212 Datarate txDr = GetDatarate(GetSettings()->Session.TxDatarate);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 213 int8_t max_pwr = _dutyBands[band].PowerMax;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 214
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 215 if (GetChannel(_txChannel).Frequency < 922100000) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 216 max_pwr = 10;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 217 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 218 max_pwr = 14;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 219 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 220
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 221 int8_t pwr = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 222
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 223 pwr = std::min < int8_t > (GetSettings()->Session.TxPower, (max_pwr - GetSettings()->Network.AntennaGain));
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 224
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 225 for (int i = 20; i >= 0; i--) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 226 if (RADIO_POWERS[i] <= pwr) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 227 pwr = i;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 228 break;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 229 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 230 if (i == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 231 pwr = i;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 232 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 233 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 234
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 235 logDebug("Session pwr: %d ant: %d max: %d", GetSettings()->Session.TxPower, GetSettings()->Network.AntennaGain, max_pwr);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 236 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 237
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 238 uint32_t bw = txDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 239 uint32_t sf = txDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 240 uint8_t cr = txDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 241 uint8_t pl = txDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 242 uint16_t fdev = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 243 bool crc = txDr.Crc;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 244 bool iq = txDr.TxIQ;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 245
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 246 if (GetSettings()->Network.DisableCRC == true)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 247 crc = false;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 248
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 249 SxRadio::RadioModems_t modem = SxRadio::MODEM_LORA;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 250
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 251 if (sf == SF_FSK) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 252 modem = SxRadio::MODEM_FSK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 253 sf = 50e3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 254 fdev = 25e3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 255 bw = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 256 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 257
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 258 GetRadio()->SetTxConfig(modem, pwr, fdev, bw, sf, cr, pl, false, crc, false, 0, iq, 3e3);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 259
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 260 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 261
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 262 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 263 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 264
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 265
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 266 uint8_t ChannelPlan_KR920::SetRxConfig(uint8_t window, bool continuous) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 267
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 268 RxWindow rxw = GetRxWindow(window);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 269 GetRadio()->SetChannel(rxw.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 270
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 271 Datarate rxDr = GetDatarate(rxw.DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 272 uint32_t bw = rxDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 273 uint32_t sf = rxDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 274 uint8_t cr = rxDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 275 uint8_t pl = rxDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 276 uint16_t sto = rxDr.SymbolTimeout();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 277 uint32_t afc = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 278 bool crc = false; // downlink does not use CRC according to LORAWAN
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 279
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 280 if (GetSettings()->Network.DisableCRC == true)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 281 crc = false;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 282
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 283 Datarate txDr = GetDatarate(GetSettings()->Session.TxDatarate);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 284 bool iq = txDr.RxIQ;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 285
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 286 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 287 iq = txDr.TxIQ;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 288 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 289
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 290 SxRadio::RadioModems_t modem = SxRadio::MODEM_LORA;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 291
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 292 if (sf == SF_FSK) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 293 modem = SxRadio::MODEM_FSK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 294 sf = 50e3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 295 cr = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 296 bw = 50e3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 297 afc = 83333;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 298 iq = false;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 299 crc = true; // FSK must use CRC
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 300 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 301
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 302 // Disable printf's to actually receive packets, printing to debug may mess up the timing
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 303 // logTrace("Configure radio for RX%d on freq: %lu", window, rxw.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 304 // 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 305
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 306 GetRadio()->SetRxConfig(modem, bw, sf, cr, afc, pl, sto, false, 0, crc, false, 0, iq, continuous);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 307
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 308 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 309 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 310
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 311 Channel ChannelPlan_KR920::GetChannel(int8_t index) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 312 Channel chan;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 313 memset(&chan, 0, sizeof(Channel));
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 314
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 315 chan = _channels[index];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 316
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 317 return chan;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 318 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 319
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 320 uint8_t ChannelPlan_KR920::SetFrequencySubBand(uint8_t sub_band) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 321 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 322 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 323
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 324 void ChannelPlan_KR920::LogRxWindow(uint8_t wnd) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 325
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 326 RxWindow rxw = GetRxWindow(wnd);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 327 Datarate rxDr = GetDatarate(rxw.DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 328 uint8_t bw = rxDr.Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 329 uint8_t sf = rxDr.SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 330 uint8_t cr = rxDr.Coderate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 331 uint8_t pl = rxDr.PreambleLength;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 332 uint16_t sto = rxDr.SymbolTimeout();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 333 bool crc = false; // downlink does not use CRC according to LORAWAN
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 334 bool iq = GetTxDatarate().RxIQ;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 335
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 336 logTrace("RX%d on freq: %lu", wnd, rxw.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 337 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 338 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 339
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 340 RxWindow ChannelPlan_KR920::GetRxWindow(uint8_t window) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 341 RxWindow rxw;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 342 int index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 343
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 344 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 345 rxw.Frequency = GetSettings()->Network.TxFrequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 346 index = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 347 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 348 if (window == 1) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 349 // Use same frequency as TX
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 350 rxw.Frequency = _channels[_txChannel].Frequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 351
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 352 if (GetSettings()->Session.TxDatarate > GetSettings()->Session.Rx1DatarateOffset) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 353 index = GetSettings()->Session.TxDatarate - GetSettings()->Session.Rx1DatarateOffset;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 354 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 355 index = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 356 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 357
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 358 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 359 // Use session RX2 frequency
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 360 rxw.Frequency = GetSettings()->Session.Rx2Frequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 361 index = GetSettings()->Session.Rx2DatarateIndex;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 362 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 363 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 364
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 365 rxw.DatarateIndex = index;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 366
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 367 return rxw;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 368 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 369
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 370 uint8_t ChannelPlan_KR920::HandleRxParamSetup(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 371 status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 372 int8_t datarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 373 int8_t drOffset = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 374 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 375
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 376 drOffset = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 377 datarate = drOffset & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 378 drOffset = (drOffset >> 4) & 0x07;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 379
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 380 freq = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 381 freq |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 382 freq |= payload[index++] << 16;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 383 freq *= 100;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 384
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 385 if (!CheckRfFrequency(freq)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 386 logInfo("Freq KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 387 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 388 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 389
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 390 if (datarate < _minRx2Datarate || datarate > _maxRx2Datarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 391 logInfo("DR KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 392 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 393 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 394
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 395 if (drOffset < 0 || drOffset > _maxDatarateOffset) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 396 logInfo("DR Offset KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 397 status &= 0xFB; // Rx1DrOffset range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 398 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 399
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 400 if ((status & 0x07) == 0x07) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 401 logInfo("RxParamSetup accepted Rx2DR: %d Rx2Freq: %d Rx1Offset: %d", datarate, freq, drOffset);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 402 SetRx2DatarateIndex(datarate);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 403 SetRx2Frequency(freq);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 404 SetRx1Offset(drOffset);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 405 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 406 logInfo("RxParamSetup rejected Rx2DR: %d Rx2Freq: %d Rx1Offset: %d", datarate, freq, drOffset);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 407 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 408
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 409 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 410 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 411
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 412 uint8_t ChannelPlan_KR920::HandleNewChannel(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 413
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 414 status = 0x03;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 415 uint8_t channelIndex = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 416 Channel chParam;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 417
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 418 channelIndex = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 419 lora::CopyFreqtoInt(payload + index, chParam.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 420 index += 3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 421 chParam.DrRange.Value = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 422
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 423 if (channelIndex < 3 || channelIndex > _channels.size() - 1) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 424 logError("New Channel index KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 425 status &= 0xFE; // Channel index KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 426 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 427
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 428 if (!GetRadio()->CheckRfFrequency(chParam.Frequency)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 429 logError("New Channel frequency KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 430 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 431 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 432
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 433 if (chParam.DrRange.Fields.Min > chParam.DrRange.Fields.Max) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 434 logError("New Channel datarate min/max KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 435 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 436 } else if (chParam.DrRange.Fields.Min < _minDatarate || chParam.DrRange.Fields.Min > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 437 logError("New Channel datarate min KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 438 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 439 } else if (chParam.DrRange.Fields.Max < _minDatarate || chParam.DrRange.Fields.Max > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 440 logError("New Channel datarate max KO");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 441 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 442 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 443
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 444 if ((status & 0x03) == 0x03) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 445 logInfo("New Channel accepted index: %d freq: %lu drRange: %02x", channelIndex, chParam.Frequency, chParam.DrRange.Value);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 446 AddChannel(channelIndex, chParam);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 447 SetChannelMask(0, _channelMask[0] | 1 << (channelIndex));
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 448 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 449
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 450 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 451 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 452
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 453 uint8_t ChannelPlan_KR920::HandlePingSlotChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 454
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 455 lora::CopyFreqtoInt(payload + index, _beaconRxChannel.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 456 index += 3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 457
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 458 if (_beaconRxChannel.Frequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 459 _beaconRxChannel.DrRange.Value = payload[index];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 460 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 461 // TODO: set to default beacon rx channel
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 462 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 463
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 464 status = 0x03;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 465 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 466 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 467
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 468 uint8_t ChannelPlan_KR920::HandleBeaconFrequencyReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 469
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 470 status = 0x03;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 471 Channel chParam;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 472
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 473 // Skip channel index
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 474 index++;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 475
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 476 lora::CopyFreqtoInt(payload + index, chParam.Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 477 index += 3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 478 chParam.DrRange.Value = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 479
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 480 if (!GetRadio()->CheckRfFrequency(chParam.Frequency)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 481 status &= 0xFE; // Channel frequency KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 482 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 483
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 484 if (chParam.DrRange.Fields.Min < chParam.DrRange.Fields.Max) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 485 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 486 } else if (chParam.DrRange.Fields.Min < _minDatarate || chParam.DrRange.Fields.Min > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 487 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 488 } else if (chParam.DrRange.Fields.Max < _minDatarate || chParam.DrRange.Fields.Max > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 489 status &= 0xFD; // Datarate range KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 490 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 491
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 492 if ((status & 0x03) == 0x03) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 493 _beaconChannel = chParam;
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 (_beaconChannel.Frequency == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 497 // TODO: Set to default
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 498 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 499
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 500 status = 0x01;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 501
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 502 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 503 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 504
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 505
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 506 uint8_t ChannelPlan_KR920::HandleAdrCommand(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 507 uint8_t power = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 508 uint8_t datarate = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 509 uint16_t mask = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 510 uint16_t new_mask = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 511 uint8_t ctrl = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 512 uint8_t nbRep = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 513
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 514 status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 515 datarate = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 516 power = datarate & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 517 datarate = (datarate >> 4) & 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 518
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 519 mask = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 520 mask |= payload[index++] << 8;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 521
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 522 nbRep = payload[index++];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 523 ctrl = (nbRep >> 4) & 0x07;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 524 nbRep &= 0x0F;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 525
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 526 if (nbRep == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 527 nbRep = 1;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 528 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 529
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 530 if (datarate > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 531 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 532 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 533 //
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 534 // Remark MaxTxPower = 0 and MinTxPower = 7
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 535 //
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 536 if (power < 0 || power > 7) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 537 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 538 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 539
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 540 switch (ctrl) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 541 case 0:
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 542 SetChannelMask(0, mask);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 543 break;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 544
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 545 case 6:
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 546 // enable all currently defined channels
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 547 // set bits 0 - N of a number by (2<<N)-1
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 548 new_mask = (1 << _channels.size()) - 1;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 549 SetChannelMask(0, new_mask);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 550 break;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 551
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 552 default:
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 553 logWarning("rejecting RFU or unknown control value %d", ctrl);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 554 status &= 0xFE; // ChannelMask KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 555 return LORA_ERROR;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 556 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 557
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 558 if (GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 559 GetSettings()->Session.TxDatarate = datarate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 560 GetSettings()->Session.TxPower = TX_POWERS[power];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 561 GetSettings()->Session.Redundancy = nbRep;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 562 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 563 logDebug("ADR is disabled, DR and Power not changed.");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 564 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 565 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 566 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 567
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 568 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 569
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 570 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 571 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 572
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 573 uint8_t ChannelPlan_KR920::ValidateAdrConfiguration() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 574 uint8_t status = 0x07;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 575 uint8_t datarate = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 576 uint8_t power = GetSettings()->Session.TxPower;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 577
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 578 if (!GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 579 logDebug("ADR disabled - no applied changes to validate");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 580 return status;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 581 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 582
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 583 if (datarate > _maxDatarate) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 584 logWarning("ADR Datarate KO - outside allowed range");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 585 status &= 0xFD; // Datarate KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 586 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 587 if (power < _minTxPower || power > _maxTxPower) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 588 logWarning("ADR TX Power KO - outside allowed range");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 589 status &= 0xFB; // TxPower KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 590 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 591
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 592 // mask must not contain any undefined channels
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 593 for (int i = 3; i < 16; i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 594 if ((_channelMask[0] & (1 << i)) && (_channels[i].Frequency == 0)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 595 logWarning("ADR Channel Mask KO - cannot enable undefined channel");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 596 status &= 0xFE; // ChannelMask KO
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 597 break;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 598 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 599 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 600
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 601 return status;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 602 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 603
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 604 uint8_t ChannelPlan_KR920::HandleAckTimeout() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 605
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 606 if (!GetSettings()->Network.ADREnabled) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 607 return LORA_ADR_OFF;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 608 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 609
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 610 if ((++(GetSettings()->Session.AckCounter) % 2) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 611 if (GetSettings()->Session.TxPower < GetSettings()->Network.TxPowerMax) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 612 logTrace("ADR Setting power to maximum");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 613 GetSettings()->Session.TxPower = GetSettings()->Network.TxPowerMax;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 614 } else if (GetSettings()->Session.TxDatarate > 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 615 logTrace("ADR Lowering datarate");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 616 (GetSettings()->Session.TxDatarate)--;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 617 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 618 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 619
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 620 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 621 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 622
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 623
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 624 uint32_t ChannelPlan_KR920::GetTimeOffAir()
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 625 {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 626 if (GetSettings()->Test.DisableDutyCycle == lora::ON)
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 627 return 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 628
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 629 uint32_t min = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 630 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 631
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 632
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 633 min = UINT_MAX;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 634 int8_t band = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 635
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 636 if (P2PEnabled()) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 637 int8_t band = GetDutyBand(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 638 if (_dutyBands[band].TimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 639 min = _dutyBands[band].TimeOffEnd - now;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 640 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 641 min = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 642 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 643 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 644 for (size_t i = 0; i < _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 645 if (IsChannelEnabled(i) && GetChannel(i).Frequency != 0 &&
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 646 !(GetSettings()->Session.TxDatarate < GetChannel(i).DrRange.Fields.Min ||
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 647 GetSettings()->Session.TxDatarate > GetChannel(i).DrRange.Fields.Max)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 648
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 649 band = GetDutyBand(GetChannel(i).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 650 if (band != -1) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 651 // logDebug("band: %d time-off: %d now: %d", band, _dutyBands[band].TimeOffEnd, now);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 652 if (_dutyBands[band].TimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 653 min = std::min < uint32_t > (min, _dutyBands[band].TimeOffEnd - now);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 654 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 655 min = 0;
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 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 659 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 660 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 661 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 662
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 663
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 664 if (GetSettings()->Session.AggregatedTimeOffEnd > 0 && GetSettings()->Session.AggregatedTimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 665 min = std::max < uint32_t > (min, GetSettings()->Session.AggregatedTimeOffEnd - now);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 666 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 667
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 668 now = time(NULL);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 669 uint32_t join_time = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 670
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 671 if (GetSettings()->Session.JoinFirstAttempt != 0 && now < GetSettings()->Session.JoinTimeOffEnd) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 672 join_time = (GetSettings()->Session.JoinTimeOffEnd - now) * 1000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 673 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 674
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 675 min = std::max < uint32_t > (join_time, min);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 676
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 677 return min;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 678 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 679
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 680
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 681 void ChannelPlan_KR920::UpdateDutyCycle(uint32_t freq, uint32_t time_on_air_ms) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 682 if (GetSettings()->Test.DisableDutyCycle == lora::ON) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 683 _dutyCycleTimer.stop();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 684 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 685 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 686 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 687 return;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 688 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 689
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 690 _dutyCycleTimer.start();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 691
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 692 if (GetSettings()->Session.MaxDutyCycle > 0 && GetSettings()->Session.MaxDutyCycle <= 15) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 693 GetSettings()->Session.AggregatedTimeOffEnd = _dutyCycleTimer.read_ms() + time_on_air_ms * GetSettings()->Session.AggregateDutyCycle;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 694 logDebug("Updated Aggregate DCycle Time-off: %lu DC: %f%%", GetSettings()->Session.AggregatedTimeOffEnd, 1 / float(GetSettings()->Session.AggregateDutyCycle));
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 695 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 696 GetSettings()->Session.AggregatedTimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 697 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 698
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 699
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 700 uint32_t time_off_air = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 701 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 702
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 703 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 704 if (_dutyBands[i].TimeOffEnd < now) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 705 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 706 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 707 _dutyBands[i].TimeOffEnd -= now;
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 (freq >= _dutyBands[i].FrequencyMin && freq <= _dutyBands[i].FrequencyMax) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 711 logDebug("update TOE: freq: %d i:%d toa: %d DC:%d", freq, i, time_on_air_ms, _dutyBands[i].DutyCycle);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 712
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 713 if (freq > _minFrequency && freq < _maxFrequency && (GetSettings()->Session.TxPower + GetSettings()->Network.AntennaGain) <= 7) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 714 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 715 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 716 time_off_air = time_on_air_ms * _dutyBands[i].DutyCycle;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 717 _dutyBands[i].TimeOffEnd = time_off_air;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 718 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 719 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 720 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 721
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 722
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 723 ResetDutyCycleTimer();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 724 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 725
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 726 std::vector<uint32_t> lora::ChannelPlan_KR920::GetChannels() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 727 std::vector < uint32_t > chans;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 728
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 729 for (int8_t i = 0; i < (int) _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 730 chans.push_back(_channels[i].Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 731 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 732 chans.push_back(GetRxWindow(2).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 733
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 734 return chans;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 735 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 736
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 737 std::vector<uint8_t> lora::ChannelPlan_KR920::GetChannelRanges() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 738 std::vector < uint8_t > ranges;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 739
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 740 for (int8_t i = 0; i < (int) _channels.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 741 ranges.push_back(_channels[i].DrRange.Value);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 742 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 743
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 744 ranges.push_back(GetRxWindow(2).DatarateIndex);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 745
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 746 return ranges;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 747
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 748 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 749
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 750 void lora::ChannelPlan_KR920::EnableDefaultChannels() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 751 _channelMask[0] |= 0x0003;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 752 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 753
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 754 uint8_t ChannelPlan_KR920::GetNextChannel()
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 755 {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 756 if (GetSettings()->Session.AggregatedTimeOffEnd != 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 757 return LORA_AGGREGATED_DUTY_CYCLE;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 758 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 759
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 760 if (P2PEnabled() || GetSettings()->Network.TxFrequency != 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 761 logDebug("Using frequency %d", GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 762
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 763 if (GetSettings()->Test.DisableDutyCycle != lora::ON) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 764 int8_t band = GetDutyBand(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 765 logDebug("band: %d freq: %d", band, GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 766 if (band != -1 && _dutyBands[band].TimeOffEnd != 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 767 return LORA_NO_CHANS_ENABLED;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 768 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 769 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 770
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 771 GetRadio()->SetChannel(GetSettings()->Network.TxFrequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 772 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 773 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 774
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 775 uint8_t start = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 776 uint8_t maxChannels = _numChans125k;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 777 uint8_t nbEnabledChannels = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 778 uint8_t *enabledChannels = new uint8_t[maxChannels];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 779
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 780 if (GetTxDatarate().Bandwidth == BW_500) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 781 maxChannels = _numChans500k;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 782 start = _numChans125k;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 783 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 784
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 785 // Search how many channels are enabled
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 786 DatarateRange range;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 787 uint8_t dr_index = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 788 uint32_t now = _dutyCycleTimer.read_ms();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 789
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 790 for (size_t i = 0; i < _dutyBands.size(); i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 791 if (_dutyBands[i].TimeOffEnd < now || GetSettings()->Test.DisableDutyCycle == lora::ON) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 792 _dutyBands[i].TimeOffEnd = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 793 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 794 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 795
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 796 for (uint8_t i = start; i < start + maxChannels; i++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 797 range = GetChannel(i).DrRange;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 798 // logDebug("chan: %d freq: %d range:%02x", i, GetChannel(i).Frequency, range.Value);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 799
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 800 if (IsChannelEnabled(i) && (dr_index >= range.Fields.Min && dr_index <= range.Fields.Max)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 801 int8_t band = GetDutyBand(GetChannel(i).Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 802 // logDebug("band: %d freq: %d", band, _channels[i].Frequency);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 803 if (band != -1 && _dutyBands[band].TimeOffEnd == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 804 enabledChannels[nbEnabledChannels++] = i;
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
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 809 logTrace("Number of available channels: %d", nbEnabledChannels);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 810
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 811 uint32_t freq = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 812 uint8_t sf = GetTxDatarate().SpreadingFactor;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 813 uint8_t bw = GetTxDatarate().Bandwidth;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 814 int16_t thres = DEFAULT_FREE_CHAN_RSSI_THRESHOLD;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 815
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 816 if (nbEnabledChannels == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 817 delete [] enabledChannels;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 818 return LORA_NO_CHANS_ENABLED;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 819 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 820
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 821 if (GetSettings()->Network.CADEnabled) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 822 // Search for free channel with ms timeout
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 823 int16_t timeout = 10000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 824 Timer tmr;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 825 tmr.start();
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 826
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 827 for (uint8_t j = rand_r(0, nbEnabledChannels - 1); tmr.read_ms() < timeout; j++) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 828 freq = GetChannel(enabledChannels[j]).Frequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 829
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 830 if (GetRadio()->IsChannelFree(SxRadio::MODEM_LORA, freq, sf, thres, bw)) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 831 _txChannel = enabledChannels[j];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 832 break;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 833 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 834 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 835 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 836 uint8_t j = rand_r(0, nbEnabledChannels - 1);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 837 _txChannel = enabledChannels[j];
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 838 freq = GetChannel(_txChannel).Frequency;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 839 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 840
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 841 assert(freq != 0);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 842
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 843 logDebug("Using channel %d : %d", _txChannel, freq);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 844 GetRadio()->SetChannel(freq);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 845
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 846 delete [] enabledChannels;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 847 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 848 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 849
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 850
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 851 uint8_t lora::ChannelPlan_KR920::GetJoinDatarate() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 852 uint8_t dr = GetSettings()->Session.TxDatarate;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 853 static uint8_t cnt = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 854
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 855 if (GetSettings()->Test.DisableRandomJoinDatarate == lora::OFF) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 856 if ((cnt++ % 20) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 857 dr = lora::DR_0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 858 } else if ((cnt % 16) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 859 dr = lora::DR_1;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 860 } else if ((cnt % 12) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 861 dr = lora::DR_2;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 862 } else if ((cnt % 8) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 863 dr = lora::DR_3;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 864 } else if ((cnt % 4) == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 865 dr = lora::DR_4;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 866 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 867 dr = lora::DR_5;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 868 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 869 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 870
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 871 return dr;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 872 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 873
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 874 uint8_t ChannelPlan_KR920::CalculateJoinBackoff(uint8_t size) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 875
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 876 time_t now = time(NULL);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 877 uint32_t time_on_max = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 878 static uint32_t time_off_max = 15;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 879 uint32_t rand_time_off = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 880
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 881 // 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 882
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 883 if ((time_t)GetSettings()->Session.JoinTimeOffEnd > now) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 884 return LORA_JOIN_BACKOFF;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 885 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 886
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 887 uint32_t secs_since_first_attempt = (now - GetSettings()->Session.JoinFirstAttempt);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 888 uint16_t hours_since_first_attempt = secs_since_first_attempt / (60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 889
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 890 static uint8_t join_cnt = 0;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 891
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 892 join_cnt = (join_cnt+1) % 8;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 893
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 894 if (GetSettings()->Session.JoinFirstAttempt == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 895 /* 1 % duty-cycle for first hour
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 896 * 0.1 % next 10 hours
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 897 * 0.01 % upto 24 hours */
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 898 GetSettings()->Session.JoinFirstAttempt = now;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 899 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 900 GetSettings()->Session.JoinTimeOffEnd = now + (GetTimeOnAir(size) / 10);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 901 } else if (join_cnt == 0) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 902 if (hours_since_first_attempt < 1) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 903 time_on_max = 36000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 904 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 905 // time off max 1 hour
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 906 time_off_max = std::min < uint32_t > (time_off_max * 2, 60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 907
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 908 if (GetSettings()->Session.JoinTimeOnAir < time_on_max) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 909 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 910 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 911 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 912 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 913 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 914 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 915 } else if (hours_since_first_attempt < 11) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 916 if (GetSettings()->Session.JoinTimeOnAir < 36000) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 917 GetSettings()->Session.JoinTimeOnAir = 36000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 918 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 919 time_on_max = 72000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 920 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 921 // time off max 1 hour
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 922 time_off_max = std::min < uint32_t > (time_off_max * 2, 60 * 60);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 923
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 924 if (GetSettings()->Session.JoinTimeOnAir < time_on_max) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 925 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 926 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 927 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 928 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 929 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + 11 * 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 930 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 931 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 932 if (GetSettings()->Session.JoinTimeOnAir < 72000) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 933 GetSettings()->Session.JoinTimeOnAir = 72000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 934 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 935 uint32_t join_time = 2500;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 936
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 937 time_on_max = 80700;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 938 time_off_max = 1 * 60 * 60; // 1 hour
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 939 rand_time_off = rand_r(time_off_max - 1, time_off_max + 1);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 940
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 941 if (GetSettings()->Session.JoinTimeOnAir < time_on_max - join_time) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 942 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 943 GetSettings()->Session.JoinTimeOffEnd = now + rand_time_off;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 944 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 945 logWarning("Max time-on-air limit met for current join backoff period");
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 946 // Reset the join time on air and set end of restriction to the next 24 hour period
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 947 GetSettings()->Session.JoinTimeOnAir = 72000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 948 uint16_t days = (now - GetSettings()->Session.JoinFirstAttempt) / (24 * 60 * 60) + 1;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 949 logWarning("days : %d", days);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 950 GetSettings()->Session.JoinTimeOffEnd = GetSettings()->Session.JoinFirstAttempt + ((days * 24) + 11) * 60 * 60;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 951 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 952 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 953
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 954 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 955 } else {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 956 GetSettings()->Session.JoinTimeOnAir += GetTimeOnAir(size);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 957 GetSettings()->Session.JoinTimeOffEnd = now + (GetTimeOnAir(size) / 10);
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 958 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 959
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 960 return LORA_OK;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 961 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 962
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 963 uint8_t ChannelPlan_KR920::HandleMacCommand(uint8_t* payload, uint8_t& index) {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 964 return LORA_ERROR;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 965 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 966
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 967 void ChannelPlan_KR920::DefaultLBT() {
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 968 _LBT_TimeUs = 5000;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 969 _LBT_Threshold = -65;
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 970 }
Jenkins@KEILDM1.dc.multitech.prv 82:0f5a742a08cd 971