PearlLib and Tools

Because Open Source is good Karma.

As described in the protocol overview, each message sent is of a specific type. The known types are documented below, along with their request/response formats and quirks.

The protocol messages documented here were found in one of two ways:

  1. They were captured by my network analyzer during my initial traces.
  2. They were found in the packetTypes.properties file in the Rio Media Manager Lite distribution.
  3. In the case of NAK and Busy, they were pointed out by the KarmaLib folks. (Note [2 Jan 2003]: I've now captured Busy messages in the wild and they're documented here, as well as some of the Write-related messages.)
The packets I haven't personally seen in the wild are noted but not fully documented, as I don't have the information yet. I'm currently working to elicit these packets using my fledgling protocol implementation.

Message Header

The part of the protocol that comes closest to being consistent is the message header. As mentioned above, each message begins with a 64-bit header, consisting of the protocol signature and the message type.

The protocol signature is always Hex 52 69 c5 8d.

The message type is specific to the type of message (yay tautologies!) and is a 32-bit little-endian integer. In the listing of types below, I've specified the message types as a sequence of four bytes in the order that the bytes are transmitted on the line.

The eight-byte sequence of (signature || message type) is abbreviated as "message header" in the descriptions below.

Protocol Version

Type:0 (Hex 00 00 00 00)
Request:
  1. message header
  2. Major version (uint32)
  3. Minor version (uint32)
Response:
  1. message header
  2. Major version (uint32)
  3. Minor version (uint32)
Authentication:Not Required

This message appears to be used to exchange protocol versions of both the Client and the Karma.The interpretation of the fields as "major" and "minor" versions is supported by the Karma's protocol type as reported by UPnP: "empeg-com:protocol2".

The Karma doesn't seem to actually do anything with this message. Sending "2.0" gets the same response as sending "232.232", and omitting the message entirely doesn't seem to hurt. I suppose, primarily, this exchange is for the benefit of the client software, not the Karma.

Example

(The requests and responses are identical.)
52 69 c5 8d  signature
00 00 00 00  message type (Protocol Version)
02 00 00 00  major version (2)
00 00 00 00  minor version (0)

NAK

Type:1 (Hex 01 00 00 00)

Progress

Type:2 (Hex 02 00 00 00)
Response:
  1. message header
  2. Progress (uint32)
  3. Goal (uint32)

This message is sent by the Karma to report progress on a lengthy task. In the case of my packet captures, RMML sends a Release Database Lock immediately after uploading new file info; the Karma sends Progress messages until it finishes updating the file info, and only then responds to the Release Database Lock message.

Example

Request (ONLY FOR EXAMPLE PURPOSES):
52 69 c5 8d  signature
0a 00 00 00  message type (Release Database Lock)
Response:
52 69 c5 8d  signature
02 00 00 00  message type (Progress)
00 00 00 00  current progress
20 00 00 00  goal

52 69 c5 8d  signature
02 00 00 00  message type (Progress)
01 00 00 00  current progress
20 00 00 00  goal
...
52 69 c5 8d  signature
02 00 00 00  message type (Progress)
20 00 00 00  current progress
20 00 00 00  goal

52 69 c5 8d  signature
0a 00 00 00  message type (Release Database Lock)
00 00 00 00  status (here, indicates success)

Get Salt

Type:3 (Hex 03 00 00 00)
Request:
  1. message header
Response:
  1. message header
  2. Salt (16 bytes)
Authentication:Not Required

This message asks the Karma for salt to use when hashing the user's password. (Salting the password prevents a block replay attack on the authentication exchange.)

The salt appears to be valid for only one Authenticate message. Each time a new password is attempted, a new salt must be retrieved. This is only logical.

Example

Request:
52 69 c5 8d  signature
03 00 00 00  message type (Get Salt)
Response:
52 69 c5 8d  signature
03 00 00 00  message type (Get Salt)
b1 ab 51 c0  \
de 16 fb 2e   | salt
ca c4 01 d4   |
80 fc 59 4a  /

Authenticate

Type:4 (Hex 04 00 00 00)
Request:
  1. message header
  2. Password hash (128 bits, 16 bytes)
Response:
  1. message header
  2. Status (uint32)
  3. Access Type (uint32)
Authentication:Not Required

This message should follow an Get Salt request, and provides the Karma with a salted hash of the user's password.

