Lora UDP packet forwarder gateways compatibility


I develop an arduino based sensor, that is sending samples using LoRa gateway to an AWS server.

It is currently working using Pilot Gateway Pro, RAK 7243

The gateway is configured to use the Semtech udp packet forwarder.

I have a LoRa udp server on my AWS machine that successfully receives the packets and move their to contents to the next layer.

I want to use RAK7258 gateway. I setup the gateway using the same settings I have in the RAK 7243.

The packets arrive at the destination but the server throws CRC fail error on the gateway id CRC checking stage. It successfully reads the server id but it fails on CRC. I suspect that there is a difference in the way it calculates the gateway id part of the packet

Is there a difference in the packet forwarders of these gateways?

i can send the Configuration files of both gateways if needed.


There’s no encryption of the gateway ID in the Semtech UDP protocol. You can see the documentation of the protocol for yourself here:

packet_forwarder/PROTOCOL.TXT at master · Lora-net/packet_forwarder · GitHub

There’s no CRC below the level of the UDP transport, either.

There’s a CRC in raw LoRa packets, inserted and checked by the radio hardware.

Typically a gateway is set not to forward packets with invalid CRC, but the validity or not of CRC will be shown in the packet report.

Many kinds of LoRa traffic such as LoRaWan also use a cryptographic checksum within the radio packet body. If that’s coming in wrong you have collected actual errors in transmission, or have mismatches in the keys or frame counts used to calculated it.

That’s right, decryption is not the correct word, I fixed it, thanks.
Although it is not shown in the PROTOCOL.TXT page, the server is checking CRC in that stage and it always passes for the older gateway packets and fails for the newer gateway packets.Maybe it is the gateway MAC crc test, since the gateway ID is made of it.If i get it right it reads the 6 bytes starting from the 4th byte of the packet. 4,5 bytes are the CRC, 6-8 are the gateway id/MAC.

Sorry, but that’s simply not how the Semtech protocol works

The reality, as documented at the earlier link, is that the entirety of header bytes 4-11 constitute an arbitrary identifier. There is no internal pattern within that, and there is definitely not any sort of CRC or check byte there.

If your software improperly assumes there’s going to be some pattern within that field, then your software is incompatible with the standard protocol and will not work with a full range of standard gateways.

Probably on the pilot, that the value is constructed from an OUI belonging to Broadcom or the pi foundation, then has some filler and then the rest of the pi’s ethernet or wifi mac; but that particular OUI at the start would obviously only be true for a pi-based gateway. And even there, is only circumstance - there is no requirement whatsoever that a pi-based gateway not use some other fully arbitrary value, including one simply made up by the person installing it. As the sx1302 comes into wider use you’ll probably see gateways using the unique hardware ID of the concentrator chip rather than values derived from other network interfaces or made up.

If you want compatibility with the protocol, then you have to keep your expectations in line with the protocol, by treating header bytes 4-11 as the arbitrary and pattern-less identifier which they actually are.

Additional information that may help

1.Gateways server version:

Old gateway:

RAKWireless gateway RAK2245 version 4.0.0R

New gateway:

Firmware Version 1.2.0065_Release r209

2.Protocol related info:

packet_forwarder/PROTOCOL.TXT at master · Lora-net/packet_forwarder (github.com)

In this protocol description file, lines 100,102 you can find Token and GatewayID/MAC bytes.

I suspect the token is generated differently in each gateway,

It fails when it checks the crc of the gateway ID bytes in the received packet, and it uses the token in that process.

In the protocol documentation the token is explicitly stated to be RANDOM. It exists merely to match push/pull requests with their acks. Ideally it would be distinct for each request/ack cycle - presumably it’s there to protect against UDP’s rare but characteristic possibility of delivering packets out of order.


As long as your software expects things that are not part of the protocol, you should expect your software to fail, even if you lucked out in getting away with such invalid assumptions on one particular gateway, they are not valid assumptions and will not generally be met.

If you review the code included in the same repo as the protocol description; you will find that the CRC you are imagining simply is not there in a standard gateway:

Here you can see the uplink frame constructed using the arbitrary ID from the config file:

packet_forwarder/lora_pkt_fwd.c at master · Lora-net/packet_forwarder · GitHub

And here you can see a random token value filled in:

packet_forwarder/lora_pkt_fwd.c at master · Lora-net/packet_forwarder · GitHub

This is the behavior of the standard reference gateway, any expectation of anything else is an invalid assumption.

This is from the UDP server.

What am I missing?

Wherever that mystery code came from, it is NOT for use with the Semtech UDP protocol but only with some privately hacked variation or quite possibly some other protocol entirely.

Where did this code come from?

At the least you should remove the invalid check, but who knows what other incompatibilities you might find.

What exactly is the unusual server program you are trying to run here?

Then how come it works with the older gateway?

Either corresponding hacks to the packet forwarder on that gateway or blind luck.

It’s not something that should work, and it’s not going to work with any standard packet forwarder.

And again, what is the identity of this mystery incompatible server you are running?

I don’t know actually, but I can try to find out