# Benben Remote Protocol Version 1

All data is in little-endian.  Version 1 is subject to change prior to Benben
v0.6.0's release.

## Communication

Communication happens over a UNIX domain socket.  The default location of this
socket is `$XDG_DATA_HOME/benben/remote.sock`.  The socket **MUST** be created
by Benben (server side), will always be owned by the effective user/group that
started Benben, and have permissions of 0600.

The client initiates a connection, sends a request, the program responds, and
the connection is closed.

## Requests and Responses

A request uses the following format:

```
[8 bytes: Unix Timestamp]
[1 byte: opcode]
```

Request's timestamp must be within 2 seconds of the system's time.  Benben will
then issue a response in the following format:

```
[1 byte: response code]
[0..n bytes: response body, if any]
```

The response body (if present) is always in the following format:

```
[1 byte: response body type]
[n bytes: actual response body]
```

## Opcodes

```
0. Next
1. Previous
2. Toggle EQ
3. Toggle soft clipping
4. Toggle stereo enhancer
5. Toggle reverb
6. Toggle tag language
7. Volume up
8. Volume down
9. Toggle pause
10. Increase loops
11. Decrease loops
12. Exit
13. Stop after current
14. Toggle interpolation
15. Toggle chorus
16. Seek forward
17. Seek backward
18. Toggle repeat queue
100. Get current song title
101. Get current track number
102. Get total tracks
103. Get current track length in seconds
104. Get current track position in seconds
105. Get all information on all tracks (titles, lengths in seconds, etc.)
106. Get "stop after current" status
107. Get playback status (paused/playing...)
108. Get format
109. Get track artist (or format-specific info)
110. Get track album (or format-specific info)
111. Get track date (or format-specific info)
112. Get track genre (or format-specific info)
113. Get current loop
114. Get max loop
115. Get format number
200. Get program version
201. Get protocol version
255. reserved
```

## Response Codes

### General error

```
[1 byte]: The response code 0
[string]: Message, string data type.
```

### OK

```
[1 byte]: The response code 1
[varies]: Data for the response, if any, depending on the request's opcode.
```

### Bad opcode

```
[1 byte]: The response code 2
[string]: Message, string data type.
```

## Response Body Types

### 64-bit unsigned integer

```
[1 byte]: A data type of 0
[8 bytes]: The number
```

### 32-bit unsigned integer

```
[1 byte]: A data type of 1
[4 bytes]: The number
```

## 16-bit unsigned integer

```
[1 byte]: A data type of 2
[2 bytes]: The number
```

### 8-bit unsigned integer

```
[1 byte]: A data type of 3
[1 byte]: The number
```

### 64-bit signed integer

```
[1 byte]: A data type of 4
[8 bytes]: The number
```

### 32-bit signed integer

```
[1 byte]: A data type of 5
[4 bytes]: The number
```

### 16-bit signed integer

```
[1 byte]: A data type of 6
[2 bytes]: The number
```

### 8-bit signed integer

```
[1 byte]: A data type of 7
[1 byte]: The number
```

### Boolean

Booleans are encoded as an 8-bit unsigned integer; 1 = true, 0 = false.

```
[1 byte]: A data type of 8
[1 byte]: The value 1 or 0
```

### 32-bit IEEE float

These values are encoded as a 32-bit unsigned integer.

```
[1 byte]: A data type of 9
[4 bytes]: The number
```

### 64-bit IEEE float

These values are encoded as a 64-bit unsigned integer.

```
[1 byte]: A data type of 10
[8 bytes]: The number
```

### String

```
[1 byte]: A data type of 11
[2 bytes]: The length of the string data, in bytes.
[n bytes]: The string data, not null-terminated
```

### Unix Timestamp

This is encoded as a 64-bit signed integer.

```
[1 byte]: A data type of 12
[8 bytes]: The number
```

### Bytes

This data type is for raw data that is opcode-specific and does not fall into
any of the other data types.  In other words, it's a "block of bytes".  The
block **MUST** be 8 megabytes (8,388,608 bytes) or smaller in size.

If the size field of the message is larger than 8,388,608 bytes, then the
connection must be immediately terminated.

```
[1 byte]: A data type of 13
[4 bytes]: The size of the data block, in bytes.
[n bytes]: The data block.
```

### Tag information


```
[1 byte]: A data type of 14
[2 bytes]: The format number of the track.
[2 bytes]: The length of the string data, in bytes.
[n bytes]: The string data, not null-terminated.
```

### Time Span

