Giter Club home page Giter Club logo

lora-packet's People

Contributors

anthonykirby avatar dependabot[bot] avatar felipefdl avatar kalik1 avatar ngraziano avatar nunomcruz avatar ricardostoklosa avatar taraskuzyk avatar tommas-factorylab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lora-packet's Issues

Online decoder using wrong Session Key

I noticed that the online decoder is not using the right key for MIC comparison.

If a given packet uses FPort > 0, then the key being used for MIC calculation is the NetSessionKey instead of the AppSessionKey

Typescript and support for modern Node.js API

hi @anthonykirby, I'm the software architect at TagoIO, the lora-packet is amazing, we would like to use the library on our Payload Parser feature, however, we use typescript types for auto-completion on our front-end (online editor) also the current version is using deprecated API from Node.js as new Buffer(). So, we have rewritten the library to use Typescript and fix it to use new Node.js API (>10.x), also it keeps the same functions, same arguments, totally compatible, so I would like to know if you have the interest to merge both projects to avoid unnecessary fragmentation.

Thanks.

How to use the library with TypeScript ESM?

Hi,

I'm trying to use the library with a node ESM package.
I'm sure that I'm missing something, but I cannot make lora-packet work with ESM and TypeScript.

Could it be possible to create an ESM release of lora-packet ?

.toString() function giving "Attempt to access memory outside buffer bounds" on Join Accept messages

I wrote a script that logs out packets as they are received from the sensors. Data messages work without issue, however when it tries to read in a Join Accept it will throw an error when stringify is attempted.

var loraPacket  = require('lora-packet');

let payload;

payload = "MIAAAA==";
// payload = "QPF9vkkAAgABlUN4disR/w0="; // base64 equivalent to 40F17DBE4900020001954378762B11FF0D used on the npm example

let bytes = Buffer.from(payload, "base64");
let packet = loraPacket.fromWire(bytes);

console.log(packet.toString());

If you uncomment the second payload, .toString() will work without issue.

This occurs on every join accept received, currently I am simply ignoring the output of these message types but it would be extremely helpful if this data could be logged in this format.

Decrypt Packet

Hi @anthonykirby ,

I really need your help.

I've subscribed to lora mqtt topic from node and get the json.

{"devEUI":"0102030405060708","fPort":1,"gatewayCount":1,"rssi":-74,"data":"APyLyjXKDQ=="}

I already have appSKey and nwkSKey.

But I don't know how to use your library to decrypt the data.

In your documentation, you wrote this

// decode a packet
var packet = lora_packet.fromWire(new Buffer('40F17DBE4900020001954378762B11FF0D', 'hex'));

Is the string in Buffer construction should be replaced with data from my JSON?

I really appreciate your help.

Thanks

Support of LoRaWAN 1.0.2

Like the issue#25, I did another comparison between LW 1.0.1 final and the 1.0.2 final version:
https://www.draftable.com/compare/xbpYDtNRPAPH

