Physical protocols

class pygarmin.link.P000

Bases: object

Physical layer for communicating with Garmin.

Bases: P000

Protocol to communicate over a serial link.

The port is opened on object creation.

The port value is a device name depending on operating system, e.g. /dev/ttyUSB0 on GNU/Linux, /dev/cu.serial on macOS or COM1 on Windows.

Support for the Garmin USB-serial protocol on GNU/Linux needs the garmin_gps kernel module which is part of the official kernels since version 2.6.11.

escape(data)

Escape any DLE characters, aka “DLE stuffing”.

If any byte in the Size, Data, or Checksum fields is equal to DLE, then a second DLE is inserted immediately following the byte. This extra DLE is not included in the size or checksum calculation. This procedure allows the DLE character to be used to delimit the boundaries of a packet.

unescape(data)

Unescape any DLE characters, aka “DLE unstuffing”.

checksum(data)

The checksum value contains the two’s complement of the modulo 256 sum of all bytes in the data. Taking a two’s complement of a number converts it to binary, flips 1 bits to 0 bits and 0 bits to 1 bits, and adds one to it.

unpack(buffer)

All data is transferred in byte-oriented packets. A packet contains a three-byte header (DLE, ID, and Size), followed by a variable number of data bytes, followed by a three-byte trailer (Checksum, DLE, and ETX).

pack(pid, data)

All data is transferred in byte-oriented packets. A packet contains a three-byte header (DLE, ID, and Size), followed by a variable number of data bytes, followed by a three-byte trailer (Checksum, DLE, and ETX).

Serial Packet Format

Byte Number

Byte Description

Notes

0

Data Link Escape

ASCII DLE character (16 decimal)

1

Packet ID

identifies the type of packet

2

Size of Packet Data

number of bytes of packet data (bytes 3 to n-4)

3 to n-4

Packet Data

0 to 255 bytes

n-3

Checksum

2’s complement of the sum of all bytes from byte 1 to byte n-4

n-2

Data Link Escape

ASCII DLE character (16 decimal)

n-1

End of Text

ASCII ETX character (3 decimal)

read()

Read one packet from the buffer.

send_packet(pid, data, acknowledge=True)

Send a packet.

read_ack(pid)

Read a ACK/NAK packet.

If an ACK packet is received the packet was received correctly and communication may continue. If a NAK packet is received, the data packet was not received correctly and should be sent again.

send_ack(pid)

Send an ACK packet.

send_nak()

Send a NAK packet.

NAKs are used only to indicate errors in the communications link, not errors in any higher-layer protocol.

close()

Close the serial port.

Bases: P000

Implementation of the Garmin USB protocol.

Support for the Garmin USB protocol needs libusb 1.0 and probably removing and blacklisting the garmin_gps kernel module. It will talk to the first Garmin GPS device it finds.

property dev

Return the Garmin device.

This property will cause some USB traffic the first time it is accessed and cache the resulting value for future use.

property cfg

Configure the Garmin device and return the current configuration.

This property will cause some USB traffic the first time it is accessed and cache the resulting value for future use.

property intf

Return the current interface configuration.

This property will cause some USB traffic the first time it is accessed and cache the resulting value for future use.

property ep_in

Return the Interrupt IN instance.

This property will cause some USB traffic the first time it is accessed and cache the resulting value for future use.

property ep_out

Return the Bulk OUT instance.

This property will cause some USB traffic the first time it is accessed and cache the resulting value for future use.

unpack(buffer)

Unpack a raw USB packet.

pack(layer, pid, data=None)

Pack an USB packet.

USB Packet Format:

Byte Number

Byte Description

Notes

0

Packet Type

USB Protocol Layer = 0, Application Layer = 20

1-3

Reserved

must be set to 0

4-5

Packet ID

6-7

Reserved

must be set to 0

8-11

Data size

12+

Data

read()

Read buffer.

write(buffer)

Write buffer.

read_packet()

Read a packet.

send_packet(pid, data)

Send a packet.

send_start_session_packet()

Send a Start Session packet.

The Start Session packet must be sent by the host to begin transferring packets over USB. It must also be sent anytime the host deliberately stops transferring packets continuously over USB and wishes to begin again. No data is associated with this packet.

Start Session Packet

N

Direction

Packet ID

Packet Data Type

0

Host to Device

pid_start_session

n/a

read_session_started_packet()

Read Start Session packet.

The Session Started packet indicates that transfers can take place to and from the device. The host should ignore any packets it receives before receiving this packet. The data returned with this packet is the device’s unit ID. We ignore this, because it is retrieved elsewhere as well.

Session Started Packet

N

Direction

Packet ID

Packet Data Type

0

Device to Host

pid_session_started

uint32

start_session()

Start USB session and return the unit ID.