Receiving (decrypted) device data / FRMPayload

Please note that the data is not encrypted but base64 encoded. As the payload is basically an array of bytes, you either make sure that on the device you encode the data using the Cayenne LPP encoding, or you need to define your own decoder function to decode your data from an array of bytes to a JSON object.

Hi @trt_rtrt,

For just an example, I am sending an Hex payload over the node. So at mosquitto subscribing I will receive encode in base 64. So I used some libraries that take the data, decode64 and encode16. That returns my original data sent by node.

Which library did you use?

Hi @trt_rtrt!

For each application you can use owns called encripted/decrypted libraries.

For example if use Node-RED you can install encrypt library search n the Manage Palletes

Thanks for answering!

1 Like

Since LoRa App Server 0.19.0 you will also be able to see the live event logs for a given device. This will show the join, ack, error and uplink events and contain exactly the same data as the MQTT of HTTP integration messages. This is for debugging only, and is not a replacement for building integrations.

https://forum.loraserver.io/t/release-lora-app-server-0-19-0/1089

FYI, I am not seeing the downlink messages in the Live Event Log. I see the ack from a confirmed downlink, but not the downlink itself.

you can use this:

credits to @RussNelson

i’m try to send data from node to server, now it success but i can’t decode payloads. i’m not understand data format. someone explain for me.

note: i used to send this data to ttn then i’m modify that code for send to loraserver, in ttn payloads are hex ascii format it easy to decode.
.
.
.
this is data format that i can see

please help me !!!

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.