Here are the main differences :

  • Physical layer moved to a dedicated document named "Regional Parameters" (last version for LW 1.0.2 (RevC) in attachment
    LoRaWAN Regional Parameters v1.0.2_revB.pdf
  • Some typo correction and refactoring
  • Two new MAC commands: (0x0A) DlChannelReq/Ans and (0x09) TxParamSetupReq/Ans
  • Clarification regarding AppKey
  • The end-device is able to process multiples ADRReq in a single block

It's not a big deal to be 1.0.2 compliant and I can help you to do it

New parsed field

Hello,

I am working on an device which use lora.

I tried to parse the following frame :
Message Type = Data
PHYPayload = 6049270226BA00000340020071033500FF0101867B63F7834E04CAC51E59

      ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
              MHDR = 60
        MACPayload = 49270226BA00000340020071033500FF0101867B63F7834E04
               MIC = CAC51E59

      ( MACPayload = FHDR | FPort | FRMPayload )
              FHDR = 49270226BA00000340020071033500FF01
             FPort = 01
        FRMPayload = 867B63F7834E04

            ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
           DevAddr = 26022749 (Big Endian)
             FCtrl = BA
              FCnt = 0000 (Big Endian)
             FOpts = 0340020071033500FF01

      Message Type = Unconfirmed Data Down
         Direction = down
              FCnt = 0
         FCtrl.ACK = true
         FCtrl.ADR = true

It seems that the field FPending in FCtrl is missing.

Could you help on that?

Regards,

Could you explain this error, please.

Error (lora-packet verify): expecting pktBufs packet.MIC to be a Buffer length=4

I can send you the packet and keys if you want. It was a 28 byte payload that should have had GPS readings. A friend has just put up a LoraWAN gateway, and was receiving my packets but I wasn't getting data from TTN, so I copied and pasted from his screen into your simulator to see if it decoded.

Error on decoding

Hi,
I have a MAC payload "0307" which is normaly a "UnconfirmedDataUp". But the decoding function return a Mtype = Join Request.

Any idea please ?

Thx

Support of LoRaWAN 1.0.1 final

As I can see on the README.md, the current implementation is based on LoRaWAN 1.0.1 draft 3.
I did first a quick comparison between LW 1.0.1 draft 3 and the final version:
https://www.draftable.com/compare/aywIsYazscsj

Here are the main differences (very few):

  • General refactoring and typo correction
  • New paragraph page 20 to explain that FPort 224 is dedicated LoRaWAN Mac layer test protocol
    when draft 3 just say that FPort 224 to 255 are reserved
  • RXParamSetupAns and RXTimingSetupAns but there is no impact on packet parsing or generation.

By checking quickly the difference it will be possible to say that the lora-packet module is LW 1.0.1 compliant

Buffer Deprecation Warning

Hi,

the lora-packet is raising a DeprecationWarning, as shown in following the image
image

This is due to the node-aes-cmac lib that uses the deprecated Buffer constructor. There is a PR in the original repo fixing this, but was completely ignored. The last update was 7 years ago.

One possible solution is to use aes-cmac. This is a typescript implementation of node-aes-cmac.

Packet decoding as a service

Could i use this library as a service? Essentially, i would like to send the phy payload that my mqtt broker receives from my gateway to the cloud. Then i would like to make requests to the service with the phy payload as input and then it could return me as json format the output with the decoded and decrypted lora packet information.Is is feasible?

After FCNT crosses 65535, MIC Matched, but decryption of data is wrong

Till 65535, decryption of data is perfect, but after rollover, MIC packet matched, but decryption goes wrong, I think it is due to not taking fcnt as 32bit after rollover (i.e. if after rollover value of FCNT is 10, then 65545, value of FCNT should take for decryption.

Thank You

Decode Beacon frame

Could be fine to decode beacon frames 😄

See LoRaWAN Specification, Chapter 15: Beaconing (Class B option)

npm issue

Showing error while installing lora decoder using npm

Lora packet Decoding

Hi Anthony,
I find your work on LoRa packet decoding quite intersting. I am currently exploring LoRAWAN with TTN.
I have hard time decoding these payloads.

My data is: 7B226D656173757265496473223A5B315D2C2276616C756573223A5B32325D2C2270726F66696C654964223A313030327D

to me this looks like a HEX string.

I am following the same example you have provided in this GitHUB. How ever when I use the nwSKey and AppSKey, I am not able to see my payload decoded.

The MIC check fails. Is there a way to cross check the decoding process ?
any help is appreciated
Dom

Command Line frame decoding ...

Hello!

I've got the following :
lora-packet-decode --appkey 176C3C601A5FEE50F26FA6D1D193D611 --nwkkey 4A43B74FE531126056CDE739EC05C92B --base64 QNmZCyYAMFwFAVh1pho=

Which yields :

decoding from Base64:  QNmZCyYAMFwFAVh1pho=
Decoded packet
--------------
Message Type = Data
            PHYPayload = 40D9990B2600305C05015875A61A

          ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
                  MHDR = 40
            MACPayload = D9990B2600305C0501
                   MIC = 5875A61A (BAD != CF0C43F5)

          ( MACPayload = FHDR | FPort | FRMPayload )
                  FHDR = D9990B2600305C
                 FPort = 05
            FRMPayload = 01
             Plaintext = CC ('.')

                ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
               DevAddr = 260B99D9 (Big Endian)
                 FCtrl = 00
                  FCnt = 5C30 (Big Endian)
                 FOpts = 

          Message Type = Unconfirmed Data Up
             Direction = up
                  FCnt = 23600
             FCtrl.ACK = false
             FCtrl.ADR = false
       FCtrl.ADRACKReq = false

But I know the key and transmission to be good. I also have checked on that website :
https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh/?data=QNmZCyYAMFwFAVh1pho%3D&nwkskey=4A43B74FE531126056CDE739EC05C92B&appskey=176C3C601A5FEE50F26FA6D1D193D611
Which seems to use your tool ... but which gave me :

Assuming base64-encoded packet
QNmZCyYAMFwFAVh1pho=

Message Type = Data
  PHYPayload = 40D9990B2600305C05015875A61A

( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
        MHDR = 40
  MACPayload = D9990B2600305C0501
         MIC = 5875A61A (from packet)
             = 5875A61A (expected, assuming 32 bits frame counter with MSB 0001)

( MACPayload = FHDR | FPort | FRMPayload )
        FHDR = D9990B2600305C
       FPort = 05
  FRMPayload = 01 (from packet, encrypted)
             = CC (decrypted)

      ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
     DevAddr = 260B99D9 (Big Endian)
       FCtrl = 00
        FCnt = 5C30 (Big Endian)
       FOpts = 

Message Type = Unconfirmed Data Up
   Direction = up
        FCnt = 23600 (from packet, 16 bits) 
             = 89136 (32 bits, assuming MSB 0x0001)
   FCtrl.ACK = false
   FCtrl.ADR = false

Happy to help if I can answer any question

Just did a fresh Node lts install ... and installed your tool using npm. (so should be pretty much last version)

Decrypt FramePayload

Is there also a terminal command to take the framepayload as input and the AppSKey and return the decrypted output?

Construct a packet with no payload

Hello Anthony,

And first of all, things for this library, it's great! :)

I'm trying to use it with Node-Red do do a minimal LoRaWAN server, and I'm trying to send a downlink packet to respond to a "Confirmed Data Up".
This kind of response does not require a FRMPayload, and so does not require a FPort.

But I can't find the way to specify such a packet to the fromFields() function.
When I set the 'payload' field empty, I still get the FPort set. Can we avoid it?

My code is like:

var constructedPacket = lora_packet.fromFields(
    {
        payload:'',
        MType: 'Unconfirmed Data Down',
        DevAddr: new Buffer('11223344', 'hex'),
        FCtrl: {
            ADR: false,       // default = false
            ACK: true,        // default = false
            ADRACKReq: false, // default = false
            FPending: false   // default = false
        },
        FCnt: new Buffer('0000', 'hex'), // can supply a buffer or a number
    },
    null,
    new Buffer("2B7E151628AED2A6ABF7158809CF4F3C", 'hex') // NwkSKey
);

And I get the frame:
YK8BzAAgAAABmjJuDQ==

( MACPayload = FHDR | FPort | FRMPayload )
FHDR = AF01CC00200000
FPort = 01
FRMPayload =

It's not really critical, but we could avoid this extra-byte for FPort. Is that possible?

Thanks a lot

LoRa packets from YoLink sensors

YoLink provides a range of smart home sensors that communicate with the hub over LoRa. I sniffed few LoRa packets off the temperature and humidity sensor.
I used the following components to do this...

  1. https://github.com/rpp0/gr-lora
  2. An RTL-SDR

I had to make the following changes to the grc files...

  1. Changed the radio frequency to 910.3 (found by scanning the permitted range in USA)
  2. Changed the spreading factor to 7

Here are few packets I sniffed every time I pressed the button on the sensor...

 26 31 d0 80 9e c1 05 0b 00 44 01 01 d2 17 b9 d1 f3 05 ee 1c 41 73 14 c4 6b b8 61 cf 7e 76 01 b3 94 7f 39 25 34 e2 ad 12 cc 83 d2 (DAska~v9%4)
 26 31 d0 80 9e c1 05 0b 00 45 01 01 7d f3 2b 99 60 9e f7 4d 05 aa 99 56 2d 8a f6 2f 3d a2 b0 03 fd 5c 53 64 fb d3 f9 3b bd c0 38 (E}+`MV-/=\Sd;8)
 26 31 d0 80 9e c1 05 0b 00 46 01 01 39 7f 17 e6 22 60 80 ac 77 76 fe 4a 0c 6c ac ab 73 a0 6b d2 9c 9b 84 e5 2d ae 67 62 74 ce 07 (F9"`wvJlsk-gbt)
 26 31 d0 80 9e c1 05 0b 00 47 01 01 4b 82 db fb 7e f7 4a 70 43 10 93 ae 14 16 49 45 c5 0b 78 37 3d 5d ff d1 a8 13 cd cf 58 98 12 (GK~JpCIEx7=]X)
 26 31 d0 80 9e c1 05 0b 00 48 01 01 dc c1 b5 38 8c 1f 78 7d bf c6 51 56 c0 eb e8 bd 6d 6b 8b 82 ed cf 3b c9 30 f2 84 08 78 6b dc (H8x}QVmk;0xk)
 26 31 d0 80 9e c1 05 0b 00 49 01 01 b6 a9 f3 e5 09 70 7c 00 a3 bf de b2 30 3e 7e 09 8b 25 49 7e 25 64 75 76 23 7d b4 e0 f1 14 1e (Ip|0>~%I~%duv#})
 26 31 d0 80 9e c1 05 0b 00 4a 01 01 60 8d 48 34 ce c6 52 05 ee 55 c0 ea 16 a0 a5 eb 09 c4 60 a2 1b 88 4c d1 e3 fc 17 72 47 1b 6c (J`H4RU`LrGl)

FCnt upper bytes are always all zeroes

Hi Anthony, nice work building this node module!

I have some nodes that have been sending data for quite a while now. If I parse the raw data (using the correct NwkSKey / AppSKey I do not get the result I expect: e.g.:

Message Type = Data
  PHYPayload = 40232E012600711C06BE41598238

( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
        MHDR = 40
  MACPayload = 232E012600711C06BE
         MIC = 41598238

( MACPayload = FHDR | FPort | FRMPayload )
        FHDR = 232E012600711C
       FPort = 06
  FRMPayload = BE

      ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
     DevAddr = 26012E23 (Big Endian)
       FCtrl = 00
        FCnt = 1C71 (Big Endian)
       FOpts = 

Message Type = Unconfirmed Data Up
   Direction = up
        FCnt = 7281
   FCtrl.ACK = false
   FCtrl.ADR = false

All of the above is correct.

Of course, you are parsing the encrypted data exactly as per spec so that is not the problem, the thing is however that my FCnt has already rotated past 0xFFFF. So actually for the given message the FCnt that was used by the node to encrypt the message was 0x11C71 (notice the extra 0x1 in front, instead of 0x1C71). The fact that over the air only 2 FCnt bytes are sent means that there is an extra burden on the receiving side to remember the actual FCnt for each particular node.

This causes the 'decrypt' to fail; if I put in the correct higher two bytes in lib/crypt.js:88

87       util.reverse(packet.getBuffers().FCnt),
88       util.bufferFromUInt16LE(0x01), // upper 2 bytes of FCnt (zeroes, sometimes higher ;-) )

the decryption results in the data I expect.

Still investigating the best approach for a solution, if I find one I'll create a PR for you to review

Where to find Nwskey and Appskey

Hi,

I am new to LoRaWAN. I have a lora packet, where I have to provide the Nwskey and Appskey for the tool to decrypt my data. Could any one help me locate the Appskey and Nwskey of the communication. Where can i find the same in my gateway/application?

Your support is required!

Thanks.

decryptJoin question

excuse me, I have a join accept packet's PHY paylod from ttn webpage, I want to decode and decrypt it, what should I do??

command not found

Hello,
I've installed lora-packet on Ubuntu 2204

npm -v
9.2.0
node -v
v19.3.0

npm install --no-fund lora-packet
up to date, audited 19 packages in 2s

when i try to run command-line packet decoding
e.g.
~$lora-packet-decode --hex 40F17DBE4900020001954378762B11FF0D
~$lora-packet-decode: command not found

what am I doing wrong?

Lora Join accept giving error in Crypt JS

When I try to decrypt join accept message, it is giving error in crypto.js Line 131

var packet = lora_packet.fromWire(new Buffer('20425f1c2efd7e1079e704298cfec4814be1f18c6c8b9babd632ea2dfc3eb6242b', 'hex'));

appKey = new Buffer("2b7e151628aed2a6abf7158809cf4f3c", 'hex');

console.log("packet.toString()=\n" + packet);
var DecryptedPacket = lora_packet.decryptJoinAccept(packet, appKey);

console.log("packet.toString()=\n" + DecryptedPacket);

Some packet parsing errors

Awesome job. In the guise of helping out, below are a few packets we're seeing failures on (we're not the source of these, just sniffing so they could be malformed or non LoRaWAN anyway).

{"tmst":2561278763,"chan":3,"rfch":0,"freq":917.4,"stat":-1,"modu":"LORA","datr":"SF7BW125","codr":"4/8","lsnr":-11.2,"rssi":-103,"size":32,"data":"MxBer9FeBKYocsl/ghlVobdUIPD/zCDPmZNH4YqoojU="}
/usr/local/lib/node_modules/lora-packet/lib/packet.js:707
            msg += "DLSettings.RX1DRoffset = " + that.getRxOneDRoffset() + "\n";
                                                      ^

TypeError: that.getRxOneDRoffset is not a function
    at LoraPacket.toString (/usr/local/lib/node_modules/lora-packet/lib/packet.js:707:55)
    at Socket.stage0.on (/Users/rob/Documents/repositories/nisient/loragw/gwtest1680.js:44:41)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)

    
{"tmst":101395732,"chan":5,"rfch":1,"freq":917.8,"stat":-1,"modu":"LORA","datr":"SF7BW125","codr":"4/7","lsnr":-11,"rssi":-103,"size":107,"data":"OzXyHlIP87QFJcUUSwJJ05OfMI16FN+11LBIFbx0i3Ml76YDsWE6EXTuVIHcZHq8W9y7YkvXIzD/UjDn90geq+cIc1ESELjmS/3PKQuz2mkh4gaIODijgYsO6y3tgS5pN8GfWnWFfaL6QnM="}
/usr/local/lib/node_modules/lora-packet/lib/packet.js:707
            msg += "DLSettings.RX1DRoffset = " + that.getRxOneDRoffset() + "\n";
                                                      ^

TypeError: that.getRxOneDRoffset is not a function
    at LoraPacket.toString (/usr/local/lib/node_modules/lora-packet/lib/packet.js:707:55)
    at Socket.stage0.on (/Users/rob/Documents/repositories/nisient/loragw/gwtest1680.js:45:42)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)

    
{"tmst":1159216707,"chan":4,"rfch":1,"freq":917.6,"stat":-1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":-12.5,"rssi":-103,"size":82,"data":"LguOqcAjnlkI3QiAlgbBFu4jHqHM6fkVARZiMz0wkO1LxfR8xzTJ2bC6Zv9geek2gTorqOUIgSLQZKpKvuZGUc9NsbZBegjRKqmzhvS0IfkNQQ=="}
/usr/local/lib/node_modules/lora-packet/lib/packet.js:707
            msg += "DLSettings.RX1DRoffset = " + that.getRxOneDRoffset() + "\n";
                                                      ^

TypeError: that.getRxOneDRoffset is not a function
    at LoraPacket.toString (/usr/local/lib/node_modules/lora-packet/lib/packet.js:707:55)
    at Socket.stage0.on (/Users/rob/Documents/repositories/nisient/loragw/gwtest1680.js:44:42)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)
 
    
{"tmst":2889130812,"chan":5,"rfch":1,"freq":917.8,"stat":-1,"modu":"LORA","datr":"SF7BW125","codr":"OFF","lsnr":-8.8,"rssi":-102,"size":6,"data":"mp6cIKwk"}
buffer.js:972
    throw new RangeError('Index out of range');
    ^

