RFPPF 4.0.9
dotnet add package RFPPF --version 4.0.9
NuGet\Install-Package RFPPF -Version 4.0.9
<PackageReference Include="RFPPF" Version="4.0.9" />
<PackageVersion Include="RFPPF" Version="4.0.9" />
<PackageReference Include="RFPPF" />
paket add RFPPF --version 4.0.9
#r "nuget: RFPPF, 4.0.9"
#:package RFPPF@4.0.9
#addin nuget:?package=RFPPF&version=4.0.9
#tool nuget:?package=RFPPF&version=4.0.9
RFPPF {#mainpage}
RF-Networks Protocol Parser Framework
LICENSE
Copyright (C) 2019 RF-Networks Ltd. All Rights Reserved.
Changelog
3.0.0 - First version
3.0.2 - Check-In message voltage fix
- Check-In message voltage byte(15) is divided to 62.53.0.3 - Old protocol tag periodic message fix
- Old protocol tag periodic message max voltage raised up to 5V3.0.4 - GPIO sensor message change
- GPIO sensor message added trigger mask and value mask3.0.5 - GPS message added
- Receiver GPS message added3.0.6 - Old protocol receiver configuration message fix
- Receiver Configuration message bugfix3.0.7 - Old protocol receiver configuration messages added
- Receiver Configuration Voltage, External Voltage, Temperature messages added - Receiver Modem Voltage message added3.0.8 - Old protocol receiver configuration messages fix
- Receiver Configuration message bugfix3.0.9 - Old protocol receiver configuration external voltage messages fix
- Receiver Configuration External voltage message DataSize exception fix bugfix3.0.10 - Minor bugfixes
- Minor bugfixes3.0.11 - Old protocol receiver configuration temperature messages fix
- Receiver Configuration Temperature message DataSize exception fix bugfix (old versions of radio send 2 bytes instead of 1)3.0.12 - Java version fix
- Java version bugfixes3.0.13 - New message types added
- Mesh BME280 message changed - Mesh GPIO16, Analog3 messages added3.0.14 - Message factory fix for RFM protocol
- ParseMeshMessage function added3.0.15 - Bugfixes
- Minor bugfixes and Mesh message ToString function implemented3.0.16 - Bugfixes
- Mesh protocol parsing bugfix3.0.17 - Mesh scheduler messages
- Mesh scheduler messages implementation - Minor bugfixes3.0.18 - Mesh scheduler event messages
- Mesh scheduler event messages implementation3.0.19 - Bugfix
- Mesh set scheduler messages parsing bugfix3.0.20 - Bugfix
- Java version fixes3.0.21 - DS18B20 Sensor Bugfix
- DS18B20 Sensor mesh message size fixes3.0.22 - DS18B20 Sensor Bugfix
- DS18B20 Sensor mesh message temperature fixes3.0.23 - Bugfix
- Minor bugfixes3.0.24 - DiagnosticTestInfoMessage change
- DiagnosticTestInfoMessage structure change3.0.25 - DiagnosticTestInfoMessage fixes
- DiagnosticTestInfoMessage fixes3.0.26 - TesterCommandMessage fix
- TesterCommandMessage fix3.0.27 - TagAveragePulsesPerSecondMessage added
- TagAveragePulsesPerSecondMessage message type added3.0.28 - Old protocol parser fix
- Old protocol parser fix3.0.29 - TagAveragePulsesPerSecondMessage change
- TagAveragePulsesPerSecondMessage message structure change (Voltage removed)3.0.30 - TagAveragePulsesPerSecondMessage Java fix
- TagAveragePulsesPerSecondMessage message Java fix3.0.31 - C# Bug fix
- Data sensor missing messages type fix3.0.32 - Receiver Weight & Modbus Meter messages added
- Receiver Weight message added - Receiver Modbus Meter message added3.0.33 - Mesh protocol version 2 implemented
- Mesh protocol version 2 implemented3.0.34 - Mesh protocol check out message added
- Mesh protocol check out message added3.0.35 - DS18B20 Sensor Message parsing fix
- DS18B20 Sensor Message parsing fix3.0.36 - Old protocol Acknowledge Message parsing fix
- Old protocol Acknowledge Message parsing fix3.0.37 - Old protocol Extended Protocol with GPS message added
- Old protocol Extended Protocol with GPS message added3.0.38 - Old protocol Extended Protocol with PH & EC message added
- Old protocol Extended Protocol with PH & EC message added3.0.39 - Old protocol Extended Protocol with PH & EC message fix
- Old protocol Extended Protocol with PH & EC message fix3.0.40 - Old protocol Mesh & Mesh RSSI parsers added
- Old protocol Mesh & Mesh RSSI parsers added3.0.41 - Old protocol Mesh & Mesh RSSI parsers fix
- Old protocol Mesh & Mesh RSSI parsers fix3.0.42 - Old protocol Extended Protocol with magnitude message added
- Old protocol Extended Protocol with magnitude message added3.0.44 - Old protocol Extended Protocol with magnitude message fixes
- Old protocol Extended Protocol with magnitude message fixes3.0.45 - Bufgixes
- Tag Extended protocol message RSSI fix - Tag Extended protocol magnitude message added3.0.46 - Bufgixes
- Tag Extended protocol message GPS fix3.0.47 - Bufgixes
- Tag Extended protocol parsing fix3.0.48 - Tag Extended protocol Moistures array & Temperatures array messages
- Tag Extended protocol Moistures array & Temperatures array messages added3.0.49 - Mesh protocol messages bugfix
- Mesh protocol messages bugfix3.0.50 - Mesh protocol GPIOV2 & AnalogV2 messages
- Mesh protocol GPIOV2 & AnalogV2 messages added3.0.51 - Old protocol Receiver WhoIAm, PRCRequest and RPCResponse messages added
- Old protocol Receiver WhoIAm, PRCRequest and RPCResponse messages added3.0.52 - Bugfixes
- Bugfixes3.0.53 - Gateway messages added to GPRS message
- Gateway messages added to GPRS message - Old protocol Receiver WhoIAm, PRCRequest and RPCResponse messages are depricated3.0.54 - GPRS message Gateway messages generate functions added
- GPRS message Gateway messages generate functions added3.0.55 - GPRS message Gateway message generation function fix
- GPRS message Gateway message generation function fix3.0.56 - GPRS message parametrized constructor bugfix
- GPRS message parametrized constructor bugfix3.0.57 - GPRS WhoIAm message radio bootloader version field added
- GPRS WhoIAm message radio bootloader version field added3.0.58 - Old protocol tag pressure message pressure multiplier changed to 100
- Old protocol tag pressure message pressure multiplier changed to 103.0.59 - Java bit-stuffing decode bugfix
- Java bit-stuffing decode bugfix3.0.60 - Mesh protocol SI7021V2 message
- Mesh protocol SI7021V2 message added3.0.61 - Mesh protocol DiagnosticChildrenList message
- Mesh protocol DiagnosticChildrenList message added3.0.62 - Mesh protocol GPIOV2 message fix
- Mesh protocol GPIOV2 message fix3.0.63 - Mesh protocol CheckIn message change
- Mesh protocol CheckIn message Upload and Download error percentage fields added3.0.64 - Old protocol Extended Protocol CO2 and Binary data messages added
- Old protocol Extended Protocol CO2 and Binary data messages added3.0.65 - Old protocol Extended Protocol parsing fix
- Old protocol Extended Protocol parsing fix3.0.66 - Old protocol Extended Protocol message size fix
- Old protocol Extended Protocol message size fix3.0.67 - Mesh protocol PulseCounterV2 message added
- Mesh protocol PulseCounterV2 message added3.0.68 - Old protocol Extended Protocol Repeater message added
- Old protocol Extended Protocol Repeater message added4.0.0 - Architecture refactor: handler chains, Template Method parsers, decorators
- Handler chain (Chain of Responsibility) added for each protocol family: OldProtocol/Mesh (`MeshMessageHandler → ReceiverMessageHandler → TagMessageHandler → ErrorMessageHandler`), RFM (`RFMEnvelopeHandler → ErrorMessageHandler`), GPRS (`GPRSEnvelopeHandler → ErrorMessageHandler`) - `ProtocolParser` rewritten as a Template Method base handling buffer management and event firing; subclasses implement only `ParseFrame`; frame extraction moved into pluggable `IFrameDecoder` strategies (`BitStuffingFrameDecoder`, `AnchorLengthFrameDecoder`, `MagicHeaderFrameDecoder`) - `LoggingParserDecorator` and `FilteringParserDecorator` added - `MessageRegistry` converted to a Meyer's singleton with self-registering message types - Structured error reporting added: `ParseErrorCode` enum, `ParseException`, and `ErrorMessage.GetProperties()` now returns `Error`, `ErrorCode`, `RawFrame` - `MessageTypeId` enum expanded to cover all protocol families - Breaking: `MeshRSSIParser`, `SensorRecord.SensorRecords`, `SensorRecord.SensorMessage`, and `MessageFactory.ParseMeshMessage` deprecated in favour of `MeshParser`/`GetProperties()`; scheduled for removal in v5.0 - Bugfixes: `ProtocolParser.AppendBytes` missing `out` keyword corrected; `RFMParseContext` accessors fixed for .NET 4.6 compatibility4.0.1 - Frame decoding and CO2 message bugfixes
- `BitStuffingFrameDecoder` fixed to extract every complete frame present in the buffer per call instead of only the first one, so messages are no longer silently dropped or misattributed when multiple frames arrive together - `AnchorLengthFrameDecoder` now validates the anchor byte and resyncs instead of misreading trailing padding as a bogus extra frame - `TagExtendedProtocolCO2Message` now accepts both the standard 26-byte payload and the 27-byte variant produced when a reading is relayed through a repeater, instead of throwing "Payload is not correct" - `MeshRSSIMessage.ReceptionLevel` property added: null when RSSI is 0xFF (no reading), otherwise the negated RSSI value4.0.2 - Extended Protocol Repeater message dispatch fix
- `TagDataMessage.Parse` now dispatches `ExtendedProtocolMessageTypes.Repeater` to `TagExtendedProtocolRepeaterMessage` instead of falling through to the generic `TagExtendedProtocolMessage`, fixing repeater-relayed tag messages4.0.3 - Extended Protocol RSSI byte offset fix
- `TagExtendedProtocolRepeaterMessage.TagMessage` was trimming one byte too many (the outer message's own trailing RSSI byte) when re-deriving the nested tag message, shifting every field after the trim point by one byte — confirmed on real data where a CO2 message's Humidity byte was being read back as its RSSI - C++ `TagMessage::getRSSI()` is now `virtual`, with `TagExtendedProtocolMessage` overriding it to read the last byte of the (variable-length) body instead of the fixed offset that's only valid for classic 13-byte tag messages; the C# side of this override was already correct4.0.5 - Extended Protocol Repeater message trim/RSSI fixes
- The 4.0.3 trim-length fix was itself off by one byte: it widened the kept tail slice to avoid dropping the outer message's RSSI, but that byte was already kept by the pre-4.0.3 code, so the widening just pulled in an extra CRC byte instead — silently misaligning fields for single-hop relays and throwing "Payload is not correct" for double-hop-relayed CO2 readings. Reverted to trimming 3 trailing bytes (RSSI + 2-byte CRC), confirmed against existing byte-for-byte unit tests4.0.6 - RFMeshParser double bit-stuffing decode fix
- `RFMeshParser.ParseFrame` (C#) was decoding frames a second time — they arrive already de-stuffed from `BitStuffingFrameDecoder`. Harmless unless the decoded payload itself contained a literal `0xAB`/`0xCD`/`0xEF` byte (e.g. RSSI -17 == 0xEF), in which case the redundant pass misread real data as bit-stuffing control bytes and corrupted the message. Removed the extra decode call to match the C++ implementation, which never had this bug - `TagExtendedProtocolRepeaterMessage` now overrides `RSSI`/`ReceptionLevel` (C# and C++) instead of inheriting them: a Repeater message's body ends with `[RSSI, CRC byte 1, CRC byte 2]` rather than just `[RSSI]`, so the inherited "last byte of body" getter was reading the CRC as RSSI - `TagExtendedProtocolRepeaterMessage.Parse` now validates that the received frame length matches `Size + 4`, throwing a clear "Truncated Repeater message" error for an incomplete frame instead of letting it surface two calls later as a confusing, unrelated length mismatch from the nested message's own Parse4.0.7 - Repeater message truncation check and C++ CRC regression fixes
- The 4.0.5 truncation check itself validated against the wrong invariant: `Size + 4` is the outer serial envelope's declared length (protocol byte + message counter + Star message + checksum), not the length of the Star message the class actually holds. Every real gateway frame satisfies `Size + 1`, same as every other `TagMessage` — confirmed byte-for-byte against live gateway captures. The old check rejected every genuine Repeater frame as "truncated" by exactly 3 bytes; fixed in both C# and C++ to check `Size + 1` - C++ `TagMessage::getBytes()` was appending a CRC16-XModem checksum copy-pasted from the unrelated `RFMMessage::getBytes()`, making it report 2 bytes more than the message actually contains. This has no C# equivalent and no place in the OldProtocol wire format (the only checksum is the outer envelope's 1-byte sum, validated separately in `ProtocolMessageParser::parseReceiverMessage`). Harmless while the 4.0.5 bug above rejected real Repeater frames before `getBytes()` was ever called post-parse on real data; once that check was fixed, it surfaced as "expected N, got N+2" on every real Repeater frame. Removed - Added regression tests built from real gateway captures — both a direct parse of the Star message bytes and a full round trip through `MeshParser`/`MeshRSSIParser` with bit-stuffing and checksum validation — covering both fixes above4.0.8 - Repeater nested-message crash and C++ CO2 validation fixes
- C++ `TagExtendedProtocolCO2Message::parse` was missing the 26/27-byte length check its C# counterpart has, so it silently parsed a wrong-length buffer at fixed field offsets and produced a fabricated, plausible-looking CO2 reading instead of failing. Added the same length check as C# - `TagExtendedProtocolRepeaterMessage.TagMessage` (C#) / `getTagMessage()` (C++) picks which nested message subtype to parse from a byte re-sliced from the repeater's payload — a heuristic, not a confirmed field of the relayed message's real layout. On three independent real gateway captures that byte was `8`, which collides with `ExtendedProtocolMessageTypes.CO2`; parsing the reconstructed (wrong-length) buffer as CO2 then threw "Payload is not correct" in C#, crashing every caller of this property for every real Repeater message sharing that byte value. Both ports now catch a failed subtype parse and fall back to the generic probe message (`Type`/`TagID` only) instead of propagating the exception. The correct field layout of the relayed message itself remains unconfirmed pending firmware reference — this only stops a bad guess from crashing the caller - Added `TestRepeaterTagMessageDoesNotThrowOnUnreliableTypeGuess`, built from a third real gateway capture, covering the crash above4.0.9 - Repeater relayed-message field layout, and two C++ builder bugs
- `TagExtendedProtocolRepeaterMessage.TagMessage` (C#) / `getTagMessage()` / `setTagMessage()` (C++) now reconstruct the relayed message using the layout confirmed against embedded firmware source (`repeater.c`) and three independent real captures: the repeater's own header (Size/Type/TagID) and `msg_num` belong to the *original* relayed tag, reused unchanged; the relayed message itself carries no header, no `msg_num`, and no RSSI of its own — its RSSI is `FirstRSSI` (the tag→repeater hop). The previous code grafted a mangled copy of the *outer* header onto the relayed payload instead, so a wrapped `TagExtendedProtocolCO2Message` never resolved correctly. Verified with an exact-field builder round trip and against all three real captures, which now decode to physically plausible CO2 readings (~24°C, ~45-50% humidity, ~1008 hPa, ~3V) in both ports - C++ `TagMessage::setRSSI` is now `virtual` and overridden by `TagExtendedProtocolMessage` to write `body_.back()` (mirroring `getRSSI()`). Previously it always wrote the fixed offset `body_[6]`, an out-of-bounds write whenever an extended message's `body_` was still smaller than 7 bytes — e.g. calling `setReceptionLevel()` early in a builder sequence - C++ `TagExtendedProtocolMessage::setPayload` now keeps `Size` in sync (matching the C# `Payload` setter). `TagExtendedProtocolCO2Message`'s constructor never called `setPayload` at all, leaving `Size == 0` for any builder-constructed instance; `TagExtendedProtocolBinaryDataMessage` had the same gap via `setBinaryData`. Both are now fixed by this one shared change plus adding the missing constructor call - Added `TagExtendedProtocolRepeaterMessageUnitTest` covering the `TagMessage` getter and setter against the confirmed layout; replaced `TestRepeaterTagMessageDoesNotThrowOnUnreliableTypeGuess` (which asserted the previous, incorrect decode) with a defensive-fallback test for a too-short payload
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| .NET Framework | net46 is compatible. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.9 | 104 | 8/25/2026 |
| 4.0.8 | 87 | 8/25/2026 |
| 4.0.7 | 98 | 8/25/2026 |
| 4.0.6 | 91 | 8/24/2026 |
| 4.0.5 | 92 | 8/24/2026 |
| 4.0.4 | 105 | 8/24/2026 |
| 4.0.3 | 106 | 8/24/2026 |
| 4.0.2 | 98 | 8/23/2026 |
| 4.0.1 | 111 | 8/23/2026 |
| 3.0.68 | 270 | 6/17/2026 |
| 3.0.67 | 170 | 5/19/2026 |
| 3.0.66 | 400 | 8/26/2025 |
| 3.0.65 | 429 | 8/25/2025 |
| 3.0.64 | 415 | 8/25/2025 |
| 3.0.63 | 358 | 3/30/2025 |
| 3.0.62 | 358 | 3/10/2025 |
| 3.0.61 | 310 | 2/3/2025 |
| 3.0.60 | 279 | 1/30/2025 |
| 3.0.58 | 280 | 1/22/2025 |
| 3.0.57 | 292 | 1/21/2025 |
v4.0.9: TagExtendedProtocolRepeaterMessage.TagMessage (C#) / getTagMessage()/setTagMessage() (C++) reconstructed the relayed message with the wrong field layout; fixed per embedded firmware source and confirmed against three real captures -- the outer header/msg_num belong to the original relayed tag reused unchanged, the relayed message carries no header/msg_num/RSSI of its own (its RSSI is FirstRSSI), and CO2-wrapped-in-Repeater now decodes to physically plausible values in both ports. C++ TagMessage.setRSSI was not overridden for extended messages the way getRSSI was, causing an out-of-bounds write to a fixed offset when body_ was still small; now virtual and overridden to write body_.back(). C++ TagExtendedProtocolMessage.setPayload did not keep Size in sync (unlike the C# Payload setter), leaving builder-constructed CO2Message/BinaryDataMessage instances with Size==0; fixed, plus CO2Message's constructor now calls setPayload. v4.0.8: C++ TagExtendedProtocolCO2Message.Parse was missing the 26/27-byte length check C# has, so it silently accepted a wrong-length buffer and fabricated a plausible-looking CO2 reading instead of failing. TagExtendedProtocolRepeaterMessage.TagMessage (C#) / getTagMessage() (C++) now catch a failed nested-subtype Parse and fall back to the generic probe message instead of crashing/propagating -- the type byte driving that dispatch is a heuristic re-slice of the repeater's payload, not a confirmed field layout, and a wrong guess (e.g. colliding with CO2's enum value) must not take down the whole accessor. v4.0.7: TagExtendedProtocolRepeaterMessage.Parse (C# and C++) validated the received frame length against Size+4 (the outer serial envelope's length, not this class's own Star message length) instead of Size+1, the invariant every real gateway frame satisfies and every other TagMessage relies on; confirmed against live gateway captures and fixed. C++ TagMessage.getBytes() was also appending a CRC16-XModem checksum copy-pasted from the unrelated RFMMessage.getBytes() -- OldProtocol TagMessages carry no such per-message CRC on the wire -- which the Size+4 bug above had been masking; removed. Replaced the synthetic Repeater test fixtures (tuned to the old incorrect check) with real gateway captures, including a full round trip through MeshRSSIParser. v4.0.6: RFMeshParser.ParseFrame was calling BitStuffDecode a second time on frames that BitStuffingFrameDecoder had already decoded. Harmless when the decoded payload had no literal 0xAB/0xCD/0xEF bytes, but whenever it did (e.g. an RSSI of -17 == 0xEF), the redundant pass misread that real data as bit-stuffing control bytes — merging a literal 0xEF with the following byte, or silently dropping a literal 0xCD — corrupting the message. Removed the redundant decode call; ParseFrame now passes the already-decoded frame straight to the handler chain, matching the C++ implementation. v4.0.5: The v4.0.3 trim-length fix was itself off by one byte, re-widening the kept slice of the nested tag message past the outer CRC (silently misaligned fields, or "Payload is not correct" for double-hop-relayed CO2 readings); reverted to trimming 3 trailing bytes (RSSI + 2-byte CRC). TagExtendedProtocolRepeaterMessage now overrides RSSI/ReceptionLevel instead of inheriting them, since its body ends with [RSSI, CRC byte 1, CRC byte 2] rather than just [RSSI]. TagExtendedProtocolRepeaterMessage.Parse now validates the received frame length against Size+4, throwing a clear "Truncated Repeater message" error instead of a confusing unrelated failure two calls later in the nested message's own Parse. v4.0.3: TagExtendedProtocolRepeaterMessage.TagMessage dropped one byte too many when re-deriving the nested tag message, shifting its trailing fields (e.g. voltage/humidity byte misread as RSSI) instead of dropping only the CRC. v4.0.2: TagDataMessage now dispatches ExtendedProtocolMessageTypes.Repeater to TagExtendedProtocolRepeaterMessage (was falling through to the generic TagExtendedProtocolMessage, so repeater-relayed tag messages failed to unwrap/display). v4.0.1: BitStuffingFrameDecoder now extracts every complete frame per call instead of dropping/misattributing extras; AnchorLengthFrameDecoder validates the anchor byte and resyncs past trailing padding; TagExtendedProtocolCO2Message accepts the 27-byte repeater-relayed payload variant; MeshRSSIMessage.ReceptionLevel property added.