Skip to main content

Data Protocol

Note the following terminology used in this section:

  • packet: GATT-level byte data including packet headers
  • message: Payload data accumulated from one or more packets (not including packet headers)

This section will describe the data protocol used to send and receive BLE messages. The general procedure to parse a message is to:

  1. Accumulate and depacketize BLE packets to extract the message payload
  2. Decipher the message's ID and payload type
  3. Depending on the payload type, use the per-message documentation (identified by the message's ID) to parse the message
note

All byte ordering is in Big Endian unless otherwise noted.

Packetization​

The BLE protocol (<= v4.2) limits packet size to 20 bytes per packet. To accommodate this limitation, GoPro cameras use start and continuation packets to packetize larger payloads. If a message is less than 20 bytes, it can be sent with a single packet containing the start packet header. Otherwise, it must be split into multiple packets with the first packet containing a start packet header and subsequent packets containing continuation packet headers.

Packet Headers​

Message sending and receiving is accomplished by prepending General (5-bit), Extended (13-bit), Extended (16-bit), or Continuation headers onto each packet depending on the message size and state.

General (5-bit) Packets​

Messages that are 20 bytes or fewer can be sent or received using the following format:

Byte 0
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Start (0)General (00)5-bit Message Length

Extended (13-bit) Packets​

Messages that are 8191 bytes or fewer can be sent or received using the following format:

Byte 0Byte 1
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Start (0)13-bit Extended (01)13-bit Message Length
tip

Always use Extended (13-bit) packet headers when sending messages to avoid having to work with multiple packet header formats.

Extended (16-bit) Packets​

If a message is 8192 bytes or longer, the camera will respond using the format below.

Byte 0Byte 1Byte 2
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Start (0)16-bit Extended (10)Reserved16-bit Message Length
warning

This format can not be used for sending messages to the camera. It is only used to receive messages.

Continuation Packets​

When sending or receiving a message that is longer than 20 bytes, the message must be split into N packets with packet 1 containing a start packet header and packets 2..N containing a continuation packet header.

note

Counters start at 0x0 and reset after 0xF.

Byte 0
Bit 7Bit 6Bit 5Bit 4Bit 3Bit 2Bit 1Bit 0
Continuation (1)Reserved4-bit Counter

Decipher Message Payload Type​

Once the packets have been accumulated and the payload has been extracted, it is necessary to decipher the message type in order to determine whether it is TLV or Protobuf and then parse it appropriately.

Below is pseudocode describing how to do this:

Camera sends response message from UUID U (string) with payload P (array of bytes)
// Is it a Protobuf response?
for each row in the Protobuf IDs table {
F (int) = Feature ID
A (array of int) = Action IDs
if P[0] == F and P[1] in A {
P is a Protobuf Message
Match Feature ID P[0] and Action ID P[1] to a Protobuf message in the Protobuf IDs table
Use matched Protobuf message to parse byte payload into useful data structure
Exit
}
}
// Nope. It is a TLV response
if U == GP-0072 (Command) {
Parse message payload using Command Table with Command scheme
}
else if U == GP-0074 (Settings) {
Parse using Setting ID mapping with Command scheme
}
else if U == GP-0076 (Query) {
Parse message payload using Query Table with Query scheme
}

Alternatively this is described in flowchart form here:

Message Payload​

Once the payload has been extracted and had its type deciphered, it can then be parsed depending on its type. The Open GoPro protocol uses two different top-level message payload formats:

note

The byte table examples in this section do not contain the packet headers; they only consider the payload.

Type Length Value​

There are two different request / response Type-Length-Value (TLV) schemes as described in the following sections.

Commands​

Commands are messages sent / received on either:

They are summarized in the commands table and individually documented throughout the relevant feature section.

Command Request​

Below is the top level message format for command requests:

Type (Command / Setting ID)Optional Parameters
1 ByteArray of length-value pairs

where each element of the parameter array is:

LengthValue
1 ByteLength Bytes

The individual command documentation specified by the message's Command ID will define the length and value options for each of its parameters.

Command Response​

Below is the top level message format for command responses:

Type (Command / Setting ID)Command StatusOptional Response
1 Byte1 ByteVariable Length

where the possible Command Statuses are:

Command StatusDescription
0Success
1Error
2Invalid Parameter
3-255Reserved

The individual command documentation specified by the message's Command ID will define the response.

Queries​

Queries are messages sent / received on the Query and Query Response characteristics, respectively. They are summarized in the queries table and individually documented in Query.

Query Request​

Below is the top level message format for query requests:

Query IDArray of Element IDs
1 ByteVariable

The individual query documentation specified by the message's Query ID will define the elements that comprise the element ID array.

Query Response​

Below is the top level message format for query responses:

Query IDCommand StatusQuery Results
1 Byte1 ByteArray of id-length-value triplets

where each element of the results array is:

IDLengthValue
1 Byte1 byteLength Bytes

The individual query documentation specified by the message's Query ID will define the format of the result array.

Protobuf​

In order to maximize BLE bandwidth, some commands use Google Protobuf (Protocol Buffers). The Open GoPro API currently uses Protocol Buffers Version 2.

Protobuf requests and responses are identified by a Feature ID and an Action ID prepended before their serialized payload. The top level message format for a Protobuf message is as follows:

Feature IDAction IDSerialized Protobuf Message
1 Byte1 ByteVariable Length

The individual Protobuf object specified by the message's action / feature id is used to serialize / deserialize the payload.

Backwards Compatibility​

It is possible that some Protobuf message fields can be individually deprecated in which case they will be removed from the Message definition in the .proto file. The best solution to handle this is to use the newest .proto files.

Even when using the old .proto files there should be no problem serializing / deserializing. However, ensure to set the ignore_unknown_fields argument to True when relevant for Json-Protobuf conversion functions.