This is encoded as a 64-bit unsigned integer.

```
[1 byte]: A data type of 15
[8 bytes]: The total number of milliseconds
```

### Playqueue Data

This is JSON data encoded as a string.  Note that this uses a different Data
Type than a String response.

```
[1 byte]: A data type of 16
[4 bytes]: The length of the raw JSON data as a string, in bytes.
[n bytes]: The raw JSON data as a string, not null-terminated
```

## Opcode Responses

### 0: Next
No response body.

### 1: Previous
No response body.

### 2: Toggle EQ
Returns a Boolean response body where `1` means "enabled" and `2` means
"disabled".

### 3: Toggle soft clipping
Returns a Boolean response body where `1` means "enabled" and `2` means
"disabled".

### 4: Toggle stereo enhancer
Returns a Boolean response body where `1` means "enabled" and `2` means
"disabled".

### 5: Toggle reverb
Returns a Boolean response body where `1` means "enabled" and `2` means
"disabled".

### 6: Toggle tag language
No response body.

### 7: Volume Up
Returns a Float32 response body containing the new volume value.

### 8: Volume Down
Returns a Float32 response body containing the new volume value.

### 9: Toggle Pause
Returns a Boolean response where `1` means "paused" and `2` means "unpaused".

### 10: Increase loops
Returns an Int32 response body containing the new loop value.  This value is
indexed from zero. 

### 11: Decrease loops
Returns an Int32 response body containing the new loop value.  This value is
indexed from zero. A value of `-1` means "loop forever".

### 12: Exit
No response body.

### 13: Toggle "stop after current"
Returns a Boolean response where `1` means "enabled" and `2` means "disabled".

### 14: Toggle interpolation
Returns a String response body describing the new interpolation mode.

### 15: Toggle chorus
Returns a Boolean response where `1` means "enabled" and `2` means "disabled".

### 16: Seek forward
No response body.

### 17: Seek backward
No response body.

### 18: Toggle repeat queue
Returns a Boolean response where `1` means the song queue will be repeated, and
`2` means it will not be repeated.

### 100: Get current track title
Returns a Tag response body where the string segment of it contains the current
track's title.

### 101: Get current track number
Returns an Int32 response body containing the current track's position in the
playback queue.

### 102: Get total tracks
Returns an UInt32 response body containing the total number of tracks in the
playback queue.

### 103: Get current track length in seconds
Returns a Time response body containing the length of the current track.

### 104: Get current track position in seconds
Returns a Time response body containing the current playback position of the
current track.

### 105: Get all information on all tracks (titles, length in seconds, etc.)
Returns Playqueue Data containing information on all tracks in the playback queue.

### 106: Get "stop after current" status
Returns a Boolean response where `1` means "enabled" and `2` means "disabled".


### 107: Get playback status (paused/playing...)
Returns a UInt8 response body where the value indicates the current playback
state.  This value is the same as the `PlayerState` enum defined in `common.cr`.
The values are:

```
0 - Paused
1 - Playing ("frame")
2 - Fading out
3 - Playing song tails
4 - Done playing
```

### 108: Get format string
Returns a String response body containing the format of the current track as a
string.

### 109: Get track artist (or format-specific info)
Returns a Tag response body where the string segment of it contains the current
track's artist.

### 110: Get track album (or format-specific info)
Returns a Tag response body where the string segment of it contains the current
track's album.

### 111: Get track date (or format-specific info)
Returns a Tag response body where the string segment of it contains the current
track's date.

### 112: Get track genre (or format-specific info)
Returns a Tag response body where the string segment of it contains the current
track's genre.

### 113: Get current loop
Returns a UInt32 response body containing the current loop counter for the
current track.  This value is indexed from zero.

### 114: Get max loops
Returns an Int32 response body containing the maximum number of times the
current track will play.  Returns `-1` if the track is looping indefinitely.

### 115: Get format number
Returns a UInt16 response body containing the format number of the current
track.  This value is the same as the `FileType` enum defined in `common.cr`.
The values are:

```
1 - VGM
2 - Module
3 - FLAC
4 - Opus
5 - Vorbis
6 - MPEG-1
7 - MIDI
8 - PCM
9 - QOA
10 - WavPack
11 - SID
65535 - Unknown
```

### 200: Get program version
Returns a String response body containing the remote Benben's name and version.

### 201: Get protocol version
Returns a UInt16 response body containing the protocol version that the remote
Benben supports.

### 255: reserved
No response, always produces a Bad Opcode response for now.
