Bleeding edge development version of the xDot 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:   Dot-Examples Dot-AT-Firmware Dot-Examples TEST_FF1705 ... more

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