UplinkEvent vs. UplinkFrame

I am successfully receiving data from the Gateway Bridge via MQTT, using protobuf messages. For all my application data, I get an appropriate UplinkEvent, and the message attributes contain the an “Event” value of “up” I use to parse the message accordingly. I have access to the dev_eui so I know the source of the data, and I use the f_port to determine the message type if necessary (I have many different devices and types of messages, and in my application the port is used to determine how to parse the application data protobuf).

I am also parsing Event values of type “join” and such. All good.

Other message types, such as stats, contains no “Event” message attribute, but contain a “subFolder” attribute I can use to parse the message properly, as the subFolder value is “stats” – no problem so far.

However, I regularly receive a message with the subFolder attribute “up” that is not an UplinkEvent, but is instead an UplinkFrame message. I can parse it, but I don’t know what to do with the phy_payload data. There is no indication of the source device, so I don’t know what the message represents and don’t know how to parse it. The log data for both Concentatord and lora_pkt_fwd don’t look any different between the UplinkEvent and UplinkFrame.

What am I missing? I can’t seem to find anything on the difference on the forum or in the docs.


That frame may be just providing statistics on gateway performance? Or how well a gateway handled the transfer of payload?

Here is the parsed UplinkFrame. This is quite different from gateway stats, and it originates from a device. I don’t know what the phy_payload data contains. So yes, it contains tx and rx info, but I’m looking for an explanation of

  1. How to parse the phy_payload
  2. Why is this not delivered as an UplinkEvent message?

To reiterate, I’m not missing any application data. The data that is expected from end devices is being received as UplinkEvent messages. These are arriving regularly and independently from the expected data, so I does seem to be some kinds of status or heartbeat.

Ignoring these messages has no negative effect on the application, but I would like to figure out what they are.

(I have masked some of the data)

  "phy_payload": "xxxxxgGANwJv+mDL9hEtvEmzXAhP6n0283hw+rCi0j4mypdZmZW32dAgTWLr9sSTgz3wSPWgWlhoaFaIfTMz2HiZb0B5phz247Z7UuzREqrN02SLdpX2I93xrRd4J11wWzKyym0R4S2hmb4Pd2d4rgCC6mfHcEXNTp9+yxYxxxxx",
  "rx_info": {
    "FineTimestamp": null,
    "channel": 2,
    "context": "xxxxCw==",
    "crc_status": 2,
    "gateway_id": "xxxx//6zf6M=",
    "lora_snr": 6.2,
    "rssi": -21,
    "time": {
      "nanos": 70152000,
      "seconds": 1631896745
    "time_since_gps_epoch": {
      "nanos": 70000000,
      "seconds": 1315931964
    "uplink_id": "xxxxJBNlSO+NngB5zafnhQ=="
  "tx_info": {
    "ModulationInfo": {
      "LoraModulationInfo": {
        "bandwidth": 125,
        "code_rate": "4/5",
        "spreading_factor": 7
    "frequency": 904300000

There appears to be a stand-alone LoRaWAN PHY Payload Parser, in python3.

This page dives pretty deep into purpose of physical LoRaWAN layer.

To me, it looks like UplinkFrame is a superset of UplinkEvent, that also contains some physical LoRaWAN layer data. Perhaps this is necessary when writing a LoRaWAN server, as that’s the only places where these terms happen to match :thinking:

BTW, I bookmarked the rfwireless-world link, as it gives good insight into LoRaWAN and other standards - so I thank you for helping me stumble upon it!

Thanks for suggesting the PHY parser. I didn’t use it, but it prompted me to start digging into live lorawan frames page in the Chirpstack web UI for one of the gateways. I can trace these as application messages. It appears I am receiving both the raw UplinkFrame as well as the parsed and UplinkEvent in the application.

The sequence is as follows:

  1. UplinkFrame is sent multiple times – once for each gateway that receives the message
  2. UplinkEvent is sent once, as expected

It is worth noting that I am using GCP, set up similar to the guide on the website.

The gateway only receives the message once. This does not happen for every message, nor for every message of the same type. It seems to be a random message from a random device, although it is the same type of device every time. The question seems to be: Why is the UplinkFrame getting through to the application?

I am still using Network Server 3.12.3, and a similar vintage Application Server. I just read through the release notes for all the releases, and although I do not see anything that seems to be related, it’s time to upgrade everything.

Update: I am now running the latest application and network server releases. I am still receiving the extra UplinkFrame messages, one for each gateway.

I am content to move on for now, ignoring these messages, but I will eventually come back to this. The result is extra GCP PubSub traffic. Although this is currently not a big deal, at a large scale there could be both performance and monetary costs.

I really like the changes to the live frames pages. Very nice.

Please note that there are two types of MQTT topics:

gateway/.... and

Could it be that your client is subscribed to both of these topics? Topics starting with gateway/.... will contain the GW <> NS communication, where application/... is intended for AS to end-application.