Showing posts with label JSON. Show all posts
Showing posts with label JSON. Show all posts

Wednesday, May 25, 2016

Decoding a LoraWAN payload send by your ESP8266 gateway



If you are receiving a LoraWAN packet on you LoraWAN gateway using the ESP8266 module most probably  you will forward it to a back-end server to be processed by your application. But the message is encoded and encrypted so this is the procedure to do it right.


rxpk update: {"rxpk":[{"tmst":1060664170,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":12,"rssi":-28,"size":31,"data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig=="}]}




Step1. Base64

The "data":"QGIH4AIAqgABvJNVF4DpUapp/xQN1REVnI+jYoR6Ig==" need to be decoded using base64 and the result will be:

64, 98, 7, -32, 2, 0, -86, 0, 1, -68, -109, 85, 23, -128, -23, 81, -86, 105, -1, 20, 13, -43, 17, 21, -100, -113, -93, 98, -124, 122, 34





Step 2. Build the block A(i) according to the 4.3.3.1 

For each data message, the algorithm defines a sequence of Blocks Ai  for i = 1..k 
with k = ceil(len(pld) / 16). In our case the k=2 because the len(pld)=31 so there are 2 blocks that need to be constructed.

An A Block will be like this one:

-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x01



-----------------------------------------------------------------------------------------------------------
                          | Dir | Device Address     | Fcnt Up/Down       |      | Block number     
-----------------------------------------------------------------------------------------------------------
0x01 | 0x00 0x00 0x00 0x00| 0x00| 0x62 0x07 0xE0 0x02| 0xAA 0x00 0x00 0x00| 0x00 | 0x02


Where Dir is direction and it is 0 for uplink and 1 for downlink



Step 3. Encrypt each A Block

The blocks Ai are encrypted to get a sequence S of blocks S(i) :  S(i) = aes128_encrypt(K, Ai) for i = 1..k

So, on this step each A block will be encrypted ( yes encrypted !!!) AES128 with the same
key used on node side. 

A ciphertext will be like:

c7b11d72ec853e8853dd4362a77d71ad



Step 4. XOR the cipher with payload.

S = S1 | S2 | .. | Sk

Don't forget that encryption and decryption of the payload is done by truncating (pld | pad16) XOR S to the first len(pld) octets.


At the end the text {"Hello":"World1"} will be available for your application. If at the node side this text is encrypted your app will need to do a decryption to get it.





Wednesday, August 26, 2015

New progress today - ESP8266 has UNIX CRON functionality


I've added a cron functionality to my ESP8266 and is working great.
Now I can send a JSON string with unix like cron command:

{"device_name":"ESP9191919", "type":"my_isp_type", "minute":"22" , "hour":"10", "day_of_month":"26", "month":"7", "day_of_week":"3", "gpio":"14","duration":"20", "skip":"0","status":"1", "action":"add" }

to setup a cron job on a specific GPIO. I need it for my irrigation system that was using a CRON on  a raspberry PI to receive the commands for valves.

My CRON implementation support now the "*" functionality for minute, hour, day_of_month, month and day_of_week. In this version is not supporting the "*/10" functionality but if I will need it I will do it.

So sending once the JSON :

{"device_name":"ESP9191919", "type":"my_isp_type", "minute":"00" , "hour":"22", "day_of_month":"*", "month":"*", "day_of_week":"*", "gpio":"14","duration":"20", "skip":"0","status":"1", "action":"add" }

will start the valve connected to gpio 14 every day at 22:00 for 20 minutes.

If I want to skip this cron 2 days, I need to send the same JSON but with skip value of 2.

Skip value get automatically decremented and when it has the value of 0 the cron will do the job. I've need it this functionality, because finally the ESP will be an autonomous system, getting the data from Internet and from my yard, and will be able to propose me an watering plan ( in first stage to be able to test it) and finally to be able to take decisions by itself.
This is what IoT means. 

If I want to disable this cron job, I need to set the status to "0" so it will be ignored every time.


I could have also added the year as a parameter (have it but not used), but I didn't find any utility for that. But is an easy job to do it.


The important thing is that the cron data is written in the flash so a power down is not affecting the cron functionality.

Writing to flash was minimized so only if is necessary a flash update will be done. 

I've used sector 2 for storing the cron data so I can have like 400 cron jobs for now, which is enough for now. I guess I can squeeze another 1000 records in the other sectors, but for now 400 are enough.

TODO list:


Export data as JSON:
  •   {"cron_data":{"minute":"2","hour":"16",......},{"minute":"15","hour":"9",......},   {"minute":"44","hour":"12",......}, {"minute":"20","hour":"8",......}}    DONE !!!
  • */5 functionality 
  • continuity for cron jobs - if there is a power down during a cron job, continue from where it left.