Roaming LoRaWan with Helium network

Helium is an open network, decentralized, there is a wide range of option you can do as a user, like creating your own private router to have your devices encrypted end-to-end. You can also make your LoRaWan traffic to be routed from Helium network to your own network when you are a LoRaWan network provider. Let’s take the exemple of a Telco with a LoRaWan network, let’s name it B’telco and imagine B’telco have an existing network in France. Imagine they want to extends their coverage worldwide, eventually reduce their local cost by removing some redundancy in the cities. In a such case, they can roam traffic over helium.

This means that the data of B’telco devices will be acquired by helium router, exactly as a Helium data, and then it will be routed to B’telco network server transparently. That way, the customer will have a better coverage and the B’telco cost for this worldwide extension will be really low.

In this blog post, I’ll explain how this roaming feature works and what is needed to deploy it.

At first, you need to understand that the roaming is uni-directional. So the B’telco traffic will be relayed by Helium to B’telco but the Helium traffic will not be relayed over B’telco network. This could be done but in a different way, currently Helium doesn’t have a dedicated component for this.

As a prerequisite, you also need to understand that LoRaWan traffic is “public”, it means that the gateways (hotspots) on LoRaWan are receiving the whole LoRaWan traffic, from all the devices, for all the operators. So that global traffic is forwarded to the LoRaWan network servers and that one only process its own traffic. On Helium, the hotspots are some routing information to correctly route the devices to the right router. There is currently a default router (Nova labs one) for the rest of the traffic ; this is a temporary solution.

Helium roaming is “passive roaming”, it means that the device will be seen as a B’telco device within the Helium network. By opposition, hand-over roaming would have consisted in connecting the device as an Helium device and send the payload to B’telco but this is not the way it works (By the way, I don’t really see who want to implement this with all the Join related problems). Passive roaming have stateful and stateless options. In a stateful mode, roaming will be authorized per device, in stateless, all the devices belonging to B’telco will be roamed (with a consequence that all messages will be paid even if final user does not want roaming). The stateful implementation is rare. As we will see, the way Helium works makes it between the two as a device declaration is required to Join.

Understand devaddr and netid

To quickly reject the traffic that is not belonging to a given network server you can filter based on the devaddr. This is a device address, on 32bits, given to the device when the session is established (during the JOIN ACCEPT/REQUEST phase). On helium, when you are creating your own router, you acquire some devaddr on helium network, this is the way the hotspot is routing to the right router. On LoraWan, more generally, devaddr range are affected to LoRaWan operators. You can find a list of them on this page from TTN. The Helium netAddr is not listed in this page but it was 0x48 (like letter H in ascii) at the beginning and now, it is suppose to changr to 0x60002D and 0xC00053, the first one is 17 bits long and the second one 10 bits long. In terms of netAddr, it means 0xE0 and 0xFC, in a specific sub-range of the given size. The total of devAddr on Helium with this potential setting could be 128k + 1k devices. You need to know that devAddr are mutualized as we can differentiate the devices thanks to the encryption. Basically Helium should support about 15M active devices with a such range. But this seems to be under discussion and a 24bits range could be preferred allowing 1.7B devices. So wait & see for this limit.

DevAddr on the helium console

In the Helium console, you can see your device address, this one can change from a session to another as it is attributed during the JOIN Response phase. You can also see that the address is display in the reverse byte direction. At the end you see the 0x48 indicating that this device uses the previous Helium NetID, but not yet the official ones.

Now you see how a network server or a router can quickly filter a message coming from another network by only accepting the messages with a NwkAddr matching the network server one.

Roaming by accepting different NwtAddr

When you want to roam the incoming traffic, you need to accept on helium devaddr not belonging to Helium. So you need to have a router accepting the traffic for these NetAdr. This is a feature that is in development currently and I do not yet have all the details but there are some constraints. At least you need to run and register a packet purchaser. This a kind of router that will accept the traffic for a given NetID. I assume you will need to register it with a given cost. As you should not register a NetID for someone else, we may have a procedure to validate this registration. The process is not yet known but should be soon.

This procedure is validating the DevAdr based routing. This is valid for devices with existing sessions. When a device is not yet Joined, this process does not work. And it starts to be more complicated.

Roaming the JOIN Request / JOIN Accept

