Receiving (decrypted) device data / FRMPayload

You’re looking at the raw LoRaWAN frames, this is for debugging not for integration. Please take a look at the live event logs, you’ll find the decrypted data there. Also see: https://www.loraserver.io/lora-app-server/integrate/sending-receiving/.

Note that data is base64 encoded.

As i know, on app server web interface data is decoded automatically, but you need to look in “Live event logs”.

Hello,
I’m still quite a beginner and just can’t get any further…

I just set up my gateway (RPI3+ iC880A with LoRa Gateway OS) and everything works so far. My device can be activated via ABP (1.03) and also sends data in the uplink. But I don’t know how to convert them.

In my device (Arduino MKR1300) I send the string “helloWorld” (HEX: 68 65 6C 6C 6F 57 6F 72 6C 64) and use the following keys:

  • devAddr: 01be3a44
  • nwkSKey: 11396d60f102cdb1015bc0ac39b6a128
  • appSKey: 51d212cf2e759e696b84feb07b7a535d

In the LIVE-Data of my device I get a json with data “aGVsbG9Xb3JsZA==”. How do I get my original information from this?

LIVE DEVICE DATA uplink:

[
{
    "type": "uplink",
    "payload": {
        "adr": true,
        "applicationID": "1",
        "applicationName": "LoRa_office214",
        "data": "aGVsbG9Xb3JsZA==",
        "devEUI": "a8610a3233378809",
        "deviceName": "MKR1300",
        "fCnt": 3,
        "fPort": 2,
        "rxInfo": [
            {
                "gatewayID": "b827ebfffe566321",
                "loRaSNR": 7.8,
                "location": null,
                "name": "",
                "rssi": -35
            }
        ],
        "txInfo": {
            "dr": 5,
            "frequency": 868500000
        }
    }
}

]
LIVE LORAWAN FRAMES uplink:

[
{
    "downlinkMetaData": {
        "txInfo": {
            "gatewayId": "b827ebfffe566321",
            "immediately": false,
            "timeSinceGpsEpoch": null,
            "timestamp": 154418027,
            "frequency": 868100000,
            "power": 14,
            "modulation": "LORA",
            "loraModulationInfo": {
                "bandwidth": 125,
                "spreadingFactor": 7,
                "codeRate": "4/5",
                "polarizationInversion": true
            },
            "board": 0,
            "antenna": 0
        }
    },
    "phyPayload": {
        "mhdr": {
            "mType": "UnconfirmedDataDown",
            "major": "LoRaWANR1"
        },
        "macPayload": {
            "fhdr": {
                "devAddr": "0072476f",
                "fCtrl": {
                    "adr": true,
                    "adrAckReq": false,
                    "ack": true,
                    "fPending": false,
                    "classB": false
                },
                "fCnt": 10,
                "fOpts": [
                    {
                        "cid": "LinkADRReq",
                        "payload": {
                            "dataRate": 5,
                            "txPower": 4,
                            "chMask": [
                                true,
                                true,
                                true,
                                true,
                                true,
                                true,
                                true,
                                true,
                                false,
                                false,
                                false,
                                false,
                                false,
                                false,
                                false,
                                false
                            ],
                            "redundancy": {
                                "chMaskCntl": 0,
                                "nbRep": 1
                            }
                        }
                    }
                ]
            },
            "fPort": null,
            "frmPayload": null
        },
        "mic": "7f35b3a7"
    }
},
{
    "uplinkMetaData": {
        "rxInfo": [
            {
                "gatewayId": "b827ebfffe566321",
                "time": null,
                "timeSinceGpsEpoch": null,
                "timestamp": 153418027,
                "rssi": -37,
                "loraSnr": 9.8,
                "channel": 0,
                "rfChain": 1,
                "board": 0,
                "antenna": 0,
                "location": null,
                "fineTimestampType": "NONE"
            }
        ],
        "txInfo": {
            "frequency": 868100000,
            "modulation": "LORA",
            "loRaModulationInfo": {
                "bandwidth": 125,
                "spreadingFactor": 7,
                "codeRate": "4/5",
                "polarizationInversion": false
            }
        }
    },
    "phyPayload": {
        "mhdr": {
            "mType": "ConfirmedDataUp",
            "major": "LoRaWANR1"
        },
        "macPayload": {
            "fhdr": {
                "devAddr": "0072476f",
                "fCtrl": {
                    "adr": true,
                    "adrAckReq": false,
                    "ack": false,
                    "fPending": false,
                    "classB": false
                },
                "fCnt": 4,
                "fOpts": [
                    {
                        "cid": "LinkADRReq",
                        "payload": {
                            "channelMaskAck": true,
                            "dataRateAck": true,
                            "powerAck": true
                        }
                    }
                ]
            },
            "fPort": 2,
            "frmPayload": [
                {
                    "bytes": "YGDq+3trviWyMw=="
                }
            ]
        },
        "mic": "3dc83b0f"
    }
}

]

