Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Strategy for LoRaWAN with deepsleep 2

    Scheduled Pinned Locked Moved LoPy
    deepsleepjoinwake up
    34 Posts 9 Posters 12.5k Views 12 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E Offline
      Eric24 @jmarcelino
      last edited by

      @jmarcelino OK, that's reasonable. I see that as an exception case rather than normal operation. Also, the basic idea is to increase battery life and minimize airtime usage, so even if I rejoined every 10 message intervals, that's still a 10X reduction of "join overhead". The "right" interval of re-joins will be up to the application, of course, but it's hopefully somewhat less frequently than "every time" and much more than "once". I wonder if TTN (and other networks) generally provide a way for the application to know that a message was received from a known device with invalid keys?

      1 Reply Last reply Reply Quote 1
      • _ Offline
        _peter @Camot
        last edited by jmarcelino

        @Camot
        I tried with relaxed frame counter in ABP mode but it does not work. Send the data once and then nothing.
        Below the code on lopy:

        from network import LoRa
        import socket
        import binascii
        import struct
        
        # Initialize LoRa in LORAWAN mode.
        lora = LoRa(mode=LoRa.LORAWAN)
        
        # create an ABP authentication params
        dev_addr = struct.unpack(">l", binascii.unhexlify('07 11 7d e5'.replace(' ','')))[0]
        nwk_swkey = binascii.unhexlify('1b a9 32 60 6e e0 9d 0d 41 6a 51 af 98 6e ec 5b'.replace(' ',''))
        app_swkey = binascii.unhexlify('9a 28 99 2c 03 79 78 2a 3d 93 f5 c6 df b4 af e4'.replace(' ',''))
        
        # join a network using ABP (Activation By Personalization)
        lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
        
        # create a LoRa socket
        s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
        
        # set the LoRaWAN data rate
        s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
        
        # make the socket blocking
        # (waits for the data to be sent and for the 2 receive windows to expire)
        s.setblocking(True)
        print('send')
        # send some data
        s.send(bytes([0x01, 0x02, 0x03]))
        
        # make the socket non-blocking
        # (because if there's no data received it will block forever...)
        s.setblocking(False)
        
        # get any data received (if any...)
        data = s.recv(64)
        print(data)
        machine.deepsleep(60000)
        
        J 1 Reply Last reply Reply Quote 0
        • J Offline
          jmarcelino @_peter
          last edited by jmarcelino

          @_peter
          (in the future please put code between two
          ```
          ```
          lines otherwise the formatting gets all wrong, see this for more formatting tips)

          Is this your main.py file?

          _ 1 Reply Last reply Reply Quote 0
          • _ Offline
            _peter @jmarcelino
            last edited by

            @jmarcelino Excuse for unformatted code. Yes, it's my main.py

            1 Reply Last reply Reply Quote 0
            • D Offline
              dbrgn
              last edited by

              To continue the discussion from here:

              Some modules like the RN2483 do support it, some others like the RM186 don't. IMHO LoRaWan doesn't offer a clear, best-practice, strategy for doing this.

              Isn't it pretty simple? If you have a way to pre-flash every device with its own key, use ABP. If not, use OTAA. When using ABP, store the frame counter when going to sleep and restore after wakeup.

              The issue with OTAA joins on every wake up is not just battery lifetime, but also gateway airtime. Downlinks are expensive, LoRaWAN does not scale if every node that wakes up every 10 minutes must do a join procedure, blocking all other communications during the downlink transmission.

              Just wondering, are there already "real world" deployments out there with LoPy devices? What do these use, ABP with relaxed frame counter? I can't imagine getting useful battery life with an OTAA join before every transmission.

              And if you have ABP with relaxed frame counters, replay attacks are trivial, right? Basically every SDR software has a "record and replay" feature that could be used to re-send old transmissions.

              With the LoPy you could of course add the functionally to the firmware since the source code is available .

              In what part of the source code would that need to be added?

              J 1 Reply Last reply Reply Quote 0
              • J Offline
                jmarcelino @dbrgn
                last edited by jmarcelino

                @dbrgn said in Strategy for LoRaWAN with deepsleep 2:

                Isn't it pretty simple? If you have a way to pre-flash every device with its own key, use ABP. If not, use OTAA. When using ABP, store the frame counter when going to sleep and restore after wakeup.

                Well, as far as I understand it's not really that simple.

                It's not enough to just store the frame counter at every sleep and restore it at wake, if your LoPy crashes for any reason - which still happens regularly - or if it runs out power the counter would still be incorrect and your network enforcing frame counters will still reject packets until things get matched up again.

                Ideally you want to store the frame counter with each send/receive (remember there are two counters), but that takes us to flash reliability and read/write cycles so you'd have to do some wear levelling algorithm - or maybe not store all frame counters, but again that depends a lot on what the application expects.

                For OTAA I have questions about key validity. LoRaWAN is still evolving and I don't believe that currently any set of OTAA keys (there are two, NwkSKey and AppSKey) will last forever, especially the NwkSKey - they are called session keys for a reason. So again it should be up to the application to decide if/when it should restore these.

                That said - while I have concerns about doing it automatically - I'd like the ability to get and set frame counters and session keys when and how I wish from my application. It would be a good feature.

                In what part of the source code would that need to be added?

                There's a few but modlora.c would be a starting point

                As far as real world LoRaWAN my own approach is to be paranoid: don't assume anything from network - use ABP, relaxed counters and run your own encryption to prevent replay attacks

                D 1 Reply Last reply Reply Quote 0
                • D Offline
                  dbrgn @jmarcelino
                  last edited by dbrgn

                  @jmarcelino said in Strategy for LoRaWAN with deepsleep 2:

                  So again it should be up to the application to decide if/when it should restore these.
                  That said - while I have concerns about doing it automatically - I'd like the ability to get and set frame counters and session keys when and how I wish from my application. It would be a good feature.

                  Yes exactly, I wouldn't necessarily expect you to store those keys automatically, but an API for that would be great. My approach would probably be to join via OTAA once per day. In that case, if the keys would expire immediately after the join then only 1 day worth of data would be lost.

                  use ABP, relaxed counters and run your own encryption to prevent replay attacks

                  What technique would you suggest for that? It probably still requires some kind of counter in the packet.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    dbrgn
                    last edited by

                    I stumbled over this topic again, this time while using ABP with relaxed frame counters on TTN.

                    I have a node that sends a measurement every X seconds. Since ABP does not remember the frame counter, it will always be 1.

                    Now if I send a downlink from TTN to the device, that will be delivered once the device sends the next uplink. That uplink has the frame counter 1.

                    Now if another uplink is sent with the frame counter 1, the network server thinks that it is a retry message and will send the downlink again. We're now stuck in a kind of downlink loop.

                    I'd like to note that a device that does not remember the ABP frame counter is not LoRaWAN-compliant:

                    screenshot 1

                    screenshot 2

                    And since the stack is not accessible from Python (in order to restore the frame counter), it's not possible to create a LoRaWAN compliant node at the moment with stock firmware, right?

                    Any ideas how to deal with that situation?

                    @daniel are there plans to fix this in the near future? Or are there workarounds?

                    J 1 Reply Last reply Reply Quote 0
                    • J Offline
                      jmarcelino @dbrgn
                      last edited by

                      @dbrgn
                      You mean after each deep sleep?

                      On the latest firmware you can now call lora.nvram_save() before entering to deep sleep to save the counters and lora.nvram_restore() on restart, after initialising the LoRa object and before sending your data.

                      D J 2 Replies Last reply Reply Quote 0
                      • D Offline
                        dbrgn @jmarcelino
                        last edited by

                        @jmarcelino said in Strategy for LoRaWAN with deepsleep 2:

                        You mean after each deep sleep?

                        Yes.

                        On the latest firmware you can now call lora.nvram_save() before entering to deep sleep to save the counters and lora.nvram_restore() on restart, after initialising the LoRa object and before sending your data.

                        Oh, I totally missed that in the release notes! :) Thanks, that should solve that issue!

                        1 Reply Last reply Reply Quote 0
                        • J Offline
                          johncaipa @jmarcelino
                          last edited by

                          @jmarcelino Is there any example code that incorporates deepsleep and LoraWAN with these new functionalities to test it? thanks

                          1 Reply Last reply Reply Quote 0

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better 💗

                          Register Login
                          • 1
                          • 2
                          • 1 / 2
                          • First post
                            Last post

                          Pycom on Twitter

                          Pycom