Here it’s where routing starts to be complex: when a device is connected, the DevAddr allows an easy routing. Concerning the Join Request/Accept it’s another deal. The DevEUI and AppEUI are “randomly” attributed, at least at a trans-network level. To roam a Join communication, you need to know where to route it and this is basically a decision at the device level. It means the routing table becomes really large.

Helium is using the XOR filter for that job, routers have usually 5 filters, containing hash for DevEUI, AppEUI couples. XOR filter is a table storing in a compact way hash of (DevEUI, AppEUI). The table grow with the number of devices and the cost to update this table is related to the table size or table size delta soon with HIP-59. This table is stored on the blockchain and hotspots knows the XOR tables for all the OUI. The advantage of using XOR table is to quickly search over the filters to identify the router belonging to the device.

As a consequence of this, if you want B’telco devices to Join passing through the Helium network, you need to have a XOR filter set containing all the B’telco devices listed in it. This initialization step can be costly as the XOR transaction cost is related to the XOR filter size and this is a question of the number of devices. An optimization will be to create XOR filters based on AppEUI only to reduce the number of entries and the overall size. This works if B’telco has a limited number of AppEUI.

The other consequence is the update: when a new device is created on B’telco size, the XOR filter is subject to be upgraded. Once the AppEUI filter evolution will be implemented, il will not be mandatory for each device but each new AppEui. By the way, it means every time something new is created a synchronization between B’telco and Helium is needed. I did not identified in the LoRaWan roaming spec a standard way to announce new devices and it seems to be a custom. As another consequence, due to the XOR filter change processing time (and cost), a delay will be required to make that new device able to join over Helium (this is usually not the case on B’telco side). Nothing blocking but some UX impacts to be considered.

Roaming cost

When the roaming is enable, it is globally enabled. That means all the traffic from B’Telco received by a Helium hotspot will be purchased by the Helium router, world-wide, based on the NwkID. If B’telco have a single NwkID for different countries, it means you can’t roam on a single country, the whole fleet of B’Telco devices will be roamed. As Helium itself is global, it means that even in the location where B’telco is the packet will be purchased and roamed (the same packet will come from both side). This as a cost impact : every 100.000 packets costs for at least a $. You can’t select what device is roaming vs what device is not once the session is opened. Custom developments on the B’telco network servers, based on the use of sub NwkID, could solve all of this but I don’t think they are out of the box. This needs to be considered in the business model as the Helium communication have a cost, even if the B’telco reject packets cost as it got it its normal way. By default all the devices are roamed even if this is an option for B’telco customers.

On top of this, you will have all the cost related to the run of a router as I have been described it in my previous block post about the real cost of helium network communications.

What do you needs to roam with Helium ?

As a consequence of all of this, the way to do roaming (from Helium to B’telco) is at first a router, so I assume you need to buy on OUI. But you should not have to buy DevAddr as B’telco will provide them – as a side remark, I questioning myself about the possible advantage of doing roaming on Helium instead of buying the expensive DevAddr on the chain $100 each and using AppEUI XOR filter as another cost improvement.

The Helium Roaming architecture

The packet purchaser is equivalent to a router and is still in development, so currently not all the mechanism describes here are yet available, but will be soon, potentially when you will read this post it will be done. It gets the traffic and push it to B’telco network server based on the LoRaWAN roaming specification. I did take a look to the LoRaWan roaming specification, they are describing how packet purchaser and network server are interacting but I did not found an implementation yet with API. There is one, but i did not found it yet.

The roaming console allows to control the router side. I currently looks like a simplified version of the console, we can expect it will have some API to help the device addition in the XOR filters.

Helium Roaming console (from this blog post)

The integration could really depends on the network you want to roam and the network server it is using. It’s not easy to see how much you will have to customize the code currently. I will let you know once I will have investigated deeper.


Being able to roaming from Helium to another network on your own is still a non mature project and could take times. There is some approval processes to be described and protocol specification to be made with, as a consequence, some potential custom code to be made.

The roaming is already in place with different networks, managed by Nova Labs, like with Senet, Actility … I’m not sure it concerns device join in all the case and is still one-way. The roaming to the other way: receiving communications from B’Telco to Helium can be made with a gateway-rs potentially, using the Semtech-UDP protocol with a risk of scalability limitations.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.