Gateway protocol
The gateway protocol is relatively simple and consists of a single RPC call to establish a bidirectional stream of messages:
service UserGatewayService {
rpc ControlStream(stream ControlStreamRequest) returns (stream ControlStreamResponse);
};
The control stream consists of a ControlStreamRequest
message that the gateway sends to Span:
message ControlStreamRequest {
oneof msg {
ConfigRequest config = 1;
UpstreamMessage upstream_message = 2;
Keepalive keepalive = 3;
GatewayMetadataUpdate gateway_metadata = 4;
DeviceUpdate device_update = 5;
};
};
Span will then respond with a ControlStreamResponse
message:
Control stream responses
message ControlStreamResponse {
oneof msg {
DeviceConfigUpdate device_update = 1;
GatewayConfigUpdate gateway_update = 2;
DeviceRemoved device_removed = 3;
DownstreamMessage downstream_message = 4;
KeepaliveResponse keepalive_response = 5;
};
};
Startup
When the gateway starts it should request a configuration update from Span via the ConfigRequest
message
New or changed gateway configuration. Span will then respond with two kinds of messages - a single GatewayConfigUpdate
message and zero or more DeviceConfigUpdate
messages, one for each device.
The GatewayConfigUpdate
message contains the updated gateway configuration. The tags
field is for informational purposes only and may be ignored by the gateway.
message GatewayConfigUpdate {
string gateway_id = 1;
map<string,string> config = 2;
map<string, string> tags = 3;
};
If a device is changed in Span (or the gateway sends a ConfigRequest
message) Span will send a DeviceConfigUpdate
message. This message is sent every time a device is created or updated:
message DeviceConfigUpdate {
string device_id = 1;
map<string, string> config = 2;
map<string, string> tags = 3;
};
As with the gateway configuration the tags
field is for informational purposes only.
If a device is removed in Span the DeviceRemoved
message is sent to the Gateway:
// This message is sent when a device is removed via the API
message DeviceRemoved {
string device_id = 1;
};
The configuraton settings are maps with strings of strings. The interpretation and semantics of the configuration settings is at the gateway’s discretion.
Passing messages
Upstream messages (messages sent from the devices to the gateway and then Span) is sent from the gateway with the UpstreamMessage
message object. The payload is an opaque byte buffer that is set via the usual Span API call. The metadata
field can be populated to set device metadata that will be visible via the Span API:
message UpstreamMessage {
string device_id = 1;
bytes payload = 2;
map<string,string> metadata = 3;
};
In a similar vein the downstream messages (messages that should be sent from the gateway to the devices) uses the DownstreamMessage
message object. The payload is an opaque byte buffer.
message DownstreamMessage {
string message_id = 1;
string device_id = 2;
bytes payload = 3;
};
Implementation notes
The connection might be dropped from time to time. The gateway may do periodic keepalive checks by sending a KeepaliveRequest
message to Span. Span will then respond with a KeepaliveResponse
message. If the connection is dropped the gateway should reconnect automatically. The gateway will always initiate the connection to Span so there’s no need to open firewall ports on the server that runs the gateway service.