RangeError: Index out of range
    at checkOffset (buffer.js:972:11)
    at Buffer.readInt8 (buffer.js:1098:5)
    at _initialiseFromWireformat (/usr/local/lib/node_modules/lora-packet/lib/packet.js:166:33)
    at LoraPacket._fromWire (/usr/local/lib/node_modules/lora-packet/lib/packet.js:116:13)
    at Object.exports.fromWire (/usr/local/lib/node_modules/lora-packet/lib/packet.js:7:8)
    at Socket.stage0.on (/Users/rob/Documents/repositories/nisient/loragw/gwtest1680.js:43:26)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)
    
    
{"tmst":2039534628,"chan":6,"rfch":1,"freq":918,"stat":-1,"modu":"LORA","datr":"SF7BW125","codr":"4/6","lsnr":-12,"rssi":-102,"size":230,"data":"L6B+BD7/WzsJh+uNIHwKa3rV1/kP63fYQhYwXpAQWoDdsPu6iSOL9DPaC8HsKpMaFHc96wcLX5fh5SCd+mO5AoGdagie9Cdxz4bJo52R5hwDbWTXeOta0CXv+GM1vP5sBsD2hCF6NterPz3QeC7/8VvN7hfohVdkWneAa2r6JhXwFisPbh4V2Bfxrvn1k7Prc4BMVHdzt7WpTVVUUvckypPo52K1L5bl0pd1C5XD6ULNzmUSs9y9vdGsNow3PM8HScxLDvUgm9ENuooeTiEh9zmIxLSFp2OHIV0bf7TmCw4e8EPF/pE="}
/usr/local/lib/node_modules/lora-packet/lib/packet.js:707
            msg += "DLSettings.RX1DRoffset = " + that.getRxOneDRoffset() + "\n";
                                                      ^

