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:
Tue Sep 18 08:25:41 2018 -0500
Revision:
127:db053d511848
Child:
128:ff9ca3779136
xdot-library revision 3.1.0-28-g84dbee8 and mbed-os revision mbed-os-5.9.6

Who changed what in which revision?

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