See this code example: https://play.golang.org/p/GiGTor8Tf3Y

Hi there!

I’m testing the lora-server-app and I’d like to know how to decode a string sent from a lora node.

So far I see the encoded (base64) data on the data log, I implemented a decoder on JavaScript which is functional (I tested it outside the loraserver) and other decoders can also decode the payload correctly.

However, on the data log I see only gargbage (like chinese characters).

Below the code:

// Decode decodes an array of bytes into an object.
//  - fPort contains the LoRaWAN fPort number
//  - bytes is an array of bytes, e.g. [225, 230, 255, 0]
// The function must return an object, e.g. {"temperature": 22.5}

var Base64 = {
  _keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  encode:function(e)
  {
    var t = "";var n,r,i,s,o,u,a;
    var f = 0;
    e = Base64._utf8_encode(e);
    
    while (f < e.length) {
      n = e.charCodeAt(f++);
      r = e.charCodeAt(f++);
      i = e.charCodeAt(f++);
      s = n >> 2;
      o = (n & 3) << 4 | r >> 4;
      u = (r & 15) << 2 | i >> 6;
      a = i & 63;
      
      if (isNaN(r)) {
        u = a = 64
      }
      else if(isNaN(i)) {
        a = 64
      }
      
      t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
    }
    
    return t
  },
  decode:function(e)
  {
    var t = "";
    var n, r, i;
    var s, o, u, a;
    var f = 0;
    e = e.toString().replace(/\\+\\+[++^A-Za-z0-9+/=]/g, "");
    
    while (f < e.length) {
      s = this._keyStr.indexOf(e.charAt(f++));
      o = this._keyStr.indexOf(e.charAt(f++));
      u = this._keyStr.indexOf(e.charAt(f++));
      a = this._keyStr.indexOf(e.charAt(f++));
      n = s << 2 | o >> 4;
      r = (o & 15) << 4 | u >> 2;
      i = (u & 3) << 6 | a;
      t = t + String.fromCharCode(n);
      
      if (u != 64) {
        t = t+String.fromCharCode(r)
      }
      
      if (a != 64) {
        t = t + String.fromCharCode(i)
      }
    }
    
    t = Base64._utf8_decode(t);
    
    return t
  },
  _utf8_encode:function(e)
  {
    e = e.replace(/\r\n/g,"n");
    var t = "";
    
    for (var n = 0; n < e.length; n++) {
      var r = e.charCodeAt(n);
      
      if (r < 128) {
        t += String.fromCharCode(r)
      }
      else if (r > 127 && r < 2048) {
        t += String.fromCharCode(r >> 6 | 192);
        t += String.fromCharCode(r & 63 | 128)
      }
      else {
        t += String.fromCharCode(r >> 12 | 224);
        t += String.fromCharCode(r >> 6 & 63 | 128);
        t += String.fromCharCode(r & 63 | 128)
      }
    }
    
    return t
  },
  _utf8_decode:function(e)
  {
    var t = "";
    var n = 0;
    var r = c1 = c2 = 0;
    
    while (n < e.length)
    {
      r = e.charCodeAt(n);
      
      if(r < 128) {
        t += String.fromCharCode(r);
        n++
      }
      else if(r > 191 && r < 224) {
        c2 = e.charCodeAt(n+1);
        t += String.fromCharCode((r & 31) << 6 | c2 & 63);
        n += 2
      }
      else {
        c2 = e.charCodeAt(n + 1);
        c3 = e.charCodeAt(n + 2);
        t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
        n += 3
      }
    }
    
    return t
  }
}

function Decode(fPort, bytes) {
  var result = "";

  result = Base64.decode(bytes);
  
  return { "message": result };
}

Any ideas?

Hi Brocaar,

For your kind information, the recommended links are not working.
https://docs.loraserver.io/lora-app-server/integrate/data/
https://docs.loraserver.io/lora-app-server/integrate/integrations/

Thanks for mentioning, this has been fixed :slight_smile:

Hello brocaar, I’ve been following most of your answers through the forum and you seem to be very helpful!

I have tried the Go example to decode base64 encoded text but unfortunately I still being unable to decode it properly. This is the MQTT message I get from the node:


