SABRE protocol v1.1

This codument covers the protocol (SABRE) for using a separate Android application for communication with crowd-sourced data exchange servers.

The following definitions are used in this document:

The following key considerations are assumed:

This document uses YAML representation for messages in examples for easier reading; however, in actual applications, the pure JSON must be used.

Handshake

In order to be discovered, all proxy apps must have package name starting with app.sabre., followed by a plugin name.

The host application

The handshake broadcast has following contents:

ACTION: app.sabre.HANDSHAKE
CONTENTS:
    protocol_version: 1
    response_action: "@action_discovery_response"

@package_name is the package name of the host application. The action of intent should look like app.sabre.<plugin_name>.HANDSHAKE.
protocol_version is an integer. 1 must be used for implementations in accordance with this document; this should be changed only on non-bachward-compatible protocol updates. This number must match the major version number in the heading of this document.
@action_discovery_response is generated by the host app and shows, which action should be used by the proxy app to send the response.

Once a proxy app receives a message from this channel, it must response with another broadcast message.

ACTION: @action_discovery_response
CONTENTS:
    id: "@proxy_id"
    name: "@proxy_name"
    version: "@proxy_version"
    supported_sources: [
        "id": @source_id
        "name": @source_name
    ],
    request_action: "@action_fetch_request"
    report_action: "@action_submit_report"
    confirm_action: "@action_confirm_report"
    discard_action: "@action_discard_report"
    shutdown_action: "@action_shutdown"
    alternative_startup_activity: "@activity_alternative_startup"

The proxy app shouldn’t assume the discovery broadcast will always be sent (e.g. the host app may cache the data), and must wake up on any incoming broadcast having the correct action.

Proxy shutdown

On newer Android version, requests has to be processed in a foreground service. It is a good practice for a host app to notify, when the proxy isn’t needed any more, so it can immediately shut down the service and, thus, remove the mandatory notification.

In order to notify the proxy that it can shut down the service, it should send an empty broadcast with action @action_shutdown.

The proxy app shouldn’t assume the shutdown broadcast will always be sent (e.g. the host app may crash), and must shutdown itself after several minutes of no incoming broadcasts.

Alternative startup method (new in SABRE v1.1)

Some devices have incorrectly configured firmware, blocking background apps from staring foreground service even on an explicit intent. For such cases host app may support and alternative method for waking up the proxy app. It is recommended to let user enabled the alternative startup manually, and have it disabled by default.

Alternative startup sequence:

Using the alternative startup flow allows the proxy app to start its foreground service while being displayed. This overcomes limitations of some firmwares. The downside of this flow is that the proxy application is temporarily displayed on the screen during the start-up.

Notes

Fetching alerts

Alerts fetching works using the request-response model. In order for the host app to fetch an alert, it sends a broadcast with the following contents:

ACTION: @action_fetch_request
CONTENTS:
    request_id: "@request_id"
    lat: @latitude
    lon: @longidute
    radius_m: @radius
    response_action: "@action_fetch_response"

The proxy app fetches the required data and sends the following respose back:

ACTION: @action_fetch_response
CONTENTS:
    request_id: "@request_id"
    error_message: "@error_message"
    response:
        n_batches: @n_batches
        batch_id: @batch_id
        alerts: [
            alert_source: "@alert_source"
            alert_id: @alert_id
            type: "@alert_type"
            lat: @latitude
            lon: @longitude
            heading_deg: @heading
            street_name: "@street_name"
            report_ts: "@report_ts"
            confirm_ts: "@confirm_ts"
            n_confirmations: "@n_confirmations",
            is_response_accepted: "@is_response_accepted",
            speed_limit: "@speed_limit",
        ]

Reporting alerts

Sending reports about new alerts

The following message is used to report an alert

ACTION: @action_submit_report
CONTENTS:
    lat: @latitude
    lon: @longitude
    heading_deg: @heading
    altitude_m: @altitude
    type: @alert_type
    is_opposite: @is_opposite
    time_delta_s: @time_delta

The send action expects no response (fire and forget). If the action has failed, the proxy app may notify the user by showing a toast message.

Confirming reports of other users

In order to confirm a report the following message should be sent

ACTION: @action_confirm_report
CONTENTS:
    lat: @latitude
    lon: @longitude
    alert_id: @alert_id

The confirm action expects no response (fire and forget). If the action has failed, the proxy app may choose to notify the user by showing a toast message.

Marking other reports as “not there”

In order to decline a report the following message should be sent

ACTION: @action_discard_report
CONTENTS:
    lat: @latitude
    lon: @longitude
    alert_id: @alert_id

The discard action expects no response (fire and forget). If the action has failed, the proxy app may notify the user by showing a toast message.