# RYLR998 NETWORKID ↔ LoRa Sync Word Mapping ## Discovery Through SDR captures and analysis, we discovered that the RYLR998 module's NETWORKID (0-255) maps directly to the LoRa sync word byte using a simple nibble-to-bin transformation. ## The Mapping ``` Sync Word Byte: 0xHH where H = high nibble, L = low nibble CSS Symbol 1 (sync_delta_1) = H × 8 = (NID >> 4) × 8 CSS Symbol 2 (sync_delta_2) = L × 8 = (NID & 0x0F) × 8 ``` The factor of 8 is a **fixed constant** used by RYLR998 (verified through SDR captures). This differs from standard LoRa which would use `N/16` scaling. ## Verification | NETWORKID | Hex | High Nibble | Low Nibble | Sync Bin 1 | Sync Bin 2 | Verified | |-----------|------|-------------|------------|------------|------------|----------| | 3 | 0x03 | 0 | 3 | 0 | 24 | ✓ | | 5 | 0x05 | 0 | 5 | 0 | 40 | ✓ | | 17 | 0x11 | 1 | 1 | 8 | 8 | ✓ | | 18 | 0x12 | 1 | 2 | 8 | 16 | ✓ | | 52 | 0x34 | 3 | 4 | 24 | 32 | (LoRaWAN)| ## Standard LoRa Sync Words | Name | Sync Byte | NETWORKID | Sync Bins | |---------------|-----------|-----------|-------------| | Private | 0x12 | 18 | [8, 16] | | LoRaWAN Public| 0x34 | 52 | [24, 32] | ## Code Implementation ### Python ```python def networkid_to_sync_word(nid: int) -> tuple[int, int]: """Convert NETWORKID to sync word symbol deltas.""" high_nibble = (nid >> 4) & 0x0F low_nibble = nid & 0x0F return (high_nibble * 8, low_nibble * 8) def sync_word_to_networkid(deltas: tuple[int, int]) -> int: """Convert sync word deltas back to NETWORKID.""" high_nibble = deltas[0] // 8 low_nibble = deltas[1] // 8 return (high_nibble << 4) | low_nibble ``` ### Full Range Table ``` NID=0 (0x00) → sync=[ 0, 0] NID=1 (0x01) → sync=[ 0, 8] NID=2 (0x02) → sync=[ 0, 16] ... NID=16 (0x10) → sync=[ 8, 0] NID=17 (0x11) → sync=[ 8, 8] NID=18 (0x12) → sync=[ 8, 16] ... NID=255 (0xFF) → sync=[120, 120] ``` ## Why This Matters 1. **Interoperability**: You can decode RYLR998 traffic with standard LoRa hardware by knowing the sync word 2. **Filtering**: Filter frames by NETWORKID in software without full decode 3. **Testing**: Generate RYLR998-compatible frames from any SDR ## SDR Capture Notes When capturing RYLR998 frames: 1. The preamble consists of 8+ upchirps at bin 0 2. Sync word is 2 upchirps with bins = nibble × (N/16) 3. SFD is 2.25 downchirps 4. Data follows with the encoded payload The sync word symbols are measured relative to the preamble bin (which represents the carrier frequency offset).