Garmin Protocol¶
There are (at least) two big families of garmin protocol: both are using BLE. The first protocol uses different characteristics to transfer different type of information and appears to be in use on older wearables: the aforementioned contribution made Gadgetbridge support this version of the protocol.
A newer protocol uses the same characteristics for every information transfer, by encapsulating this in "threads" (or handles, or conversations) whose identifiers are prepended to each message exchange. This version of the protocol is currently unsupported.
A third version of the protocol was also reported (see issue #3063) that apparently adds some kind of sequence between the thread/handle/conversation ID and the actual payload, while using the same characteristic.
The difference between the first protocol and the rest can be detected early by the presence of the specific characteristic used in newer protocols. The second and the third protocol might probably be chosen according to some early handshake values and the way some identifiers are chosen by the watch, so it should be possible to support all three generations of the protocols with relatively little effort.
Protocol description¶
The following is a description of the protocol used by the Garmin Forerunner 245 (firmware version 13.00) and the Garmin Connect Android application version 4.66. This can be used as a basis for reimplementation, possibly in addition to package captures, application logs, and experiments involving unspecified input sequences.
Bluetooth LE service¶
The table below was retrieved using bettercap
. The protocol described in this document
is termed Multi-Link / ML and is exposed using the service
6A4E2800-667B-11E3-949A-0800200C9A66. It comprised an unknown characteristic
2803 as well as three pairs of characteristics, each implementing a read and a
write queue. Writing to any of the three characteristics 2820, 2821, 2822 will
elicit a reply in the respective readable characteristic 2810, 2811, or 2812.
Writing to any of the latter will produce a reply on the same characteristic.
Some devices like the vivosmart 5 only have the first 2 pairs ( issue #3269). Other newer devices like the Venu 3 have 2 extra pairs (2823/2813, 2824/2814).
Handles | Service > Characteristics | Properties | Data |
---|---|---|---|
0001 -> 0009 | Generic Access (1800) | ||
0003 | - Device Name (2a00) | READ | Forerunner 245 |
0005 | - Appearance (2a01) | READ | Watch: Sports Watch |
0007 | - Peripheral Preferred Connection Parameters (2a04) | READ | Connection Interval: 24 -> 36 |
Slave Latency: 0 | |||
Connection Supervision Timeout Multiplier: 400 | |||
0009 | - 2aa6 | READ | 00 |
000a -> 000d | Generic Attribute (1801) | ||
000c | - Service Changed (2a05) | INDICATE | |
000e -> 0013 | 6a4e8022667b11e3949a0800200c9a66 | ||
0010 | - 6a4e4c80667b11e3949a0800200c9a66 | WRITE | |
0012 | - 6a4ecd28667b11e3949a0800200c9a66 | READ, NOTIFY | |
0014 -> 0025 | 6a4e2800667b11e3949a0800200c9a66 | ||
0016 | - 6a4e2803667b11e3949a0800200c9a66 | READ, WRITE | 00Ã’5y |
0018 | - 6a4e2810667b11e3949a0800200c9a66 | READ, WRITE, NOTIFY | 0800020a058813©130103Ëm00 |
001b | - 6a4e2820667b11e3949a0800200c9a66 | WRITE | |
001d | - 6a4e2811667b11e3949a0800200c9a66 | READ, WRITE, NOTIFY | |
0020 | - 6a4e2821667b11e3949a0800200c9a66 | WRITE | |
0022 | - 6a4e2812667b11e3949a0800200c9a66 | READ, WRITE, NOTIFY | |
0025 | - 6a4e2822667b11e3949a0800200c9a66 | WRITE | |
0026 -> 0029 | Heart Rate (180d) | ||
0028 | - Heart Rate Measurement (2a37) | NOTIFY | |
002a -> 002f | Running Speed and Cadence (1814) | ||
002c | - RSC Feature (2a54) | READ | 0000 |
002e | - RSC Measurement (2a53) | NOTIFY |
Multi-Link Protocol¶
The Multi-Link protocol (MultiLink, ML) acts as a multiplexer of services.
Newer watches support a variant called Multi-Link reliable (MLR).
Services include GFDI (Garmin Fit Data
Interface ? -- just guessing) as implemented by older watches, e.g. the
Vivomove HR, registration (query device information), and various real-time
information that were previously handled using dedicated characteristics. They
are identified by a short
value, see [services]. Furthermore, a 8-byte value
client_uuid
is used by the application. The Garmin Connect application is
configured to use 0x01
. ML
consists of two components: handle management
(service registration, closing handles) and transportation via chunking,
encoding, and prefixing of a handle.
Handle management¶
Handle management consists of messages with minimum length 2 starting with
0x00
. No other messages start with 0x00
, as they are prefixed using a
non-zero handle byte. The second byte indicates the message type, which in turn
determines the message length. The byte encoding is little-endian.
Byte | Description |
---|---|
0x00
| Register ML/MLR service request |
0x01
| Register ML/MLR service response |
0x02
| Close handle request |
0x03
| Close handle response |
0x04
| Unknown handle response |
0x05
| Close all handles request |
0x06
| Close all handles response |
0x07
| Unknown request |
0x08
| Unknown response |
0xff
| Protocol error response |
General format¶
00 ?? ???????????????? ???? ...
- message type byte, see above
- client_uuid, 8 bytes
- service, 2 bytes
- 0-4 message-dependent bytes
client_uuid
and service
values from the respective request.
Register ML/MLR service request¶
Before using any service, it must be registered to a handle.
0000 ???????????????? ???? ??
- client_uuid, 8 byte
- service, 2 byte
- 00: request not reliable (ML)
- 02: request reliable (MLR)
Example:
0000 0100000000000000 0400 00
client_uuid = 0x01
service = 0x04 (REGISTRATION)
request_reliable = 0x00 (use ML instead of MLR)
Register ML/MLR service response¶
Registering an already connected service will return SUCCESS
using the same handle if the client_uuid
is the same. Doing the same using a different client_uuid
will result in an ALREADY_IN_USE
reply, indcating a characteristic that might allow registering said service instead.
0001 ???????????????? 0400 00 ...
- client_uuid, 8 byte
- service, 2 byte
- status
- 0x00: SUCCESS
- 0x01: INVALID_SERVICE_ID (or request message too short)
- 0x02: PENDING_AUTH
- 0x03: ALREADY_IN_USE
- 0x04: REJECTED
Known messages formats:
0x00 ?? [?? [??]]
- handle
- reliable (byte)
- 0x00: ML (default)
- > 0x00: MLR
- REGISTRATION as ML service (byte)
- 0x00: legacy characteristic
- & 0x01: use ML service
0x00 ?? 00 01 (registered as unreliable)
- handle (byte)
0x00 ?? 01 00 (registered as reliable)
- handle (byte)
0x01 (invalid service id)
0x03 ?? ?? (service registerd by another client_uuid)
- free char uuid
Examples:
0001 0100000000000000 0400 00 01 00 01
- SUCCESS, handle=0x01, reliable=False, mlService=True
0001 0100000000000000 0600 03 12 28
- ALREADY_IN_USE by 6a4e2812-667b-11e3-949a-0800200c9a66
0001 0100000000000000 0400 00 09 00
- SUCCESS, reliable=False, mlService=False (use dedicated registration characteristic)
0001 0100000000000000 0400 00 2e 00 01
- SUCCESS, handle=0x2e, reliable=False, mlService=True
0001 0100000000000000 0400 00 68 00 01
- SUCCESS, handle=0x68, reliable=False, mlService=True
0000 0100000000000001 0400 00 04 01 01
- SUCCESS, handle=0x04, reliable=True, mlService=True
0001 0100000000400000 0400 03 10 28
status = 0x03 ALREADY_IN_USE
occupied by char 6a4e2810-667b-11e3-949a-0800200c9a66
0001 0100000000500000 0300 01
status = 0x01, INVALID_SERVICE_ID (HEALTH_SDK not supported or request message invalid)
0001 0100000000000000 0100 00 86 01 00
status = 0x00, handle=0x86, reliable=True. Last byte does not seem to be relevant.
Close handle request¶
0002 ???????????????? ???? ??
- client_uuid
- service (short)
- handle
Example:
0002 0100000000000000 0600 35
client_uuid = 0x01
service = 6
handle = 0x35
Close handle response¶
0003 ???????????????? ???? ?? ??
- client_uuid
- service (short)
- handle (byte)
- status
- 00: SUCCESS
- 01: INVALID_HANDLE
- 02: NO_CONNECTION
Example:
0003 0100000000000000 0600 35 00
client_uuid: 0x01
service: 6
handle: 0x35
status: SUCCESS
0003 0100000000000000 0600 35 02
Unknown handle response¶
This message can be expected when the watch receives a message with an unregistered handle. I haven't observed the structure.
Close all handles request¶
0005 ???????????????? ????
- client_uuid
- flags? unused
Example:
0005 0100000000000000 0000
client_uuid = 0x01
Close all handles response¶
0006 ???????????????? ???? ??
- flags from request
- status, unused
0006 0100000000000000 0000 01
client_uuid = 0x01
status = 0x01, unused
Unknown request¶
Unknown response¶
Invalid request response¶
Services¶
ID | Service |
---|---|
1 | GFDI
|
2 | NFC
|
3 | HEALTH_SDK
|
4 | REGISTRATION
|
5 | CONNEXT
|
6 | REAL_TIME_HR
|
7 | REAL_TIME_STEPS
|
8 | REAL_TIME_CALORIES
|
9 | REAL_TIME_FLOORS
|
10 | REAL_TIME_INTENSITY
|
11 | REAL_TIME_DUMMY
|
12 | REAL_TIME_HRV
|
13 | REAL_TIME_STRESS
|
14 | AUTH_STATUS
|
15 | ECHO
|
16 | REAL_TIME_ACCELEROMETER
|
17 | REAL_TIME_SPAM
|
18 | REAL_TIME_BMX_RAW
|
19 | REAL_TIME_SPO2
|
20 | REAL_TIME_BODY_BATTERY
|
21 | REAL_TIME_RESPIRATION
|
22 | KEEP_ALIVE
|
26 | REAL_TIME_ACTIVE_TIME
|
For example, the Garmin Forerunner 245 (firmware version 13.00) supports
services 1, 4, 6, 7, 8, 10, 12, 13, 16, 19, 20, 21, 22
, which correspond to
GFDI, REGISTRATION,
REAL_TIME_{HR,STEPS,CALORIES,INTENSITY,HRV,STRESS,ACCELEROMETER,SPO2,BODY_BATTERY,RESPIRATION},
KEEP_ALIVE
.
Registration service¶
The registration service exposes information on the supported services (e.g. GFDI, REAL_TIME_*
), version information, and other yet to be idenfied information.
Requests are performed using by sending a single byte via to the registration characteristic or two bytes (ML handle plus single byte) to the REGISTRATION service.
Byte | Name | Description |
---|---|---|
0x00
| SUPPORTED_PROTOCOLS
| List supported protocols, aka supportedServiceIds |
0x01
| ADVERTISING_DATA
| Referenced as advertisingServiceData, e.g. 0, 19, 64 , read byte-wise. Unknown purpose
|
0x02
| MULTI_LINK_VERSION
| Referenced as MultiLinkVersion, e.g. 2.2.1
|
0x03
| PRODUCT_NUMBER
| Product number, firmware version, unit id |
0x04
| IDENTITY_ADDRESS
| Haven't seen this one being used yet |
The unit id is used when communicating to Garmin's servers and probably identifies the device uniquely.
Examples, assuming handle 0x32
:
> 3200 # request available multi-link service
< 3200 d23579 # available multilink services [1, 4, 6, 7, 8, 10, 12, 13, 16, 19, 20, 21, 22]
# 0b 1101 0010 0011 0101 0111 1001
00 0 0 11 1 0 222 1 1
76 4 1 32 0 8 210 9 6
> 3201
< 3201 00 13 40 # advertisingServiceData=[0, 19, 64]
> 3202
< 3202 01 02 02 # MultiLinkVersion(major=2, minor=2, micro=1)
> 3203
< 3203 040c 1405 deadbeef # productNumber=3076 firmwareVersion=1300 unitId=4022250974
> 3204
< 3204 ???????????????????????????????? # identityAddress, 16 bytes
GFDI¶
GFDI has been described by [1]. Messages are COBS-encoded by splitting them into chunks (split at each zero byte, remove zero byte prefix using resulting chunk length plus one. The maximum chunk length is 254. Chunks of length 254 are encoded by adding a 0xff
byte. Chunks with size greater than 253 increase the encoded message length by at least 1.
Request messages consist of a two-byte length field, a two-byte message type field that can include a 5-bit sequence number, a message-dependent part, as well as a two-byte CRC value (Crc16, e.g. crc-16
from python-crcmod
).
???? ???? ............ ????
- length, including this length field and the CRC
- message type, possibly a sequence number
- message type-specific contents
- CRC
If the fourth byte has its most-significant bit set, i.e. req[3] & 0x80
, then this byte's five least significant bits encode a sequence number req[3] & 0x1f
and the encoded message type is encoded using the third byte, i.e. 5000 + req[2]
. This scheme allows correlating GFDI requests and responses. The sequence number is usually increased by one with every request sent and wraps around to 0 after reaching 31.
Examples:
0900 08 98 280110 d7f5
- length: 9 bytes
- message type: 8 + 5000 = 5008 (Set File Flags request)
- flags
- 0x80: use single-byte encoding for message type
- 0x18: sequence number
- data
- CRC
1e00 b413 .... a6ec
- length: 30 bytes
- message type: 5044
- data
- CRC
1e00 2c 85 .... a6dd
- length: 30 bytes
- message type: 5044
- flags
- 0x80: use single-byte encoding for message type
- 0x05: sequence number
Unlike GFDI requests, GFDI responses are not acknowledged. Their message type is 5000. The encoding of this message type depends on the corresponding request's scheme: if the req[3] & 0x80
bit was set, theresponse's message type will be encoded in the third byte and the fourth byte will be contain the sequence number from the corresponding request. Otherwise both bytes will be used to encode the message type 5000. The corresponding request's message type is always encoded using two bytes, followed by a status byte.
???? 1388 ???? ?? ......... ????
- length
- message type: 5000 (response)
- original message type in two-byte format
- status
- 0x00: ACK
- 0x01: NAK
- 0x02: UNKNOWN_OR_NOT_SUPPORTED
- 0x03: COBS_DECODER_ERROR
- 0x04: CRC_ERROR
- 0x05: LENGTH_ERROR
???? 00?? ???? ?? ......... ????
- length
- message type: 5000 minus 5000 = 0
- 0x80 flag set plus sequence number of the original request
- original message type in two-byte format
- status
- 0x00: ACK
- 0x01: NAK
- 0x02: UNKNOWN_OR_NOT_SUPPORTED
- 0x03: COBS_DECODER_ERROR
- 0x04: CRC_ERROR
- 0x05: LENGTH_ERROR
Example:
0d00 0096 9013 00 00c50010 31b1
- length: 13
- message type: 5000
- sequence number: 0x16
- corresponding request's message type: 5008
- status: ACK
- data
- crc
ML service transport¶
ML services use the same characteristic(s) as the ML control protocol. All service-related communication is prefixed by the service's handle byte, as indicated in the /register service response/. The maximum message length is 20.
Handle management¶
Services are registered to single-byte handles by the ML
protocol. Establishing a connection typically looks like this:
- Pick characteristic, try registering information service until succeeds
- Query services and other information using REGISTRATION protocol
- Register
GFDI
and optionallyKEEP_ALIVE
- Optionally, unregister
REGISTRATION
Multi-Link Reliable Protocol¶
When requested upon service registration and supported by a device, Multi-Link Reliable (MLR) will be used instead of ML. Instead of prefixing each data chunk with a single byte encoding a handle, two bytes are used to encode a handle (0x00-0x07
), a request number (0x00-0x3f
), and a sequence number (0x00-0x3f
). The request number and sequence number are derived from an added stateful component, which allows ignoring out-of-order transmissions, correct handling of retransmission, sporadic acknowledgement of received sequences, and dynamically adjusted timeout and budgets involving non-acknowledged sequences. In the following, m % n
is used to denote the least positive residue. Request numbers and sequence numbers wrap around after reaching 0x3f
. This may not always be explicitly stated in this section.
Chunking works similarly to ML: given a maximum packet size, a complete message (e.g. a GFDI message) is chunked into fragments of at most max_packet_size - 2
bytes, where only the message's last fragment is at most max_packet_size - 2
bytes long. Sending messages involves adding the entire message to the connection's message queue and kicking of a protocol runner. When receiving messages, fragments are extracted, and sporadically acknowledged. Received fragments are immediately passed to the regular data handler, provided they don't appear to be out-of-sequence.
Message format¶
MLR messages use the following format.
1HHHRRRR RRSSSSSS DDDDDDDD ....
- Always set for MLR
- Handle
- request number / req_num: used to acknowledge all messages with sequence number < req_num (take care of wrapping)
- sequence number / seq_num: usually incremented by one, unless a retransmission takes place. Always zero in case there is no data
- Data fragment
The sequence number is usually incremented by one, for each packet sent, wrapping around after 0x3f
. Receiving messages does not influence the sequence number of packets to be sent. Delayed or not received acknowledgements cause a retransmission of all packets since the last acknowledged packet.
The request number implements the acknowledgement / ACK feature. Each party keeps track of the expected sequence number of the next packet. Packets with mismatching sequence numbers are dropped and will eventually be retransmitted. This ensures in-order processing of packets.
State initialisation¶
Each party initialises their state upon successful service registration.
Short name | Value | Range | Description |
---|---|---|---|
max_packet_size
| 20
| MTU, must fixed during lifetime of the registered connection | |
handle
| 0x80, ..., 0x87
| Determined by other party | |
next_send_seq
| 0x00
| 0x00, ... 0x3f
| Next sequence number |
next_rcv_seq
| 0x00
| 0x00, ... 0x3f
| Next expected sequence number for received packets |
last_acked_seq
| 0x00
| 0x00, ... 0x3f
| Last ACK'ed sequence number |
num_unacked_rcvd
| 0x00
| 0x00, ...
| Number of received packets that haven't been ack'ed |
max_num_unacked_send
| 0x20
| 0x01, ... 0x3f
| Maximum number of sequences sent pending unacknowledgement |
retransmission_timeout
| 1000
| [500, 20000]
| Dynamically adjusted retransmission timeout |
next_send_seq_before_retransmission
| 0xff
| 0x00, ..., 0x3f, 0xff
| Stores next_send_seq in case it is decremented due to retransmissions
|
message_queue
| []
| Message queue | |
first_message_ack_byte_offset
| 0
| Offset describing byte offset of the first message in message_queue covered by ACK'ed packets
| |
send_times[0x40]
| Required to estimate the round trip time |
Acknowledgement¶
Receiving in-sequence transmissions usually increases the tracked next_rcv_seq
by one, wrapping around at after 0x3f
. Acknowledgements happens automatically when sending messages, as their request number coincides with next_rcv_seq
, acknowledging all packets received with sequence number <= (next_rcv_seq - 1) % 0x40
. Having received at least five packets in-sequence should trigger a timely acknowledgement. Independently of this, acknowledgement should happen shortly after a packet is received, e.g. ~10-20 ms. last_acked_seq
is updated accordingly when receiving an ACK
. The retransmission timer is stopped. If after receiving the ACK
there are still outstanding acknowledgments, i.e.g last_acked_seq != next_send_seq
, the retransmission timer is restarted with the current retransmission_timeout
. Messages are removed from the queue and considered fully sent in terms of application logic once an ACK of the last fragment was received.
Retransmission¶
When the retransmission timeout expires, the current next_send_seq
is stored in next_send_seq_before_retransmission
given that next_send_seq
is larger than next_send_seq_before_retransmission
(considering wrap-arounds) or next_send_seq_before_retransmission
is 0xff
, indicating that it is unset. Independently the retransmission timeout is doubled (ceiled at 20 s) and the max_num_unacked_send
is halfed if the result is at least 1. The regular protocol run routine is then executed.
Protocol running¶
Fragments are only sent if the number of outstanding acknowledgements (next_send_seq - last_acked_seq) % 0x40 < max_num_unacked_send
. Otherwise, an ACK may be sent instead of required by a timer or if num_unacked_rcvd >= 5
.
Messages and fragments within messages are sent in-order, unless retransmissions "rewind" the sequence number. Sending a fragment requires identification of the correct message and the correct fragment according to the sequence number. The packet to be sent will contain next_send_seq
before it is incremented by one, as well as next_rcv_seq
.
Receiving¶
When receiving an MLR packet, the handle, request number, sequence number, and any additional data bytes are read from the packet. ML messages are handed directly over to the appropriate processing routine. If the packet's request number does not coincide with last_acked_seq
, it is first processed as an ACK. If the number of packet's being acknowledged (req_num - last_acked_seq) % 0x40
is then compared to the number of unacknowleged packets that require retransmission that have not been acknowledged (next_send_seq - last_acked_seq) % 0x40
. If it is larger and (no packets are being retransmitted (next_send_seq_before_retransmission == 0xff
) or the number of packets currenly being acknowledged exceeds the number of unacknowledged packets being retransmitted (next_send_seq_before_retransmission - last_acked_seq) % 0x40
, processing proceeds as usual. Otherwise another retransmission is initiated by setting next_send_seq
to the received packet's request number.
Missing Topics¶
Under certain conditions receiving an ACK should trigger a recomputation of the retransmission timeout and an increase of num_unacked_rcvd
by one. Details on this and possibly a revision of the above description will happen at a later time.
Relevant GFDI messages¶
5007 Directory Filter¶
This message does not seem to do anything on the Forerunner 245 or Venu 3.
5008 Set File Flags¶
This request allows archiving files. Confirmation whether this deletes files or changes their file index is missing.
???? ??
- file index, uint16, little endian
- flags
- 0x04: CRYPTO (unobserved, untested)
- 0x08: APPEND (unobserved, untested)
- 0x10: ARCHIVE
- 0x20: ERASE (seen in directory listing)
- 0x40: WRITE (seen in directory listing)
- 0x80: READ (seen in directory listing)
Examples:
# Request: archive file
c600 10
- file index: 0x00c6
- flags: archive (0x10)
# Full GFDI Response: only the ACK part seems to be relevant
0d00 0096 9013 00 00 c500 10 31b1
- length
- message type = 5000 (0 + 5000 due to flags)
- flags: 0x8: add 5000 to message type
- 0x16: GFDI message sequence number for referencing
- response to 5008
- ACK
- Unknown, status?
- File index-related. Perhaps the file got a new file index?
- flags
- crc
# Full GFDI Request: archive file
0900 0898 2801 10 d7f5
- 0x18: GFDI message sequence number
- file index: 0x0128
- flags: archive file
- crc
# Full GFDI Response
0d00 0098 9013 00 00 2701 10 119b
- 0x18: GFDI message sequence number
- ACK
- Unknown, status?
- File index-related. Original file index minus one?
- flags: archive file
- crc
Added GNCS services¶
This section describes a subset of previously undocumented GNCS protobuf-related services relevant for the Garmin Forerunner 245.
gdi_data_types
¶
Enums:
GPSFixType = {FORCE_NO_SOLUTION=1, NO_SOLUTION, DEAD_RECKONING, TWO_D, THREE_D, TWO_D_DIFFERENTIAL, THREE_D_DIFFERENTIAL}
Languages = {UNKNOWN=0, AFRIKAANS, ALBANIAN, ARABIC, ARMENIAN, AZERBAIJANI, BASQUE, BELARUSIAN, BENGALI, BOSNIAN, BULGARIAN, CATALAN, CHINESE_SIMPLIFIED, CHINESE_TRADITIONAL_HONG_KONG, CHINESE_TRADITIONAL_TAIWAN, CROATIAN, CZECH, DANISH, DUTCH, ENGLISH_UK, ENGLISH_US, ESPERANTO, ESTONIAN, FAROESE, FILIPINO, FINNISH, FRENCH_CANADA, FRENCH_FRANCE, FRISIAN, GALICIAN, GEORGIAN, GERMAN, GREEK, HEBREW, HINDI, HUNGARIAN, ICELANDIC, INDONESIAN, IRISH, ITALIAN, JAPANESE, KHMER, KOREAN, KURDISH, LATIN, LATVIAN, LITHUANIAN, MACEDONIAN, MALAY, MALAYALAM, NEPALI, NORWEGIAN_BOKMAL, NORWEGIAN_NYNORSK, PASHTO, PERSIAN, POLISH, PORTUGUESE_BRAZIL, PORTUGUESE_PORTUGAL, PUNJABI, ROMANIAN, RUSSIAN, SERBIAN, SLOVAK, SLOVENIAN, SPANISH, SPANISH_SPAIN, SWAHILI, SWEDISH, TAMIL, TELUGU, THAI, TURKISH, UKRAINIAN, VIETNAMESE, WELSH, ENGLISH_AUSTRALIA}
CoordinateSystem = {WGS84=0, GCJ02}
CompassDirection = {NORTH=0, NORTH_NORTHEAST, NORTHEAST, EAST_NORTHEAST, EAST, EAST_SOUTHEAST, SOUTHEAST, SOUTH_SOUTHEAST, SOUTH, SOUTH_SOUTHWEST, SOUTHWEST, WEST_SOUTHWEST, WEST, WEST_NORTHWEST, NORTHWEST, NORTH_NORTHWEST}
ScPoint¶
Field number | Optional | Message type | Field name | Default |
---|---|---|---|---|
1 | [ ] | sint32
| lat
| |
2 | [ ] | sint32
| lon
|
UUID¶
Field number | Optional | Message type | Field name | Default |
---|---|---|---|---|
1 | [ ] | fixed64
| most_significant
| |
2 | [ ] | fixed64
| least_significant
|
Locale¶
Field number | Optional | Message type | Field name | Default |
---|---|---|---|---|
1 | [ ] | uint32
| id
| |
2 | [ ] | uint32
| size
|
DataTransferItem¶
Field number | Optional | Message type | Field name | Default |
---|---|---|---|---|
1 | [ ] | uint32
| id
| |
2 | [ ] | uint32
| size
|
GPS CPE updates¶
GPS CPE updates are requested by the watch using the ConnectIQHTTPService.RawResourceRequest
, requesting the URL [https://api.gcs.garmin.com/ephemeris/cpe/sony/lle?coverage=WEEKS_1&constellations=GPS,GLONASS,GALILEO,QZSS]. Most headers are not necessary; for requests the header accept
is sufficient. For caching if-none-match
can be sent as well. The relevant response headers are content-type, content-length, date
, and possibly etag
for caching purposes. After the phone has download the requested file, it will send a ConnectIQHTTPService.RawResourceResponse
with the received status code and possibly filtered headers to the watch. If use_data_xfer
was set in the RawResourceRequest
, the phone will create a transferId (data_xfer_id
, possibly sequential starting at 0) to provide in addition to the file's length to the watch. Otherwise it will send the data directly using the resource_data
field. In case of the former the watch will initiate a series of DataTransferService.DataDownloadRequest
messages with various offsets and the provided data_xfer_id
to receive fragments via a series of DataTransferService.DataDownloadResponse
messages.