Pearl Protocol
|
The protocol used to talk to the Rio Karma is called the "pearl"
protocol. The pearl protocol is a fairly simple one, but there is no official
public documentation of it, and all of the information in this document has been obtained by reverse engineering.
This means any of the information might be wrong, so let the implementor beware. The protocol uses
a simple, well-defined, request/response model. Typically a request will be made up of a header and a
payload, and the response will be a header, status value, and payload. There are a few exceptions and
inconsistencies, so please note carefully the appropriate data to send and receive for each command as
described below. All data sent and received is in little endian format.
All variable length data sent and received is padded with 0's to a 4 byte boundary.
There is only one storage device on the karma and its id is 0. Generally if the response status indicates failure, no payload is
sent. The response to any command may be a NAK or a Busy.
|
The header is made up of two 32 bit unsigned integers. The first integer is a "magic number" used to
prefix every command. It is actually the word Riō, in UTF-8. The second integer is the command identifier.
An example header for the Get Device Details command is: 0x52 0x69 0xC5 0x8D 0x05 0x00 0x00 0x00
|
The status value is a 32 bit signed integer. Failure is indicated by a negative number. Success is generally indicated
by a value of 0. The status value is made up of 4 different components as follows: Bits 31-30 are the severity
Bits 27-16 are the facility Bits 15-12 are the component Bits 11-0 are the result
|
Identifier: | 0 |
Request: | header + major version (uint32) + minor version (uint32) |
Response: | header + major version (uint32) + minor version (uint32) |
This command requests the protocol version from the device.
|
|
Identifier: | 3 |
Request: | header |
Response: | header + salt (16 bytes) |
This command requests salt to be used to hash the password for authentication
|
|
Identifier: | 4 |
Request: | header + authentication token |
Response: | header + status + access rights (uint32) |
This command requests authentication. The authentication token is created by calculating
an MD5 digest of the salt obtained by the Get Authentication Salt command concatenated with the password.
The response is a 32 bit unsigned integer representing the access priveleges granted. A value of 0 indicates read
access and a value of 1 indicates read/write access. Note that even if the status indicates failure, the
access rights must be read.
|
|
Identifier: | 5 |
Request: | header |
Response: | header + name (32 bytes) + version (32 bytes) + number of storage devices (uint32) |
This command requests information about the device. The response (not including header)
is 68 bytes comprised of the following: 32 byte name (null terminated string) 32 byte version
(null terminated string) 32 bit unsigned int representing the number of storage devices (always 0)
|
|
Identifier: | 6 |
Request: | header + storage id (uint32) |
Response: | header + status + number of files (uint32) + storage size (uint64) + free space (uint64) + highest file id (uint32) |
This command requests information about the specified storage device. Note that currently
the number of files and the max file id values are always 0. Perhaps they will be implemented later.
|
|
Identifier: | 7 |
Request: | header |
Response: | header + status + properties file (null terminated and padded to 4 byte boundary) |
This command requests the device settings. They are returned as a properties file (aka ini file).
The properties file is null terminated and is padded with 0's to a 4 byte boundary.
|
|
Identifier: | 8 |
Request: | header + properties file (null terminated and padded to a 4 byte boundary) |
Response: | header + status |
This command updates the device settings.
|
|
Identifier: | 9 |
Request: | header + lock type (uint32) |
Response: | header + status |
This command requests an IO lock on the device. The lock type passed
in the request is simply 0 for read and 1 for write.
|
|
Identifier: | 10 |
Request: | header |
Response: | header + status |
This command releases any open IO locks on the device
|
|
Identifier: | 11 |
Request: | header + size (uint64) + file id (uint32) + storage id (uint32) |
Response: | header + file id (uint32) + status |
This command is defined in the protocol but not actually supported by the device.
|
|
Identifier: | 12 |
Request: | header + offset (uint64) + size (uint64) + file id (uint32) + storage id (uint32) +
data chunk (padded to a 4 byte boundary) |
Response: | header + status |
This command writes a chunk of data to a file on the device.
|
|
Identifier: | 13 |
Request: | header |
Response: | header + status+ set of properties files (null terminated and padded to a 4 byte boundary) |
This command retrieves the entire database of files on the device. The
response is a set of properties files, each separated by a new line. The entire set of data is null terminated
and padded with 0's to a 4 byte boundary.
|
|
Identifier: | 14 |
Request: | header + file id (uint32) |
Response: | header + status + properties file (null terminated and padded to a 4 byte boundary) |
This command retrieves the file information for a single file on the
device. The response is a properties file which is null terminated and padded with 0's to a 4 byte boundary.
|
|
Identifier: | 15 |
Request: | header + properties file (null terminated and padded to a 4 byte boundary) |
Response: | header + status |
This command updates the file information for a single file on the
device. The request payload is a properties file which is null terminated and padded with 0's to a 4 byte boundary.
|
|
Identifier: | 16 |
Request: | header + offset (uint64) + size (uint64) + file id (uint32) |
Response: | header + size (uint64) + status + data chunk (padded to a 4 byte boundary) + status |
This command reads a chunk of data from a file on the device. This is one
of the few commands which returns data before the status. It also returns a second status after
the data chunk.
|
|
Identifier: | 17 |
Request: | header + file id (uint32) |
Response: | header + status |
This command deletes a file from the device
|
|
Identifier: | 18 |
Request: | header + storage id (uint32) |
Response: | header + status |
This command is defined in the protocol but not actually supported by the device.
|
|
Identifier: | 19 |
Request: | header |
Response: | header + status |
Indicates to the device that the conversation is over.
|
|
Identifier: | 20 |
Request: | header + size (uint64) + data chunk (padded to 4 byte boundary) |
Response: | header + size (uint64) + status + data chunk (padded to 4 byte boundary) |
This command is defined in the protocol but not actually supported by the device.
|
|
Identifier: | 1 |
Response: | header |
This response is sent when the device rejects a command.
|
|
Identifier: | 2 |
Response: | header + step (uint32) + number of steps (uint32) |
This response is sent when the device is still busy executing a previous command. It
is basically a progress report. The busy responses must be read until the expected response for the new command is received.
|
|