The Karma responds with a status value (zero or positive on success) and the type of access (0 for read, 1 [01 00 00 00] for write).

The type of access granted should be considered undefined if the status indicates failure.

The salted hash is simply the the MD5 of the sequence (salt || password) -- that is, the salt (16 bytes) followed by the password (1+ bytes). While the Karma does not appear to allow zero-length passwords, the RMML client sends one before actually requesting a password from the user.

Example

Request:
52 69 c5 8d  signature
04 00 00 00  message type (Authenticate)
30 97 c7 75  \
f7 52 d4 17   | salted password hash
8c bf 52 6b   |
79 0d 93 55  /
Response:
52 69 c5 8d  signature
04 00 00 00  message type (Authenticate)
5b 00 04 80  status (here, indicates failure.)
00 00 00 00  access type (0, read, but really undefined due to failure)

Get Device Info

Type:5 (Hex 05 00 00 00)
Request:
  1. message header
Response:
  1. message header
  2. Software name (null-term string, padded to 32 bytes)
  3. Software version (null-term string, padded to 32 bytes)
  4. Number of storage devices (uint32)
Authentication:Not Required

This message provides the most general information about the device. The name returned probably reflects the internal name of the system software; the version returned most certainly reflects the firmware version installed. The most useful aspect of this message (and the one piece of data not available anywhere else) is the number of storage devices.

Note that this message does not carry a status field.

Example

Request:
52 69 c5 8d  signature
05 00 00 00  message type (Get Device Info)
Response:
52 69 c5 8d  signature
05 00 00 00  message type (Get Device Info)
6f 6e 79 78 00 00 00 00 \
00 00 00 00 00 00 00 00  | device name (here, "onyx")
00 00 00 00 00 00 00 00  |
00 00 00 00 00 00 00 00 /
31 2e 32 35 00 00 00 00 \
00 00 00 00 00 00 00 00  | version (here, "1.25")
00 00 00 00 00 00 00 00  |
00 00 00 00 00 00 00 00 /
01 00 00 00  number of storage devices (here, 1)

Get Storage Device Info

Type:6 (Hex 06 00 00 00)
Request:
  1. message header
  2. Storage device number (uint32)
Response:
  1. message header
  2. Status (uint32)
  3. Number of files? (uint32)
  4. Total space in bytes (uint64)
  5. Free space in bytes (uint64)
  6. Highest file ID? (uint32)
Authentication:Not Required

This message retrieves information on one of the Karma's storage devices. Since the Karma only has one, the Storage Device Number in the request should always be zero.

Number Of Files and Highest File ID in the response are both marked with question marks, because I haven't been able to verify their use. (The Karma, as of firmware 1.25 and earlier, always sends zero in these fields.)

For me, the Karma takes about three to four seconds to respond to this command.

Example

Request:
52 69 c5 8d  signature
06 00 00 00  message type (Get Storage Device Info)
00 00 00 00  storage device number (for the Karma, always zero)
Response:
52 69 c5 8d  signature
06 00 00 00  message type (Get Storage Device Info)
00 00 00 00  status (here, indicates success)
00 00 00 00  number of files? (always zero)
00 a0 52 a3 04 00 00 00  total space in bytes
00 a0 c3 76 03 00 00 00  free space in bytes
00 00 00 00  highest file ID? (always zero)

Get Device Information

Type:7 (Hex 07 00 00 00)
Request:
  1. message header
Response:
  1. message header
  2. Status (uint32)
  3. Information (null-terminated text), Only present if Status is zero
Authentication:Not Required

This message retrieves detailed information from the Karma. See the Property File documentation.

Example

Request:
52 69 c5 8d  signature
07 00 00 00  message type (Get Device Information)
Response:
52 69 c5 8d  signature
07 00 00 00  message type (Get Device Information)
00 00 00 00  status (here, indicates success.)
63 61 70 ....null-terminated ASCII text.

Change Device Settings

Type:8 (Hex 08 00 00 00)

Get Database Lock

Type:9 (Hex 09 00 00 00)
Request:
  1. message header
  2. Type of lock desired (uint32)
Response:
  1. message header
  2. Status (uint32)
Authentication:Required

This message is used to obtain a lock on the Karma's file database. The lock can be for reading (type 0, hex 00 00 00 00) or for writing (type 1, hex 01 00 00 00).

