khang_91
Diff: plans/ChannelPlan_KR920.cpp
- Revision:
- 172:7ec44396a51b
- Parent:
- 167:09fd17fee0f5
- Child:
- 178:8f7d93f3bbb5
--- a/plans/ChannelPlan_KR920.cpp Wed Aug 08 09:33:35 2018 -0500 +++ b/plans/ChannelPlan_KR920.cpp Thu Aug 30 09:05:16 2018 -0500 @@ -23,8 +23,8 @@ // MWF - changed KR920 to match final 1.0.2 regional spec const uint8_t ChannelPlan_KR920::KR920_TX_POWERS[] = { 14, 12, 10, 8, 6, 4, 2, 0 }; const uint8_t ChannelPlan_KR920::KR920_RADIO_POWERS[] = { 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20 }; -const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE[] = { 65, 151, 242, 242, 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE_REPEATER[] = { 45, 131, 222, 222, 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE[] = { 51, 51, 51, 115, 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t ChannelPlan_KR920::KR920_MAX_PAYLOAD_SIZE_REPEATER[] = { 51, 51, 51, 115, 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ChannelPlan_KR920::ChannelPlan_KR920() : @@ -94,6 +94,11 @@ GetSettings()->Session.Rx2Frequency = 921900000; GetSettings()->Session.Rx2DatarateIndex = DR_0; + GetSettings()->Session.BeaconFrequency = KR920_BEACON_FREQ; + GetSettings()->Session.BeaconDatarateIndex = KR920_BEACON_DR; + GetSettings()->Session.PingSlotFrequency = KR920_BEACON_FREQ; + GetSettings()->Session.PingSlotDatarateIndex = KR920_BEACON_DR; + logInfo("Initialize datarates..."); dr.SpreadingFactor = SF_12; @@ -264,7 +269,7 @@ } -uint8_t ChannelPlan_KR920::SetRxConfig(uint8_t window, bool continuous) { +uint8_t ChannelPlan_KR920::SetRxConfig(uint8_t window, bool continuous, uint16_t wnd_growth) { RxWindow rxw = GetRxWindow(window); @@ -278,8 +283,10 @@ uint32_t sf = rxDr.SpreadingFactor; uint8_t cr = rxDr.Coderate; uint8_t pl = rxDr.PreambleLength; - uint16_t sto = rxDr.SymbolTimeout(); + uint16_t sto = rxDr.SymbolTimeout() * wnd_growth; uint32_t afc = 0; + bool fixLen = false; + uint8_t payloadLen = 0U; bool crc = false; // downlink does not use CRC according to LORAWAN if (GetSettings()->Network.DisableCRC == true) @@ -292,6 +299,14 @@ iq = txDr.TxIQ; } + // Beacon modifications - no I/Q inversion, fixed length rx, preamble + if (window == RX_BEACON) { + iq = txDr.TxIQ; + fixLen = true; + payloadLen = sizeof(BCNPayload); + pl = BEACON_PREAMBLE_LENGTH; + } + SxRadio::RadioModems_t modem = SxRadio::MODEM_LORA; if (sf == SF_FSK) { @@ -308,7 +323,7 @@ // logTrace("Configure radio for RX%d on freq: %lu", window, rxw.Frequency); // logTrace("RX SF: %u BW: %u CR: %u PL: %u STO: %u CRC: %d IQ: %d", sf, bw, cr, pl, sto, crc, iq); - GetRadio()->SetRxConfig(modem, bw, sf, cr, afc, pl, sto, false, 0, crc, false, 0, iq, continuous); + GetRadio()->SetRxConfig(modem, bw, sf, cr, afc, pl, sto, fixLen, payloadLen, crc, false, 0, iq, continuous); return LORA_OK; } @@ -354,7 +369,8 @@ rxw.Frequency = GetSettings()->Network.TxFrequency; index = GetSettings()->Session.TxDatarate; } else { - if (window == 1) { + switch (window) { + case RX_1: // Use same frequency as TX rxw.Frequency = _channels[_txChannel].Frequency; @@ -364,8 +380,20 @@ index = 0; } - } else { - // Use session RX2 frequency + break; + + case RX_BEACON: + rxw.Frequency = GetSettings()->Session.BeaconFrequency; + index = GetSettings()->Session.BeaconDatarateIndex; + break; + + case RX_SLOT: + rxw.Frequency = GetSettings()->Session.PingSlotFrequency; + index = GetSettings()->Session.PingSlotDatarateIndex; + break; + + // RX2, RXC, RX_TEST, etc.. + default: rxw.Frequency = GetSettings()->Session.Rx2Frequency; index = GetSettings()->Session.Rx2DatarateIndex; } @@ -464,54 +492,67 @@ } uint8_t ChannelPlan_KR920::HandlePingSlotChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) { + uint8_t datarate = 0; + uint32_t freq = 0; - lora::CopyFreqtoInt(payload + index, _beaconRxChannel.Frequency); - index += 3; + status = 0x03; - if (_beaconRxChannel.Frequency != 0) { - _beaconRxChannel.DrRange.Value = payload[index]; - } else { - // TODO: set to default beacon rx channel + freq = payload[index++]; + freq |= payload[index++] << 8; + freq |= payload[index++] << 16; + freq *= 100; + + datarate = payload[index] & 0x0F; + + if (freq == 0U) { + logInfo("Received request to reset ping slot frequency to default"); + freq = KR920_BEACON_FREQ; + } else if (!CheckRfFrequency(freq)) { + logInfo("Freq KO"); + status &= 0xFE; // Channel frequency KO } - status = 0x03; + if (datarate < _minRx2Datarate || datarate > _maxRx2Datarate) { + logInfo("DR KO"); + status &= 0xFD; // Datarate KO + } + + if ((status & 0x03) == 0x03) { + logInfo("PingSlotChannelReq accepted DR: %d Freq: %d", datarate, freq); + GetSettings()->Session.PingSlotFrequency = freq; + GetSettings()->Session.PingSlotDatarateIndex = datarate; + } else { + logInfo("PingSlotChannelReq rejected DR: %d Freq: %d", datarate, freq); + } + return LORA_OK; } uint8_t ChannelPlan_KR920::HandleBeaconFrequencyReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) { + uint32_t freq = 0; - status = 0x03; - Channel chParam; + status = 0x01; - // Skip channel index - index++; + freq = payload[index++]; + freq |= payload[index++] << 8; + freq |= payload[index] << 16; + freq *= 100; - lora::CopyFreqtoInt(payload + index, chParam.Frequency); - index += 3; - chParam.DrRange.Value = payload[index++]; - - if (!GetRadio()->CheckRfFrequency(chParam.Frequency)) { + if (freq == 0U) { + logInfo("Received request to reset beacon frequency to default"); + freq = KR920_BEACON_FREQ; + } else if (!CheckRfFrequency(freq)) { + logInfo("Freq KO"); status &= 0xFE; // Channel frequency KO } - if (chParam.DrRange.Fields.Min < chParam.DrRange.Fields.Max) { - status &= 0xFD; // Datarate range KO - } else if (chParam.DrRange.Fields.Min < _minDatarate || chParam.DrRange.Fields.Min > _maxDatarate) { - status &= 0xFD; // Datarate range KO - } else if (chParam.DrRange.Fields.Max < _minDatarate || chParam.DrRange.Fields.Max > _maxDatarate) { - status &= 0xFD; // Datarate range KO + if (status & 0x01) { + logInfo("BeaconFrequencyReq accepted Freq: %d", freq); + GetSettings()->Session.BeaconFrequency = freq; + } else { + logInfo("BeaconFrequencyReq rejected Freq: %d", freq); } - if ((status & 0x03) == 0x03) { - _beaconChannel = chParam; - } - - if (_beaconChannel.Frequency == 0) { - // TODO: Set to default - } - - status = 0x01; - return LORA_OK; } @@ -982,3 +1023,39 @@ _LBT_Threshold = -65; } +bool ChannelPlan_KR920::DecodeBeacon(const uint8_t* payload, size_t size, BeaconData_t& data) { + uint16_t crc1, crc1_rx, crc2, crc2_rx; + const BCNPayload* beacon = (const BCNPayload*)payload; + + // First check the size of the packet + if (size != sizeof(BCNPayload)) + return false; + + // Next we verify the CRCs are correct + crc1 = CRC16(beacon->RFU, sizeof(beacon->RFU) + sizeof(beacon->Time)); + memcpy((uint8_t*)&crc1_rx, beacon->CRC1, sizeof(uint16_t)); + + if (crc1 != crc1_rx) + return false; + + crc2 = CRC16(beacon->GwSpecific, sizeof(beacon->GwSpecific)); + memcpy((uint8_t*)&crc2_rx, beacon->CRC2, sizeof(uint16_t)); + + if (crc2 != crc2_rx) + return false; + + // Now that we have confirmed this packet is a beacon, parse and complete the output struct + memcpy(&data.Time, beacon->Time, sizeof(beacon->Time)); + data.InfoDesc = beacon->GwSpecific[0]; + + // Update the GPS fields if we have a gps info descriptor + if (data.InfoDesc == GPS_FIRST_ANTENNA || + data.InfoDesc == GPS_SECOND_ANTENNA || + data.InfoDesc == GPS_THIRD_ANTENNA) { + // Latitude and Longitude 3 bytes in length + memcpy(&data.Latitude, &beacon->GwSpecific[1], 3); + memcpy(&data.Longitude, &beacon->GwSpecific[4], 3); + } + + return true; +}