TypeError: that.getRxOneDRoffset is not a function
    at LoraPacket.toString (/usr/local/lib/node_modules/lora-packet/lib/packet.js:707:55)
    at Socket.stage0.on (/Users/rob/Documents/repositories/nisient/loragw/gwtest1680.js:44:42)
    at emitTwo (events.js:126:13)
    at Socket.emit (events.js:214:7)
    at UDP.onMessage [as onmessage] (dgram.js:658:8)
    

Decrypted string shows random characters.

I have tried decrypting a payload. In this process, the decoding is successful, MIC Check came to be "OK".
packet MIC and calculated MIC came out to be identical.
But the Decrypted messages shows random values like �!\u0000 or \t etc.

Here is the sample data that I have used for decryption.

Payload: 402B19012600040001B2E2E4F81F44B6
NetworkSKey: EA68299F93F4AB9886D36755E7E23FC3
AppSKey: 57D69E5DE46FEAF8B5FBF6CC1F436B58

Output:

  "packet.toString()=\nMessage Type = …CK = false\n FCtrl.ADR = false\n"

  packet.toString()=
  Message Type = Data
  PHYPayload = 402B19012600040001B2E2E4F81F44B6

  ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
  MHDR = 40
  MACPayload = 2B19012600040001B2E2E4
  MIC = F81F44B6

 ( MACPayload = FHDR | FPort | FRMPayload )
 FHDR = 2B190126000400
 FPort = 01
 FRMPayload = B2E2E4

 ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
 DevAddr = 2601192B (Big Endian)
 FCtrl = 00
 FCnt = 0004 (Big Endian)
 FOpts = 

 Message Type = Unconfirmed Data Up
 Direction = up
 FCnt = 4
 FCtrl.ACK = false
 FCtrl.ADR = false

