LowPowerLab Forum

Hardware support => Low Power Techniques => Topic started by: EternityForest on March 25, 2020, 03:22:50 AM

Title: I'm working on a fork of the libs to make LP sensors easier! Any suggestions?
Post by: EternityForest on March 25, 2020, 03:22:50 AM
Just got a few IoT door sensors that I really like, but I don't like how everything goes through a cloud service that could dissapear.

So I've been putting a lot of time lately into an alternate library, which I'm calling SG1, trying to make things scalable to large numbers of cheap devices.

The biggest change is that I'm using software encryption.  Packets have timestamps which also serve as IVs for the crypto, and when a node has an incorrect time, the other nodes use bit flags in the header to decide if their local clocks are better, and if so they inform the wrong device(Using the same wrong IV as a challenge response).

For everything I'm doing, I believe it's secure enough, but clocks start out with 7 byte random negative numbers, and clocks can go backwards, so there's a possibility for very occasionally accidentally reusing an IV, even though the resolution is 256us.

I'm also only using 64 bit MACs, so I'm not sure if this is "secure enough" for most people's needs.

The other thing I've done is get rid of addresses. You don't send to a specific node, you send to a "channel key", and anyone set to that key gets it.  We never explicitly send the channel, just 3 bytes of the hashed key, as a "hint".  Collisions don't really matter, you just ignore anything you can't decrypt.


I'm also not using listen mode for the low power, because I don't like how much data you have to send and the unpredictable chance of receiving things.

Instead, I have "short beacon messages", which contain a 3 byte "private Hint sequence" that constantly changes.  When we send one of these, we listen for about 100ms for a response.

If there's no response, or the response is just another hint sequence message, we note the RSSI for the auto TX power, and go back to sleep.  I may change this response to be the hash of the hint, so you can't fake the presence of the other device just by repeating the message.

If the response is the channel's "wake sequence", we stay away for a few seconds, resetting the timer whenever we get a real message.

All messages can use full Golay error correction (which doubles the packet size, so we only use it when the power level is high).



Unfortunately this means sending a packet and listening for 100ms on a regular basis(I think you only need about 25ms, but serial ports have more latency than that, so you'd need hardware assistance to have a PV gateway respond that fast), so I'm also looking into designing some cheap LTO based energy harvesting boards, since most things can run at 1.8v these days.


The next thing I'm planning to work on is automatic pairing mode. I want to have a predefined pairing frequency, and let add a pairingMode() function plus a pairWithRemote() function that lets you set everything up automatically, Bluetooth style, and unique device UUIDs that can get discovered in the process.


Ideally, I would *really* like to see a fully open standard that's as easy to use as typical consumer equipment, to end some of this IoT waste and make the technology accessible to everyone without fragmented piles of different expensive hardware.


Anyway, here's what I have so far, Although it's all alpha and subject to change, it does seem to work pretty well on Moteinos.

What do you guys think? Should I be adding a few extra bytes of IV to get rid of the(possibly one-in-a-millon security issues?)

Should I limit the beacon recieve window to 25ms, and just rely on smarter PC interfaces that can respond without waiting for the PC?

Thanks guys!

https://github.com/EternityForest/SG1
Title: Re: I'm working on a fork of the libs to make LP sensors easier! Any suggestions?
Post by: Felix on March 25, 2020, 09:43:18 AM
Ambitious for sure!

One favor: Could you please rename the library to something else so it doesn't clash with the LowPowerLab RFM69 library.
RFM69_SG1? RFM69_EternityForest?
Thanks in advance.
Title: Re: I'm working on a fork of the libs to make LP sensors easier! Any suggestions?
Post by: EternityForest on March 26, 2020, 12:40:21 AM
Allright, I believe there should be no more clashes, I renamed everything with a similar name, or moved it to the utility folder. Thank you for the tip!

I've also found out with a little more research that most computers only have USB latency problems receiving, not sending, so I think a 40ms receive window should be enough to allow PC->lowpower transmissions at 100kbps. 

In theory it should be possible to only use 0.08mA to beacon and listen once per second, plus the MCU itself, assuming you can keep accurate time while sleeping, otherwise you need several times that for clock sync.

Thank you all for the awesome hardware that makes this possible! I'm pretty excited about this.
Title: Re: I'm working on a fork of the libs to make LP sensors easier! Any suggestions?
Post by: EternityForest on April 14, 2020, 03:07:28 AM
It's been a bit, but I've made some progress!  After way too much research on FCC law, it seems that the power limit is less than a milliwatt in 915MHz, unless you use some kind of spread spectrum.

And so I spent a few days getting FHSS working, which I did manage to do at a slow hop speed, but I did not like how long it takes to sync up, and getting the tight sync needed is hard when you also have sleep mode to worry about. So I have changed the RF profiles to mostly use 600KHz or more of bandwidth, because apparently really wide band digital counts as spread spectrum.  I'm still pretty much just relying on aggressive TX power control to manage interference.

To maintain the 8db/3khz limit, I just set the total power limit to 8dBm, which is good enough for now. I *think* the settings I have may also be legal to use in the EU, but I'm not sure.

The main reason for all this is largely lighting control related, so I've added "RT Packets". These don't use any kind of forward error correction or any acknowledge mechanism, and they only use a 2 byte checksum, but they only have 128 bit times or so of overhead, and the data is still encrypted, and (weakly) authenticated

You can't correctly decrypt these without synchronized clocks, so you have to exchange some full packets occasionally to keep the time within a few seconds.

The low-power wakeup/beacon frame mechanism seems to work, and I've changed the beacon sequence change interval to once every minute for better time sync misalignment tolerance. The code will automatically send system background requests instead of beacons as needed to stay in sync.  I don't have any RTC integration yet to actually be able to sleep and keep the clock working, but that's next.

The downside of all this is that it's using 80% of an Arduino's flash and half the RAM to be able to do this, probably partly on account of the forward error correction and the encryption. If I can find a decent Python library for Speck, I might use that instead of ChaChaPoly, but I don't want to add custom C dependancies to be able to use this in Python.

But there's still enough left for pretty much anything I actually use Arduinos for, so it's not unusable.