Mesh.on vs. Mesh.connect vs. Mesh.connecting and Cellular.connecting, vs. Particle.connect

I’ve been troubleshooting connection problems for a few hours on a Boron and though it may help others if I take some notes here of what I’ve been finding. Well, in truth, I’m posting this so I can find it again in a few months when I have forgotten it :smile:

The notes below pertain to an app that uses SYSTEM_MODE(SEMI_AUTOMATIC)
if you’re not using that: ignore.

Everything here was tested using a custom instrumented build of DeviceOS 1.3.0_alpha.1. If you’re using a different version of DeviceOS, expect something different!

Also, this is about a Boron that is supposed to be a gateway. Some of it probably applies to an Argon configured as a gateway as well. Some of it probably also applies to a pure mesh node. YMWV!

  1. if Cellular.connect() is called to bring up the cell connection and later Particle.connect() is called, the mesh is never enabled. That’s because Cellular.connect starts up networking but only enables the cell interface. Later, Particle.connect sees that networking is enabled and doesn’t bother to enable other interfaces. So, if you call XXX.connect() for some network, you have to call it also for the other networks you want enabled, don’t rely on Particle.connect. However, if you just call Particle.connect off the bat then all interfaces are enabled. That’s probably good in a way, but confusing/inconsistent.
  2. Mesh.connect() activates the Mesh connection if Particle.connect() didn’t
  3. Mesh.on() is a no-op. If you call Mesh.off() to save power, don’t call Mesh.on() to re-enable it. Call Mesh.connect() instead. Obvious, right?
  4. The border router functionality is not enabled until the cloud can be contacted to query for permission, this happens in the NetworkManager. So if your GW comes up and can’t talk to particle’s servers but can connect to the internet it will not turn on the gateway feature, hence other mesh nodes won’t be able to connect to internet servers. If you don’t like that you probably could set br_permitted to BorderRouterPermission::YES at line 124 of system/src/system_network_manager.cpp
  5. Do not base decisions on XX.connecting() because that returns true if any interface is connecting or up. For example, after calling Mesh.connect() you will see Cellular.connecting() returning true. I had code like
    if (!Mesh.connecting()) Mesh.connect()
    if (!Cellular.connecting()) Cellular.connect()
    and one of these connect calls never happened due to this “feature”.
  6. If you don’t call Particle.connect() your boron (or argon?) will not act as a border router (gateway). This means that connected mesh devices cannot talk to other servers on the Internet (or to Particle).

May your connections work! :slightly_smiling_face: :upside_down_face: :wink:

3 Likes

This wouldn't be the best thing to do even without the "issue" you mentioned.
The common way to do that would be something along the line of

  if (!Cellular.connected()) Cellular.connect();

(precautions to not call Cellular.connect() while a connction attempt is ongoing should be taken)

Mesh.connecting() should not interfere with Cellular.connected().
Nevertheless, crosstalk between Xxxx.connecting() calls can be considered a quirk - to say the least.

That's a funny reply ;-), your second sentence is saying exactly
if (!Cellular.connecting()) Cellular.connect()

If you call Particle.connect() every second while it's not yet connected it will never connect. I didn't try the same with Cellular.connect()...

IMHO the whole NetworkManager needs a thorough review and documentation. There are all kinds of assumptions built into it that I'm not thrilled by. I'm wondering whether I would save myself time overall by just rewriting it to keep all the network types apart.

Nope, I would rather go with a more mundane (but independent of device OS implementation) approach :wink:

Something like

  if (!Cellular.connected() && millis() - msLastConnect > 300000) {
    // cell connections are allowed to take up to 5 minutes!
    Cellular.connect();
    msLastConnect = millis();
 }

(no Cellular.connecting() to be seen here :wink: )