"packet MIC=f81f44b6"
"FRMPayload=b2e2e4"
"MIC check=OK"
"calculated MIC=f81f44b6"
"Decrypted='�!\u0000'"

The actual data sent from the node is a number - "222555".

  1. What is the data type of the final output? How can I convert it to get the actual payload?
  2. Am I missing something in the whole process of decryption?
  3. What is MIC here?

Tried on npm Runkit: https://npm.runkit.com/lora-packet

Please provide full decryption/encryption examples for up/down communication

Hello,

First of all I'm glad that I found your project. My research shows that everybody is just going the easy way using the thingsnetwork but I see no point in my case. I would like to receive data from my weather station and occasionally send some commands to it, I don't want to be limited to any like 40 messages per day etc.

I would like to setup an own private lora gateway which decrypts packet just for my device, ignores everything else and processes the output locally on a raspberry pi, eg data comes in->decode->write to text file.

Thank you

MIC always wrong for packets from Oyster?

Hi,

The Digital Matters Oyster node sends packets like this:

800E21062602900AE4AE010FCD776DB3DF96F4CB75656695F9CC

However, lora-packet always says the MIC is wrong.

$ node_modules/lora-packet/bin/lora-packet-decode --appkey E144C6ACB81F17F05CFEB90EF55D615C --nwkkey 448B20D2E0ED62F3DC61ADE7B589B65A --hex $trimmed_line
decoding from Hex:  800e21062602900ae4ae010fcd776db3df96f4cb75656695f9cc
Decoded packet
--------------
Message Type = Data
            PHYPayload = 800E21062602900AE4AE010FCD776DB3DF96F4CB75656695F9CC

          ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
                  MHDR = 80
            MACPayload = 0E21062602900AE4AE010FCD776DB3DF96F4CB7565
                   MIC = 6695F9CC (BAD != F9CC34D1)

          ( MACPayload = FHDR | FPort | FRMPayload )
                  FHDR = 0E21062602900AE4AE
                 FPort = 01
            FRMPayload = 0FCD776DB3DF96F4CB7565
             Plaintext = E5F33FEDA757FB5A6900A5 ('..?..W.Zi..')

                ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
               DevAddr = 2606210E (Big Endian)
                 FCtrl = 02
                  FCnt = 0A90 (Big Endian)
                 FOpts = E4AE

          Message Type = Confirmed Data Up
             Direction = up
                  FCnt = 2704
             FCtrl.ACK = false
             FCtrl.ADR = false