I am getting 2 payloads: C/4AmRUAmYIAmYIBAQIzX4zgM1+M4A== and 3EGIiDn/. Decoding it leads to weird text with weird symbols. Not readable at all:
3EGIiDn/. -> �A��9�
Any tip?

Thanks…

On your ARDUINO, you send the string “ helloWorld ” (HEX: 68 65 6C 6C 6F 57 6F 72 6C 64).
The must importante in this, it’s how this tram was encoded and sended !!!

You should search in your lora stack how the data are sent, but normally it’s send byte by byte and each caracter encoded by 8 bit and represented by two hex ( expl : ‘h’ => “68”).

So, you arduino should send 68 next 65 next 6C …

So you should in LORASERVER application configuration, creat a javascript that will restor your string byte by byte.

Exemple :

        function Decode(fPort, bytes) {

                   var my_string = bytes[0] << 72| bytes[1] << 64| bytes[2] << 56 | bytes[3]  << 48| bytes[4] << 40| bytes[5] << 32| bytes[6] << 24| bytes[7] << 16| bytes[8] << 8|  bytes[9];
                
                   return {
                              "message": my_string,
                          };
           }

The payload is not intended to be human readable (usually), it’s simply bytes. You have likely decoded it correctly. What those bytes actually mean will depend on your device. You should check your device’s docs and see how those bytes should be interpreted.

Hi @trt_rtrt, can you help please. I’m using http instead of mqtt, but i don’t know what API i must use to take the data.

Hello bro, can i get working link for this?
https://docs.loraserver.io/lora-app-server/integrate/data/
https://docs.loraserver.io/lora-app-server/integrate/integrations/

just replace https://docs.loraserver.io with https://www.chirpstack.io

1 Like

Hi brocaar,
I tried to use your example (https://play.golang.org/p/GiGTor8Tf3Y) in
Device Profile…device…Codec…Custom Javascript Codec Functions
There is no result in the MQTT feed.
I have the same problems as the others:
I convert a string to hex in my edge device. When it arrives in the MQTT feed, the hex payload seems to be base64 encoded. Using standard tools I can manually convert it back to text. However the mosquitto broker acts as a bridge and sends the data on to a cloud application. So I would like to convert the data back into the original json string BEFORE it reaches the broker.
I read all the documentation you cited, but frankly have not been able to make heads or tails of the MQTT Integration functionality. Certainly its not obvious from the documentation what one has to do. The only thing I could figure out was to change marshaler=“protobuf” to marshaler=“json” in chirpstack-gateway-bridge.toml. Now at least the payload is in string form, but the Decode function asks for a variable in byte array form:
function Decode(fPort, bytes, variables) {…
So how can I use this Decode function when the input is now a base64 string?

try to decode your data in the js codec, after that, when you will subscribe on the mqqt subject, you will find all your data decoded and not in base64 format !

I wrote a C# app which does this perfectly. Unfortunately I am not versed in javascript.
Actually I need to first decode from unicode byte array to base64 string, then from base 64 string to readable string. Are there any examples how to do this in javascript. And how do I add the import (library?) statement in brocaar’s example to the codec, since it does not accept it?

It’s depend, how you encode your data in the software sensor.
you should know how much bytes you send in your payload, and how much byte you encode every variables ! and finally you check if you encode on big / little endian.
You couldn’t find exemple, it can be anything :
exemple :
you encode in your sensor :

  uint32 temperature = 25;  // encoded on 4 bytes

to decode this in js codec, you will take every byte and shift them, to reconstructed your data :

function Decode(fPort, bytes) {

 var temperature_byte  = bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
 return {
              "temperature"       : temperature_byte  ,
        };
                               }

The placement of byte numbers depends on the direction you have chosen on the sensor Little or big endian.

If you have a lot of data to process, I advise you to train a little in JS !

ok, thanks, another language.
But in chirpstack-gateway-bridge.toml I set marshaler=“json”.
What does that do?

Thx, I will first try your function with uint32 temperature, and then expand from there.
When I use the following function in the codec:
function Decode(fPort, bytes, variables) {
var temperature_byte = bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
return
{
“temperature” : temperature_byte
};
}

I get the following error under Device Data:

  • type:“UPLINK_CODEC”
  • error:“execute js error: js vm error: (anonymous): Line 10:20 Unexpected token :”

the device data UpLink node value for data is:

  • data:“MjU=”
    The codec Javascript Function has the following signature:
    function Decode(fPort, bytes, variables) {…
    what is the value of bytes in this function?