device-os icon indicating copy to clipboard operation
device-os copied to clipboard

Notify the cloud about keepalive interval changes

Open sergeuz opened this issue 5 years ago • 0 comments

Problem

User applications can change the keepalive interval of the cloud connection via the Particle.keepAlive() method. The interval can also be changed by the system depending on the cellular provider and/or the type of the external connectivity used by the gateway device in a mesh network.

At present, the cloud has no means to determine the keepalive interval set on a particular device, and this affects the ability of the cloud to track the online status of the device accurately.

Solution

Publish a special private event (particle/device/keepalive) containing the actual value of the keepalive interval every time the interval changes.

Steps to Test

Flash the example application to a device. Subscribe to the device's events and verify that keepalive events get published when the keepalive interval is changed.

Note: The cloud-side handler for the keepalive events is not yet implemented, so this test requires running a local instance of the device service, which has particle/device/keepalive added to the list of known internal events.

Example App

#include "application.h"

SYSTEM_MODE(MANUAL);

namespace {

int cloudStatus = cloud_status_disconnected;
bool done = false;

void cloudStatusChanged(system_event_t event, int param) {
    cloudStatus = param;
}

void waitCloudStatus(int status) {
    while (cloudStatus != status) {
        Particle.process();
    }
}

} // unnamed

void setup() {
    System.on(cloud_status, cloudStatusChanged);
}

void loop() {
    if (done) {
        return;
    }

    // The default keepalive interval should be published after the protocol handshake
    Particle.connect();
    waitCloudStatus(cloud_status_connected);
    delay(1000);

    // This should generate a new keepalive event
    Particle.keepAlive(10);

    // This should not generate a new event, since the interval has not changed
    Particle.keepAlive(10);

    // Disconnect from the cloud
    delay(1000);
    Particle.disconnect();
    waitCloudStatus(cloud_status_disconnected);

    // Set the interval before establishing a connection to the cloud. The interval should be
    // published after the protocol handshake
    Particle.keepAlive(20);
    Particle.connect();
    waitCloudStatus(cloud_status_connected);

    // Disconnect from the cloud
    delay(1000);
    Particle.disconnect();
    waitCloudStatus(cloud_status_disconnected);

    // Set the interval while the handshake is in progress. Two events should be published during
    // the handshake. Note: At present, the events may be delivered in the wrong order
    Particle.connect();
    waitCloudStatus(cloud_status_connecting);
    // Run one more iteration of the system loop to let the system start the handshake
    Particle.process();
    Particle.keepAlive(30);

    // Disconnect from the cloud
    delay(1000);
    Particle.disconnect();
    waitCloudStatus(cloud_status_disconnected);

    done = true;
}

sergeuz avatar Sep 06 '19 15:09 sergeuz