`

I'm pretty confident in those keys because the FRMPayload plaintext is correct (it's an actual, accurate, GPS packet).

Let me know if I can provide anything else to help.

About the payload from different sensors

I have the Nexus Demoboard from ideetron which sends some temperature and humidity measures at a specific logic for the Things Network and the Cayenne Dashboard.

If i choose to buy customed temperature/humidity sensors , they will send a payload at a different logic and they cannot be configured.

Do you think that i have to use the same sensors for my app in order to receive the same type of payload at the uplink?

unable to decode payload: FRMPayload is empty

I've double checked all the nwk and appkey to be correct, and confirmed that the data works fine int he ttn device data console. When I try to use the module through node red, the msg.payload.out if emnty.

when I tried the CLI for lora_packet I get the same blank payload returned.

./node_modules/lora-packet/bin/lora-packet-decode --appkey "7679A920DC79C0DECC693E34E670B11F" --nwkkey "4BBA414130E0A0C87FE0A7EAA257E9BD" --base64 "YGcXASaKCwADQAIAcQM1AP8BbePzEg=="

decoding from Base64: YGcXASaKCwADQAIAcQM1AP8BbePzEg==
Decoded packet

Message Type = Data
PHYPayload = 60671701268A0B000340020071033500FF016DE3F312

      ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
              MHDR = 60
        MACPayload = 671701268A0B000340020071033500FF01
               MIC = 6DE3F312 (OK)

      ( MACPayload = FHDR | FPort | FRMPayload )
              FHDR = 671701268A0B000340020071033500FF01
             FPort = 
        FRMPayload = 

            ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
           DevAddr = 26011767 (Big Endian)
             FCtrl = 8A
              FCnt = 000B (Big Endian)
             FOpts = 0340020071033500FF01

      Message Type = Unconfirmed Data Down
         Direction = down
              FCnt = 11
         FCtrl.ACK = false
         FCtrl.ADR = true

in the ttn console the data is on port 1, (but port in outpue is "")

this should return the byte array of be9e524781aa01070f2a

Join Accept details cannot be shown without decrypting using the AppKey

lora-packet shows incorrect details for a Join Accept:

  1. Without first decrypting the message, the following lines in _initialiseFromWireformat are not quite valid:

    lora-packet/lib/packet.js

    Lines 138 to 149 in 53190fa

    } else if (that.isJoinAcceptMessage()) {
    p.AppNonce = util.reverse(incoming.slice(1, 1 + 3));
    p.NetID = util.reverse(incoming.slice(4, 4 + 3));
    p.DevAddr = util.reverse(incoming.slice(7, 7 + 4));
    p.DLSettings = incoming.readInt8(11);
    p.RxDelay = incoming.readInt8(12);
    if (incoming.length == 13+16+4) {
    p.CFList = incoming.slice(13, 13+16)
    } else {
    p.CFList = new Buffer(0);
    }
    p.MIC = incoming.slice(incoming.length - 4);

  2. I guess toString should only print the message type, without any of the erroneous details:

    lora-packet/lib/packet.js

    Lines 408 to 414 in 53190fa

    } else if (that.isJoinAcceptMessage()) {
    msg += "Message Type = Join Accept" + "\n";
    msg += " AppNonce = " + asHexString(p.AppNonce) + "\n";
    msg += " NetID = " + asHexString(p.NetID) + "\n";
    msg += " DevAddr = " + asHexString(p.DevAddr) + "\n";
    // TODO & the rest
    msg += " MIC = " + asHexString(p.MIC) + "\n";

Background

For a not-encrypted Join Request like 00DC0000D07ED5B3701E6FEDF57CEEAF0085CC587FE913 lora-packet correctly shows:

Message Type = Join Request
      AppEUI = 70B3D57ED00000DC
      DevEUI = 00AFEE7CF5ED6F1E
    DevNonce = CC85
         MIC = 587FE913

For a matching response, 204DD85AE608B87FC4889970B7D2042C9E72959B0057AED6094B16003DF12DE145, it currently erroneously suggests:

Message Type = Join Accept
    AppNonce = 5AD84D
       NetID = B808E6
     DevAddr = 9988C47F
         MIC = F12DE145

This is wrong as the Join Accept payload (including its MIC) is encrypted using the secret AppKey (not to be confused with the session AppSKey, which is actually derived from the Join Accept). When decrypted using AppKey B6B53F4A168A7A88BDF7EA135CE9CFCA, the above Join Accept would yield:

    AppNonce = E5063A
       NetID = 000013
     DevAddr = 26012E43
  DLSettings = 03
     RXDelay = 01
      CFList = 184F84E85684B85E84886684586E8400
             = decimal 8671000, 8673000, 8675000, 8677000, 8679000
         MIC = 55121DE0

(The Things Network has been assigned a 7-bits "device address prefix" a.k.a. NwkID %0010011. Using that, TTN currently sends NetID 0x000013, and a TTN DevAddr always starts with 0x26 or 0x27.)

When the DevNonce from the Join Request is known as well, then the session keys can be derived:

     NwkSKey = 2C96F7028184BB0BE8AA49275290D4FC
     AppSKey = F3A5C8F0232A38C144029C165865802C

Example to derive the values

The following working example can also be seen at https://runkit.com/avbentem/deciphering-a-lorawan-otaa-join-accept

/*
 * Shows how to decode a LoRaWAN OTAA Join Accept message, and derive the session keys.
 */

var reverse = require('buffer-reverse');
'use strict';
var CryptoJS = require('crypto-js');
var aesCmac = require('node-aes-cmac').aesCmac;

// Secret AppKey as programmed in the device
var appKey = Buffer.from('B6B53F4A168A7A88BDF7EA135CE9CFCA', 'hex');

// DevNonce as generated in Join Request
var devNonce = Buffer.from('CC85', 'hex');

// Full packet: 0x20 MHDR, Join Accept (12 bytes, 16 bytes optional CFList, 4 bytes MIC)
var phyPayload = Buffer.from(
    '204dd85ae608b87fc4889970b7d2042c9e72959b0057aed6094b16003df12de145', 'hex');

// Initialization vector is always zero
var LORA_IV = CryptoJS.enc.Hex.parse('00000000000000000000000000000000');

// Encrypts the given buffer, returning another buffer.
function encrypt(buffer, key) {
    var ciphertext = CryptoJS.AES.encrypt(
        CryptoJS.lib.WordArray.create(buffer),
        CryptoJS.lib.WordArray.create(key),
        {
            mode: CryptoJS.mode.ECB,
            iv: LORA_IV,
            padding: CryptoJS.pad.NoPadding
        }
    ).ciphertext.toString(CryptoJS.enc.Hex);
    return new Buffer(ciphertext, 'hex');
}

// ## Decrypt payload, including MIC
//
// The network server uses an AES decrypt operation in ECB mode to encrypt the join-accept
// message so that the end-device can use an AES encrypt operation to decrypt the message.
// This way an end-device only has to implement AES encrypt but not AES decrypt.
var mhdr = phyPayload.slice(0, 1);
var joinAccept = encrypt(phyPayload.slice(1), appKey);

// ## Decode fields
//
// Size (bytes):     3       3       4         1          1     (16) Optional   4
// Join Accept:  AppNonce  NetID  DevAddr  DLSettings  RxDelay      CFList     MIC
var i = 0;
var appNonce = joinAccept.slice(i, i += 3);
var netID = joinAccept.slice(i, i += 3);
var devAddr = joinAccept.slice(i, i += 4);
var dlSettings = joinAccept.slice(i, i += 1);
var rxDelay = joinAccept.slice(i, i += 1);
if (i + 4 < joinAccept.length) {
    // We need the complete little-endian list (including its RFU byte) for the MIC
    var cfList = joinAccept.slice(i, i += 16);
    // Decode the 5 additional channel frequencies
    var frequencies = [];
    for (var c = 0; c < 5; c++) {
        frequencies.push(cfList.readUIntLE(3 * c, 3));
    }
    var rfu = cfList.slice(15, 15 + 1);
}
var mic = joinAccept.slice(i, i += 4);

// ## Validate MIC
//
// Below, the AppNonce, NetID and all should be added in little-endian format.
// cmac = aes128_cmac(AppKey, MHDR|AppNonce|NetID|DevAddr|DLSettings|RxDelay|CFList)
// MIC = cmac[0..3]
var micVerify = aesCmac(
    appKey,
    Buffer.concat([
        mhdr,
        appNonce,
        netID,
        devAddr,
        dlSettings,
        rxDelay,
        cfList
    ]),
    {returnAsBuffer: true}
).slice(0, 4);

// ## Derive session keys
//
// NwkSKey = aes128_encrypt(AppKey, 0x01|AppNonce|NetID|DevNonce|pad16)
// AppSKey = aes128_encrypt(AppKey, 0x02|AppNonce|NetID|DevNonce|pad16)
var sKey = Buffer.concat([
    appNonce,
    netID,
    reverse(devNonce),
    Buffer.from('00000000000000', 'hex')
]);
var nwkSKey = encrypt(Buffer.concat([Buffer.from('01', 'hex'), sKey]), appKey);
var appSKey = encrypt(Buffer.concat([Buffer.from('02', 'hex'), sKey]), appKey);

var r = '     Payload = ' + phyPayload.toString('hex')
    + '\n        MHDR = ' + mhdr.toString('hex')
    + '\n Join Accept = ' + joinAccept.toString('hex')
    + '\n    AppNonce = ' + (reverse(appNonce)).toString('hex')
    + '\n       NetID = ' + (reverse(netID)).toString('hex')
    + '\n     DevAddr = ' + (reverse(devAddr)).toString('hex')
    + '\n  DLSettings = ' + dlSettings.toString('hex')
    + '\n     RXDelay = ' + rxDelay.toString('hex')
    + '\n      CFList = ' + cfList.toString('hex')
    + '\n             = decimal ' + frequencies.join(', ')
    + '\n message MIC = ' + mic.toString('hex')
    + '\nverified MIC = ' + micVerify.toString('hex')
    + '\n     NwkSKey = ' + nwkSKey.toString('hex')
    + '\n     AppSKey = ' + appSKey.toString('hex');

console.log('<pre>\n' + r + '\n</pre>');

Decoding 1.1 LoRaWAN payload

Hello, i'm trying to use lora-packet-decode to decode payload :
lora-packet-decode --nwkkey 95AC484C0B6CA199F80311CADAA774C1 --appkey F5D893278F7E3F23C3DAB5A19AE0CD6C --base64 QPjyCyaAhAEKxgot72bu6AZmyLrY
and i obtain :

      ( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
              MHDR = 40
        MACPayload = F8F20B268084010AC60A2DEF66EEE806
               MIC = 66C8BAD8 (BAD != 83269847)

      ( MACPayload = FHDR | FPort | FRMPayload )
              FHDR = F8F20B26808401
             FPort = 0A
        FRMPayload = C60A2DEF66EEE806
         Plaintext = 7665F6EBEE99543D ('ve....T=')

            ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
           DevAddr = 260BF2F8 (Big Endian)
             FCtrl = 80
              FCnt = 0184 (Big Endian)
             FOpts = 

      Message Type = Unconfirmed Data Up
         Direction = up
              FCnt = 388
         FCtrl.ACK = false
         FCtrl.ADR = true
   FCtrl.ADRACKReq = false

Where it seems there is a problem concerning MIC. Is this problem come from the use of LoRaWAN version 1.1 or other ?
Thanks
Eric

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.