SourceForge.net Logo

Pearl Protocol

General Info

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.

Things to remember:
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.


Common Data Elements

Header

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


Status Value

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


Protocol Commands

Get Protocol Version
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.


Get Authentication Salt
Identifier:3
Request:header
Response:header + salt (16 bytes)

This command requests salt to be used to hash the password for authentication


Authenticate
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.


Get Device Details
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)


Get Storage Details
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.


Get Device Settings
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.


Update Device Settings
Identifier:8
Request:header + properties file (null terminated and padded to a 4 byte boundary)
Response:header + status

This command updates the device settings.


Request IO Lock
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.


Release IO Lock
Identifier:10
Request:header
Response:header + status

This command releases any open IO locks on the device


Prepare
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.


Write File Chunk
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.


Get All File Details
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.


Get File Details
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.


Update File Details
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.


Read File Chunk
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.


Delete File
Identifier:17
Request:header + file id (uint32)
Response:header + status

This command deletes a file from the device


Format Storage
Identifier:18
Request:header + storage id (uint32)
Response:header + status

This command is defined in the protocol but not actually supported by the device.


Hangup
Identifier:19
Request:header
Response:header + status

Indicates to the device that the conversation is over.


Device Operation
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.


Abnormal Responses

NAK
Identifier:1
Response:header

This response is sent when the device rejects a command.


Busy
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.