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

    LoRaWAN Sequence Numbers

    Scheduled Pinned Locked Moved LoPy
    21 Posts 9 Posters 9.2k Views 10 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.
    • K Offline
      kiwi64ajs
      last edited by

      Hi Guys,

      I'm having a problem whereby I can send the very first LoRaWAN data packet to a MultiConnect Conduit gateway device that is connected to LORIOT.io and I can see the packet in the user console log screen, but then all subsequent re-runs of my app on the LoPy do show any more packets getting passed through.

      Apparently the subsequent packets and are actually logged on LORIOT somewhere but are not passed through to the user console etc. Apparently the logs show the packets as having the same Sequence Number (of 1) and so doesn't pass it through.

      Is there any way I can get/set the Sequence Numbers used in the LoRaWAN stack?
      If not then can this be added?

      Exposing the other LoRaWAN stack settings like the SF DR etc might be useful while we are having to experiment with get the LoPy working well over LoRaWAN with the different gateway devices as it seems they are not all created or configured equally and so the ability to do some tweaks are needed...

      Regards

      Alex Shepherd

      K 1 Reply Last reply Reply Quote 1
      • K Offline
        kiwi64ajs @kiwi64ajs
        last edited by

        @kiwi64ajs

        Doing some more debug, the duplicate Sequence Numbers are being detected at the LOTIOT.io server level. Manually resetting the sequence number allows subsequent packets through but then it blocks again because each time I reset my LoPy and run the same script the sequence number resets back to 1 and fails to get through the LORIOT server.

        I expect I need to store the Sequence number on a file on the file system and then with each invocation of the program restore the last sequence, increment and set the LoRaWAN stack to the new sequence number and then send

        Regards

        Alex Shepherd

        1 Reply Last reply Reply Quote 0
        • bmarkusB Offline
          bmarkus
          last edited by

          If LoPy is not incrementing FCNT it is a bug in the LoRaWAN stack implementation.

          Login to your loriot.io account and select your device in Dashboard > Applications > SampleApp menu. In the lower right corner you find LoRaWAN Sequence numbers settings, disable Seqno checking. By default it is enabled (strict) to protect network against buggy devices like LoPy.

          K 1 Reply Last reply Reply Quote 0
          • bmarkusB Offline
            bmarkus
            last edited by

            Alex

            would you mind to share your code?

            Regards... Béla

            K 1 Reply Last reply Reply Quote 0
            • K Offline
              kiwi64ajs @bmarkus
              last edited by kiwi64ajs

              @bmarkus

              Hmmm... couldn't figure out how to attach a file so hopefully this works... ;)

              from network import LoRa
              from socket import *
              import socket
              import binascii
              import struct
              import os
              
              print('Begin LoRaWAN Connection Test')
              print
              # Initialize LoRa in LORAWAN mode.
              lora = LoRa(mode=LoRa.LORAWAN, sf=7)
              
              print("Board Info")
              b = os.uname()
              print('Sysname: ',  b.sysname)
              print('Nodeame: ',  b.nodename)
              print('Release: ',  b.release)
              print('Version: ',  b.version)
              print('Machine: ',  b.machine)
              print
              
              print('LoRa MAC: ', end="")
              print(binascii.hexlify(lora.mac()).upper().decode('utf-8'))
              
              print('Setup channels')
              lora.add_channel(0, frequency=865000000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(1, frequency=865200000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(2, frequency=865400000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(3, frequency=866200000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(4, frequency=866400000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(5, frequency=866600000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(6, frequency=866800000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.add_channel(7, frequency=867000000, dr_min=0, dr_max=5, duty_cycle=0)
              lora.remove_channel(8)
              lora.remove_channel(9)
              lora.remove_channel(10)
              lora.remove_channel(11)
              lora.remove_channel(12)
              lora.remove_channel(13)
              lora.remove_channel(14)
              lora.remove_channel(15)
              
              print('Setup keys')
              # create an ABP authentication params
              dev_addr =  struct.unpack(">l", binascii.unhexlify('00000000'))[0]
              nwk_swkey = binascii.unhexlify('00000000000000000000000000000000')
              app_swkey = binascii.unhexlify('00000000000000000000000000000000')
              
              print('Join LoRaWAN')
              # join a network using ABP (Activation By Personalization)
              lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
              
              # wait until the module has joined the network
              while not lora.has_joined():
                  time.sleep(1)
                  print('Waiting to Join LoRaWAN Network...')
              
              print('Setup Socket')
              # 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, 0)
              s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False)
              
              s.setblocking(True)   # Make the socket blocking, socket.send() won't return until completed
              s.settimeout(5)     # Configure the timeout of the socket
              
              print('Sending Data... ', end="")
              
              # Try sending some data
              try:
                  s.send('Hello World')
              
                  print('Complete')
              except timeout:
                 print("Timeout Sending Data")
              
              # Check to see if there is any data waiting for us to Receive..
              try:
                  print('Try to Receive Data... ', end="")
              
                  data = s.recv(64)
              
                  print('Received Data: ', end="")
                  print(data)
              except timeout:
                 print("No Data Received")
              
              print('Test Complete')
              

              Regards

              Alex Shepherd

              1 Reply Last reply Reply Quote 0
              • K Offline
                kiwi64ajs @bmarkus
                last edited by kiwi64ajs

                @bmarkus said in LoRaWAN Sequence Numbers:

                If LoPy is not incrementing FCNT it is a bug in the LoRaWAN stack implementation.

                Well the issue is my code start, connects and sends the data and then exist. The first run is ok, but any subsequent runs restarts the lora stack and the Sequence starts from 1 again, which is fine for the sender, but the receiving end at the server see packets with the same Sequence number and assumes they are duplicates, which is not so not good from the sender's perspective, but ignoring the duplicate Sequence numbers if not a good thing either from a robustness perspective.

                I changed my code to send packets in a loop and the Sequence number IS being incremented each time it goes around the loop, but if I run and then exit and then run again the Stack only send one packet per run and so the Sequence restarts from 1 each time.

                Being able to manage (get, persist, restore, set) the Sequence numbers used in the LoRa stack is probably a better approach. That way the developer has some choices about how best to manage this issue.

                Regards

                Alex Shepherd

                1 Reply Last reply Reply Quote 0
                • S Offline
                  somu
                  last edited by

                  Hello @kiwi64ajs

                  Thank you so much for your code snippet. We are facing the similar issue of duplication of packets. Did you solved the problem?

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    hemalchevli
                    last edited by

                    Hi Alex,
                    I was struggling to get the data to server, using your code you shared it worked once, I don't have debug information from the server side. Were you able to fix the issue?
                    I'm a newbie in python, where can I find the fcnt or sequence number variable?
                    Thanks
                    Cheers!

                    K 1 Reply Last reply Reply Quote 0
                    • A Offline
                      Antony
                      last edited by

                      Incrementing the sequence number is mandatory in the LoRaWAN spec, and is necessary for devices to be secure. Hacking this at the Loriot server isn't a good solution. Alex, what you say is right - you need to cache the sequence number counter and then restore it. Or even better, the stack would do it for you.

                      But I don't see anything in the Pycom LoRa API that makes it possible to do this? For example, it could be done through socket.setsockopt() but there is no mention of this in the (1.8.4) documentation.

                      Should this be submitted as a bug?

                      Antony

                      bmarkusB 1 Reply Last reply Reply Quote 0
                      • bmarkusB Offline
                        bmarkus @Antony
                        last edited by

                        @Antony said in LoRaWAN Sequence Numbers:

                        Incrementing the sequence number is mandatory in the LoRaWAN spec, and is necessary for devices to be secure. Hacking this at the Loriot server isn't a good solution. Alex, what you say is right - you need to cache the sequence number counter and then restore it. Or even better, the stack would do it for you.

                        But I don't see anything in the Pycom LoRa API that makes it possible to do this? For example, it could be done through socket.setsockopt() but there is no mention of this in the (1.8.4) documentation.

                        Should this be submitted as a bug?

                        Antony

                        In other cases, like RN2483 sequence number is incremented by the LoRaWAN stack and not by the application.

                        At the Loriot server it is a great feature to disable sequence number during development, it saves you hours. Agree, in production system it is not adviced.

                        1 Reply Last reply Reply Quote 0
                        • K Offline
                          kiwi64ajs @hemalchevli
                          last edited by

                          @hemalchevli said in LoRaWAN Sequence Numbers:

                          Hi Alex,
                          I was struggling to get the data to server, using your code you shared it worked once, I don't have debug information from the server side. Were you able to fix the issue?
                          I'm a newbie in python, where can I find the fcnt or sequence number variable?

                          No and there does not seem to be anyway to really fix this at an application level unless the check at the server is turned off - which is NOT ideal.

                          The stack could cache the last used number in EEPROM / FLASH and resume from there next time, but we don't have get/set access the sequence number at the API level so I don't know what to do next.

                          This is a problem when you're trying to develop a product against a commercial LoRaWAN service provider who does have the sequence number check enabled... Guess I need my own LoRaWAN Gateway with the sequence check turned off for now

                          Alex

                          Regards

                          Alex Shepherd

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

                            I agree these settings should be exposed somewhere (and both the UpLinkCounter and DownLinkCounter!) but please take care if making them restore automatically - and if so definitely make it optional.

                            The Flash chip is only specced for 100,000 erase/program cycles, so if you're updating the frame counter in Flash every time and you send a frame for example every 5 minutes the Flash would only last one year.

                            The recommended way is really to use OTAA and do a join at every reset, so you get fresh counter and don't have to worry about this. In this case storing the counters would be of no use.

                            If you really want to store your counters I suggest some external FRAM (Ferroelectric) which is good for 10 trillion cycles. There are easy to use chips with I2C and ready made breakouts for prototyping.

                            bmarkusB 1 Reply Last reply Reply Quote 0
                            • bmarkusB Offline
                              bmarkus @jmarcelino
                              last edited by

                              @jmarcelino said in LoRaWAN Sequence Numbers:

                              The recommended way is really to use OTAA and do a join at every reset, so you get fresh counter and don't have to worry about this

                              Depends on your use case. OTAA is good for fixed sensor devices, but for e.g. moving mobile devices (trackers) doesn't, there ABP is the proper method.

                              J 1 Reply Last reply Reply Quote 0
                              • H Offline
                                hemalchevli @kiwi64ajs
                                last edited by

                                @kiwi64ajs Yep, I'm developing a product for a commercial LoRaWAN and they have provided a nano gateway from orbiwise and on the server I can only view the data, no server settings are exposed, may be I'll too have a gateway setup for the product demo if this doesn't work.

                                One more option its to edit and compile the firmware and try exposing it at app level, don't know how that will go, but I'll give it a try.

                                Thanks again for your code, it really made my day to see that one frame being uploaded to my server. :)
                                Cheers!!

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

                                  @bmarkus
                                  I disagree, for mobile devices in particular the advantages of OTAA (provisioning setup inc. counter reliability and added security) outweigh the disadvantages.

                                  Here's a big problem with ABP: imagine you leave an active ABP node outside of reach of a gateway for a while. The frame counter on the node will keep on ticking, increasing the difference between it and what the backend expects. According to the spec once this difference goes over the allowed range (just 16384 packets for TTN) the backend will start rejecting any further packets. If you send a packet every minute this happens in less 12 days, a realistic scenario for a mobile LoRa device.

                                  This would then have to be detected and counters manually reset at both node and backend. A provisioning nightmare if you have devices in the hands of users!

                                  With OTAA once the node receives a join response you can be sure 1) there's coverage and 2) the data you send will match up, no guessing if you have stale encryption keys or frame counters. Also if you receive a fail response from the backend your node can alert the user.

                                  To me there's just a small set of use cases where you really need ABP and for most applications - especially if you're deploying devices to other users and want to sleep at night - OTAA really is the way to go.

                                  1 Reply Last reply Reply Quote 0
                                  • C Offline
                                    cmsedore
                                    last edited by

                                    @kiwi64ajs I've written an add-on for the firmware to allow setting the uplink counter. I need to test it tomorrow (I don't have a functional gateway at home)--assuming it works, I'll create a pull request.

                                    1 Reply Last reply Reply Quote 0
                                    • H Offline
                                      hemalchevli
                                      last edited by

                                      I was able to solve my problem, and now having seamless uplinks and downlinks. There was a issue with my channels settings that the gateway supported.
                                      Also was having issues with pymakr with uploading code to lopy which caused delay in code testing. Now compeletly abandoned pymakr and moved to transfer file using FTP.

                                      1 Reply Last reply Reply Quote 0
                                      • K Offline
                                        kots
                                        last edited by

                                        hello!
                                        Anyone who found how to solve this problem?

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

                                          @kots
                                          In the latest firmware you can now use lora.nvram_save() to save your current frame counters and then lora.nvram_restore() to restore them again after power-on/reset.

                                          K 1 Reply Last reply Reply Quote 2
                                          • K Offline
                                            kots @jmarcelino
                                            last edited by

                                            @jmarcelino Thanks!
                                            Any idea how they work?

                                            J 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
                                            • 2 / 2
                                            • First post
                                              Last post

                                            Pycom on Twitter

                                            Pycom