PearlLib and Tools

Because Open Source is good Karma.

Pearl is the network protocol used by the Rio Karma digital audio player. Using Pearl, a computer can inventory the Karma's contents, upload or download files, and adjust device settings, all over the built-in Ethernet.

What's on your iPod? Is that drool?

(This page documents the Pearl protocol. If you're looking for PearlLib API docs, they are elsewhere.

Table of Contents

  1. Terms, Conventions, and Other Details
  2. Protocol Overview
  3. RMML Connection Sequence
  4. Throughput
  5. Known Status Codes
  6. Protocol Messages (separate page)
  7. Property File Format and Keys (separate page)

Terms, Conventions, and Other Details

Terms

The Rio Karma device being accessed is the Server.

The system accessing the Karma is the Client.

This is probably pretty intuitive, but I thought I'd better specify that just in case.

Hardware Used

The specific model of Rio Karma used in this exercise is Hardware Revision 4 using firmware v1.25. I'm not sure what the Hardware Revision actually indicates, but the device insists that it's "hwrev=0x4", so I'm humoring it.

I've been using a Unix system as the Client side of all exchanges, but my reference implementation is in Java, so with any luck this is irrelevant.

Protocol Overview

Pearl uses TCP port 8302 on the server (device) side. The protocol is a simple synchronous request-response system.

A word of warning to other reverse engineers: unlike the vast majority of modern network protocols, Pearl sends all multibyte data in little-endian format. For those of us used to "network byte order," this makes reading protocol traces a bit more interesting. Because network byte order is set so strongly in the minds of many of us network folk, I'll write all integers in this document as a sequence of hex bytes instead of 32-bit values.

Generally, a request is made up of a 32-bit protocol signature, a 32-bit command number, and a payload. For some requests, the payload is empty.

Likewise, a response generally consists of a 32-bit protocol signature, a 32-bit command number, a 32-bit status value, and a payload. Again, the payload is empty in some cases, particularly if the response indicates a failure or error.

All data I've seen thus far has been padded to a multiple of four bytes with trailing nulls. The KarmaLib folks have run into some odd issues where they receive excess data after a transmission; I've been unable to reproduce this but am watching for it.

Request/Response Structure

The first element in all messages is a protocol signature, 0x52 0x69 0xc5 0x8d. (Coincidentally, this is the brand name in UTF-8.) Next comes the command number (another 32-bit int), which determines the type of message. Generally, a response bears the same command number as the request to which it responds. (This is not true in some failure cases; I'll cover this in a bit.) In a response, a 32-bit status value usually follows the command number, depending on the command.

Next is the payload, which is some combination of 32 and 64-bit integers and arbitrary byte streams. The format of the payload is specified by each command; some commands have variable-length payloads, and each has its own way of indicating the payload length. (Ain't consistency great?)

The Karma will respond to a request in one of three ways:

  1. With a response matching the request's command number and carrying command-specific information;
  2. With a NAK response indicating that the command has been rejected;
  3. With a Busy response indicating that the device is otherwise occupied, and giving a progress estimation for the other task.

The details of the NAK and Busy responses will be described in the Protocol Messages section once it's completed. It's worth noting that I have yet to actually encounter a NAK or Busy command in the wild; I've only seen them referenced on the KarmaLib pages.

Connection Sequence

When a Client connects to the Karma, a specific sequence of requests and responses are exchanged. This particular sequence is performed by the RMML Java client, and is provided for illustration purposes.

  1. Protocol Version. (In the Java client, this actually happens twice.)
  2. Database Lock for Read -- denied by the Karma.
  3. Authentication Salt.
  4. Authentication request using an empty password. If the Karma has an empty password set, skip to step 7.
  5. Authentication Salt, again.
  6. Authentication request with a new token, for the actual password..
  7. Database Lock for Read.
  8. Device Info.
  9. Storage Info for storage device zero.
  10. All File Info.
  11. ...User actions within the program go here...
  12. Release Database Lock for read.
  13. The Client simply closes the TCP connection.

Throughput

After reading some discussion on the KarmaLib forums, I started wondering about throughput, both of my implementation and of the Karma itself.

File Metainfo from the Get All File Info message

Sending the file metadata seems to be capped at about 28kBps by the Karma itself -- it's not CPU-limited in my implementation and it's on 100mbps ethernet.

Known Status Codes

I've found the following status responses in the traces so far. The high bit appears to indicate failure. (Remember that the high bit is the MSB in the fourth byte.)

  • 00 00 00 00 - generic success
  • 5b 00 04 80 - password incorrect
  • 5e 00 04 80 - lock required
  • 5d 00 04 80 - authentication required
  • 5f 00 04 80 - password not yet set

Please read the disclaimer.

Links
About
What?
News
Check for updates and additions.
PearlLib
Downloads and docs for the Java library.
Tools
Karma Tools.
Documentation
The Pearl protocol dissected.
Author
More software from Cliff L. Biffle.
See Also
KarmaLib
Same goals; different code.
Rio Audio
Manufacturer of the Rio Karma.
Riovolution
Rio-owner community forums.