The existence of two separate types of locks suggests that the Karma may support a many-reader, one-writer style of locking. I've verified that it supports multiple readers, at least.

Others have called this lock the "IO Lock;" the name "Database Lock" comes from the class names used within RMML and, I suspect, more accurately reflects its purpose.

Example

Request:
52 69 c5 8d  signature
09 00 00 00  message type (Get Database Lock)
00 00 00 00  lock type (0, read)
Response:
52 69 c5 8d  signature
09 00 00 00  message type (Get Database Lock)
5d 00 04 80  status (here, indicates failure.)

Release Database Lock

Type:10 (Hex 0a 00 00 00)
Request:
  1. message header
Response:
  1. message header
  2. Status (uint32)
Authentication:Required

This message releases a lock previously obtained with an Get Database Lock message. There's not much more to it than that.

Example

Request:
52 69 c5 8d  signature
0a 00 00 00  message type (Release Database Lock)
Response:
52 69 c5 8d  signature
0a 00 00 00  message type (Release Database Lock)
00 00 00 00  status (here, indicates success.)

Prepare

Type:11 (Hex 0b 00 00 00)

Write

Type:12 (Hex 0c 00 00 00)
Request:
  1. message header
  2. Offset into file (uint64)
  3. Size of chunk (uint64)
  4. File ID (uint32)
  5. Storage ID (uint32)
  6. Data chunk (length specified above, null-padded to four-byte boundary)
Response:
  1. message header
  2. Status (uint32)
Authentication:Required

Writes to a file on the device. This is used when uploading new files. It probably also allows existing files to be modified, but this is a very unusual case with music files, and one I'll have to force artificially to verify.

It's worth noting that I've seen this command take upwards of 4 seconds to complete, even after the upload has finished.

Example

Request:
52 69 c5 8d  signature
0c 00 00 00  message type (Write)
00 00 00 00 00 00 00 00  offset (in bytes)
00 40 00 00 00 00 00 00  size of chunk (16384 bytes)
a0 58 00 00  file ID
00 00 00 00  storage ID
49 44 33 ... binary data, null-padded to multiple of four bytes.
Response:
52 69 c5 8d  signature
0c 00 00 00  message type (Write)
00 00 00 00  status (here, indicates success.)

Get All File Information

Type:13 (Hex 0D 00 00 00)
Request:
  1. message header
Response:
  1. message header
  2. Status (uint32)
  3. Information (null-terminated text), Only present if Status is zero
Authentication:Required

This message retrieves all file metadata from the Karma. The files do not appear to be in any particular order, not even the order in which they were loaded onto the device. Information on each file is in key-value pairs; see the Property File documentatin.

Example

Request:
52 69 c5 8d  signature
0d 00 00 00  message type (Get All File Information)
Response:
52 69 c5 8d  signature
0d 00 00 00  message type (Get All File Information)
00 00 00 00  status (here, indicates success.)
61 72 74 ....null-terminated ASCII text.

Get File Info

Type:14 (Hex 0e 00 00 00)

Change File Info

Type:15 (Hex 0f 00 00 00)
Request:
  1. message header
  2. File ID (uint32)
  3. Properties file (null-terminated text)
Response:
  1. message header
  2. Status (uint32)
Authentication:Required

This message uploads new properties for a single file. The properties are in the same format returned by the Get File Info and Get All File Info messages; see the Property File documentation.

Example

Request:
52 69 c5 8d  signature
0f 00 00 00  message type (Change File Info)
80 46 00 00  file ID
64 75 72 ....null-terminated ASCII text.
Response:
52 69 c5 8d  signature
0f 00 00 00  message type (Change File Info)
00 00 00 00  status (here, indicates success.)

Read

Type:16 (Hex 10 00 00 00)

Delete

Type:17 (Hex 11 00 00 00)
Request:
  1. message header
  2. File ID (uint32)
Response:
  1. message header
  2. Status (uint32)
Authentication:Required

This message deletes a file by FID. It requires a write lock, logically enough.

Example

Request:
52 69 c5 8d  signature
11 00 00 00  message type (Delete)
80 46 00 00  file ID
Response:
52 69 c5 8d  signature
11 00 00 00  message type (Delete)
00 00 00 00  status (here, indicates success.)

Format

Type:18 (Hex 12 00 00 00)

Device Operation

Type:19 (Hex 13 00 00 00)

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.