The Bemused Protocol v1.73

Introduction

This document describes the protocol which the Bemused client application for Symbian OS uses to communicate with the Bemused server application for Windows. Its intended audience is those who are interested in porting the Bemused server to other operating systems, or in extending or porting the Bemused client.

Transport

The Bemused protocol is designed to operate over Bluetooth; in particular, RFCOMM. RFCOMM provides a reliable, stream-based service which is exposed by Symbian OS as a socket. Most Windows Bluetooth stacks expose RFCOMM as one or more virtual serial ports which can be opened and used by applications as with any other serial port.

Service Discovery and Connection

All Bemused connections are initiated by the client, which runs on the phone. To determine which RFCOMM channel to connect to, the client performs an SDP inquiry, looking for Serial Port Profile records. Windows Bluetooth stacks with support for the Serial Port Profile will return an SDP record for each supported virtual serial port. Unfortunately, there is no way to distinguish between these serial ports. The client therefore always attempts to connect to the last serial port. On other operating systems, it may be possible or necessary for the server program to add new records to the Bluetooth service database.

Bemused protocol basics

The Bemused protocol is a simple command-response protocol. The client (on the phone) sends commands to the server (on the PC). However, for efficiency, not every command by the client generates a response from the server. A Bemused command is 4 ASCII bytes, and may be followed by variable-length arguments. The following commands are currently supported.
CommandArgumentsResponsePurpose
CHCKNoneSingle byte "Y"Checks that the server is running OK
DINFNoneDetailed info structureGets detailed information about the current song
DLSTFilename structureDirectory listingLists a specific directory
DOWNFilename structureFile structureDownloads the specified file
FADENoneNoneStops the current song by fading it out
FFWDNoneNoneFast-forwards by five seconds
FINFFilename structureFile info structureGets information about the specified file
GVOLNoneVolume structureGets the current volume, if supported
INFONoneSong info structureGets information from Winamp
INF2NoneSong info 2 structureGets information from Winamp, not waiting for a song to start
LADDFilename structureNoneAdds the specified file to the playlist
LISTNoneDirectory listingLists the entire directory tree
NEXTNoneNonePlays the next song in the playlist
PAUSNoneNonePauses the current song
PLAYFilename structureNonePlays the specified file
PLENNone2-byte playlist lengthWrites the length of the playlist to the phone
PLSTNonePlaylist structureWrites the current playlist to the phone
PREVNoneNonePlays the previous song in the playlist
REPT1 byte, 0 or 1NoneEnables or disables repeat mode
RMALNoneNoneRemoves all songs from the playlist
RWNDNoneNoneRewinds by five seconds
SHFL1 byte, 0 or 1NoneEnables or disables shuffle mode
SEEK4-byte positionNoneSeeks to a position in seconds in the current track
SHUTNoneNoneShuts down the PC
STENNoneNoneStops at the end of the current track
SLCT2-byte indexNoneSelects song at [index] in playlist
STOPNoneNoneStops the current song immediately
STRTNoneNoneStarts playing the current song
VOLM1 byteNoneSets the volume to the value specified
VERSNone1 byte major, 1 byte minor versionWrites the version of the server to the phone

Structures used in Bemused commands

The following structures are used by Bemused commands. Note that numeric values in structures are always in big-endian format (most significant byte first).
StructureFormat
Detailed infoBytes 0 to 6: "DINFACK"
Bytes 7 to 10: bit rate (in Kbps)
Bytes 11 to 14: sample rate (in KHz)
Bytes 15 to 18: number of channels
FilenameBytes 0 and 1: filename length (big-endian)
Bytes 2 onwards: filename without terminating NULL
File infoBytes 0 to 6: "FINFACK"
Bytes 7 to 10: file length (in bytes, big-endian)
FileBytes 0 to 6: "DOWNACK"
Bytes 7 onwards: downloaded file
PlaylistBytes 0 to 6: "PLSTACK"
Bytes 7/8: current playlist index
Bytes 9 onwards: all songs in playlist, separated by '\n'
Final byte: NULL
Song infoBytes 0 to 6: "INFOACK"
Byte 7: play state (bit 0 set = playing, bit 1 set = paused)
Bytes 8 to 11: song length (secs)
Bytes 12 to 15: current time (secs)
Byte 16: shuffle (0 = off, 1 = on)
Byte 17: repeat (0 = off, 1 = on)
Bytes 18 onwards: track name
Song info 2Bytes 0 to 6: "INFOACK"
Byte 7: play state (bit 0 set = playing, bit 1 set = paused)
Bytes 8 to 11: song length (secs)
Bytes 12 to 15: current time (secs)
Byte 16: shuffle (0 = off, 1 = on)
Byte 17: repeat (0 = off, 1 = on)
Bytes 18 onwards: track name
Final byte: NULL
VolumeIf getting the volume is supported:
Bytes 0 to 6: "GVOLACK"
Byte 7: volume (0-255)

If getting the volume is not supported:
Bytes 0 to 6: "GVOLNAK"

Structure of directory listings

Directory listings are the most complicated part of the Bemused protocol. A request from the phone for a directory listing generates a response which consists of the string "LISTACK" followed by a directory list structure. This structure is a compact representation of a tree. Essentially, a stream of "nodes" is sent, where each node encodes a filename, the file's type, and its relationship to the previously sent node. The last node sent is a dummy "terminator" node. The structure of a node is:
Byte 0, top 4 bitsThe type of the node. Possible values:
0x0: Root node
0x1: Child of previous node
0x2: Only child of previous node
0x3: Sibling of previous node
0x4: Last sibling of previous node
0xF: Dummy terminator node
Byte 0, bottom 4 bitsThe type of file represented by the node. Possible values:
0x0: Drive
0x1: Directory
0x2: File
0x3: Unexpanded directory
Bytes 1 onwardsThe file's name, followed by a NULL. Relative to the current directory.

So the first node has node type "root" and file type "directory" (usually). The filename of the root node is actually ignored by the client. The next node has node type "first child", and so on. The simplest way to understand the structure of a directory listing is to copy the "c:\system\apps\bemused\songlist.dat" file from the phone, and examine it in a hex editor.

The "unexpanded directory" file type is for handling the case where the user wants to list directories only when required. This allows directories to easily be grafted onto the current directory tree held on the phone.

Tips